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

284 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
```text
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):
```text
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.
```