acdream/docs/research/2026-08-14-campaign-la-handoff.md
Erik 4edc122085 docs: Campaign LA handoff — worktree paths, stopped-agent recovery, kickoff prompt
Both remaining agents were stopped for token budget and their partial work
committed as WIP (75a6724d LA1 fix round, c6019424 LA2). The handoff now
carries: full worktree paths with branches and HEADs, exactly what each
stopped agent had finished versus what it still owes, and a paste-ready
kickoff prompt naming all three resumable items plus the two owed merge
items.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 16:34:06 +02:00

16 KiB
Raw Permalink Blame History

Campaign LA — session handoff (2026-08-14)

Read this first, then docs/plans/2026-08-14-launcher-campaign.md (the plan + ledger), then docs/superpowers/specs/2026-08-14-launcher-campaign-design.md (the approved design). Memory crib: claude-memory/project_launcher_direction.md.

Worktrees (full paths — work in the campaign worktree, NOT the repo root)

Purpose Full path Branch HEAD at handoff
Campaign branch — START HERE C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-launcher-credentials-4d2f7c claude/acdream-launcher-credentials-4d2f7c 75a6724d
LA2 slice C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-la2 campaign-la2 c6019424
LA3 slice C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-la3 campaign-la3 26feba81
LA7a slice (merged — removable) C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-la7a campaign-la7a 0c8643a7

The repo root C:\Users\erikn\source\repos\acdream is on main and is NOT where this campaign happens.


1. What Campaign LA is

One external product — the acdream launcher — that is simultaneously the installer, the updater, and the multi-server / multi-account / multi-character session launcher (ThwargLauncher UX model), on Windows and Linux; plus the one client-side feature the launcher flow exposes as missing, the retail character-management screen.

Design decisions already made and NOT to be re-litigated (spec §2):

  • Avalonia UI; AcDream.Launcher (thin) + AcDream.Launcher.Core (BCL-only).
  • Credentials in a plaintext file — user-decided. 0600 on Linux; never in logs, arguments, session configs, or the status stream.
  • Approach A, file-contract orchestrator: the launcher speaks NO game protocol. Config file in → password via child stdin → JSONL status events out. (Launcher embedding Runtime was REJECTED: a probe login that fails to tear down gracefully poisons the ACE account ~3 min.)
  • Full CRUD in the launcher UI; hand-editing JSON is never required.
  • Character enumeration by headless probe (connect → CharacterList → graceful disconnect BEFORE EnterWorld → exit) plus cache-from-observation.
  • Retail char-select has NO 3D preview — recon-corrected. Retail's gmCharacterManagementUI is a flat listbox + Enter/Delete/Restore + dialogs; the rotating-model viewport is character-CREATION-only. Create Character is a future campaign.
  • Everything (launch + install + update) in ONE campaign.
  • Linux posture (user-directed): the full launcher stack ships Linux-tested in this campaign; GUI client launches stay Windows-only until Slice L resumes later. The launcher renders gui/guiSelect disabled on Linux with an explicit Slice-L note.

2. Slice ledger at handoff

Slice State Commits
LA0 AcDream.Platform extraction DONE (review closed) cb6502c8, a49e92df, 7a839cba
LA1 launch contract (App CLI + status writer + roster seam) implemented; Opus review FIX-FIRST; fix round WIP — stopped mid-task, see §3 db9ad53c (MIXED — see §4), note e1322a06, WIP 75a6724d
LA2 probe mode + idle policy WIP — stopped mid-task, see §3 c6019424 on branch campaign-la2
LA3 AcDream.Launcher.Core implemented; review FIX-FIRST (12 findings); fix round LANDED — all 12 fixed, 94/94 Windows + WSL; owes narrow re-review, then merge 37d74e44, 26feba81 on branch campaign-la3
LA7a character wire messages DONE + MERGED 6a32f375, 4338b1c1, 0c8643a7, merge fa2de1c4
LA4 Avalonia UI not started (needs LA3)
LA5 plugin hosting not started (needs LA1)
LA6 login commands not started (needs LA1, LA5)
LA7b char-select state + flow not started (needs LA1)
LA8 authored char-select screen not started (needs LA7b)
LA9 installer / LA10 updater / LA11 closeout not started

Register: AD-97 filed (guid-only CharacterRestore request is an adaptation — retail sends ≥16 bytes, we send 8; ACE ignores the tail).


3. Work STOPPED MID-TASK — resume these first

Two agents were killed for token budget and their partial work is committed as clearly-marked WIP. Build/test state at both WIP commits is UNVERIFIED — build and test before trusting either.

  1. LA1 fix round — WIP at 75a6724d (campaign worktree/branch). DONE in the WIP: F1 best-effort SessionStatusWriter (never throws into login/teardown, creates its parent directory), F2 App reader tolerance (parse-and-ignore process.paths, explicit named refusal of mode: "probe"), F5 --session-config argument hardening, new tests. STILL OWED: F4 production-shape the shared fixture (tests/Fixtures/campaign-la/session-config-shared-fixture.json — add process.content, switch credential to standardInput/session, assert values on BOTH sides; this was the agent's literal next step); F3 reconnect emits disconnected before the second connected + record the mid-play wire-drop limitation in the plan's status-stream section; F6 exited idempotency + distinct reason strings; F7 make the Runtime redaction test structural (assert the exact serialized property set per event kind); F8 platform-guard file-set test + fix the overstating isLinux comment; optional RuntimeOptions.PrintMembers redaction of LivePass. Then: run Runtime/App/Headless Release suites (+ WSL for Runtime/Headless) and dispatch the NARROW re-review.
  2. LA2 — WIP at c6019424 (worktree ...\acdream-la2, branch campaign-la2). DONE in the WIP: probe flag through LiveSessionConnectOptions, the StartCore short-circuit before selection, the mode field with the JsonRequired→semantic-validation move, host exit-code mapping, 34 tests passing including 3 probe tests (agent's last report before the stop). STILL OWED: idle-policy unit tests (its next step), full Runtime+Headless Release suites on Windows AND WSL, then the Opus dual-lens review.
  3. LA3 fix round — COMPLETE at 26feba81 (worktree .claude/worktrees/acdream-la3, branch campaign-la3). All 12 findings fixed: the CRITICAL "paths": {} emission (now omitted entirely), probe composition (ComposeProbe + mode field), graceful stop (Linux SIGINT via libc kill, Windows gap filed as ISSUES #397 with the CREATE_NEW_PROCESS_GROUP + CTRL_BREAK direction), 0600 temp-file window, the Launcher.Core dependency-boundary guard, non-throwing parser/tailer, monotonic supervisor state, 0x-prefix id parsing, uint SecondsGreyedOut, and MalformedStatusEvent. 94/94 Windows AND WSL. NEXT: narrow re-review of 26feba81, then merge campaign-la3 (with the two owed merge items below).

To recover: git -C <worktree> log --oneline -3 and git status per branch. If a fix round committed, run its narrow re-review; if it did not, re-dispatch it from the finding list above (the reviews' full text is in the original session transcript, but the finding summaries here are sufficient to re-derive the work).

Owed at merge time (do not lose these):

  • Cross-assembly contract test when LA1+LA3 meet: feed an AcDream.Launcher.Core composer-produced document to BOTH host loaders (App + Headless) and assert it parses. This is the permanent anti-drift enforcement for the pinned contract.
  • CI lane: add tests/AcDream.Launcher.Core.Tests to .github/workflows/headless-portability.yml (both paths: filters + the Linux test array), mirroring what LA0 did for AcDream.Platform.Tests.
  • After LA2 lands, App's reader must refuse mode: "probe" (covered by LA1 fix-round F2 — verify it actually landed).

4. Landmines / lessons from this session

  1. Never run git state commands in a worktree while an implementer agent is live in it. git add <path> scopes the ADD; git commit commits the whole INDEX. A docs commit swept 37 in-progress LA1 files into db9ad53c; the marker commit e1322a06 documents it. Memory: claude-memory/feedback_no_commits_beside_live_agents.md.
  2. Auto-created agent worktrees can be based on stale history. The first LA3 dispatch landed on a spell-bar-era commit. Always create the worktree yourself from the campaign HEAD and make the agent verify its base commit as its first action.
  3. PowerShell 5.1 mangles double quotes inside heredoc commit messages — keep git commit bodies quote-free.
  4. The pinned contract must live on disk, not in agent prompts. It now does (plan §"Pinned launch-contract schema (v1, BINDING)"). The LA3 CRITICAL was a direct consequence of it living only in prompts.
  5. Reviews have caught something tests could not, four slices running: lost Linux CI lanes (LA0), a real-but-mislabeled wire deviation (LA7a → AD-97), a cross-worktree contract break (LA3), an observability sink that could fail the transaction it observes (LA1). Do not downgrade the review step.

5. How we work (binding process)

  • Fable plans, sequences, integrates. Sonnet implements bounded slices. Opus reviews every slice boundary, dual-lens: (a) architectural — ownership, layering, dependency-guard integrity, seams; (b) retail fidelity against docs/research/named-retail/ wherever the slice touches retail behavior. Findings → fix round → NARROW re-review of the fixes → slice DONE in ledger.
  • Max 34 agents in parallel INCLUDING children; subagents never spawn subagents. Every implementer prompt carries: spec+plan paths, files to read first, the pinned contract text if relevant, acceptance criteria, commit style, and a base-commit verification as its first action.
  • One implementer per worktree; that agent owns the worktree's git index.
  • dotnet build + dotnet test green before a slice is DONE; ≥1 commit per slice tagged Campaign LA; every retail deviation adds its docs/architecture/retail-divergence-register.md row in the same commit; no workarounds without explicit user approval.
  • Linux: every slice touching Launcher.Core/Headless/Runtime/Bake/Platform runs its test projects under WSL or native Ubuntu before it is DONE.
  • The ONLY stop-and-wait is a user connected/visual gate. Everything else is Claude's call — never present the user a work-order menu.
  • Keep the plan ledger, docs/plans/2026-04-11-roadmap.md, the CLAUDE.md Current-state pointer, and claude-memory/ current as slices land.

6. Kickoff prompt for the new session

Paste this as the FIRST message of the new session (it names the three resumable work items explicitly), then set the goal in §7.

Resume Campaign LA (the acdream launcher). Work in
C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-launcher-credentials-4d2f7c
on branch claude/acdream-launcher-credentials-4d2f7c. Read
docs/research/2026-08-14-campaign-la-handoff.md first, then the ledger in
docs/plans/2026-08-14-launcher-campaign.md.

Three items are waiting, all recoverable from git — two are partial work from
agents that were stopped mid-task for token budget, and their build/test state
is UNVERIFIED:

1. LA1 fix round — WIP commit 75a6724d on this branch. An agent had completed
   findings F1 (best-effort SessionStatusWriter that never throws into the
   login/teardown transactions and creates its parent directory), F2 (App
   reader tolerates process.paths and explicitly refuses mode:"probe"), and F5
   (--session-config argument hardening). It was stopped just as it started F4.
   Finish: F4 production-shape tests/Fixtures/campaign-la/session-config-shared-fixture.json
   (add process.content, switch the credential to standardInput/session, assert
   values in BOTH host suites), F3 (reconnect emits disconnected before the
   second connected; record the mid-play wire-drop limitation in the plan's
   status-stream section), F6 (exited idempotency + distinct reason strings),
   F7 (make the Runtime redaction test structural — assert the exact serialized
   property set per event kind), F8 (platform-guard file-set test + fix the
   overstating isLinux comment), and optionally redact LivePass from
   RuntimeOptions.PrintMembers. Then build, run Runtime/App/Headless Release
   suites plus WSL for Runtime/Headless, and dispatch the narrow re-review.

2. LA2 — WIP commit c6019424 in worktree
   C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-la2 (branch
   campaign-la2). An agent had implemented the probe flag through
   LiveSessionConnectOptions, the StartCore short-circuit before selection, the
   mode field with the JsonRequired-to-semantic-validation move, and the host
   exit-code mapping, with 34 tests green including 3 probe tests. It was
   stopped before writing the idle-policy unit tests. Finish those, run the
   Runtime+Headless Release suites on Windows and WSL, then dispatch the Opus
   dual-lens review.

3. LA3 — COMPLETE at 26feba81 in worktree
   C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-la3 (branch
   campaign-la3). All 12 review findings fixed, 94/94 Windows and WSL. It needs
   only a narrow Opus re-review of 26feba81 against the finding list in §3 of
   the handoff, then merge into the campaign branch.

At the LA1+LA3 merge, do not lose the two owed items: the cross-assembly
contract test (feed a Launcher.Core composer document to BOTH host loaders) and
adding tests/AcDream.Launcher.Core.Tests to the Linux CI lane in
.github/workflows/headless-portability.yml.

After those land, continue the ledger: LA4 (Avalonia UI), LA5 (plugin hosting),
LA6 (login commands), LA7b (char-select state+flow), LA8 (authored screen), LA9
(installer), LA10 (updater), LA11 (closeout).

7. The goal to set

Set this with /goal in the new session (it is the same directive this session ran under, refreshed for the current state):

GOAL: Ship Campaign LA — the acdream launcher/installer/updater + retail character-select screen.

Work in C:\Users\erikn\source\repos\acdream\.claude\worktrees\acdream-launcher-credentials-4d2f7c
(branch claude/acdream-launcher-credentials-4d2f7c). Start at
docs/research/2026-08-14-campaign-la-handoff.md, then the ledger in
docs/plans/2026-08-14-launcher-campaign.md. Finish the three waiting items
first — LA1 fix round (WIP 75a6724d, unverified), LA2 (WIP c6019424 on
campaign-la2, unverified), LA3 (complete at 26feba81 on campaign-la3, owes a
narrow re-review then merge) — then continue slice by slice.

Process, per slice:
1. Fable plans/sequences/integrates — never present work-order menus; pick and announce.
2. Sonnet subagents implement bounded slices. Each prompt carries spec+plan paths, the
   exact files to read first, the pinned contract text when relevant, acceptance criteria
   (build+test green), commit style, and a base-commit verification as first action.
   Subagents may not spawn subagents. Hard cap 3-4 agents in parallel including children.
   One implementer per worktree; that agent owns the index — the orchestrator makes no git
   state changes in a worktree while an agent is live in it.
3. Every slice boundary gets an Opus dual-lens review: (a) architectural — ownership,
   layering, dependency-guard integrity, seams; (b) retail fidelity against
   docs/research/named-retail/ wherever the slice touches retail behavior. Fix findings,
   then a narrow re-review of the fixes.
4. dotnet build + dotnet test green before any slice is declared done; Linux (WSL or
   native Ubuntu) runs for every slice touching Launcher.Core/Headless/Runtime/Bake/
   Platform. One commit per slice minimum, tagged "Campaign LA". Any retail deviation adds
   its divergence-register row in the same commit. No workarounds without explicit approval.
5. As slices land: update the plan ledger, docs/plans/2026-04-11-roadmap.md, the CLAUDE.md
   Current state pointer, and claude-memory/.
6. The only stop-and-wait is a user connected/visual gate (launch modes vs local ACE,
   character-probe round-trip, char-select visual matrix, first-run wizard, update swap).
   When a slice reaches one: write the exact test script under docs/research/, announce the
   gate, and keep driving any slices not blocked behind it.

DONE = all slices code-complete, automated gates green, dual reviews closed, and the
connected-gate checklist delivered to the user in one script document.