Commit graph

735 commits

Author SHA1 Message Date
Erik
9a84230c4f feat(runtime): Campaign CC slice CC3 — RuntimeCharacterCreationState
Ports retail's CharGenState as the one Runtime-owned character-creation
state machine, mirroring RuntimeCharacterSelectionState's exact pattern
(snapshot/delta/event-stream, borrow-only view, generation-gated
commands, one mutable owner, no App types). Every command ports a named
retail function: SetHeritageGroup, SetGender, SetTemplate/ApplyTemplate
(Custom = template 0, Olthoi force-lock), the six attribute setters plus
GetAbsRemainingCredits/BalanceAttributes (retail's literal round-robin
order and fairness cursor), SetSkillLevel plus ResetSkillLevels' free-skill
baseline (reusing CC1's ChargenSkillCreditMath two-tier cost lookup
verbatim), RandomizeStartArea, and DoFinish's complete gate sequence
(empty name / unspent attribute credits / already-Pending / client-side
roster-vs-slotCount cap).

LiveSessionController gained a sibling IRuntimeCharacterCreationCommands
implementation, a CreateCharacter wire hook, and a response handler that
reuses existing machinery rather than inventing new paths: the Ok
identity is appended to the roster via RuntimeCharacterSelectionState's
own ApplyRoster, and the "log straight in" behavior reuses the private
EnterSelectedCore. ILiveSessionLifecycleHost gained two default-no-op
hooks (ApplyCharacterCreated/ApplyCreationFailed) so AcDream.App needs
zero changes to keep compiling; wiring them to the status stream is a
CC4 follow-up.

