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>
This commit is contained in:
Erik 2026-08-14 16:04:32 +02:00
parent 0bcc7ba3a3
commit db9ad53c1c
38 changed files with 2397 additions and 40 deletions

View file

@ -108,6 +108,69 @@ referencing only `AcDream.Platform`.
## LA1 — launch contract (client side)
### Pinned launch-contract schema (v1, BINDING — committed per LA3 review)
This text is the single source of truth for the launcher↔host file
contract. Both host readers (LA1), the composer (LA3), and the probe
loader (LA2) implement EXACTLY this; any change is an amendment to THIS
section first, implementations second. The LA1+LA3 merge adds a
cross-assembly test feeding a composer-produced document to both host
loaders — that test is the seam's permanent enforcement.
Session-config document (System.Text.Json, camelCase,
`UnmappedMemberHandling.Disallow`, camelCase string enums):
```json
{
"version": 1,
"process": {
"content": { "datDirectory": "...", "preparedAssetPath": "..." }
},
"sessions": [{
"id": "sess-1",
"endpoint": { "host": "127.0.0.1", "port": 9000 },
"account": "testaccount",
"mode": "probe",
"character": { "id": 1342177290 },
"policy": { "id": "idle" },
"credential": { "provider": "standardInput", "reference": "session" },
"plugins": ["ExamplePlugin"],
"loginCommands": ["/vt start"],
"loginCommandDelayMs": 500,
"statusFile": ".../launcher/sessions/sess-1/status.jsonl"
}]
}
```
Field rules:
- `process.paths` is OMITTED unless a caller genuinely supplies overrides
(never an empty object — the App reader has no `paths` member and
strict parsing rejects unknown keys; LA3 review finding 1).
- `mode`: ABSENT for normal play sessions; `"probe"` for the LA2 probe
(connect → characterList → graceful disconnect, no EnterWorld). The
headless loader accepts the field starting at LA2.
- `character`: exactly ONE of index|id|name; OMITTED entirely (not null)
for guiSelect and for probe sessions.
- `policy`: `{ "id": "idle" }` for headless play sessions ONLY; omitted
for gui/guiSelect/probe.
- `credential`: always `{ "provider": "standardInput", "reference":
"session" }` for launcher-composed configs.
- `plugins`/`loginCommands`/`loginCommandDelayMs`/`statusFile`: optional,
omitted-when-unset (never null, never `[]` for empty). Absent
`loginCommandDelayMs` means 500.
Status stream (`statusFile`, one JSON object per line, writer flushes per
line, writer opens `FileShare.Read`, tailer opens
`Read/FileShare.ReadWrite|Delete`): events `started`, `connected`,
`characterList{accountName,slotCount,characters[{id,name,secondsGreyedOut}]}`,
`enteredWorld{characterId,characterName}`, `pluginLoaded{plugin}`,
`pluginFailed{plugin,error}`, `disconnected{reason}`,
`exited{code,reason}` — every line carries `"v":1`, `"e"`, `"t"`
(ISO-8601 UTC), `"sessionId"`. `secondsGreyedOut` is a uint on BOTH
sides. Unknown `e` values must parse to a typed Unknown event, never
throw; a known `e` with a wrong payload shape should be distinguishable
from an unknown `e` (LA3 review finding 12).
Three pieces, one slice, because they share the session-config/status seam:
1. **App `--session-config <path>`:** parsed once in `Program.cs` into
@ -416,7 +479,7 @@ LA6 adds CH-regression scrutiny; LA0 adds guard-integrity scrutiny.
| LA0 | **DONE 2026-08-14** | `cb6502c8`, `a49e92df` | Opus dual-lens PASS; all 6 findings CLOSED in narrow re-review | Byte-identity proven; Linux CI lanes restored; Platform BCL-only self-guard added; K0 guard untouched |
| LA1 | in flight (Sonnet) | | | pinned contract v1 + 5 optional fields |
| LA2 | — | | | |
| LA3 | implemented (`37d74e44`, campaign-la3); Opus review in flight | `37d74e44` | review in flight | 71/71 Windows AND 71/71 WSL (0600 test real on Linux); reviewer checking contract token-fidelity + tailer fix |
| LA3 | review FIX FIRST; fix round in flight | `37d74e44` + fixes pending | Opus 2026-08-14: 12 findings — 1 CRITICAL (`"paths": {}` breaks App loader), probe composition owed, Stop→SIGKILL hazard, 0600 temp window | Contract text now COMMITTED into LA1 section (review process note); cross-assembly loader test owed at LA1+LA3 merge; CI lane addition at merge |
| LA4 | — | | | |
| LA5 | — | | | |
| LA6 | — | | | |