ADR-0045: The War Tent — Commander's Field Command Post
Accepted War Room Territory-SpecificDate: 2026-07-16
Context
The Commander works the war-room from multiple concurrent Claude Code sessions (concurrent-General operation is standard doctrine) plus ad-hoc terminal windows for territory intelligence. There is no single surface from which the war-room is worked: sessions are scattered across terminals, and territory state (spy coverage, mission outcomes) lives in files that must be read by hand or via skills (/recon, /agenda).
The Commander ordered a desktop command post: a Windows-native app with tabs — one hosting six always-open seats for General sessions, one showing the territories with spy-coverage stats and an average spy score — extensible with more tabs later, auto-updating, running against the WSL side where the war-room lives.
Two constraints shaped the deliberation:
- The lab already solved the hard substrate problems. The Mezzanine (the-laboratory's Tauri v2 gadget) carries a runtime-ratified WSL2 bridge (Windows UI,
portable-ptywrappingwsl.exe -d <distro> -- bash -lc "cd … && exec claude", xterm.js rendering, POSIX-string path hygiene) and a live-ratified auto-updater (the Ascent:tauri-plugin-updater, signed NSIS bundles on GitHub Releases, version lockstep). Re-deriving either would be waste; copying the Mezzanine wholesale would violate the Commander's explicit "inspiration, not imitation" boundary. - War-room campaign doctrine excludes expansion (the four campaign types are cartography / structural reform / fortification / quality enforcement). A war-room-built app is new development — the first of its kind. Precedent exists for infrastructure territories (town-crier annexed, time-machine founded ally-driven), but a General-built app territory needed an explicit founding ruling rather than silent precedent-stretching.
Decision
Found war-tent (Goosterhof/war-tent, private; submodule at territories/war-tent; default main; full war-room doctrine authority): a Windows-native Tauri v2 + Vue 3 desktop app bridging into WSL2, built by the war room for the Commander.
Commander rulings at founding (2026-07-16):
- Name: war-tent.
war-tablewas rejected — the lab's Helldivers experiment already holds the codename The War Table, and an allied-codename collision would poison the design brief handed to the lab's own designers.command centerwas rejected as generic (fails the naming standard both the war room and the lab hold). - Six fixed seats. The Generals tab holds six standing seats, always visible; an empty seat is a visible fact. The count is config (
SEAT_COUNTinsrc/generals/seats.ts), not a layout constant. The lab's Workbench precedent (six fixed benches, retired for a dynamic roster) was weighed and distinguished: Mezzanine scientists dispatch to varying targets, war-tent Generals all sit in the same war-room root — fixed seats mirror concurrent-General doctrine. - Spy scores are stamped forward. No uniform numeric score existed in spy memory (ad-hoc Quartermaster/Sapper letter grades at best). Rather than parse the inconsistent past, every spy SOP now stamps
**Last Mission Score:** N/10 — {rationale}in its memory header on every mission (calibration scale in the spy definitions). The territories tab renders coverage freshness from day one and averages scores as stamps accumulate — it must tolerate absence. - Substrate inherited, soul not. The Mezzanine's AD-1 WSL2 bridge, pty substrate, path hygiene, and Ascent updater pattern are adopted as proven machinery. The metaphor, voice, seat semantics, and all Mezzanine-specific surfaces (floor canvas, Grind, chronicle shape) are explicitly not ported.
- Design is a lab campaign. Visual design waits for a deliberate campaign with the-laboratory's Artisan/Illusionist now that the name exists; the scaffold ships deliberately plain.
Phases: 0 founding (scaffold, tab shell, CI — landed 2026-07-16) → design (lab campaign) → 1 the seats (pty + xterm + wizard) → 2 the map table (coverage + scores over the bridge) → 3 the update (Ascent port; updater keypair minting and private-key escrow are Commander-gated).
Options Considered
| Option | Verdict | Reason |
|---|---|---|
| Extend the Mezzanine with war-room targets | Rejected | Different master (investor vs Commander), different domain semantics; the lab owns the Mezzanine's training and voice — a war-room surface inside it blurs both sovereignties. |
| Web app on a territory stack (Laravel/Vue) | Rejected | The core feature is hosting native pty sessions against a local WSL2 filesystem — a browser cannot spawn wsl.exe; a local server sidecar re-invents Tauri with more moving parts. |
| Agent SDK instead of pty-wrap | Rejected | The lab's Apprentice died on this (SDK incompatible with the account class, retired 2026-04-30); pty-wrap of the claude CLI is the proven integration and renders the full TUI. |
| New Tauri v2 territory on the Mezzanine substrate line | Accepted | Proven bridge + updater, native pty, Windows-first with WSL2 reach; clean sovereignty split (substrate inherited, product owned). |
Consequences
Positive
- One surface to work the war-room: six seats + territory intelligence.
- Substrate risk retired up front — bridge and updater are ports of runtime-ratified designs, not inventions.
- The score stamp creates a fleet-health time series the war room never had (useful beyond the app:
/recon,/intel).
Negative
- A new territory to maintain (deps, CI, releases) with a single user.
- Rust side sits outside standard spy lanes (as with Horadric Cube) — Vue side is scoutable, the substrate is General/ally-reviewed only.
- Score stamps are self-graded by spies — calibration drift across spy types is likely and averages must be read as trend, not truth.
Risks
- Fixed-six regret (the Workbench arc) — Mitigation: seat count is config; a ruling changes one number.
- Design-after-scaffold drift (plain scaffold ossifies) — Mitigation: design campaign is a named phase gating Phase 1's visual surfaces.
- Updater key compromise — Mitigation: keypair minting and escrow Commander-gated (Ascent A-0 precedent), never stored in-repo.
Enforcement
| What | Mechanism | Scope |
|---|---|---|
| Gates at PR time | ci-passed rollup (oxlint type-aware, oxfmt, vue-tsc, vitest, vite build, cargo fmt/check/clippy/test) | war-tent repo |
| POSIX path hygiene on the bridge | Substrate regression test (Phase 1, ported from Mezzanine pty/substrate.rs) | src-tauri |
| Score stamp presence | Spy SOP format rules (all 8 definitions); /muster memory-currency checks surface missing stamps | war-room spy memory |
| Version lockstep (Phase 3) | scripts/version.mjs check in CI (Ascent port) | four manifests |
Implementation
| Territory | State | Notes |
|---|---|---|
| war-tent | Phases 1–3 complete | Phase 0 landed 2026-07-16 (founding commit 591615e). Phase 1 (The Seats) COMPLETE 2026-07-17 (PRs #6–#12: pty substrate + live seats + xterm canvas + first-run wizard, smoke-tested live). Phase 2 (The Map Table) COMPLETE 2026-07-17 — Slice 1 resolve_for_std_fs bridge reader (#13), Slice 2 list_territory_coverage scan (#15), Slice 3 Territories tab (allied Illusionist, Fable 5; #16 merged e407de4 after the Commander's live WebView2 smoke-test). The #16 review's Major+Minor fold into WR-0477 (the silent-scan-failure family). Phase 3 (The Update — Ascent port) COMPLETE 2026-07-17 — Slice A version lockstep (#19), Slice B updater plugin + baked pubkey 218A383BEBD51D3 (#20), Slice C signed-release workflow with SHA-pinned actions (#21); keypair Commander-minted/escrowed, General read only the .pub. Follow-ups WR-0490 (parked review notes) + WR-0491 (Mezzanine ascent.yml SHA-pin). Live end-to-end updater ratification owed on the first Commander v* tag — the update path is built but unexercised. No planned Phase 4 (later tabs = Commander's ideas queue). |
| war-room | Partial | Spy SOP score stamps landed 2026-07-16; stamps accumulate per mission |