Skip to content

ADR-0045: The War Tent — Commander's Field Command Post

Accepted War Room Territory-Specific

Date: 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:

  1. 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-pty wrapping wsl.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.
  2. 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):

  1. Name: war-tent. war-table was 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 center was rejected as generic (fails the naming standard both the war room and the lab hold).
  2. Six fixed seats. The Generals tab holds six standing seats, always visible; an empty seat is a visible fact. The count is config (SEAT_COUNT in src/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.
  3. 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.
  4. 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.
  5. 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

OptionVerdictReason
Extend the Mezzanine with war-room targetsRejectedDifferent 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)RejectedThe 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-wrapRejectedThe 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 lineAcceptedProven 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

WhatMechanismScope
Gates at PR timeci-passed rollup (oxlint type-aware, oxfmt, vue-tsc, vitest, vite build, cargo fmt/check/clippy/test)war-tent repo
POSIX path hygiene on the bridgeSubstrate regression test (Phase 1, ported from Mezzanine pty/substrate.rs)src-tauri
Score stamp presenceSpy SOP format rules (all 8 definitions); /muster memory-currency checks surface missing stampswar-room spy memory
Version lockstep (Phase 3)scripts/version.mjs check in CI (Ascent port)four manifests

Implementation

TerritoryStateNotes
war-tentPhases 1–3 completePhase 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-roomPartialSpy SOP score stamps landed 2026-07-16; stamps accumulate per mission

Architecture documentation for contributors and collaborators.