Filed four divergence-register rows for the corners deliberately not
ported: the FPU-unrecoverable FitTemplateToCharacter auto-detect (AP-207,
ACE only reads the field for title text), the per-style color-count
approximation (AP-208, CC1's model has no per-style palette data), the
classID DAT-DID placeholder (AP-209, ACE ignores the field), and
ApplyTemplate's atomic-vs-sequential attribute apply (AP-210).

34 new tests: full state-machine coverage (every Finish gate, every
rejection-code mapping, duplicate-NameInUse tolerance, Olthoi lock,
attribute balance/lock interaction, uncostable-skill rejection) plus a
LiveSessionController integration suite proving the wire send is exactly
55 skill slots (decoded from a real WorldSession + GameMessageCapture)
and the full Ok/rejection round trip through WorldSession.ProcessDatagram.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 14:26:10 +02:00
Erik
f3ef7baae2 docs+fix(chargen): CC1/CC2 review closeout — R2/R3 residuals closed, ledger final
Both narrow re-reviews returned CLOSED. This closeout takes the two cheap
re-review residuals before CC3 takes references to the shared model:

R2: every array handed into the typed chargen model is now wrapped in
Array.AsReadOnly at the projection seam — a T[] behind IReadOnlyList<T>
was still downcast-mutable, and ChargenOptions is a process-shared
singleton graph.

R3: the no-Chorizite-leak guard now also walks public fields; every
current type uses properties, but a public field would have slipped
through the property-only walk.

Ledger: CC1 fix-round sha corrected to cb4703e8 (the cell previously
cited the pre-amend 459a87f2), CC1/CC2 rows flipped to REVIEW-CLOSED
with the re-review outcomes, R1 (retail refunds +1 credit on a
both-tier cost miss; port charges 0 — unreachable via retail's own
listbox, noted for CC3) and the Olthoi-locked-to-template-0 decomp fact
recorded for CC3/CC4.

Core.Tests 4736/1 skip, Content.Tests 145/0, Release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 13:41:37 +02:00
Erik
55fc51ed8c Merge campaign-cc2: CC2 CharacterCreate wire, review-closed
CC2 review PASS (checksum term set confirmed against the CG_Pack
accumulator; account-outside-body and GetPackSize=172 independently
proven), fix round e77ebf10 (F1 latch scope + pin test, AD-100, ACE
double-NameInUse note, creationFailed reason/name split, pointer fix,
retail-discriminator citations), narrow re-review CLOSED, residual
anchor fix 95e95bb6.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 13:39:08 +02:00
Erik
cb4703e8d5 fix(chargen): CC1 review fix round — Custom is template 0, SkillTable cost fallback, frozen model
Implements all six Opus review findings against 04450041 (Campaign CC
CC1 chargen data layer):

- F1 (HIGH, blocking): ChargenTemplate's doc claimed "Custom" has no
  ChargenTemplate entry and cited two nonexistent addresses. Verified
  against the named retail decomp: gmCGProfessionPage::UpdateProfession
  @ 0x004821b0 resolves BOTH the highlighted button and the description
  string from CharGenState.template_ 0..6, and case 0 is button
  0x100003d9 / ID_CharGen_CustomText. Custom IS template index 0 (the
  "Adventurer" row CC1 already found sitting at the attribute floor).
  CharGenState::SetTemplate @ 0x005C5A60 confirms every button (including
  Custom) calls CharGenState::ApplyTemplate @ 0x005C5080 when committing,
  so selecting Custom resets the sliders/skills to that row rather than
  leaving them untouched.

- F2 (MEDIUM): retail's skill-cost lookup is two-tiered
  (ACCharGenData::GetSkillTrainedCost/GetSkillSpecializedCost @
  0x005C26D0/0x005C27D0 fall through to the global SkillTable,
  portal.dat 0x0E000004, on a heritage-list miss — confirmed against
  ACE's identical PlayerFactory.cs precedence). ChargenTableReader now
  also projects the global SkillTable into
  ChargenOptions.GlobalSkillCostsBySkillId, and
  ChargenSkillCreditMath.ComputeSpent/RemainingCredits check the
  heritage list first and the global list on a miss. Added an
  installed-DAT completeness assertion recording reality: the global
  table prices 38/54 advancement skill ids, every one of the 13
  installed heritages ships exactly one heritage-specific override
  (always also priced globally), and 16 ids are genuinely uncostable in
  both tiers. Also filed a CC7 risk-item note: ACE's own heritage-
  override branch over-deducts on Specialize (PlayerFactory.cs:184-211)
  — a retail-legal build may be rejected by local ACE at the CC7
  connected gate; that is an ACE bug, not an acdream defect.

- F3 (MEDIUM): every collection ChargenTableReader hands into the
  record model is now frozen at projection (ToFrozenDictionary/ToArray,
  matching MagicCatalog's house pattern), including both
  ChargenOptions.Empty dictionaries.

- F4 (LOW): added a reflection guard test
  (ChargenNoChoriziteLeakTests) that walks every public
  AcDream.Core.CharGen member (property/indexer/constructor/method
  types, recursively through generic arguments) and fails if any
  resolves to the DatReaderWriter or a Chorizite* assembly.

- F5 (LOW): ChargenGenderOptions.HasAnyAppearanceOptions's doc now
  states precisely what the installed-DAT gate proves (an OR across
  eight lists, for at least one gender per heritage) rather than the
  stronger claim it previously made, and explicitly calls out the three
  omitted color lists. Added a second installed-DAT gate that records
  per-list reality across every gender of every heritage — found
  complete, no empty lists anywhere in the installed DAT today.

- F6 (LOW): ChargenOptions.TryGetHeritage/TryGetStarterArea now use
  [MaybeNullWhen(false)] instead of null! suppression, matching the
  house pattern already used elsewhere in the test suite. Fixed every
  call site this surfaced (more than the five originally estimated,
  since Content.Tests has TreatWarningsAsErrors).

Core.Tests: 4737 passed / 1 skip (pre-existing, unrelated).
Content.Tests: 145 passed / 0 skip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 13:33:37 +02:00
Erik
e77ebf100f CC2 review fix round: latch scope narrowed, AD-100, creationFailed reason key
F1 (MEDIUM): the correlation-latch docs claimed replies are never
misattributed; in truth an overlapping send OVERWRITES the latch and the
first reply routes to the newest request's event. Narrowed all three doc
sites to the exact contract (single outstanding request; overlap refusal
is CC3's Runtime verification gate, retail's DoFinish UNDEF-state rule)
and pinned the overwrite behavior with
OverlappingSend_OverwritesTheLatch_ReplyRoutesToNewestRequest.

F2 (LOW): filed register AD-100 for the drop-unless-armed deviation —
retail's Handle_CharGenVerificationResponse@0x0055E8B0 has no armed gate
and processes whatever arrives against its persistent verification state.

F3 (LOW): doc note in CharacterCreate.cs — ACE double-sends NameInUse
(IsCharacterNameAvailable runs twice; the first callback's return exits
only the lambda), so the second reply hitting the drop path during a
connected gate is EXPECTED, not a defect.

F4 (LOW): creationFailed's enum-member key renamed name -> reason and the
ATTEMPTED character name added as name, before any consumer shipped —
one status vocabulary must not give the same key two meanings
(characterCreated.name is a character name). Contract, writer, tailer,
and shape-pinning tests updated in lockstep.

F5 (LOW): the thread-id probe-note pointer now cites
ProbeNetLogOutbound's doc comment, where the note actually lives.

Fidelity fold (reviewer's positive note): the latch is retail's OWN
discriminator one layer down — 0x0055E8B0 case 1 branches on
GetVerificationState()==PENDING (create) vs not (restore) — now cited in
both the latch doc and CharGenVerificationResponse.cs.

Core.Net 994, Runtime 1667, Launcher.Core 324, all green Release.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 13:10:24 +02:00
Erik
70d52b0da2 docs: Campaign CC ledger — CC1 and CC2 implemented, reviews in flight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 12:54:39 +02:00
Erik
5eaad2c88c feat(net,runtime): Campaign CC CC2 — CharacterCreate wire, 0xF643 correlation, creation status events
Wire (Core.Net):
- CharacterCreate.cs: outbound 0xF656 builder, byte-exact port of
  Proto_UI::SendCharGenResult@0x00546a70 -> ACCharGenResult::Pack@0x005c7570
  -> CG_Pack@0x005c7200. Account String16L first (packed outside CG_Pack),
  then the constant-1 u32, heritage/gender, 14 appearance strip/style/color
  u32s, 6 f64 shades (skin/hair/headgear/shirt/trousers/footwear, retail
  order), template, 6 attributes, slot, classId, numSkills + exactly 55
  u32 skill-advancement classes (ReadOnlySpan validated ==55, throws
  ArgumentException otherwise — ACE terminates the session on any other
  count via PlayerFactory.CreateResult.ClientServerSkillsMismatch), name
  String16L, startArea, isAdmin, isEnvoy, and a trailing checksum whose
  exact 19-term accumulation set (heritage+gender+3 strips+hairColor+
  eyeColor+hairStyle+headgearStyle+shirtStyle+trousersStyle+footwearStyle+
  template+6 attributes) is read byte-for-byte off CG_Pack's decompiled
  accumulator (0x005c7213-0x005c74c3) — headgearColor/shirtColor/
  trousersColor/footwearColor/shades/slot/classId are deliberately absent
  from the sum despite sitting adjacent on the wire. Cross-checked against
  ACE's CharacterCreateInfo.Unpack/Appearance.Unpack and holtburger's
  CharacterCreateRequestData (types.rs:236-369), which agree on every
  field and order. Retail routes via SendToLogon — the same queue
  CharacterDelete already uses.
- CharGenVerificationResponse.cs (new): promotes the shared 0xF643 parse
  out of CharacterRestore — full Code enum (Undef..AdminPrivilegeDenied=7,
  ACE's CharacterGenerationVerificationResponse) plus the conditional
  Ok-only identity payload (guid/String16L name/u32 secondsGreyedOut).
  CharacterRestore.Parse now delegates to it; CharacterRestore's public
  Parsed shape, Parse signature, and every existing test expectation are
  UNCHANGED.
- PacketWriter.WriteDouble: f64 little-endian helper for the shade fields.

WorldSession dispatch (Core.Net):
- Added an awaiting-request latch (None/Restore/Create), armed by
  SendRestoreCharacter/the new SendCharacterCreation immediately before
  each send (SendCharacterCreation builds the body first so a skill-count
  throw never arms the latch for a request that was never sent), cleared
  the instant a matching 0xF643 is dispatched (success OR parse failure —
  a malformed reply must never wedge the latch open) and on Dispose.
  0xF643 now routes to CharacterRestoreReceived or the new
  CharacterCreateResponseReceived (Action<CharGenVerificationResponse.Parsed>)
  by that latch; an unexpected 0xF643 with nothing outstanding logs once
  and is dropped, never misattributed. Fixed
  WorldSessionCharacterSelectionTests' restore-dispatch test, which
  previously fed a bare CharacterRestore response with no preceding
  SendRestoreCharacter — that shape is now the "no outstanding request"
  drop path by design.

Status events (Runtime + Launcher.Core, contract first):
- Amended docs/plans/2026-08-14-launcher-campaign.md §LA1's pinned status
  vocabulary to add characterCreated{guid,name} (Ok reply identity, named
  to mirror CharGenVerificationResponse's own fields and to read distinct
  from enteredWorld — retail logs a freshly created character straight in
  without a fresh characterList) and creationFailed{code,name} (raw Code
  value + its enum member name).
- SessionStatusWriter.CharacterCreated/CreationFailed implement that
  contract.
- Launcher.Core: CharacterCreatedStatusEvent/CreationFailedStatusEvent +
  StatusEventParser cases, in lockstep.

Tests: CharacterCreateTests (byte-exact layout incl. checksum term-set,
55-slot fixture, wrong-count throws), CharGenVerificationResponseTests
(every Code value), WorldSessionCharacterCreationTests (create-then-
response routes correctly, restore unaffected, no-outstanding drop,
second-response-after-consumed drop, Dispose clears the latch, a builder
throw never arms it), SessionStatusWriterTests + Launcher.Core
StatusEventParserTests/StatusFileTailerTests (pinned shape + tailer
round-trip) for the two new events.

Verified: dotnet build AcDream.slnx -c Release — 0 errors. Full solution
test run green (Core.Net.Tests 993/993, Runtime.Tests 1667/1667,
Launcher.Core.Tests 323/323, plus every other project in the solution).
WSL Ubuntu: Core.Net.Tests 993/993, Runtime.Tests 1667/1667.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 12:49:52 +02:00
Erik
c3a8c231b8 docs: Campaign LA gate round 2 REVIEW-CLOSED — batch review + fix round + re-review complete
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 12:30:59 +02:00
Erik
ee80138fba docs: Campaign CC plan — retail character creation, slices CC1-CC7
Recon-grounded (three parallel sweeps 2026-08-15): full retail flow
(gmCharGenMainUI mode 0x1000000b, six ECGProgress pages with every widget
id), byte-exact 0xF656 layout incl. the trailing checksum ACE never reads,
0xF643 create semantics (local roster append + retail logs straight in; no
fresh CharacterList), the chargen DAT table shape, the preview rig
(gmCG3DView over CreatureMode - Appearance/Summary pages only), and every
acdream seam to reuse (generic layout resolver, fixed canvas, offscreen
viewport pipeline, RuntimeCharacterSelectionState as the J-owner template,
the 0xF643 correlation landmine). Slice order CC1 data / CC2 wire (parallel)
then CC3 Runtime owner, CC4/CC5 form pages, CC6a/b appearance+preview
staged, CC7 end-to-end + user gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 12:28:33 +02:00
Erik
36c14902a8 docs: Campaign LA gate round 2 — char-select matrix USER-PASSED
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 12:07:04 +02:00
Erik
936077d576 docs: Campaign LA gate round 2 record — retail-UI product default + JPEG background decode
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 09:13:45 +02:00
Erik
981e168fb9 fix(launcher): Campaign LA gate-round-1 review findings F1-F6 + hardening
F1: the crash reporter comment claimed the launcher never holds a password
in any field - false (ProfileEditorDialogViewModel, AccountProfile.Password,
StartRequest.Password). Reworded to the true, narrower invariant (no throw
site interpolates a credential VALUE into an exception message) and pinned
it with CrashReportNeverContainsAStoredPassword: a real STJ failure over a
profiles document containing a known password, corrupted after the
credential, must yield a crash file with the stack and without the value.

F2: the co-deploy Inputs covered only Bake own sources; a Content edit
never refreshed the 83 MB exe. Now the full reference closure. Fixing it
surfaced two more incrementality traps, both fixed and comment-documented:
SkipUnchangedFiles left the output older than the triggering input (target
re-ran forever - added an explicit Touch), and %(Item.Metadata) in a plain
Include does not batch (the literal percent-text became a permanently
out-of-date phantom input - globs are now spelled per project). Verified:
Core edit retriggers, then two consecutive clean incremental builds.

F3: RID publishes ran BOTH co-deploy paths (two self-contained bake
publishes). Build-time target now guarded on _IsPublishing; verified a
real win-x64 publish runs zero build-target co-deploys and still ships
both exes.

F4: comment misattributed PublishBakeTool=false to CI lanes; it is
target-local recursion guarding. F5: the x:Name reflection sweep now walks
the markup as XML and tolerates template-scoped names (no generated field
exists for those). F6: dead using removed. Hardening: the crash reporter
positional --data-dir fallback requires a fully-qualified path so a
relative or flag-shaped value cannot create ./crash-reports at an
arbitrary CWD.

Launcher 67/67, Launcher.Core 317/317.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 08:19:23 +02:00
Erik
1f87acf1af docs: Campaign LA gate round 1 record — #398 closed, #399 merged-closed, bake co-deploy
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 07:58:41 +02:00
Erik
c25545e8d6 docs(launcher): prepare Campaign LA user gate 2026-08-15 02:16:41 +02:00
Erik
a22f54117b docs(launcher): record Campaign LA11 automated closeout 2026-08-15 02:08:18 +02:00
Erik
d39f3098d5 merge: Campaign LA LA11 - automated closeout review-closed
# Conflicts:
#	docs/plans/2026-08-14-launcher-campaign.md
2026-08-15 02:07:39 +02:00
Erik
134edabed2 feat(launcher): complete Campaign LA11 pre-gate support 2026-08-15 00:02:04 +02:00
Erik
0ac8bf6171 docs(launcher): close Campaign LA10 2026-08-14 23:50:23 +02:00
Erik
da4fb3de19 merge: Campaign LA LA10 - updater review-closed 2026-08-14 23:47:25 +02:00
Erik
f881e5b467 feat(launcher): prepare Campaign LA11 user gate 2026-08-14 23:42:30 +02:00
Erik
09d84387a8 fix(launcher): verify self-update rollback sources 2026-08-14 23:41:55 +02:00
Erik
1955ca8ab5 fix(launcher): harden updater crash recovery 2026-08-14 23:12:15 +02:00
Erik
2d2a5b5046 feat(launcher): implement verified atomic updates 2026-08-14 22:09:34 +02:00
Erik
df824f366c docs(launcher): close Campaign LA6 LA8 and LA9 2026-08-14 21:18:05 +02:00
Erik
2bb8ccb6b6 merge: Campaign LA LA6 - login commands review-closed 2026-08-14 20:48:42 +02:00
Erik
41b15efd4d feat(runtime): share chat commands and run login sequence 2026-08-14 20:27:45 +02:00
Erik
267804465e docs(launcher): close Campaign LA4 LA5 and LA7 2026-08-14 19:36:00 +02:00
Erik
f820eb258d fix(plugins): close LA5 ownership races 2026-08-14 19:28:14 +02:00
Erik
6c4cd2bbc6 docs(launcher): close Campaign LA2 integration 2026-08-14 17:31:33 +02:00
Erik
e01b2cd12f merge: Campaign LA LA2 - probe and idle review-closed
# Conflicts:
#	docs/plans/2026-08-14-launcher-campaign.md
#	src/AcDream.Headless/Hosting/HeadlessSessionHost.cs
2026-08-14 17:30:07 +02:00
Erik
1c5e66c05b fix(launcher): Campaign LA close LA2 review findings 2026-08-14 17:20:02 +02:00
Erik
3313577dcc docs(launcher): Campaign LA close LA1 and LA3 2026-08-14 17:17:56 +02:00
Erik
890cf267fc docs(launcher): record Campaign LA LA1 fix-round gates 2026-08-14 17:00:46 +02:00
Erik
d511e4c348 fix(launcher): close Campaign LA LA1 review findings 2026-08-14 17:00:09 +02:00
Erik
000ea979d5 test: Campaign LA finish LA2 probe and idle gates
Prove idle play remains passive and live until cancellation, then converges through one truthful status teardown. Keep probe mode string-only so numeric enum aliases cannot expand the pinned v1 contract, and record the Windows/WSL gates.
2026-08-14 16:49:51 +02:00
Erik
498f1c1182 docs: Campaign LA ledger — LA7a DONE+merged (fa2de1c4); LA1 implemented, review dispatching
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 16:08:45 +02:00
Erik
db9ad53c1c docs: Campaign LA — pinned launch-contract schema COMMITTED into plan LA1
The LA3 Opus review process note was right: the contract both sides
implement lived only in orchestrator prompts, which is exactly the drift
mode the pin exists to prevent (and it produced the paths-key CRITICAL).
The schema, field rules, probe-mode discriminator, and status vocabulary
are now a binding plan section; amendments change this text first,
implementations second. Ledger: LA3 fix round dispatched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 16:04:32 +02:00
Erik
0bcc7ba3a3 docs: Campaign LA — spec §11.4 corrected per LA7a review; LA7b hazards recorded
The spec seeded the wrong claim (restore extra strings = decompiler
artifact, no register row needed); the LA7a Opus review decoded the
PDB-paired binary and showed the two constant-string arguments are real,
making our guid-only request an adaptation — AD-97 filed on the LA7a
branch. Plan LA7 now carries the review-surfaced LA7b hazards (ACE
silent no-reply restore path, SendToLogon/SendToControl routing,
NumErrors sentinel).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 16:02:20 +02:00
Erik
205b09cf32 docs: Campaign LA ledger — LA3 implemented (37d74e44), LA7a implemented (6a32f375), both reviews in flight
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:50:41 +02:00
Erik
7a839cba71 docs: Campaign LA LA0 DONE — ledger closed; arch-doc wording nit from narrow re-review
The re-review closed all six findings and flagged one docs-only nit: the
Platform layer block described App as reaching Platform transitively when
the same commit made the reference direct, and spoke of the launcher in
the present tense. Both corrected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:32:52 +02:00
Erik
a49e92df3a fix(platform): Campaign LA LA0 review fixes — CI Linux lanes, arch doc, self-guard
Opus dual-lens review of cb6502c8 passed with six findings; this lands
the fix round:
1. headless-portability.yml: AcDream.Platform src/tests join both path
   triggers and the presentation-free build/test arrays — the moved XDG
   tests run on ubuntu-latest again (they had fallen out of every Linux
   lane).
2. acdream-architecture.md: AcDream.Platform gets its own layer block;
   Runtime may-reference clause updated (the guard changed in cb6502c8,
   its human-readable twin had not).
3. PlatformDependencyBoundaryTests: the BCL-only contract (zero
   project/package references) is now enforced, not just observed.
4. memory/project_linux_graphical.md canonical seam renamed.
5. Plan LA0 recon corrected: the K0 Headless guard was never the guard
   needing amendment (it asserts Headless own refs); Runtime own-refs
   guard was — the commit did the right thing, the plan text now says so.
6. App declares its AcDream.Platform reference explicitly per its own
   convention instead of riding transitivity.

Platform.Tests: 4 passed (3 moved + the new guard).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:30:04 +02:00
Erik
7f24af1a37 docs: Campaign LA Linux posture — full launcher stack Linux-tested; GUI waits for Slice L
User decision 2026-08-14: everything the launcher does ships Linux-tested
in this campaign (launcher UI, install/update with manual DAT picker,
headless launches with plugins + login commands, probe, per-slice Linux
test runs, Linux connected-gate section at LA11). GUI client launches
stay Windows-only until Slice L resumes later; the launcher renders GUI
modes disabled on Linux with an explicit note, and the host-agnostic
session-config contract means Slice L lights them up with no launcher
changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:17:53 +02:00
Erik
9b0bb25581 docs: Campaign LA plan — slices LA0-LA11, recon-grounded; spec corrections
Plan doc with twelve slices, dependencies, review protocol (Opus
dual-lens: architectural + retail-faithful), and ledger. Three parallel
recon reports grounded the slice bodies:

- Retail select screen is gmCharacterManagementUI: flat listbox +
  Enter/Delete/Restore + dialogs. NO 3D preview (that machinery is
  chargen-only gmCG3DView) — the spec 3D-preview slice is deleted, the
  old retail-ui/05-panels.md pedestal claim is uncited and wrong.
  Restore + CharacterError join scope; delete sends account+slot.
- Chat-command core (parser/router/catalog/ChatVM) is dependency-clean
  BCL+Core; extraction to Runtime is a move, not a rewrite.
- Probe reuses the NoCharacters early-exit shape (graceful teardown at
  the CharacterList stage exists today); roster plumbing is new.
- Bake tool needs --progress-json + explicit --out; no whole-file SHA
  exists — launcher records/verifies its own.
- UI Studio is deleted (Campaign V) — stale references corrected.

Roadmap + CLAUDE.md Current state carry the campaign pointer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 15:10:39 +02:00
Erik
0f15c74147 chore: secure-trade closeout - strip [trade] gate probes, roadmap ledger
The two-client user gate PASSED 2026-08-14 (open both ways, stage with
the retail trading marker, accept/decline, executed swap, Clear All,
cancel text). Every TEMPORARY [trade] probe line from gate rounds 1-2 is
stripped (ItemInteractionController, SelectionInteractionController,
SecureTradeUiController, LiveSessionCommandRouter, WorldSession,
RuntimeTradeState). Roadmap gains the shipped-trade ledger row.

Suites after strip: App 4,992/3, Runtime 1,626 - green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 12:48:31 +02:00
Erik
028920420d docs: FA7 closeout — Campaign FA CODE-COMPLETE
The retail four-tab social panel (Fellowship & Allegiance) is
code-complete: all six slices landed and reviewed (dual-lens Opus review
-> fix round -> narrow re-review each). Fellowship two-session flow proven
live (FA6 bot gate PASSED). Closeout bookkeeping:
- register AD count 66 -> 67 (AD-87, the deferred allegiance bot gate);
- plan status flipped to CODE-COMPLETE with the OWED connected gates +
  #384 (allegiance-swear ACE non-response) called out;
- CLAUDE.md Current-state gains the Campaign FA paragraph
  (per feedback_claude_md_staleness), pointing at the memory digest.

Owed: the user's connected gates (§FA3-§FA6 of
docs/research/2026-08-12-campaign-fa-test-script.md) and #384's
ACE-console disambiguation. Full suite 13,304/4/0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:30:19 +02:00
Erik
01fafe7b37 docs: FA6 — ledger row + gate script §FA6 (fellowship PASSED live, allegiance deferred)
Plan ledger: fellowship two-session automated gate PASSED live 2026-08-12
(five of six runs reproduced the decisive cross-session assertion); the
allegiance bot gate is DEFERRED behind AllegianceGateEnabled=false pending
docs/ISSUES.md #384, with commit citations for every fix this slice landed
(confirmation relay, name-matched proximity, the fellowship-only
finalization).

Gate script §FA6: the fellowship automated-gate recipe + actual PASSED
result (the two-session config, the six proof points per stage, the
literal decisive-assertion log lines), the allegiance deferral writeup,
and a new [TWO-CLIENT] manual step (25) the user's own connected gate can
run to help disambiguate #384 (ACE-side rule vs wire-builder defect vs
harness-specific drop) using two real graphical clients instead of the
testaccount/testaccount2 pair.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 10:26:19 +02:00
Erik
3dde2dc149 docs: FA5 CODE-CLOSED — dual review + SF-1 fix + baseline off-by-one corrected
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 09:08:41 +02:00
Erik
bc29a1dbdb docs(fa5): register rows AD-84/AD-85/AD-86 + AD-82 addendum, gate-script SFA5, ledger
Register:
- AD-84 -- Swear button's missing "target is a player" enable-rule gate,
  same class as AD-83's Recruit-button gap.
- AD-85 -- the unported StringInfo variable-substitution engine (AD-81's
  same root cause) extended to the Allegiance page's numeric-only
  followers/rank/experience-passed-up fields and its three local
  confirmation dialogs (verbatim-or-bare-name, never invented).
- AD-86 -- ACE's deliberate zeroing of seven AllegianceProfile/
  AllegianceData fields (officers, officer titles, MOTD, MOTD-set-by,
  name-last-set-time, lock, approved vassal, timeOnline, allegianceAge),
  dropped past acdream's own parse layer to match retail's own
  gmAllegianceUI, which has no widget for any of them either.
- AD-82 addendum: the vassal-row click-target-only selection shares
  point (3)'s limitation, but NOT the invented leader/selection tints
  (point 1/2) or the Fellowship-only world-selection sync (point 4) --
  Allegiance's list-selection message has no SetSelectedObject call.

Gate script: new docs/research/2026-08-12-campaign-fa-test-script.md
SFA5 section, mirroring SFA4's structure -- the CF-1 subscription steps
(including the reconnect-while-closed MF-3-REOPEN analogue), the SF-7
per-relationship monarch/patron steps, vassal-list steps, swear/break/
kick with their confirmations, the ACE-zeroed-field honesty note, and
full "what to report"/"explicitly not in scope" lists.

Plan ledger: FA5 row filled in against 7ed79eaf with per-item summary,
directly-measured totals (13,296/4/0, +11 net from FA4's 13,285/4/0),
and the two primary-source resolutions this slice needed beyond the
research docs (the self-rank field's live buffed-quality source, and
"your follower count" == _total_vassals, confirmed by a fresh targeted
decompile of UpdatePlayerData rather than inferred).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 08:41:10 +02:00
Erik
f5bd3e5621 docs: FA4 CODE-CLOSED — MF-3 re-fix (04161def) + re-review (06dbf1cf) closed
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 08:03:42 +02:00
Erik
f041b09b7c docs(fa4): ledger FA4 row records the fix-round SHAs, per-finding dispositions, and final totals
FA4 row now names all six fix-round commits (290f9b58, 5499f058, df000306,
300d8189, 55b17e15, 1d743277) alongside the original landing's three, and
records: build/test green at every commit; the +13/0-deletion test delta
broken down per file; the final directly-measured 13,285 passed / 4
skipped / 0 failed (13,289 total); every MUST-FIX/SHOULD-FIX/NIT applied;
and the corrected dimmed-row arithmetic (35 -> 31 FA4-original -> 34
fix-round final, net one row). Also corrects item (4) of the
"contradictions/deferrals" list, which called the missing Recruit
is-a-player register row an acceptable inline comment -- MUST-FIX 5 named
that the wrong call; it is now register row AD-83.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 07:36:03 +02:00