docs: Campaign LA session handoff — state, in-flight recovery, process, goal
Self-contained handoff for a fresh session: what the campaign is and which decisions are settled, the slice ledger with commits, the in-flight slices and how to recover them from git, the two owed merge items (cross-assembly contract test, Launcher.Core CI lane), the session landmines (index-sweep, stale agent worktrees, contract-in-prompts), the binding process, and the goal text to set. Committed via pathspec so a live implementer agent index in this worktree is untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
498f1c1182
commit
c9fc7f4a66
1 changed files with 202 additions and 0 deletions
202
docs/research/2026-08-14-campaign-la-handoff.md
Normal file
202
docs/research/2026-08-14-campaign-la-handoff.md
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
# 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`.
|
||||
|
||||
Branch: `claude/acdream-launcher-credentials-4d2f7c`
|
||||
Worktree: `.claude/worktrees/acdream-launcher-credentials-4d2f7c`
|
||||
HEAD at handoff: `498f1c11`
|
||||
|
||||
---
|
||||
|
||||
## 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 returned FIX-FIRST**; fix round IN FLIGHT | `db9ad53c` (MIXED — see §4), note `e1322a06` |
|
||||
| LA2 probe mode + idle policy | implementer IN FLIGHT | branch `campaign-la2` (base `498f1c11`) |
|
||||
| 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 IN FLIGHT at handoff — recover these first
|
||||
|
||||
Three agents were running when this handoff was written. Their results arrive
|
||||
as task notifications in the ORIGINAL session only; a new session must verify
|
||||
state from git instead of waiting.
|
||||
|
||||
1. **LA1 fix round** — main worktree, branch
|
||||
`claude/acdream-launcher-credentials-4d2f7c`. Findings: F1 (HIGH, required)
|
||||
the `SessionStatusWriter` must never throw into the login/teardown
|
||||
transactions and must create its parent directory (an unwritable/missing
|
||||
status path currently fails a healthy session — first-run trigger);
|
||||
F2 App reader must TOLERATE `process.paths` (parse-and-ignore, like the
|
||||
existing `policy`) and explicitly REFUSE `mode: "probe"` with a named error;
|
||||
F4 production-shape the shared fixture (`process.content`, `standardInput`
|
||||
credential); F3 reconnect emits `disconnected` first + record the mid-play
|
||||
drop limitation; F5–F8 minor hardening.
|
||||
2. **LA2 implementer** — worktree `.claude/worktrees/acdream-la2`, branch
|
||||
`campaign-la2`.
|
||||
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 3–4 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. 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.
|
||||
|
||||
Start at docs/research/2026-08-14-campaign-la-handoff.md, then the ledger in
|
||||
docs/plans/2026-08-14-launcher-campaign.md. Recover the three in-flight slices
|
||||
first (LA1 fix round on the campaign branch, LA2 on campaign-la2, LA3 fix round
|
||||
on campaign-la3) by inspecting git state, 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.
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue