Fleet Harness — Delivery Board¶
Meet the team¶
Our build crew is a family of AI teammates — we call them by name. The name is the teammate; the "Runs on" column is the AI tool they work through. So when a task or review says Cedric did it, that's the teammate — the underlying tool is in the table.
| Teammate | Runs on | What they usually do |
|---|---|---|
| Clahadore Jones-Gaffney | Claude (Anthropic) | Planning, coordinating the work, reviewing, and the hard calls |
| Cedric "Cody" Jones-Gaffney | Codex / ChatGPT (OpenAI) | Writing code and giving a second-opinion review |
| Jenny Jones-Gaffney | Gemini (Google) | Writing code, research, and review |
| Gronktayvius "Gronk" Jones-Gaffney | Grok (xAI) | Tough adversarial review — trying to break things before users can |
All four share the surname Jones-Gaffney because they're family. Led by Andrew (Andrew David Jones-Gaffney).
Canonical board for the universal-harness epic (LangGraph over the C# fleet rails) and the council steal-list (2026-07-14 council: reject framework-as-brain for usage savings, steal contracts/policies; REVISED same day — outage continuity + career value make a scoped LangGraph supervisor a funded build).
Redundancy rule: this file + Vikunja (http://localhost:3456) + Jira (once trialed) move in lockstep on every status transition. This file is the source of truth until the other two prove sync.
Statuses: Backlog · Ready · In Progress · In Review · Blocked · Done
USABILITY VERDICT — 2026-07-15 22:5x CDT (WT-0026, night mode; council = authority)¶
The harness is USABLE. It shipped a real change to a real repo, end-to-end, tonight. This verdict replaces document-reading with an actual run — the earlier "~70%, blocked" read was assessed from docs and is superseded.
Evidence (one live run, python -m fleet_harness run --ticket FLT-14, NO --yes):
- Routed: implementer=claude, reviewer=grok — the blind reviewer seat convened.
- Isolated: created wt/FLT-14/harness-560d612e + its own worktree; registered the lock in the
worktree registry (which correctly DENIED a peer session touching it — the lock works).
- Validated itself: ran dotnet test and read the result — exit 0, 93 passed. FLT-3's
never-trust-agent-claims gate is real, not aspirational.
- HUMAN GATE EXERCISED LIVE, first time ever: printed Approve this work? [y/N], took y on
stdin, recorded approval:{approved:true}. The --yes bypass was NOT used. This closes FLT-1's
outstanding acceptance criterion ("human approval gate not yet exercised live; all runs use --yes").
- Output was CORRECT and landed: master 306d3d3. Verified against ground truth independently
(frontend fleet-live.service.ts listens for exactly GovernorTier/QuotaUpdated/RunUpdated/
WorkerHeartbeat — all four names the harness wrote).
- probe reports all 8 seats UP: codex, claude, gemini-flash, gemini-pro-high, grok,
agy-gpt-oss, agy-claude, ollama. 88/88 tests pass (grown from the 51 baseline).
Stale blockers now CLEARED:
- ~~"No remote / single-PC bus factor"~~ — fleet-harness now has andrewjonesdev-tools/fleet-harness.
- ~~"Human gate never exercised"~~ — exercised tonight, see above.
- ~~"FLT-63 councils unreachable"~~ — partially stale: gaming-pc council answered 200 tonight; all 8
harness seats probe UP. Streaming-pc (:37878) is genuinely down.
REAL residual gap — FLT-4. CORRECTED 2026-07-15 after reading graph.py:121-145; my first pass
here was sloppy and is superseded. Two kinds of blindness are being conflated, and they are severable:
- Blind to the IMPLEMENTER'S NARRATIVE — deliberate, correct, KEEP IT. The packet is spec + diff
- unverified test claims, with "no implementer narrative, no summary, no self-assessment" because "Reviewer anchoring on the implementer's confident prose is the failure mode this breaks". That is precisely the defense against FLT-4's own history (97/97 green, two self-reviews, unwired features shipped). Do NOT weaken this. The packet is also size-capped on purpose — a big diff trips third-party CLI input limits.
- Blind to the REPO — this is the actual gap. Grok reviewed tonight's run and said so itself:
"Event names ... could not be cross-checked against FleetHub.cs / FleetPollingService.cs ... in this
empty harness workspace", flagging
GovernorTieras the likeliest mis-name. It was right to be uncertain, and the risk was a false alarm — GovernorTier is correct (frontendfleet-live.service.tslistens for exactly those four). Five seconds ofgrepwould have settled it. It nonetheless returnedneeds_human_review:falsewhile listing risks it could not verify.
CORRECTION #2 (same session) — "point the reviewer's cwd at the worktree" is WRONG and would BREAK
the harness. Do not do it. graph.py:330-338 gives the second rationale I had not read:
"the reviewer is a full coding CLI — pointing it at the worktree would let it edit the very code we just
measured, invalidating the diff, the changed-file list, and the validation run that follows. Reviewers
judge; they do not touch." There is even a belt-and-braces check at graph.py:472 for a reviewer that
"somehow reached" the tree. So the empty sandbox is deliberate on TWO independent counts (anti-anchoring
AND write-isolation), and both are correct.
The gap is still real — grok needed FleetHub.cs, which is NOT in the diff, so the claim that "the
blind packet already contains everything a reviewer legitimately needs" does not hold for cross-file
fact-checking. But the fix must grant READ without WRITE.
Proposed fix (preserves BOTH defenses): give the reviewer a throwaway COPY of the worktree
contents as its cwd — not the live worktree. It can grep/read any file to check a fact; anything it
writes dies with the temp dir and cannot touch the measured diff, the changed-file list, or the
validation run. Packet stays exactly as-is (no narrative, size-capped), so anti-anchoring is untouched.
Cost is one tree copy per review — bound it (skip .git, node_modules, bin/obj) or reuse a detached
worktree at the same commit. A reviewer that cannot distinguish "this looks wrong" from "I cannot see
enough to tell" produces false alarms and, worse, false all-clears.
Also likely STALE on the FLT-4 entry: "agent worktrees not registered with the WorktreeOwnership
registry" — tonight the registry DID hold a lock (WT-044e owns wt/FLT-14/harness-560d612e) and
correctly DENIED a peer session touching that checkout. Re-verify before trusting that gap line.
FLT-6 anti-fork STILL unproven: only usage-governor/docs/agy-quota-policy.md (a DOC) mentions
routing.yaml. No second code reader. The shared-role-table property remains asserted, not tested.
Verdict for the Sunday deadline: the harness is usable NOW for real work with a human at the gate. It shipped a correct change to a real repo tonight and refused to take the implementer's word for anything.
UPDATE 2026-07-16 — the one blocker this verdict named is CLOSED (663c5c1). The reviewer now gets a
read-only copy of the source, so it can check facts instead of guessing at them, and still cannot touch
the measured tree. The remaining bar for UNATTENDED is now evidentiary, not architectural: nobody has
yet run the harness end-to-end with the fixed reviewer and watched it CATCH A REAL DEFECT it would
previously have missed. Until that run exists, "trustworthy overnight" is a reasonable expectation, not a
demonstrated fact — and this board's own history (FLT-4: 97/97 green, two self-reviews, unwired features
shipped) is the argument for demanding the demonstration. Next session: give the harness a task with a
planted cross-file defect and confirm the reviewer catches it. That is the negative control.
Ranked next steps: (1) ~~FLT-4 — throwaway copy as reviewer cwd~~ DONE — landed 663c5c1
(2026-07-16, implemented by codex, reviewed + independently test-verified by WT-0026).
_prepare_review_cwd() copies the implementer's worktree into the throwaway sandbox; reviewer cwd is the
COPY, never the live tree. symlinks=False so a link cannot escape back to the measured tree; entry/byte
caps fall back to the old empty-dir behavior rather than failing the ladder (so a huge repo degrades,
it does not break); partial copies are cleaned before fallback; every fallback path logs which one fired.
Packet unchanged — anti-anchoring intact. Tests 88 → 96 passed, 1 skipped, independently re-run.
The load-bearing test simulates a VANDAL reviewer that writes into its cwd, then asserts the real worktree
is byte-identical and the reviewer's new file does not exist there — it cannot pass vacuously, because if
cwd were the live tree the assert fails. Fixture is named FleetHub.cs: the exact file grok could not read. (2) FLT-6 — a second
CODE reader of routing.yaml (today: one code reader + one doc mention; the anti-fork property is
asserted, not tested). (3) streaming-pc seat (:37878 down; gaming-pc answers, all 8 harness seats probe UP).
Method note for whoever reads this: the previous "~70%, blocked" assessment was produced by reading docs, and three of its blockers were already stale (remote existed, gate worked, seats were up). This one was produced by running the thing. Run it before you rate it.
⚠ Board IDs and Jira keys are NOT the same numbering space¶
FLT-13 on this board and FLT-13 in Jira are different tickets. This board's IDs were
assigned by the 2026-07-14 council before the Jira trial existed; Jira then minted its own keys in
creation order, and the two sequences diverged the moment Jira imported the delivered work
(FLT-D1..D5) into keys 13–17 that this board was already using for live epic items.
Aligned: board FLT-1..FLT-12 ≡ Jira FLT-1..FLT-12 (same tickets, same numbers — coincidence of import order, not a guarantee).
Colliding — the board ID and the Jira key of the same number are unrelated tickets:
| This board | Jira key | What Jira's same-numbered key actually is |
|---|---|---|
| FLT-13 · Mission Control PWA | FLT-46 | FLT-13 = FLT-D1 worktree-identity |
| FLT-14 · Private IDE extensions | FLT-47 | FLT-14 = FLT-D2 usage-governor |
| FLT-15 · agy quota ledger | FLT-49 | FLT-15 = FLT-D3 fleet-dispatch |
| FLT-16 · CI tooling pack | FLT-60 | FLT-16 = FLT-D4 fleet-telegram |
| FLT-61 · Tavily narrow-adopt | FLT-61 | FLT-17 = FLT-D5 NATS fleet.v1 + MemBus |
Later entries (FLT-51, FLT-53, FLT-54, FLT-57, FLT-58, FLT-59, FLT-61, FLT-62, FLT-63) use the
Jira key as the heading — that is the convention going forward. New entries: title the section
with the Jira key, never a locally-invented number. Cite an old board ID only with its Jira key
attached (board FLT-13 / Jira FLT-46), because a bare FLT-13 is ambiguous across the two spaces
and will route a reader to the wrong ticket.
Reconciling the four legacy collisions (renumber the board vs. renumber Jira vs. leave the map) is FLT-11's job. Until FLT-11 lands, this table is the map.
Epic¶
FLT-1 · Universal harness: LangGraph/Deep Agents supervisor over all model CLIs — Acceptance VERIFIED — ceiling sign-off GRANTED (Sunday posture); gate 2 open by design; unattended gated on FLT-4 (WT-f255 built; WT-0924 reviewed 2026-07-14; WT-37e6 verified + signed off 2026-07-18)¶
ACCEPTANCE VERIFIED + ceiling sign-off GRANTED (WT-37e6, 2026-07-18, master 8b712b2). Ran the
suite under the repo .venv (Python 3.13.11): 26 passed, 1 skipped. The load-bearing test
tests/test_graph.py::test_acceptance_simulate_down_claude is not a mock-pass — it drives the REAL
compiled LangGraph (only the agent seats are faked) with simulate_down=["claude"] and asserts the
ticket still flows: implement→codex, review→grok (Claude skipped in the review ladder),
validation.passed True, and critically registry["claude"].calls == [] — Claude is TRULY never
invoked, not merely labelled down — then resumes through the human gate to approved. Sibling tests
prove the FLT-3 discipline: a failed implementer escalates AND its worktree is swept (half-edits
cannot leak forward), reviewer ≠ implementer always, and all-seats-down escalates to a human with
implementer=None (nothing pretended to work). routing.yaml confirmed on the exact Sunday posture:
ladder [claude, codex, gemini-flash, grok, agy-gpt-oss, ollama], max_pool_lockouts: 1,
agy-claude reserve_only + unreachable by any classifier. Verdict: the FLT-1 acceptance
criterion (a ticket flows route→implement→review→gate with the Claude CLI unavailable) is
demonstrably met; harness is usable now, attended. Gate 2 (fleet-global capacity ledger) stays
OPEN by design — per [[65c2553]] wiring the undercounting ledger is worse than NullLedger's
honest "unknown"; it is post-Sunday follow-up, not an acceptance blocker. Unattended operation
remains gated on FLT-4 (blind reviewer must catch a real planted defect) — a separate ticket.
Build a Claude-independent orchestration layer: LangGraph/Deep Agents supervisor (Python — stated
C#-first deviation: ecosystem-standard tooling + career skill acquisition + the orchestrator that
covers Claude outages must not depend on Claude) that routes ticket-sized work across codex,
claude, gemini (agy), grok CLIs and local Ollama. Supervisor model is swappable (any
provider) — that is the outage-continuity property. Executes through existing C# rails
(fleet-dispatch listeners, git worktrees, NATS trust tiers) via the FLT-2 contract; replaces no
working tool. Includes minimal mission-control UI (Agent Chat UI or LangSmith Studio local dev
only). Acceptance: with the Claude CLI unavailable, a board ticket still flows
route → implement (Codex) → adversarial review (Grok) → validation gate → human approval.
Driver: 2-day Claude outage this week (unacceptable); portfolio value.
Ceiling sign-off (WT-0924, 2026-07-14) — HELD, not a redo. Code is sound: FLT-3 discipline
throughout (git's answer, never the agent's), fresh worktree per escalation attempt (a failed
agent's half-edits cannot leak into the next), blind reviewer runs in a THROWAWAY EMPTY DIR
(reviewers judge, they do not touch — preserves the measured diff), approval_required halts the
graph rather than testing past a raised control point, no-reviewer degrades to mandatory human
review. Real-run codex --json fix = FLT-3 proving itself.
Blocking finding — correlated failure is live in code. routing.yaml ships
escalation_ladder: [ollama, codex, claude, gemini, grok], which predates the FLT-15/WT-df2d agy
research and contradicts it: Grok must precede agy-GPT-OSS (third scarce fixed-cap pool, not a
free lane); gemini is one lane where agy exposes four of differing scarcity; agy-Claude has no
reserve distinction, so a keyword classifier can reach the ~1-call/5h interrupt budget and
evaporate it. And graph.py treats rate_limited as "a transient vendor 429" and walks to the
next rung — the independent-capacity assumption. Per WT-df2d a locked-out agy pool transfers load
to Codex/Grok and ACCELERATES their limits, so the harness hands out bandwidth it does not have
exactly when pools are collapsing.
Gates to land: (1) FLT-6 corrects routing.yaml (order + agy lanes + agy-Claude as
governor-flag-only, unreachable by any classifier); (2) FLT-15 dependency — rate_limited must
consult the agy ledger for cap-proximity instead of assuming the next rung is fresh.
Gate 1 CLEARED + gate 2 seamed (WT-f255, 2026-07-14, 0491f9e). routing.yaml is now modelled
on pools, because seats are what we route and pools are what run out:
- pools (native-claude, codex, agy-gemini unified, agy-claude fixed-cap reserve, agy-gpt-oss
fixed-cap, grok, local) each with kind + scarcity + windows.
- The four agy lanes split out, model labels verified against live agy models (wrong labels
fail SILENTLY): gemini-flash (bulk), gemini-pro-high (escalate_only — SAME pool as Flash,
so never a fallback for it), agy-gpt-oss, agy-claude.
- Ladder corrected → claude, codex, gemini-flash, grok, agy-gpt-oss, ollama. Grok precedes
gpt-oss (third scarce fixed-cap pool, not a free lane).
- agy-claude is reserve_only: no ladder, no role, unreachable by any classifier;
--break-glass {native_red,review_gate,council_synth} appends it as the LAST resort and records
the reason in the gate packet. RoutingTable.validate() fails the build if anyone puts the
reserve on a ladder or makes it a role's primary — the config guards itself.
- review_ladder is family-distinct: agy's Claude lanes are Anthropic seats behind a Google
login, so name-only exclusion would let Claude review Claude.
rate_limited no longer means "try the next rung." A 429 locks the seat's whole POOL
(siblings share the cap and were never fallbacks). After max_pool_lockouts (1) distinct non-local
pools lock, the ladder STOPS and escalates to the human rather than spending pools whose
cap-proximity is unknown — deliberately pessimistic, since over-escalating during a correlated
collapse is the expensive failure and a human gate is cheap. One lockout is still survivable (a
single 429 is not an outage). CapacityLedger is the FLT-15 seam; NullLedger knows only what the
current run saw and answers cap_proximity() → None — unknown, said out loud, never a comforting
0.0. Lockouts live in graph state, so they survive node hops and checkpoint/resume without leaking
across runs. Gate 2 remains open until FLT-15's fleet-global ledger exists — this bounds the
damage, it does not measure capacity.
Gate 2 re-affirmed OPEN — do NOT close it by wiring the current ledger (WT-66db, 2026-07-15).
The FLT-15 ledger cannot answer cap_proximity() honestly yet, and a dishonest answer is worse
than None. Two structural holes, verified tonight, both biased the SAME direction — undercount:
- Not fleet-global. AgyConfig.SharedPath is unset in the live ~/.claude/usage-governor/config.json
(no agy block at all), so GovernorPaths.AgyLedgerPath() takes the local-BaseDir fallback.
Each PC counts only its own spend; see [[agy-gate-bypassed-by-skills]].
- Undercounts even locally. agy-wrap.ps1 still has ZERO production invokers (re-verified
2026-07-15: every agy-wrap hit across source
epos is a test, doc, CI file, or the wrap
itself). Skill-driven agy spend — /gemini-review, the council Gemini seat — calls agy.exe
direct and is never booked.
An undercounting ledger returns a LOW cap_proximity — "plenty of room" — exactly during the
correlated collapse gate 2 exists to catch, and graph.py would act on that number. This is the
Kerr shape ([[kerr-lens-standing-gate]]): closing gate 2 would reward "the ledger returns a float"
while hoping for "the harness knows real capacity." NullLedger's None — unknown, said out loud
— is the SAFER posture, and the build already got this right; wiring the ledger would undo it.
Sunday posture: ship FLT-1 usable on NullLedger + max_pool_lockouts=1. Acceptance (a ticket
flows route → implement → review → gate with the Claude CLI unavailable) does not require a ledger.
Gate 2 is post-Sunday and needs the two holes closed — shared UNC ledgerPath, plus the admit moved
into a helper the skills actually call — not a wire-up.
INDEPENDENTLY CONFIRMED, and the wire-up was built anyway before it was checked (WT-3e93,
2026-07-16). WT-3e93 built exactly the wire-up WT-66db forbade — GovernorLedger +
cap_proximity_skip=0.9 consumed in Router.is_available() — took it through a full 6-seat council
(2 High / 4 Medium found and fixed, 6 convergence passes), and only then rebased onto 65c2553 and
read this entry. WT-66db is right on both holes, and WT-3e93's own artifacts prove it:
- Hole 1 confirmed by measurement, not argument. The live ~/.claude/usage-governor/config.json
has NO agy block: ledgerPath and sharedPath are both empty, so the resolved path is the
local C:\Users\fives\.claude\usage-governor\agy-ledger.jsonl. The probe output printed that
local path and it went unread — the "fleet-global" premise was in the module docstring, never in
the config.
- Hole 2 confirmed by the numbers. Deployed agy-status --json reports gemini
spentWeekly: 83222 / 60000000 over 16 calls — ~0.2% — on a night this very session ran the agy
Gemini seat twice through agy.exe direct. capProximity came back 0.0019: a
four-PC-shared, months-old pool reporting itself untouched. That is the LOW-proximity
"plenty of room" failure in the wild, and cap_proximity_skip would have routed on it.
Held, not landed: wt/WT-3e93/FLT-15 is pushed for review but deliberately NOT on master. It
is the right code against a premise that is not true yet; landing it would trade None (honest) for
0.0019 (confident and wrong). Gate 2 stays OPEN. Revisit only once both holes close, and re-verify
the ledger is shared by reading the resolved path out of agy-status --json, not by reading the
code that supports one.
Landed prerequisite: agy-status --json (usage-governor master 2aba701, deployed + smoke-
verified on this PC via deploy.ps1; 249/249). It is orthogonal to the wiring question — a
read-only, versioned status contract that FLT-13's cockpit and any future gate-2 work both need, and
it makes nothing act on the undercount. Its ledgerPresent/capProximity: null semantics are also
what let a consumer say "unknown" out loud instead of inferring zero.
Steal list (council 2026-07-14)¶
FLT-2 · run_agent uniform contract as C# adapter layer — Done (WT-0bf0, 2026-07-14: landed master 3a027bb, 168/168 green)¶
run_agent(task, repo, branch, mode) → structured JSON (status ∈ completed/failed/timed_out/
rate_limited/approval_required, summary, changed_files, tests_attempted, known_risks,
needs_human_review) wrapping all four CLIs inside fleet-dispatch. Host owns timeouts, retries,
worktree creation, diff collection. This is the tool surface FLT-1 consumes — build first.
Shipped: IAgentRunner + adapters (codex/claude/gemini-via-agy/grok) in
fleet-dispatch/src/FleetDispatch.Core/AgentRun/; host-owned worktree ({repo}-agents/{jobId},
branch wt/{jobId}/{ticket}), 20-min default timeout, one retry, git status --porcelain -z diff
collection, and the FLT-3 validator. Two entry points: queue kind run_agent + CLI verb
run-agent. TOKENROI_CONTEXT=fleet-dispatch in child env. Schema frozen and documented for
FLT-1 in fleet-dispatch/docs/run-agent-contract.md.
Verified end-to-end (not just mocks): real codex run created a file in its worktree,
changed_files collected, summary extracted. FLT-3 gate proven live — codex reported "Succeeded
completely… All applicable tests pass" against a failing validator and the contract returned
status=failed, claim discarded, exit 1.
Council gate: Codex + Gemini + Grok seats, Codex chairing (local Ollama seat crashed OOM on the
64KB diff; house seats not run — gaming MCP transport dropped, streaming skipped under YELLOW
context-diet). 3 High fixed: status spoofing via classifiers on exit 0, unbounded/undeadlined
output drains, git option injection via base branch. Convergence pass then caught orphaned
descendants surviving the timeout → Windows job object. Real-run verification caught a wrong codex
--json event schema that every mock had agreed with.
Known gaps: agent worktrees not registered with the WorktreeOwnership registry; no GC for
abandoned {repo}-agents/*; mode recorded but not behavioral.
FLT-3 · Never-trust-agent-claims validation gate — Done (WT-0bf0, 2026-07-14: both halves landed — fleet-dispatch 3a027bb + llm-council 4f228d2)¶
Gate (council-code-review + FLT-2 host) reruns build/tests/lint itself; agent self-reported "tests pass" carries zero weight. Highest-ROI item, pure policy. Codify in the review skill and in FLT-2's validator.
Code half (fleet-dispatch 3a027bb): AgentRunValidator reruns build/tests itself and
records ACTUAL exit codes in tests_attempted; agent claims never consulted.
needs_human_review is only waivable when validation actually ran, passed, the diff is non-empty,
and no risks were recorded. Proven live — codex claimed "all applicable tests pass" against a
failing validator; contract returned status=failed.
Skill half (llm-council 4f228d2): council-code-review gains Round 4 — validation,
replacing the old Round 3 step "run the project's build/tests if they exist and are fast
enough" (which permitted verifying nothing). Now: rerun build/tests/lint yourself, take commands
from the repo's own entrypoints and name the source, paste cwd + command + exit code + evidence,
and a mandatory Validation block in the final report. The two halves are twins and must not drift
apart.
Council gate found the hole in the first draft — all three seats independently: "not a
subset… unless you say so" made disclosure into permission (run a fast subset, admit it, still
report passed). Grok also caught that Round 4 contradicted this skill's own seat contract,
which already teaches that exit code is not proof. Fixes are mechanical, not discretionary,
because the implementer IS the validator: subset/filter/0-tests → max unverified even when
disclosed; diff touching tests/mocks/CI → max unverified unless a real smoke ran and is pasted;
verdict = worst outcome any rule triggers; FAILED/unverified is not commit-ready.
Also closed en route: the tracked skill had been stale since 07-10 while the deployed
~/.claude copy gained four days of hardening (Ollama HTTP-API seat, canary probe, seat
validation contract, house-seat main-thread rule). Adopted as its own commit (35f5489) so the
policy diff stayed reviewable; live and tracked copies are now byte-identical.
Deployed fleet-wide 2026-07-14. All 4 PCs now run the same skill, verified byte-identical by
SHA256 (ACB17AAC…, 35317 bytes, 579 lines, frontmatter parses on each). Copied with scp
(byte-exact) — great-room, gaming (10.0.0.7), streaming (10.0.0.26), bedroom (10.0.0.36).
Fixed en route: streaming and bedroom were carrying mojibake — em-dashes corrupted to
replacement chars by whatever ad-hoc method placed the 07-10 copies (gaming was clean; that was
the 4-byte size difference that exposed it). The new file is dense with —/→/braille, so a
byte-unsafe deploy would have corrupted it again. scp fixed it as a side effect.
Not closed:
- Validation still runs from the agent's own tree, so an agent that weakens its own tests can
pass. The skill now caps that at unverified rather than pretending otherwise, but a true
independent oracle (pristine test pack) remains unbuilt.
- There is no standing skill-deploy mechanism. The 07-10 copies were placed ad-hoc, which is
exactly how the encoding corruption got in and how the boxes drifted 4 days behind. Today's
deploy was also manual — the next skill edit will drift again unless this is automated
(candidate: a fleet-dispatch job, since the rails now exist).
- The codex-harness-mirror carries a deliberately INVERTED council-code-review (Claude chairs,
Codex implements). It did not get the FLT-3 Round 4 policy — same never-trust argument
applies there and it is now inconsistent with this skill.
FLT-4 · Blind reviewer seat for llm-council — In Progress — built, NOT landed, does not meet acceptance (WT-aa8c, 2026-07-15)¶
Seat variant receiving ONLY spec + diff + test output — no implementer narrative — to break reviewer correlation/anchoring. Wire into /council-code-review as a standard seat.
Built by Codex on wt/WT-aa8c/FLT-4 (f2e31c1, unpushed). Codex reviewed it with its own seats
twice — "no blocking findings", 97/97 green. One independent vendor-distinct seat (Grok) then
found the feature IS NOT WIRED TO ANYTHING. Verified directly:
- SelectBlindReviewer — defined CouncilConfig.cs:111, called ONLY from tests.
- BlindCodeReview — defined CouncilEngine.cs:193, called ONLY from tests.
- CouncilEngine.RunAsync never reads IsBlindReviewer/ReviewMode/Family.
So reviewMode: "blind-review" has zero runtime effect — run the binary and Gemini gets
ordinary Stage 1/2/3. The blind pipeline is library helpers + unit tests + SKILL.md prose telling
an agent to do it by hand. 97/97 passes while proving nothing about the real flow.
Two deeper findings, both real:
- The no-narrative test is theater. It asserts by reflection that the prompt builder has no
parameter named narrative — the signature's shape, not the payload. Narrative still arrives via
caller-controlled ticketSpec, diff, or testOutput, and the prompt grants repo access
(scratchpads, BOARD notes, agent logs). This board previously recorded that pin as "structural";
that was wrong.
- "ACTUAL TEST OUTPUT" launders an agent claim as evidence. testOutput is a caller-supplied
string under an authoritative header the seat is told to trust. No capture wrapper, exit-code
binding, or runner stamp. This re-opens the FLT-3 hole upstream, inside the seat built to be
trustworthy. Real fix: the harness captures test output; the implementer never hands it over.
Also: only gemini is tagged blind-capable, so Gemini-authored work has no family-distinct
blind seat and selection throws (right instinct, brittle pool — tag several families). Families are
free strings with no load-time schema check, so a mislabelled Anthropic-behind-Google lane is taken
at face value.
Left for a fresh session, not bodged at 02:00 under RED: wiring blind selection into
CouncilEngine is a design decision (replace Stage 2 for that seat, or add a stage?) and deserves
one. Branch kept — the family/fail-closed logic and prompt builder are sound, just unconnected.
Meta-result worth keeping: one independent vendor-distinct seat caught a non-feature that a self-review passed twice. That is this ticket's own thesis, demonstrated on this ticket — and the argument for building it properly.
FLT-5 · Capability manifests in fleet-dispatch registry — Backlog¶
Per-PC manifest: GPU/VRAM/RAM, installed models + roles + context, CLIs, tools, max_jobs, online. Dispatch checks manifest before routing; improves Ollama routing (gaming=qwen3-coder primary, streaming=CPU heavyweights batch-only).
FLT-6 · Deterministic role-routing config + escalation ladder — In Review (WT-f255, 2026-07-14: table shipped)¶
Config (not code): implementation→Codex, architecture/deep review→Claude, browser/QA→Gemini, research/adversarial→Grok, high-volume cheap (triage/summaries/format checks)→Ollama; escalation local-small→local-large→cloud→independent reviewer→human. Shared by usage-governor, fleet-dispatch, and FLT-1 so all three read one table.
Shipped 2026-07-14 as fleet-harness/routing.yaml (repo root so the C# readers need no
Python package knowledge). Contains: roles table, keywords classifier, advisory_roles
(text-only roles that skip worktree/review/validation — the seam that lets the non-editing
Ollama seat own cheap-bulk), escalation_ladder, review_ladder (blind reviewer must be a
different vendor), timeouts. Read live by FLT-1. Outstanding: usage-governor and
fleet-dispatch must be pointed at this same file — until they are, this is one table with one
reader, and the anti-fork property is unproven.
Outstanding (2026-07-14, from FLT-15 council): the table models gemini as one lane, but agy
actually exposes four with different scarcity — gemini-flash (bulk default), gemini-pro-high
(escalate-only), agy-gpt-oss (burst overflow behind Grok, own small cap), and agy-claude
(out-of-band reserve, never routable by the ladder). escalation_ladder must be reordered to
… → agy-Gemini → Grok → agy-GPT-OSS → local, and agy-Claude must be expressible as a
governor-flag-only lane that no keyword classifier can reach — "hard task → agy-Claude" evaporates
the reserve. review_ladder's different-vendor rule needs family-distinct seats: agy-Sonnet/Opus is
a Claude seat, not a Google one.
Correlated-failure hazard for FLT-1 (2026-07-14, WT-df2d): the rungs are NOT independent capacity. When an agy pool locks out, load transfers to Codex/Grok and accelerates THEIR limits — correlated degradation, not graceful. FLT-1's availability probe + escalation MUST weight downstream pools by upstream cap-proximity, not treat each rung as fresh bandwidth; a model that assumes independent fallback overestimates total fleet throughput. Verify this in the FLT-1 ceiling sign-off before it lands.
FLT-7 · SARIF/machine-readable CI gates — Backlog¶
Security + accessibility + analyzer outputs emitted as SARIF/JUnit/JSON; thresholds enforced by CI before any expensive LLM review runs. Baseline-vs-PR comparison so legacy findings don't drown regressions.
FLT-54 · Ollama seat wrapper must fail loudly on empty/degraded output — Done (WT-aa8c, 2026-07-15: landed llm-council master 529ecd2)¶
The silent no-op: a RAM-starved ollama seat returned nothing and the council counted it as SUCCESS.
Ollama never errors when a model does not fit — it silently offloads to CPU, and the
"insufficient VRAM" signal is slog.Debug-only. The caller is therefore the ONLY place this can
ever be caught, which is why this is a wrapper fix and no admission gate or telemetry could
substitute for it.
Shipped: all four degraded shapes (non-zero exit, empty, whitespace-only, implausibly short) plus timeout now fail loudly at the single invocation seam every production seat call passes through, attributed with seat/model/host/condition. No fallback, no retry — council ruled loud refuse over silent degrade.
Council gate (Codex chair + Gemini + Grok, 3/3) + a Codex convergence pass. What the gate
actually bought, since this is the argument for keeping the gate:
- Exit-code asymmetry (all 3 seats). Empty output kept ExitCode 0 while merely-short output
got the -3 sentinel — the more severe shape was the one a caller reading the exit code would
wave through. It was non-silent only because Success separately checks emptiness, so the guard
would have quietly died the day someone simplified Success. Every unusable exit-0 shape now
carries the sentinel.
- Threshold (all 3 seats). 8 chars is indefensible: "I agree." is exactly 8. Now word count
+ char floor, centralized as CliResult.IsPlausibleAnswer so the rule cannot drift.
- Host attribution (Grok). An ollama seat pointed at another box via OLLAMA_HOST runs there
while the council runs here; MachineName named the wrong machine. The convergence pass then
found two real bugs in that fix (raw command tested before env expansion; substring match
catching not-ollama.exe) — now matched on the expanded basename.
- Temp-path injection (Codex). Config-controlled seat names landed in a filesystem path.
91/91 tests, rerun independently rather than taken on the builder's word; the exit-code guard is mutation-checked (revert the fix and it fails).
Deliberately not taken → FLT-57 (CliResult.Success should own the plausibility rule; ~15 fake
fixtures to rewrite, and prod has exactly one ICliRunner so the bypass is test-only) and
FLT-58 (council drops a failed seat and still exits 0 — pre-existing designed behavior, wider
than this ticket; a 5-seat verdict silently produced by 4).
Access + boards¶
FLT-8 · Mesh network: Tailscale pilot, Headscale decision gate — PHASE 1 DONE (WT-0924, 2026-07-15)¶
Phase 1 shipped 2026-07-15. Tailscale 1.98.8 on all 4 PCs, one tailnet, owner andrewjonesdev1@:
andygreatroompc 100.69.90.95 · andrewbedroomtv 100.85.245.95 · desktop-d249kd4 100.110.224.88
· desktop-scdt9hi 100.78.38.60. netcheck: UDP true, direct paths (not DERP-relayed; nearest
DERP Chicago) — bedroom verified direct 10.0.0.35:41641 with live traffic. Cost $0 (Personal plan,
unlimited own devices). Fleet installs ran via fleet-dispatch (--kind pwsh --payload-file; winget
elevated fine under the listeners); per-PC auth URLs written to
OneDrive\PC-Bootstrap\_shared ailscale\<PC>.txt, Andrew clicked each.
Two failure modes worth keeping: (1) tailscale login must run DETACHED — the auth URL dies with
its process, which cost three retries on the main PC; the fleet script starts it with Start-Process
so it survives the dispatch job. (2) --kind pwsh executes the payload as a SCRIPT — prose payloads
exit 1 with no useful error. Natural language needs --kind claude.
Outstanding (not phase 1): repoint hardcoded 10.0.0.x in council MCP configs, claude-mem, and
fleet-dispatch peers at MagicDNS names — until then the Wi-Fi-drift breakage class is only fixable,
not fixed. Phones (iPhone + Pixel Fold) not yet joined. Headscale decision gate untouched (only
pays off if tester seats would cost money).
Phase 1: Tailscale free plan on all 4 PCs + phone (unlimited own devices, $0, zero ops); testers
via node sharing. Kills Wi-Fi-drift breakage class via MagicDNS/stable addresses; SSH mesh + NATS
stay (Tailscale = connectivity layer, not exec/bus). Phase 2 gate: IF testers need full
membership (would cost $8/user/mo) OR self-host mandate → evaluate Headscale (self-hosted
open-source control plane, $0 license) with DR: config + SQLite state backed up nightly, warm
standby on second PC, documented failback. Decision recorded here before phase 2 spend.
FLT-9 · Vikunja hardening + DR (the self-hosted "Jira") — In Review — gates passed; one exposure decision open for Andrew (WT-aa8c, 2026-07-15: landed master 8ffa9c7; WT-37e6, 2026-07-17: PS 5.1 encoding fix 0f6a95a)¶
Nightly pg_dump -> OneDrive, restore verification into a throwaway container, healthz watch on
the claude-mem watchdog pattern, + Scheduled Task install/uninstall. Scripts proven against the
LIVE stack; the Scheduled Tasks are deliberately NOT registered — that would put live tasks on a
schedule unasked. One command away when wanted.
Council gate (Codex, adversarial) found 2 Criticals. Both real, both fixed:
- docker rm -f $TempContainer ran before anything proved the container was throwaway.
-TempContainer vikunja-db-1 would have destroyed the live board's Postgres. Now every removal
passes a label gate (flt9-throwaway=true, checked via docker inspect) plus a name-equality
refusal. Verified by extracting the REAL shipped guard functions and driving them against an
unlabelled stand-in: it refused, and the container survived. vikunja-db-1 carries no such
label, so it hits the same refusal. The guard was deliberately NOT tested by pointing a delete at
the live database — a guard you must risk the board to trust is not a guard.
- The dump was written inside the LIVE container's /tmp, so a mid-run failure left a full
dump (password hashes, tokens) sitting in it. Now removed in a finally on every path.
Stated deviation: the in-container temp file was KEPT rather than streaming pg_dump to stdout,
because PS 5.1 native-stdout redirection is not byte-safe for a SQL dump. Byte integrity beat
elegance.
- Also fixed: the live DB password rode on the docker.exe command line where local process
telemetry can read it (the container now resolves its own $POSTGRES_PASSWORD internally, so it
never appears host-side); docker cp ignored its exit code, so a truncated copy still logged
BACKUP OK (now byte-count verified); sh -c interpolated $DbName/$DbUser, so a hostile
param could execute arbitrary shell inside the live container (now allowlist-validated).
Verified independently, not on the agent's word: backup byte-matches (137849 bytes host ==
container); restore into the throwaway asserts 2 projects / 50 tasks / 1 user + real project titles
against a sidecar baseline captured from live at dump time, so it cannot pass vacuously by
checking the dump against itself; throwaway torn down; live vikunja-db-1 / vikunja-vikunja-1
untouched (10h uptime, healthy); live row counts unchanged; no /tmp residue.
OPEN DECISION FOR ANDREW — deliberately not made unilaterally. The dump is the FULL database (password hashes, API/session tokens, all user and task data) and lands in OneDrive, unencrypted. The ticket asked for OneDrive, so this is as-specified, and it is now documented plainly rather than buried — but it is a real exposure choice: encrypt at rest, keep local-only, or accept. Nothing is scheduled, so nothing syncs on a timer; dumps from tonight's proof runs are already in OneDrive.
Honest limit: restore verification checks projects/tasks/users counts + project titles. That proves the restore path works; it would NOT catch a future dump silently excluding labels, comments, attachments, or tokens. Deferred per ticket scope: second-PC warm standby, mesh exposure (blocked on FLT-8/Tailscale), agent API tokens, board-sync (FLT-11, owned elsewhere).
Update 2026-07-17 (WT-37e6): PS 5.1 encoding corruption fixed — landed master 0f6a95a.
Restore-verify false-failed under Windows PowerShell 5.1 (the host Install-VikunjaDrTasks.ps1
falls back to when pwsh is absent): Get-Content decoded the BOM-less UTF-8 .meta.json sidecar
as ANSI, mojibaking em-dash project titles and failing the known-project assertion (pwsh passed
the identical run). Root-causing exposed a worse writer-side bug: under 5.1 with the cp437 OEM
console (the Task Scheduler default), docker exec psql UTF-8 stdout is decoded as cp437, so
Backup-VikunjaDb.ps1 wrote mojibake sidecars corrupt at rest — hex-confirmed: em-dash stored
as the UTF-8 bytes of "ΓÇö". Fix: verifier reads the sidecar via [System.IO.File]::ReadAllText;
both scripts force [Console]::OutputEncoding to UTF-8 for the script lifetime (restored in
finally, try/catch for console-less hosts). The two corrupt 2026-07-17 sidecars (19:03, 20:17)
were repaired in place and re-verify green. Validated end to end, all exit 0: full restore-verify
under 5.1 + cp437 console, plain 5.1, and pwsh; fresh backup under 5.1 + cp437 writes true
E2 80 94 em-dash bytes. Gate: cavecrew-reviewer (0 findings) + 2-member gaming council
(qwen3-coder:30b, devstral:24b — 0 confirmed findings; note for future gates: the full 5-model
council fan-out exceeds the MCP transport timeout on both council PCs, pass a members subset).
FLT-10 · Jira Cloud Free + Rovo MCP trial (parallel, not replacement) — Backlog¶
$0 cloud tier, 10 users. NOTE: self-hosted Jira not viable (Server EOL 2024; Data Center pricing absurd for solo) — Vikunja (FLT-9) is the self-hosted lane. Trial: Andrew creates Atlassian account + site (agent cannot create accounts), then: FLEET project, agent-oriented statuses (Ready for Agent → Agent Working → Automated Review → Needs Human Review → Done), custom fields (Primary Agent, Review Agent, Risk, Branch, Run ID), Rovo MCP wired to FLT-1. Retire a board only after board-as-contract checklist passes: local export, stable ticket IDs, status transitions via API, token-roi hooks, offline fallback.
FLT-11 · Three-board redundancy sync — Done — WT-77c4, landed¶
Board sync: 2026-07-18T19:35:09Z — WT-77c4 moved FLT-11 from In Review to Done.
Board sync: 2026-07-18T19:09:59Z — WT-77c4 moved FLT-11 from In Progress to In Review.
Board sync: 2026-07-18T19:08:37Z — WT-77c4 moved FLT-11 from Backlog to In Progress.
This file + Vikunja + Jira kept in lockstep: small C# sync tool (or FLT-1 graph node) that mirrors ticket status transitions across all three; conflict rule = this file wins until Jira trial passes checklist, then re-vote. Every transition timestamps + names the mover.
FLT-51 · Skill/config deploy mechanism — byte-exact, hash-verified, drift-aware — Done (Jira key FLT-51)¶
Board sync: 2026-07-18T21:23:23Z — WT-4426 moved FLT-51 from Backlog to Done.
No standing way to deploy ~/.claude/skills (and peer config) across the 4 PCs. Every deploy is
ad-hoc, and that cost real damage twice in one day (2026-07-14, found by FLT-3):
- Silent staleness — the tracked skill sat at 07-10 while great-room's deployed copy gained 4
days of hardening never committed back; the other 3 PCs sat 4 days behind.
- Encoding corruption — streaming + bedroom carried mojibake (em-dashes → replacement chars)
from whatever ad-hoc method placed the 07-10 copies. Not cosmetic: the seat validation contract
matches on braille spinner glyphs (U+2800–U+28FF), so a mangled copy silently breaks the
check that catches dead council seats. A 4-byte size difference is the only reason it surfaced.
The non-obvious requirement: drift is bidirectional. A naive push tool would have destroyed
the good version — on great-room the live file was AHEAD of the repo. This cannot be a one-way
scp fan-out; it must detect unrecognized drift and refuse to clobber it.
Scope: canonical = the git repo, never a live ~/.claude file; byte-exact transport (scp-class,
NEVER Set-Content/Out-File — that caused the mojibake); SHA256 verify per target after write
with a printed match table (no "deployed" without an observed match — FLT-3 applies to this tool
too); drift check BEFORE write; idempotent. Rails exist: fleet-dispatch (kind pwsh or
run_agent) + the SSH mesh. C# in fleet-dispatch per standing language policy.
Acceptance: one command deploys to all 4 PCs and prints a per-PC hash table; a deliberately drifted PC is flagged, not clobbered; a file with em-dash/arrow/braille round-trips byte-identical (regression test for the real bug); a re-run reports no-op.
Also decide (don't assume): codex-harness-mirror carries a deliberately INVERTED
council-code-review. It is a variant, not a stale copy, so this tool must not overwrite it —
but it also never got FLT-3's Round 4 policy, so the two gates now disagree about whether an
agent's "tests pass" counts. Either the tool understands variants, or variants are explicitly out
of scope and tracked another way.
Origin: fell out of FLT-3 (llm-council 4f228d2). Same class as FLT-11 (keeping N copies in
lockstep) — the two may share a mechanism. ~/.claude/CLAUDE.md belongs in this tool's scope
too — see FLT-53, which is the same root cause found in the same place.
FLT-53 · CLAUDE.md drift: 3 PCs missing 4 standing policies, each with its own stale review-gate section — Backlog (Jira key FLT-53)¶
Found 2026-07-14 deploying the board-footer rule. Surfaced, not fixed — fixing means
overwriting hand-written content. The 3 remote PCs' ~/.claude/CLAUDE.md are NOT copies of
great-room's; all four differ (great-room 7510b; gaming 5904b; streaming 5480b; bedroom 5819b, all
remotes dated 07-11).
Two directions of drift at once:
1. Remotes lack four STANDING policies great-room has: language policy (C#-first — which
itself says "Applies on every machine, every model, every harness"), worktree/session
identity, model escalation ladder, usage governor. worktree-identity + claude CLI are
installed on all three, so sessions DO run there — without knowing about C#-first, the ladder,
or the governor's YELLOW/RED rules.
2. Each remote has a review-gate section great-room lacks, all three worded differently
("Review gate standard" / "Review gate (house standard)" / "Council review gate (standard)"),
and all three reference /council-review — a slash command that does not exist. The skill
is council-code-review. Three PCs point sessions at a non-existent command, three ways.
The board-footer rule was therefore appended as its own marker-fenced block
(<!-- board-footer-begin -->), built locally and scp'd byte-exact, leaving each PC's content
intact — verified block present + review-gate preserved + SHA256 match on all three.
Decide then do: which policies are genuinely fleet-wide vs deliberately great-room-only; reconcile
the three review-gate sections into one and fix the /council-review name; and whether CLAUDE.md
should be composed of marker-fenced blocks from a canonical source (the shape FLT-51 could manage)
with only machine-specific content local. Blocked on/related: FLT-51, same root cause.
FLT-13 · Mission Control frontend: Angular + NSwag PWA cockpit — In Progress — PHASE 1 SHIPPED + QUOTA SURFACE (Jira key FLT-46)¶
Phase 1 status wall DELIVERED 2026-07-14 (WT-df2b) in new repo fleet-mission-control
(local master, 2 commits, NOT pushed). ASP.NET Core net10.0 minimal API + SignalR /hubs/fleet
(WorkerHeartbeat/RunUpdated/GovernorTier, 5s poll) reading fleet-dispatch queues read-only +
governor state.json + Jira REST (60s cache). Angular 22.0.x pinned PWA, NSwag TS client generated
from build-emitted openapi/*.json (hub DTOs forced in via /api/meta/hub-events;
npm run check:drift = CI failure). 3-pane/dual-pane/card-stack via container queries, light+dark,
WW resilience interceptor. Verified LIVE against real dispatch data (4 workers probed, 50-run
stream, YELLOW governor, hub ● live). Council gate ran: seats Codex+Gemini+Grok+local qwen3:8b
+gaming:qwen3-coder:30b+streaming:llama3.3:70b (gaming devstral FAILED/canceled; local+house diffs
bounded); chairman 1 High (probe SSRF allowlist) + 6 Med + 5 Low — ALL implemented; backend 20/20,
frontend 19/19, builds green. Phase 2 (approve/reject) unblocked; FLT-14 unblocked for read-only panels.
Stack decision REVERSED 2026-07-14 by runoff council (unanimous 5/5 + 2 house seats, DECISIVE):
Angular latest + CI-generated NSwag clients beats Blazor InteractiveAuto. Deciding: time-to-cockpit
(usage bleed now), hub-DTO generation kills the type-drift argument (only hub method names stay
hand-written), Blazor prerender double-fire risk on the approve button, npm purity already dead at
the VS Code extension, McKinley innovation token already spent on the LangGraph harness. Flip
condition on record: heavy run_agent contract churn → revisit Blazor (contract is frozen, 168/168).
npm mitigations mandatory: lockfile + pins + private mirror + tailnet-only. Design/mockups unchanged
(visual language is stack-agnostic):
Design proposal: https://claude.ai/code/artifact/1849163f-6a8d-42a9-9c8a-d8a5e536a14c — steel/amber
ops cockpit. C# Blazor Server PWA on the tailnet (Tailscale Serve HTTPS; iOS + Android Tailscale
apps cover iPhone + Pixel 10 Fold, PWA install, no app stores). Responsive: desktop 3-pane
(fleet+queue | activity stream | approval gate), iPhone card-stack approvals, Fold dual-pane
unfolded. Phases: 1 status wall (SignalR read-only) → 2 approval gate (FLT-1 interrupt() +
FLT-2 approval_required) → 3 dispatch-from-phone → 4 VS Code extension panel.
Quota surface (added 2026-07-14 from FLT-15): the status wall is the natural place to make the FLT-15 agy ledger visible, because the ledger is heuristic — there is no quota API, so a human eyeballing drift is part of the design. Phase 1 shows per-pool gauges (native Claude 5h/weekly, agy-Gemini unified pool, agy-Claude reserve as remaining invocations not a percentage, agy-GPT-OSS, Codex, Grok) with the weekly cap rendered as the hard cliff it is, and a "reserve intact / spent" indicator for agy-Claude. Phase 2's approval gate is also where an agy-Claude break-glass invocation gets its reason code — the one human control point that keeps reason drift to "convenience" visible. Cockpit reads the ledger; it must never be a second writer (FLT-15's single-writer rule). VS Code fork REJECTED (TS/Electron 1.5M-LOC maintenance trap; IDE exists — gap is command & control). Native mobile SKIPPED (PWA + fleet-telegram push suffice).
✅✅ FLT-14 COMPLETE — 6/6 SURFACES LANDED ON MASTER (2026-07-16 22:5x)¶
adeb6a2 — VS 2026 extension landed. All six surfaces are real and receipted:
| Surface | Receipt |
|---|---|
| web/desktop, iPhone 17 Pro Max, Pixel Fold 10 | 236a73f, CI green, mutation FE 94.44% |
| VS Code + Antigravity x2 (ONE VSIX) | cc26da2, real extension host, VS Code 1.107.0 (the version the forks ship) |
| VS 2026 | adeb6a2, human click -> NavigationCompleted success=True — PIXELS RENDERED, then scroll confirmed docked |
The last two bugs were found by Andrew using it, not by any gate:
1. Style=Float 900x600 could not be resized at all. Now Style=Tabbed docked against Solution
Explorer (GUID 3ae79031-...), so it behaves like a normal VS tool window. The old code's comment
blamed Tabbed for a never-visible frame — that diagnosis was wrong; the frame was invisible because
of the programmatic auto-show, which no longer exists.
2. THE COCKPIT HAD NO SCROLL CONTAINER — ANYWHERE. Every overflow in the app was hidden for text
ellipsis or a gauge. So the moment the panes stacked (<600px: a phone, or the cockpit docked narrow
in VS) the stack was taller than the pane and the bottom was UNREACHABLE. Fixed 43c39bb
(overflow-y:auto on .cockpit-container; min-height:0 was already there, which is what lets a flex
child shrink and scroll). Pinned with a NEGATIVE-CONTROLLED test — remove the rule and it fails. 106->107.
This was broken on a surface already called "landed", and Lane A's screenshots could never have caught
it: a screenshot shows the TOP of a layout and says nothing about reaching the rest.
Council gate on the VS extension caught 4 real defects before landing (codex + own pass):
HIGH — missing bundled cockpit only logged exists=False then mapped+navigated anyway => BLANK cockpit,
all signals green. Now throws. HIGH — csproj packaged a VSIX with no cockpit behind a <Warning>; now an
<Error>. MED — WebView2 never disposed (owns a browser process + user-data lock) => leak per open/close.
MED — Loaded re-fires on EVERY re-parent, stacking duplicate inits; this fired live in testing 7s after
render, and it was a regression I introduced by removing a guard I had wrongly called a hack.
SESSION TALLY — 8 false success signals. frame.Show()==S_OK / IsOnScreen=1 / IsVisible=S_OK /
DocView==our pane all true while nothing rendered; VSIXInstaller exit 0 installing nothing; Stryker exit 0
running zero mutants (x2); a workflow "red X" that was actually zero jobs = CI fully off; council seats
"completing" with Argument list too long. Every real answer came from an artifact — a score, a file on
disk, a probe line, or a human looking at the screen.
✅ VS 2026 RENDERS. SOLVED 2026-07-16 21:48 — manual open works; my descope verdict was WRONG.¶
Andrew clicked View > Fleet Mission Control in a real Exp instance. Probe, verbatim:
21:48:13.937 Execute: on main thread, calling ShowToolWindowAsync
21:48:14.034 Loaded FIRED: control is parented, HWND exists -- starting WebView2 init
21:48:14.402 EnsureCoreWebView2Async OK -- WebView2 is live inside VS
21:48:14.405 virtual host mapping set: fleet.cockpit -> ...\media\webapp
21:48:14.406 Navigate() -> https://fleet.cockpit/index.html?apiBaseUrl=http%3A%2F%2Flocalhost%3A5170
21:48:14.520 NavigationCompleted success=True -- PIXELS RENDERED
Loaded fires, the control is parented with a real HWND, WebView2 initialises,
the virtual host maps the bundled Angular dist, and navigation completes. VS 2026 hosts the WebView2 cockpit
fine. DO NOT DESCOPE. The 6th surface is real.
What actually went wrong — all of it mine, none of it the platform:
1. Manual open works; programmatic auto-show does not. Every automated attempt used
ShowToolWindowAsync from InitializeAsync under [ProvideAutoLoad]. That path leaves the content
unparented (PresentationSource=NULL forever). A user-invoked .vsct command parents it instantly.
This is why the extension must open from a command, never auto-show.
2. MSYS mangled /rootsuffix into C:/Program Files/Git/rootsuffix on every bash launch, so devenv
opened the REGULAR instance where nothing was installed. Andrew's screenshot of VS's own
"these files could not be found" dialog is what exposed it. Launch via PowerShell Start-Process
-ArgumentList '/rootsuffix','Exp' — never from bash.
3. I sent Andrew to the wrong menu (View > Other Windows). The .vsct parents the group to
IDM_VS_MENU_VIEW = the View menu itself, priority 0x0600 (bottom). Lane C had documented this and
I did not read my own notes.
4. extensions.configurationchanged persisting was a red herring — the Extension Manager showed the
extension Installed + Enabled the whole time.
My "platform blocked, descope to commands-only" verdict was WRONG and is fully retracted. The council (codex/grok/gemini) refused it on VERIFIED grounds — no documented VS 18 bug, classic VSIX + ToolWindowPane + WebView2 is still supported — and they were right. Every "platform" symptom traced to my own harness.
Standing lesson: frame.Show()==S_OK, IsOnScreen=1, IsVisible=S_OK and DocView==our pane were ALL
true while nothing rendered. The only honest receipt was NavigationCompleted success=True — and it only ever
came from a human clicking. See [[verify-by-artifact-not-exit-code]].
FLT-14 · Private IDE extensions: VS Code + Visual Studio 2026 panels — In Progress — 4/6 surfaces landed; VS 2026 render unproven (Jira key FLT-47 · 2026-07-15 session WT-0026)¶
Scope corrected 2026-07-15. Requested as 6 surfaces (web/desktop, web/iPhone 17 Pro Max, web/Pixel Fold 10, VS Code, VS 2026, Antigravity). Actually 3 codebases: the Angular cockpit serves all three web postures; ONE VSIX serves VS Code + both Antigravity installs (product.json proves Antigravity = VS Code fork 1.107.0, gallery = open-vsx.org — so no separate Antigravity extension exists to build). There is no Antigravity 2.0 on this box (IDE 1.107.0, agy CLI 1.1.3); the "2.0 built from scratch" story came from content-farm blogs, not Google.
LANDED on master (repo now has a remote: andrewjonesdev-tools/fleet-mission-control, PRIVATE — it was
local-only until 2026-07-15, so CI had never run once):
- 774261e — web postures: viewport-fit=cover + env(safe-area-inset-) for Dynamic Island/home indicator.
- 0b8d416 — cleared 12 pre-existing master ESLint errors the repo's first-ever CI run exposed.
- 236a73f — fixed the dead Fold layout (see gate note below) + a safe-area overflow.
- c75883a — runtime backend origin: FLEET_API_BASE_URL (which NSwag already generated and the client already
consumed — app.config.ts just never provided it) now fed from window.__FLEET_CONFIG__; hub URL un-hardcoded.
106/106 tests, default same-origin behavior byte-identical.
- cc26da2 — VS Code + Antigravity VSIX (one extension, three installs). Proven with a REAL extension host
(@vscode/test-electron) on VS Code 1.107.0 — deliberately the version both Antigravity installs fork from —
4/4 passing, round-tripping a probe message OUT of the webview against the real 248KB ng build bundle. A
negative control (sabotaged CSP nonce) makes the probe fail, so it isn't vacuous. Distribution PRIVATE.
- 8473941 — docs: architecture (technical, file:line cited), architecture-plain (non-engineer), making-of.
6 Mermaid diagrams, all validated via mermaid.parse() (the CLI's puppeteer path was broken on a missing
webfont; the agent bypassed the renderer rather than declare it unverifiable).
- CI green both jobs (first green in repo history). Frontend mutation 94.44%* (255/270 killed).
cc26da2 CAUGHT FLT-13's EXACT FAILURE ABOUT TO REPEAT. Angular/beasties emits
<link rel=stylesheet media="print" onload="this.media='all'">. A nonce cannot whitelist an inline event
handler, so under the webview's strict CSP the onload is blocked, media stays "print", and the main stylesheet
never applies — the cockpit would render with critical CSS only while every string-assertion test stayed green.
That is FLT-13's false "rendered with CSS" verbatim, six weeks later in a different codebase. It surfaced ONLY
because the agent built the REAL frontend instead of trusting a hand-written fixture. See memory
nonce-csp-breaks-angular-deferred-css.
COUNCIL GATE CAUGHT A REAL DEFECT (the reason to keep the gate under deadline): the Fold two-pane code was
dead on the target device. @media (horizontal-viewport-segments: 2) fires only in Device Posture folded
(device bent to a book/tent angle); a Pixel Fold opened flat is continuous and reports 1 segment, so the
block never matched and the unfolded Fold fell through to the phone card-stack. 95/95 tests green, screenshots
taken, feature never ran — the FLT-4 pattern exactly. Fixed via 600dp width classes (Google's own compact/medium/
expanded), verified by screenshot (620px was card-stack, now dual-pane). See memory
viewport-segments-needs-folded-posture.
CI GATES LANDED 2026-07-16 (64e269d -> 0d20732, fleet-mission-control master). The FLT-16 pack
finally exists on this repo: 7 jobs — backend, frontend, extensions (its 38 unit + 4 real-extension-host
tests had NEVER run on push), inspectcode, semgrep, churn 5x, mutation. Codex implemented; verified locally
with real artifacts before landing: InspectCode 24 warnings -> 0 (via path-scoped .editorconfig
suppressions, NOT by renaming DTOs — see the Kerr note), semgrep SARIF 0 findings, churn 5/5 identical
(93 tests), backend mutation 80.60%, frontend 94.44%.
KERR TRAP DEFUSED, ON PURPOSE. All 24 InspectCode warnings are false positives. Gating on a raw
zero-warning count would have REWARDED breaking the wire contract: it wants Events5h->Events5H,
Pct5h->Pct5H on DTOs in Contracts/ that serialize to JSON, and the NSwag TypeScript client is
generated from that OpenAPI doc. Suppressions are path-scoped with the reason written next to each. 5h
means five hours; it is correct domain language, not a casing mistake.
I BROKE MASTER'S CI DOING THIS AND WANT IT ON THE RECORD. The first gates push was rejected by GitHub
at parse time — 0s, ZERO jobs, so nothing ran, not even the backend/frontend gates that worked before.
An ungated master that looks gated is worse than no gates. Cause: the runner context is valid ONLY at
STEP scope — not workflow-level env:, and not job-level either. My first "fix" moved it workflow->job
and I pushed that; still dead. Two runs, two 0s failures, three wrong hypotheses (I also wrongly suspected
unresolvable SHA-pinned actions — all three verified live). actionlint found it in seconds.
yaml.safe_load parses every broken variant happily; YAML-valid != Actions-schema-valid. I reverted master to
the known-good workflow first, then fixed and re-landed with actionlint proving it clean BEFORE the push.
The tell I missed for two cycles: gh run list prints the workflow FILE PATH instead of its name: when
GitHub cannot parse it. See memory actionlint-catches-dead-workflows. Follow-up: wire actionlint INTO the
workflow so a bad workflow can never silently disable CI again.
ACTIONLINT GATE LANDED 2026-07-16 (d4117cc). Deliberately a separate workflow file
(.github/workflows/actionlint.yml), NOT a job inside ci.yml: GitHub rejects an unparseable workflow before
scheduling any of its jobs, so a lint job inside ci.yml could never catch ci.yml's own parse error — it would
be theater. A separate file is parsed independently and still reports. .github/actionlint.yaml declares the
real self-hosted labels (read from the org runners API) instead of passing -ignore, because ignoring the
label rule would also blind us to REAL label typos — and a typo'd label doesn't fail, it queues forever.
Verified both directions, no ignore flag: clean on the repo (exit 0), and a negative control that
reintroduces the exact job-scope runner bug that killed master fails it (exit 1, correct line). The gate can
actually fail. Image digest read from docker inspect, not guessed.
MEASURED 2026-07-16 — the single-runner cost is no longer theoretical:
- The 7-job run (0d20732, 18:47) was still 44+ minutes in with 5 of 7 jobs QUEUED. The equivalent
GitHub-hosted 2-job runs earlier the same night: ~1m40s, green.
- home-ci capable: ["greatroom-tools"] — of three ONLINE org runners, only one carries the label.
ANDREWBEDROOMTV and ANDYGREATROOMPC do not.
- The mutation job failed after 39 minutes with every one of its steps GREEN (backend + frontend Stryker
both success), dying in post/cleanup with post-steps never completing. Logs already expired
(BlobNotFound) so the cause is unproven — but "all steps pass, job dies in cleanup" is an infrastructure
flake, not a gate finding. Consistent with one box serializing 7 heavy jobs.
ON REDUNDANCY / SWARM / K8s — the answer the data supports: "redundancy across one PC" is not redundancy;
it is a single point of failure wearing the word. But the gap is a missing label, not a missing orchestrator.
GitHub Actions runners are stateful agents that poll GitHub and execute jobs; there is no scheduling problem
for Swarm/K8s to solve here — GitHub IS the scheduler, and it already load-balances across every runner
carrying the right label. Adding home-ci to ANDREWBEDROOMTV + ANDYGREATROOMPC is a config edit per box and
buys 3x parallelism immediately; containerising the runners buys nothing on top of that and costs a
Windows-container story for .NET+VS tooling that is genuinely painful. A prior council already REJECTED
Swarm/K8s for the tool fleet (memory tool-ci-redundancy-4pc) — this data supports that verdict rather than
reopening it. Cheapest real fix, in order: (1) label the other two runners; (2) or move this repo back to
GitHub-hosted, which demonstrably works for the andrewjonesdev-tools org — the billing block in memory is
scoped to the PERSONAL account, and tonight's green runs were windows-latest/ubuntu-latest.
RESOLVED 2026-07-16 — the fleet now runs its own CI. NO GitHub-hosted minutes.
Was: 1 runner could take home-ci work, 7 jobs serialised on one box, 44+ min with 5/7 still queued.
Now: 6 org runners across 3 PCs, jobs land in parallel, gates green (backend, frontend, churn,
InspectCode, mutation all pass on the new boxes).
- Root cause was LABEL != GROUP. ANDYGREATROOMPC + ANDREWBEDROOMTV were already IN the home-ci
runner GROUP but lacked the home-ci LABEL — and runs-on: matches labels, not groups. greatroom-tools
had the label but sat in Default. Nobody was wrong about the intent; the wiring was crossed.
- Added runners to the two idle boxes: streaming DESKTOP-SCDT9HI (32c/94GB) had ZERO runners → 3;
gaming DESKTOP-D249KD4 (32c/47GB) had zero ORG runners (its only one was bound to the WorkWingman REPO,
invisible to the org) → 2, capped to leave headroom for the Ollama council models.
- Three real bugs surfaced only once jobs ran concurrently — a single serialised runner had hidden all of
them: (1) fresh runners fail EVERY powershell step with PSSecurityException until
Set-ExecutionPolicy -Scope LocalMachine RemoteSigned; (2) runners run as NETWORK SERVICE so they SHARE one
NuGet cache and concurrent restores collide — fixed in each runner's own .env, not workflow env, because
step-env covers only its step and job-env cannot use runner.* at all; (3) shell: powershell runs with
ErrorActionPreference=Stop, so docker's stderr progress lines became terminating NativeCommandErrors and
failed semgrep while the scan itself succeeded.
- Excluded until fixable, so they stop failing jobs: ANDYGREATROOMPC (ExecutionPolicy needs an elevated
shell) and ANDREWBEDROOMTV (SSH to 10.0.0.36 times out). Labels pulled; re-add after fixing.
- Remaining bottleneck: docker. Docker Desktop on Windows is per-user, so a runner service can't reach
another user's daemon. Only greatroom-tools is PROVEN to serve it, so semgrep + actionlint pin to the
docker label and serialise there. Widening needs a real per-box test, not an assumption.
- Not Swarm/K8s — GitHub is already the scheduler and load-balances across labelled runners. The gap was a
missing label and missing runners, not a missing orchestrator. Consistent with the prior council rejection.
See memory home-ci-runner-fleet.
SUPERSEDED — INFRA FINDING — home-ci is ONE runner, not four. All 7 jobs target [self-hosted, home-ci, windows]
(matching llm-council, the house pattern). But of three online org runners, only greatroom-tools carries
the home-ci label; ANDREWBEDROOMTV and ANDYGREATROOMPC do NOT. So the "CI redundancy across 4 PCs" intent
is not real — every job serializes on one PC, and CI dies when that PC is off. Worth deciding: label the
other runners, or move this repo back to GitHub-hosted (which demonstrably works — tonight's green runs
were windows-latest/ubuntu-latest; the billing block in memory is scoped to the personal account, and
andrewjonesdev-tools is a separate org that bills fine).
Also note: DOTNET_INSTALL_DIR was invented from a hint in my brief — llm-council does not use it at all,
so a follow-up could simply drop it.
IN FLIGHT:
- wt/WT-0026/FLT-14-vscode-ext — VSIX rebasing onto c75883a; deleting a fetch/XHR/WebSocket monkey-patch in
favour of a nonce'd window.__FLEET_CONFIG__ script; correcting distribution docs to PRIVATE sideload.
- wt/WT-0026/FLT-14-vs2026 @ b8dd99c — classic VSIX builds (needs FULL VS MSBuild; dotnet build fails),
33 tests pass, package loads (ActivityLog Begin/End package load), command dispatches, frame.Show()
returns S_OK — but WPF Loaded NEVER FIRES, so WebView2 init never even starts.
It has never rendered a pixel and is not claimed to.
Two of my own diagnoses here were WRONG — recording both so nobody re-buys them:
1. "The ctor-dispatch fallback is the bug." Removing it did NOT produce a render. It was a real bug (it
burns the single init attempt before an HWND exists, then _started swallows the real Loaded) and
removing it was correct — but it was not THE bug.
2. "Float vs Tabbed isn't the differentiator, because the spike used Float and also failed." Unsound —
with the hack present, the guard would have swallowed Loaded in that run regardless. I had no evidence
either way and asserted it as if I did. Float has since been tried and is not sufficient alone.
Also retracted (by the lane agent, correctly): "zero child HWNDs ⇒ WebView2 never attached." VS 18's MAIN
window also reports kids=0 — the whole shell is composition-based (same reason screenshots are black).
Zero children is normal here and proves nothing.
ANSWERED 2026-07-16 18:4x — IT IS NOT WEBVIEW2, AND VS'S OWN API LIES ABOUT IT.
Isolation spike: a plain TextBlock, zero WebView2, in a healthy Exp instance (483-707MB, responding,
correct title). Polled PresentationSource.FromVisual(this) every 5s:
t+ 5s loaded=False visible=False size=0x0 presentationSource=NULL hwnd=0x0
t+20s loaded=False visible=False size=0x0 presentationSource=NULL hwnd=0x0
frame.Show() hr=0x00000000, frame.IsOnScreen onScreen=1, and
frame.IsVisible S_OK (visible).
The WPF content is NEVER attached to a window - no PresentationSource, no HWND, IsVisible=False, forever.
So Loaded cannot fire, and EnsureCoreWebView2Async cannot complete (it needs a real sized HWND). Not a
sizing bug, not dock style, not WebView2. Show()==S_OK, IsOnScreen=1 and IsVisible=S_OK are FALSE
RECEIPTS - VS bookkeeping that does not mean the content rendered. Trusting them cost ~5 cycles chasing
WebView2. (Seventh lying success-signal of this session; see memory verify-by-artifact-not-exit-code.)
RETRACTED 2026-07-16 by council (codex/grok/gemini CLI seats, no house councils). MY "PLATFORM BLOCKED"
VERDICT WAS WRONG — DO NOT DESCOPE YET. Two seats independently, with VERIFIED citations:
- No documented VS 18/2026 breaking change exists for classic VSIX tool windows. Grok: "Known bug ->
UNKNOWN / NOT FOUND. Do not treat as platform defect until identity + command-path experiments fail."
Classic in-proc VSPackage + ToolWindowPane.Content + WebView2 is still the SUPPORTED WebView2 path.
- The real mechanism: WindowPane overrides IVsWindowPane.CreatePaneWindow, which is what creates the
HwndSource and sets RootVisual = Content. If the shell defers realization, that hook NEVER RUNS — so no
PresentationSource, no Loaded. Consistent with every symptom.
- I misread my own evidence: hwnd=0x0 on the control is EXPECTED BY DESIGN — direct-hosted WPF
content has no dedicated content HWND. It was never evidence of a platform break.
- Two likely causes, both OURS: (a) showing during [ProvideAutoLoad(NoSolution)] is too early — the
docking layout is not restored, so the frame exists but the pane is never realized; fix = defer to
KnownUIContexts.ShellInitializedContext or a real user-invoked .vsct command. (b) VsDockStyle.Float
puts the pane in a separate top-level frame whose realization the shell defers when shown early/inactive,
whereas Tabbed/Linked docks into the main window's existing visual tree and forces immediate realization.
- Also corrected: my claim that Remote UI "is WPF-only with no webview" is inaccurate (grok) — though the
Extensibility SDK still has no 18.x release, so classic VSIX remains the path regardless.
COUNCIL EXPERIMENTS RUN 2026-07-16 19:2x-19:3x — ALL FOUR HYPOTHESES ELIMINATED. Evidence:
19:33:10.740 ShellInitializedContext ACTIVE <- fired in 1ms: shell was ALREADY up. NOT too early.
19:33:10.923 OnToolWindowCreated: Content is CockpitToolWindowControl, sameInstanceAsProbe=True
<- grok's #1 (wrong instance) ELIMINATED
19:33:10.984 frame.Show() hr=0 / onScreen=1 / IsVisible=S_OK
19:33:10.986 VSFPROPID_DocView hr=0x00000000 value=VsixSpike.CockpitToolWindow isOurPane=True
<- the frame's CLIENT VIEW *IS* OUR PANE
19:33:10.987 VSFPROPID_DocData hr=0x80020003 (DISP_E_MEMBERNOTFOUND) value=NULL
t+5s..20s loaded=False visible=False size=0x0 presentationSource=NULL <- with Style=TABBED this time
KnownUIContexts.ShellInitializedContext; it was already active (1ms).
- NOT identity — OnCreate + OnToolWindowCreated both fire and sameInstanceAsProbe=True; we ARE
probing the object the shell hosts.
- NOT dock style — VsDockStyle.Tabbed behaves IDENTICALLY to Float, refuting gemini's [SPECULATION]
that Tabbed forces realization.
- NOT "frame is metadata only" — VSFPROPID_DocView is our CockpitToolWindow. Per codex's own
decision rule that means: VS created the logical pane and installed it as the client view, but failed to
HOST its WPF content. The fault is the IVsUIElementPane hosting step, nothing upstream of it.
Council value, honestly: they refuted my premature "platform bug" verdict and supplied the DocView probe
that pinned the fault — but two of three also produced APIs that DO NOT EXIST: gemini's
CreatePaneWindow override (CS0115 — and codex separately confirmed IVsWindowPane.CreatePaneWindow is
obsolete, superseded by IVsUIElementPane), and Tabbed-forces-realization was simply wrong. All three
independently found no documented VS 18 bug for this, and codex found Microsoft ships no VS 2026-specific
extension-creation docs yet — so "unsupported/undocumented" remains live, but "known platform bug" is
still NOT established.
FINAL PROBE — the shell DOES request the UI element, then does not host it. Codex identified the real
(non-obsolete) hosting contract: WindowPane implements IVsUIElementPane; IVsWindowPane.CreatePaneWindow
is obsolete. Re-implemented that interface on the pane to log it:
*** IVsUIElementPane.SetUIElementSite CALLED ***
*** IVsUIElementPane.CreateUIElementPane CALLED *** returning CockpitToolWindowControl
VSFPROPID_DocView value=VsixSpike.CockpitToolWindow isOurPane=True
t+5s..20s loaded=False visible=False size=0x0 presentationSource=NULL
IVsUIElementPane SHADOWS WindowPane's own implementation, so
in THIS run the hosting path is partly ours. The finding holds only because the earlier runs — on WindowPane's
stock implementation — failed identically. This run alone is not clean evidence.
REMAINING UNTESTED (only one left, and automation cannot do it): every attempt has shown the window PROGRAMMATICALLY. Nobody has opened it by HAND from View > Other Windows in an interactive VS. That is now the single discriminator between "VS never hosts a programmatically-shown pane" and "VS 18 cannot host this at all" — and it needs a human at the keyboard, not automation.
PRIOR NEXT EXPERIMENT (now done, see above): override CreatePaneWindow and log it; switch Float -> Tabbed;
defer the show to ShellInitializedContext. If CreatePaneWindow never logs, the shell is deferring
realization (our bug, fixable). Also assert ReferenceEquals(window.Content, control) and read
VSFPROPID_DocView to prove we are probing the object the shell actually hosts.
SUPERSEDED RECOMMENDATION (was premature) - descope the VS 2026 embedded cockpit. On VS 2026 Insiders 18.8.11925.187 a
programmatically shown ToolWindowPane.Content does not render. Ship the VS 2026 extension as commands only
(open the cockpit in a browser + status-bar state) - a real surface on the same backend - and revisit the
embedded cockpit at VS 18 GA or when MS documents the composition-shell hosting contract. The other 5 surfaces
already carry a real embedded cockpit. Untried leads: open the window MANUALLY from View > Other Windows (every
attempt so far was programmatic), IVsWindowFrameNotify3.OnShow, or ToolWindowPane.Window (raw HWND) instead
of .Content. See memory vs2026-classic-vsix-webview2.
PRIOR UPDATE 2026-07-16 12:1x - MY OWN "USE F5" RECOMMENDATION IS WRONG. Retracting it.
F5 does not use VSIXInstaller; it uses MSBuild's DeployExtension target. I set
<DeployExtension>true</DeployExtension> (the scripted equivalent of F5) and it fails immediately:
error VSSDK1048: Error trying to read the VSIX manifest file ...\obj\Debug\extension.vsixmanifest.
Could not load file or assembly 'System.Collections.Immutable, Version=10.0.0.8, ...'
Microsoft.VSSDK.BuildTools 18.9.820. Since F5 drives that same target, F5 would very likely hit the same
error. So "just open it in real VS and hit F5" is not the clean escape hatch I claimed it was. Anyone
trying it should expect VSSDK1048 first, and may need to fix the System.Collections.Immutable binding
(or find the version VS's own devenv resolves, since devenv may bind differently in-process) before F5 works.
Also newly observed: the Exp instance WEDGES ON REPEAT LAUNCH. Clean cycle (install → verify DLL on disk
→ /updateconfiguration → launch) gives pass-1 devenv healthy at 353MB responding; killing it and
launching again gives pass-2 stuck at 33MB, no probe, no load. That reproduces the "48MB empty title"
wedge seen earlier and is almost certainly what has been poisoning the last several attempts — it is a
property of repeatedly cycling the Exp hive, not of the extension.
THE BEST EVIDENCE WE HAVE IS STILL THE EARLY RUNS, when the hive was healthy and the package DID load:
21:02:59.966 ctor: control constructed
21:02:59.972 frame.Show() hr=0x00000000 <- S_OK, VS says the window is shown
21:03:00.008 CoreWebView2Environment created, runtime=150.0.4078.65
22:13:12.987 ShowToolWindowAsync returned: window=ok frame=ok (Lane C, later, hack removed)
22:13:12.989 frame.Show() hr=0x00000000
Loaded never fires. That is the finding. Everything since has been fighting the environment.
PRIOR UPDATE 2026-07-16 07:5x — hive REBUILT, and the experiment STILL has not produced a result.
Deleted both 18.0_7c1948ebExp dirs (Local + Roaming; the real 18.0_7c1948eb was never touched and is
fine) and recreated via /updateconfiguration. That fixed a real fault: devenv used to hang at startup
at ~48MB with an empty title; it now launches clean (351MB, responding, titled "Microsoft Visual Studio").
Reinstalled the TextBlock spike into the fresh hive — pkgdef registration is verifiably perfect
(CodeBase=$PackageFolder$\VsixSpike.dll, AllowsBackgroundLoad=1, AutoLoadPackages under the
NoSolution GUID {adfc4e64-...}, ToolWindow registered Style=Float) — and the package still never loads:
no probe line, no ctor. An extensions.configurationchanged marker is present, i.e. VS knows the extension
set changed but has not reconciled it.
Honest status: ~4 cycles spent on ENVIRONMENT faults (corrupt cache, hung devenv, timed-out chains,
MSYS arg mangling, a Remove-Item safety hook false-positiving on the VS path) and ZERO cycles that actually
answered the question. The question is still exactly: does ANY WPF content realize in a VS 18 tool window,
or is this WebView2-specific? Recommend the next session STOP re-running the same install/launch loop and
instead build the spike as a normal VSIX project opened in the REAL VS (F5 → Experimental Instance is the
supported, tooled path — StartAction=Program/StartArguments=/rootsuffix Exp are already in the csproj)
rather than driving VSIXInstaller + devenv from a script. The scripted path has now failed for four distinct
environmental reasons and is not earning its keep.
PRIOR STATE (superseded, kept for the record): the experiment was BLOCKED BY A CORRUPTED EXP HIVE.
The next test (strip WebView2 entirely, host a plain TextBlock, see whether ANY WPF content realizes —
if a TextBlock also never fires Loaded, this is VS 18 composition-shell hosting of ToolWindowPane.Content
and every further WebView2 cycle is wasted) could not be run. The Exp hive 18.0_7c1948eb**Exp** is
damaged after many install/uninstall cycles: ActivityLog shows CPkgDefCacheNonVolatileBase: PkgDef cache
creation failed. Going volatile and trying again., VSSDK\ResetExperimental.cmd exits 1 and does not
reset, and after a clean /updateconfiguration (exit 0, caches rebuilt 07:47) devenv still hangs at startup
at ~48MB with an empty window title. Package never loads; no probe line. This is an environment fault.
NEXT: rebuild the Exp hive from scratch (delete %LOCALAPPDATA%\Microsoft\VisualStudio\18.0_7c1948ebExp +
the matching %APPDATA% dir, then devenv /rootsuffix Exp /updateconfiguration), THEN run the TextBlock
isolation test. The real VS install (18.0_7c1948eb, no Exp suffix) was never touched and is fine.
One useful existence proof found: VS 18's own shell ships Microsoft.Web.WebView2.Core.dll in
Common7\IDE\PrivateAssemblies, so WebView2 demonstrably works inside the devenv process. The open question
is narrowly whether OUR tool window realizes its WPF content — not whether VS 2026 can host WebView2 at all.
VS 2026 path decided by spike (see memory vs2026-classic-vsix-webview2): classic in-proc VSIX + WebView2,
NOT the "modern" VisualStudio.Extensibility SDK — that SDK has no 18.x release and its WPF Remote UI cannot host
a webview at all, while Microsoft.VSSDK.BuildTools ships 18.x and VS 2026 ships v18.0 VSSDK targets. This means
ONE cockpit across all six surfaces instead of a hand-written WPF twin that drifts.
Distribution stays PRIVATE per the design below — sideloaded VSIX + tailnet gallery + fleet-dispatch to all 4 PCs. No marketplace listing. (An earlier brief in this session wrongly said "VS Code Marketplace + Open VSX"; nothing was published — corrected.)
Mockups in the FLT-13 artifact. Thin clients on the cockpit API — VS Code: activity-bar tree
(needs-you / running / queue / fleet) + status-bar gate + diffs open in the real editor (TS,
UI-only; logic stays server-side C#). VS 2026: C#/VS SDK docked tool window + status bar.
Distribution PRIVATE: sideloaded VSIX + self-hosted tailnet extension gallery (VS private
gallery atom feed; VS Code --install-extension), pushed to all 4 PCs by fleet-dispatch.
No marketplace listing.
FLT-142 · Vikunja board mirror + Option-1 failover — Done — deployed to all 4 PCs 2026-07-19 (WT-902b) (Jira FLT-142 · Vikunja proj 7/8 · master d1d1d0e)¶
Vikunja stood up as the third board-redundancy leg (Jira source + BOARD.md canonical + Vikunja derived mirror). One-way idempotent Jira→Vikunja sync (fleet-harness/ops/board-sync/), single-writer FleetBoardSync task on greatroom every 30 min (verified result 0; self-healing). Full mirror live: FLT (142) → Vikunja project 7, WING (86) → project 8. Codex review gate (6 findings, 3 HIGH on the restore path, all fixed). Backup leg = vikunja-dr VikunjaNightlyBackup (OneDrive) + VikunjaRestoreVerify (test-restore). Failover depth set by a 9-seat LLM council, unanimous Option 1 (rebuildable + replicated backup); hot HA rejected as over-engineering for a derived, minutes-to-rebuild mirror (report llm-council/reports/2026-07-19_003152_evaluate-the-right-failover-depth-for.md). Recovery on any PC: Rehydrate-Vikunja.ps1 -FromJira. Global ~/.claude/CLAUDE.md standing rule added. Known follow-up: vikunja-dr VikunjaHealthzWatch task fails to register (bad trigger duration — FLT-9 installer bug, flagged separately).
FLT-15 · agy quota ledger + agy-Claude reserve gate (usage-governor) — Done — Jira FLT-49 closed by Andrew 2026-07-17 after Raft HA landed; residual sub-items (skills-bypass undercount, fleet ledgerPath rollout, Raft deploy) tracked below, spin out new tickets if picked up (Jira key FLT-49 · Vikunja 48 · WT-902b, 2026-07-17)¶
Raft HA LIVE ON THE FLEET 2026-07-17 (WT-902b) — drill GREEN on real machines, single-writer authority replaced by the 3-voter Raft cluster + bedroom observer. Timing-stabilized (0 elections/9min). All 3 availability follow-ups (wedge watchdog, client peer-walk, E3 retro review) landed + rolled fleet-wide 2026-07-18 (usage-governor master 34418ed) — watchdog task Ready on gaming/streaming/bedroom, greatroom pending one elevated command. Runbook docs/RAFT-DEPLOY-RUNBOOK.md in usage-governor: usage-governor master → c553721 on origin
(the 10 gated commits from wt/WT-0026/FLT-17-raft-ha, tip c091939; post-land suite 273/273
green — the branch name's "FLT-17" is the legacy board-ID space, NOT Jira FLT-17). The admission authority's Raft HA (3 voters + stateless observer,
replicated quota ledger, leader-only admit, client AdmitId exactly-once) passed its final council
re-gate: the last open item — a minority-live-leader partition test (RAFT-BLOCKERS #4, a
still-running leader severed from the majority must not commit) — now runs as an executed
fault-injection test via a blockable outbound IConnectionFactory (dotNext
CustomTransportConfiguration seam; destination-side proxies provably cannot cut a dialing leader).
Negative-controlled 3 ways (no-block RED, inbound-only RED reproducing the historical failure,
executable NEGATIVE_CONTROL in CI); 273/273 green; seats codex+gemini+grok+local, codex chairman,
all findings fixed. **Raft stays opt-in (raft.enabled=false); live authority = single-writer on
gaming, untouched. Deploy = separate Andrew gate; pre-deploy gaps: WAL compaction (RAFT-BLOCKERS
2), Raft-port mTLS/firewall (#3).**¶
Follow-up 2026-07-18 (WT-902b) — Jepsen flaky-test fix committed 09184ae on wt/WT-0026/FLT-17-raft-ha (staged ONLY AgyRaftJepsenTests.cs): four converged-ledger asserts raced async follower-apply — AssertLedgersConverged reads every voter, but the tests waited on one node (or, for the happy path, not at all) before asserting, so a follower still applying committed entries could trip "expected N entries, found M" under full-parallel load. Each guard now waits on ALL voters (WaitUntil(cluster.Voters.All(v => Count == N))). Read-side race, independent of the E3 propose-timeout fix 3b33da0. Verified full suite 295/295 green + Jepsen class 8/8 under a stress loop. Local branch ahead of origin by 4 (b81270a, 2816953, 3b33da0, 09184ae) — held for the coordinated landing pass, not pushed.
Landed 2026-07-16 (2aba701, deployed + verified): agy-status --json, a versioned read-only
status contract (schema: agy-status/v1). The council pass turned it into one rule — the score
must derive from the same binding constraints as the gates — after finding four places where it
did not: Claude's locked read a display tier the gate ignores; Gemini's proximity ignored the
tapering floor (55% spend is ~92% of the way to denial under a 40% floor); weighted pools scored
against 100% when ComputeTier REDs at 85%; and the Claude reserve was counted as routable. Ledger
presence now comes from ONE open (TryReadSince) — the old Exists-then-read raced, and an
unreachable share threw instead of degrading.
NOT done, and this is the actual ticket: the ledger still is not fleet-global (no agy block in
the live config → local path) and still undercounts (skills call agy.exe direct, bypassing the
admit). Until both close, cap_proximity is a confident lie and must not be wired — see the gate-2
entry under FLT-1. The remaining work is a shared ledgerPath on all 4 PCs plus an admit helper the
skills actually call; the harness consumer already exists on wt/WT-3e93/FLT-15, held for that day.
Google AI Ultra Max ($200/mo, 20x Pro) exposes four fallback lanes through the agy/Antigravity CLI
that the fleet was not modelling: Gemini 3.5 Flash + 3.1 Pro (one unified pool, drawn at API
prices, 20x multiplier — the big pool), Claude Sonnet/Opus 4.6 and GPT-OSS 120B (separate small
fixed caps). Field-verified: one agy-Claude conversation burns ~60% of a 5h window even on Ultra;
windows are 5h refresh plus a weekly cap (Google copied Anthropic); credits are paid overage only;
no quota API exists. Probe-verified 2026-07-14: agy models lists all four; Sonnet + GPT-OSS lanes
answer live.
Council verdict (fable tier, ranking Claude > Grok > Codex > Gemini > local; report
llm-council/reports/2026-07-14_222458_fleet-routing-policy-question-context-researched.md):
- agy-Gemini = primary offload pool. Flash default; 3.1 Pro High escalate-only (second gate
failure, or security/architecture pre-escalate) — not the routine "hard" path.
- agy-Claude is NOT a ladder rung — an out-of-band interrupt budget: triple gate (native Claude
RED AND ceiling skip-list task AND no acceptable substitute), 1 call/5h window, ≤2-3/day,
gated on the weekly cap (the 5h refresh is a decoy at ~60%/convo), Sonnet-first, one-shot
print mode, size-bounded, no follow-ups (incomplete → Gemini Pro High, never a second Claude
call), reason codes (native_red/review_gate/council_synth) on every invocation.
- GPT-OSS-as-Haiku-lane REJECTED — it is a third scarce pool, not free relief. Burst overflow
behind Grok/local only; never an arbiter/correctness chair.
- Corrected ladder: Fable → Opus/Sonnet → Codex → agy-Gemini → Grok → agy-GPT-OSS → local ollama,
with agy-Claude out-of-band alongside it.
Build (C#, in usage-governor): fleet-global single-writer ledger — 4 PCs × N sessions share
one Google account, so per-session ledgers each think the pool is full and drain it 4x; must cover
every agy consumer (offload subagents, /gemini-review, the council Gemini seat, the
fleet-dispatch agy lane). Reserve units not percentages (no quota API ⇒ % is fake precision on an
unknown denominator): always ≥1 agy-Claude invocation held per window; Gemini weekly floor ~40% Monday
tapering to ~15% toward the weekly reset (floor covers remaining calendar exposure). Weekly-exhausted
= hard-deny state until rollover (else agents thrash every 5h and burn the remainder). 429s are ground
truth → recalibrate the ledger on every limit hit, distinguishing quota-lockout from transient
transport failure (misclassification either corrupts the ledger or triggers a retry storm).
allow_paid_overage=false default; floor = hard deny into the next tier, never "continue on credits".
Pre-route token estimate (a massive-diff one-shot can burn 100% of a window). Weekly agy models +
dry-run probe (labels/quotas drift silently; metering already regressed once in March 2026, so 60% is
a point-in-time number). Council accounting: agy-Sonnet/Opus counts as a Claude seat for the
≥3-frontier-seats family-diversity rule.
Feeds FLT-6 (routing.yaml grows the agy lanes) and FLT-13 (cockpit surfaces the ledger).
Memory: agy-multimodel-fallback-quotas.md. Gate via /council-code-review before landing.
FLT-16 · CI tooling pack fleet-wide (vuln gate + InspectCode + mutation baseline) — Done (Jira key FLT-60 · Vikunja 51 · WT-df2b, 2026-07-15: LANDED on origin/master, all 11 repos)¶
Standard analysis/security gates for every C# repo. Contract + rollout status:
usage-governor/docs/ci-tooling-pack.md (piloted in usage-governor, council-gated there).
Pack: (1) vulnerable-package gate — enforcing, fails the build; (2) InspectCode
(inspect.yml) — gates error-severity only (pilot: 177 findings / 0 errors; gating warnings
would red every repo on day one and train the fleet to ignore a red X); (3) Stryker
(mutation.yml) — report-only, weekly, staggered cron per repo; (4) npm audit + ESLint where
a real JS/Angular toolchain exists.
Mutation stays report-only ON PURPOSE. This infra scores VsTest socket timeouts as KILLED mutants — the usage-governor pilot run itself logged 3 timeouts at 72.40%. The WorkWingman council removed a broad enforcing gate on 2026-07-11 for exactly this; a fleet-wide threshold on the same infra would repeat that mistake at 10x blast radius. Promote per-repo only once the score is real and the runner is stable.
Council gate (pack template, 6 seats: Codex, Gemini, Grok, qwen3:8b, gaming qwen3-coder:30b +
devstral:24b; streaming llama3.3:70b FAILED at the 600s member cap). Chairman 0C/3H/4M/1L, all
implemented. The three Highs were real and would each have multiplied 10x:
- vuln gate failed OPEN — dotnet list package --vulnerable exits 0 when it FINDS
vulnerabilities but nonzero when it FAILS TO RUN, and a failed scan emits no > rows, so
parse-only reported a dead scan as a clean tree. Now checks $LASTEXITCODE first (verified:
broken sln → exit 1, rows 0 → old version passed green).
- floating dotnet tool install -g on persistent runners → results depend on leftover profile
state / whatever NuGet serves. Now pinned via .config/dotnet-tools.json + tool restore/tool run.
- identical Monday 06:00 cron in all 10 repos → hour-long jobs dogpile the shared home-ci pool,
contradicting the workflow's own anti-starvation rationale. Now staggered (table in the pack doc).
Verified per repo by the orchestrator, not on the agent's word (FLT-3): fleet-dispatch 179/179, fleet-telegram 211/211, worktree-identity 207/207, token-roi 127/127, membus 101/101, llm-council 69/69, PavlokPager 59/59, claude-mem-house 31/31, audio-loop-mcp 22/22, WorkWingman build+gate, usage-governor pilot (Stryker 72.40%). 0 vulnerable packages fleet-wide.
Implementation offloaded to Codex (governor hit RED mid-sweep — projected 173%; Claude routed, reviewed and verified only).
Open: (a) all 11 branches UNPUSHED — awaiting land decision; (b) claude-mem-house has a
stronger gate than the rest (asserts a positive clean-scan marker, so an exit-0 scan printing
nothing can't read as clean) — backport to the other 10; (c) stryker-js does not bootstrap against
Angular's builder-managed vitest ("No tests were executed") — frontend mutation parked, not claimed;
(d) fleet-mission-control mutation baseline 39.19% needs real tests.
Follow-on (2026-07-15, WT-975b): test-impact-analysis for the pack's Stryker component — RESEARCHED,
REJECTED, no work to do. Question was whether to scope mutation runs to changed code (TIA / affected-test
selection) via GHA or MCP. Council convened (llm-council opus, 5/5 seats; report
llm-council/reports/2026-07-15_195506_what-tooling-exists-to-pinpoint-test.md). The council's verdict is
moot and the log carries a correction block — do not act on it. Measurement afterward killed the premise:
--coverage-analysis perTestis already the default. Stryker.NET's documented default ISperTest(https://stryker-mutator.io/docs/stryker-net/configuration/). All 11 backend configs leave the key unset, i.e. they have been running perTest all along. The council's #1 "free headline win" is a no-op.- No .NET mutation bottleneck exists. Real durations 2026-07-15: llm-council 2m35s (75 tests), membus 3m15s (67), claude-mem-house 5m14s (26), usage-governor 10m48s (157), audio-loop-mcp 15m23s (16). Separate repos → they run in parallel; fleet mutation wall-clock ≈ 15 min, bounded by the slowest single repo. TIA buys a few minutes against false-negative selection risk + stale-baseline score inflation. Bad trade.
- No MCP server exposes TIA / coverage-diff → affected-test selection today (unanimous, and verified — Datadog/Develocity/Codecov/Sonar MCPs expose coverage queries, no selector). Nothing to adopt.
- Verified NOT broken while measuring: staggered crons are real (Mon 06:00 usage-governor / 10:00
llm-council / 12:00 membus / 20:00 claude-mem-house — the High from the pack council holds);
audio-loop-mcponly appears to lackmutation.ymllocally (checkout 2 commits behind origin — it is on origin/master).
Kerr note for whoever revisits this: the reward here is minutes-saved/tests-skipped (countable, dashboard- friendly); the goal is regressions caught (a non-event nobody gets credit for). If TIA is ever reconsidered, escape rate — mutants/tests failing a nightly unscoped run that a scoped run skipped — must be published beside minutes saved, or the number is meaningless. Stryker baselines invert the metric outright: a stale baseline raises the reported score while real coverage decays. Baseline TTL + expired-means-full-run is the mitigation, and it is not optional garnish.
WorkWingman mutation CI — NOT part of FLT-16. ⚠️ This entry was written wrong TWICE (claim, then retraction). Third version, timestamp-verified. If you are reading a "capacity" explanation anywhere, it is the bad one.
What was actually true. Commit b606a93 (2026-07-08, "route jobs to the self-hosted warm pool") moved 8
ci.yml jobs and both mutation.yml jobs onto [self-hosted, workwingman, linux, docker, x64] when cloud
minutes ran out. It pointed them at a designed pool of one Linux Docker runner + one Windows host runner per
PC. The Windows half was registered. The Linux half was never built, and no provisioning code was ever
committed. For a week, no runner matched the linux label, so those ten jobs per run queued until GitHub's
24-hour limit cancelled them. mutation.yml: 17 cancelled, 0 passed, ever. Any mutation score attributed to
CI predates this and did not come from CI. (Source: .github/runner/README.md, PR #23.)
Timeline (verified against commit timestamps and docker inspect, not inferred):
- 2026-07-08 — b606a93 routes 10 jobs to a linux label with nothing behind it.
- 07-08 → 07-15 23:11 CDT — every one of those jobs queues to the 24h limit and dies. This is the window of
the failures this entry set out to diagnose.
- 2026-07-15 23:11:49 CDT — peer session lands 0f787ef "provision the Linux runner the workflows already
required" (Dockerfile + start-runner.ps1 + README). Container ww-andygreatroompc-linux starts 41
seconds later at 04:12:30Z.
- 2026-07-16 02:15 CDT — peer lands 228c3cf, raising the container cap 5g → 6g for StrykerJS.
- 2026-07-16 04:22:25Z — mutation-gate (run 29467990821) executes for the first time in the repo's history.
- 2026-07-16 04:54:37Z — killed at 32 min by cancel-in-progress when push 6cab516 landed at 04:42:43Z.
Three wrong calls, and why. Read this part; it is worth more than the finding.
1. ~~"Nothing answers that label set."~~ — Was RIGHT for 07-08 → 07-15 23:11, i.e. for exactly the failures
being diagnosed. It only became false 34 minutes before it was checked, because a peer had just fixed it.
2. ~~"The runner is online, labels match — the cause is capacity."~~ — The retraction was itself WRONG. The
runner was online (34 min old), but there was never a capacity problem: there was a nonexistent runner.
Retracting a correct claim on a 34-minute-old observation is the worst error in this entry.
3. ~~"No OOM: zero memory errors in the log, container never restarted."~~ — Invalid method. Per
start-runner.ps1: a worker killed by the cgroup OOM killer does NOT set the container's OOMKilled flag —
only PID 1 dying does. The starvation is invisible to exactly the two measurements used, and surfaces as
Stryker's opaque "Test runner crashed." The peer's 5g→6g raise was the real fix.
Root cause of all three: sampling a system a peer session was actively repairing, and reading their in-flight
fixes as findings. Each diagnosis was published confidently and overturned within the hour. Contributing
artifact: GitHub reports run status as queued while any job in it still waits, so
runs?status=in_progress reads empty while a job is demonstrably running — run status ≠ job status; query
/actions/runs/<id>/jobs. Before diagnosing shared infra: check git log for peer commits in the window, and
date every observation against them.
Frontend mutation 94.16% on record is not merely stale — it never came from CI (local run 2026-07-15 measured 24.12%). CI had never run it.
Method lesson: five seats debated Coverlet attribution semantics and baseline TTL design for ~10 minutes of
wall-clock; a 10-minute gh run list would have ended the question before it was worth asking. Measure the
bottleneck before convening a council about it — a council will argue your premise, not tell you it is false.
Note also the chairman seat and the top-ranked seat were the same lineage ("4-of-5 ranked A first" reads more
independent than it was), and both house councils were unreachable (gaming dropped on FLT-63, streaming never
queried), so no non-Anthropic lineage checked this.
FLT-61 · Tavily narrow-adopt: shared C# web-search MCP wrapper on membus — Backlog — blocked on BYO key (Jira key FLT-61 · WT-8f94, 2026-07-15: council-approved, not started)¶
Council verdict (llm-council opus, 5/5 seats converged independently): NARROW-ADOPT. Report:
llm-council/reports/2026-07-15_103940_should-we-adopt-tavily-the-llm-oriented.md.
The gap is NOT search for Claude — WebSearch/WebFetch + the grounded Gemini/Grok seats already cover research at zero marginal cost. Three real gaps: (a) deployment — Codex and Ollama have no web tool at all, and a local model doing RAG has zero grounding today; (b) capability — WebFetch is one-URL/one-prompt, there is no primitive for "ingest all the NATS docs", so map/crawl is the actual purchase; (c) council parity — non-Claude seats can't cite the evidence the Claude seat saw. Capability purchase = crawl/map/extract; deployment reason = Codex/Ollama. Conflating the two is how this creeps into a paid fleet-wide default.
Scope: free tier only (1,000 credits/mo, alert at 800, no PAYG without an explicit decision) ·
one key server-side behind a C# MCP server on the membus, generic IWebSearch + Tavily adapter so
Brave/Exa/Firecrawl are a config swap · basic search + extract for Codex/Ollama, map/crawl page-capped
on demand · research and advanced hard-denied at the wrapper · wrapper owns credit ledger,
URL-hash cache, page caps, truncate-to-disk, shared rate limiter, per-seat quotas · fallback native →
Tavily basic → WebFetch → fail loudly.
NOT in scope: per-seat keys (ever) · routing Claude/Gemini/Grok through it by default (double taxation — you pay Tavily credits and model tokens, converting a free search into a paid one) · the vendor MCP server as permanent surface (fine for a time-boxed trial; it hands every seat a raw key with no credit accounting, exactly what the governor prevents) · a JSON-schema extraction gateway (Tavily returns cleaned page content, not schema-conformant objects — the Ollama seat proposed this from a misreading; four seats caught it).
Sharpest failure mode: the Research endpoint burns up to 250 credits in ONE call = 25% of the monthly free tier. Hard-deny it. Others: free-tier exhaustion blinding Ollama mid-overnight, crawl-loop burn, shared-key 429 starving the fleet, wrapper crash blinding seats (must degrade loudly, never hallucinate), scope creep to the Claude seats. Lock-in: near-zero — search+extract is a commodity; the only real lock-in is behavioral (prompts learning Tavily's result shape) and the interface kills it.
Unverified — do not propagate: Grok asserted (unsourced, uncorroborated) that Nebius acquired Tavily Feb 2026 and that 2026 benchmarks rank Brave/Exa/Firecrawl above Tavily. Chairman refused to certify both. Free-tier-only prices in roadmap risk either way; the exit condition is a head-to-head on our own query mix, not a leaderboard.
Exit condition: sustained >800 credits/mo → Brave/Exa head-to-head on our real query mix before paying anyone. Blocked on: BYO credentials — Andrew creates the account and supplies the key.
Caveat on the run: both house open councils were unavailable (streaming-pc MCP never connected;
gaming-pc transport dropped mid-call twice), so this verdict rests on the 5 CLI seats with no
open-model corroboration. Codex's peer-review pass also crashed on non-ASCII stdin
(input is not valid UTF-8 (invalid byte at offset 2745)) — same root cause shape as the FLT-16
PowerShell non-ASCII bomb, unticketed as of this writing.
FLT-62 · llm-council writes child stdin in the ANSI codepage, not UTF-8 — In Review — gate PASSED, awaiting land + republish (Jira key FLT-62 · WT-8f94, 2026-07-15: 2377379 on wt/WT-8f94/FLT-62, NOT pushed)¶
src/CliRunner.cs:67 pinned StandardOutputEncoding/StandardErrorEncoding to UTF-8 but never
StandardInputEncoding, so Windows wrote child stdin in cp1252. Every stage-2 review prompt (which
embeds other seats' answers — LLM prose full of em-dashes and smart quotes) crossed the pipe
corrupted. Codex refused it outright (input is not valid UTF-8, invalid byte at offset 2745) and
the council continued with 4/5 review seats and still exited 0.
Worse than the error suggests, and measured, not inferred: without the fix an em-dash (UTF-8
226 128 148) arrives at the child as byte 45 — an ASCII hyphen — because the ANSI encoder
best-fit maps rather than failing. Codex is simply the only stdin seat that validates its input
and says so. The claude and local/ollama seats (promptVia: "stdin") were silently
receiving mangled review prompts and returning confident rankings on corrupted text. The arg
seats (gemini, grok) pass via argv and were unaffected.
Fix: StandardInputEncoding = new UTF8Encoding(false) — deliberately NOT Encoding.UTF8,
whose encoderShouldEmitUTF8Identifier would prepend a BOM to the child's first stdin bytes and
trade one corruption for another. Plus a byte-level regression test proven to fail without the fix
(the pre-existing stdin test used pure ASCII, which is exactly why CI stayed green while the pipe
was broken). Same family as the FLT-16 PowerShell non-ASCII parse bomb: non-ASCII crossing a
process boundary with an unpinned encoding. FLT-58 (failed seat drops out, run still exits 0)
is what let this hide.
The runtime smoke found a SECOND live bug the 92 green tests could not. Program.cs read the
piped question via Console.In, which decodes with the console INPUT codepage (437 here) — so a
non-ASCII question was mojibake before any seat saw it, the mirror image of the same bug on the
way in. Proof, same input, real binary + real codex CLI: before, the report recorded the question as
Here they are ΓÇö µùѵ£¼Φ¬₧; after, Here they are — 日本語, echoed back intact by the seat. The
unit suite never caught it because it never feeds the real binary a real question — Program.cs is
excluded from coverage by design (TESTING.md). Both ends now pinned.
Gate (council-code-review, 5 seats seated): codex (chairman + member), gemini, grok, local
qwen3:8b, gaming-PC qwen3-coder:30b. Chairman surfaced exactly one finding — the capture path was
interpolated into a single-quoted PowerShell literal, breakable by a temp path containing an
apostrophe — applied. Dropped: the argv-has-the-same-bug claim (refuted by probe — ArgumentList
→ CreateProcessW → UTF-16, round-trips byte-identical) and the console-codepage-must-change claim
(the child reads a redirected pipe, not a console). Streaming-PC skipped (box off, TCP probe to
10.0.0.26:37878 False); gaming-PC qwen3-next:80b FAILED (canceled at 863s, server member cap).
Local seat's first canary was a false negative — $env:OLLAMA_HOST did not inherit into the
pwsh child, so it fell back to :11434 and got connection-refused; healthy on retry in 3.5s.
Validation (run by hand, FLT-3): pwsh -File tests/Invoke-CI.ps1 — the CI entrypoint per
ci.yml:33, not a hand-picked dotnet test — exit 0, 92/92, line coverage 100% (floor 70%).
Runtime smoke exit 0.
NOT DONE — the fix is committed but not live. publish/ is gitignored, and the llm-council
skill executes llm-council/publish/llm-council.exe from master. Landing the branch is not
enough: master's publish/ must be rebuilt or every council run keeps the bug. Same trap as
FLT-51 (publish/ gitignored ≠ deployed).
FLT-63 · House open councils unreachable in practice: open_council exceeds the MCP client's drop ceiling — Backlog (Jira key FLT-63 · WT-8f94, 2026-07-15)¶
Surfaced during the FLT-61 Tavily council: both house councils absent, so a council verdict shipped
with zero open-model corroboration. Not a server fault — :37800/health answers 200 in
0.11s and ask_model on gpt-oss:20b returns instantly; ICMP loss to 10.0.0.7 is the firewall
dropping ping, not an outage. Root cause is the known subagent-mcp-600s-cap: the MCP client
abandons long calls at a variable ~390-700s, and open_council serializes N models on one GPU with
weight hot-swaps between them. No member subset is both small enough to be safe and large enough to
be a council. Fix direction: submit+poll job API (open_council_submit → jobId,
open_council_status) so a client drop stops destroying completed GPU work; same treatment for
code_review_council and the CPU-bound streaming PC. Also open: the streaming-PC MCP server did
not connect at all this session.
FLT-12 · Macro self-host evaluation — Blocked (optional)¶
Only if comms-stack consolidation (email/chat/docs) becomes a goal — NOT a harness need (council: reject; MCP write surface unproven). If opened: AGPL self-host on spare capacity, DR on claude-mem pattern (Postgres replication + warm standby + watchdog), Tailscale-only exposure, license note: modifications served over network trigger AGPL source-sharing.
Delivered (pre-board fleet/tool work, retro-tracked 2026-07-14)¶
WW product work lives on the WorkWingman board (docs/BOARD.md + artifact kanban) — not duplicated here.
- FLT-D1 worktree-identity — C# CLI + UserPromptSubmit hook, session naming/governance registry · Done
- FLT-D2 usage-governor — scanner + GREEN/YELLOW/RED tiers + PreToolUse spawn gate, LIVE · Done
- FLT-D3 fleet-dispatch — C# command queue + listeners, 4/4 PCs operational · Done
- FLT-D4 fleet-telegram — C# Telegram command center, phase 1+2 · Done
- FLT-D5 NATS fleet.v1 bus + MemBus C# — wire contract, 3 trust tiers, signed envelopes · Done
- FLT-D6 llm-council — C# 5-seat council (answer/peer-review/verdict) + house council MCPs · Done
- FLT-D7 token-roi — impact-per-token metering, CPDT, Stop hook, statusline · Done (phase 2 owed)
- FLT-D8 PavlokPager — CLI + skill, wake-the-human escalation with budget · Done
- FLT-D9 claude-mem house — worker :37777 + Docker server :37877 + DR standbys (bedroom, streaming) · Done (gaming standby outstanding)
- FLT-D10 claude-session-watchdog — Scheduled Task pager on overnight session death · Done
- FLT-D11 audio-loop-mcp — C# WASAPI loopback + Whisper STT + SAPI TTS MCP · Done
- FLT-D12 caveman suite — compression skills + cavecrew subagents + savings scripts · Done
- FLT-D13 tools org — andrewjonesdev-tools, 8 private repos, pipelines, home-ci runner group on 4 PCs · Done
- FLT-D14 codex-harness-mirror — harness fleet (Codex/Gemini/NanoClaw/Odysseus/Grok) shared brief+brain, inverted review · Done
- FLT-D15 home bootstrap kit — OneDrive PC-Bootstrap per-PC setup.ps1 · Done
- FLT-D16 SSH mesh — all 4 PCs, PowerShell shells, EncodedCommand nesting · Done
- FLT-D17 Grok MCP — healthy on 4 PCs · Done
- FLT-D18 Docker update-outage fix — AutoDownloadUpdates off + root-cause writeup (2026-07-14) · Done
Prior open work (retro-boarded 2026-07-14, was tracked only in memory/repo boards)¶
- FLT-B1 CMH-5 claude-mem failover watchdog — SHIPPED master d150527 (3-fail + 5-min grace failover, 5-min failback) but NOT INSTALLED on any PC; install fleet-wide. Feeds/merges with FLT-W1. · Backlog
- FLT-B2 claude-mem gaming-PC DR standby — bedroom + streaming LIVE; gaming outstanding (blockers: logged out + UAC) · Backlog
- FLT-B3 token-roi phase 2 — owed from TROI epic (two-ledger + Kerr follow-through) · Backlog
- FLT-B4 fleet.v1 bus envelope mismatches — 2 mismatches between worktree-mail + fleet-telegram maps vs contract · Backlog
- FLT-B5 worktree-identity hook fail-open fix — ed26858 (JSON-deny + add-A rescope) built; fleet-wide redeploy pending · Backlog
- FLT-B6 fleet-dispatch listener hardening — RunLevel Highest + firewall rules on all 4 PCs · Backlog
- FLT-B7 xAI credential vaulting + Grok seat polish (SuperGrok remaining work) · Backlog
- FLT-B8 codex gpt-5.6 retest — bump llm-council fable tier when account enables it · Backlog
- FLT-B9 CI exit-code masking fix across tool repos (WinPS wrapper propagation) · Backlog
- FLT-B10 fleet-telegram acceptance completion — all worktrees × models × harnesses × councils reachable · Backlog
In flight (other sessions / blocked)¶
- FLT-W1 claude-mem auto-failover watchdog — spawned task running (own session) · In Progress
- FLT-W2 MCP dev-tool suite rollout (FLT-32) — DONE: 14 PRs merged. ESLint+Angular MCP (pinned, gated) + ReSharper CLT 12 repos + docker-autoheal (claude-mem) + read-only SQLite MCP (fleet-telegram). MSSQL deferred (no SQL/EF targets); KittySploit rejected (ZAP already in WW ci.yml). pwsh .mcp.json launchers need a Claude Code restart to verify. · Done
- FLT-W3 WW-77 LiteRT.js embeddings spike — prototype c96d601, blocked on Gemma model availability · Blocked
- FLT-W4 fleet-routine — cross-harness routines (WTS trigger + C# runner + NATS registry), not built · Backlog
- FLT-W5 polyharness parity phase 2 — fleet-dispatch mirror @9cede5b · In Progress
Log¶
- 2026-07-14 · Board created from council verdict + revised universal-harness framing (session WT-0924).
- 2026-07-14 · Vikunja bootstrapped (was empty — zero users):
fleet-agentservice user + project 2 "FLEET — Universal Harness" + all 12 tickets mirrored. Creds + 1yr API token:C:\Users\fives\docker\vikunja\fleet-agent-credentials.json(local only, NOT for any repo). Board URL: http://ANDYGREATROOMPC:3456/projects/2 · Jira mirror pending FLT-10 account step. - 2026-07-14 · Jira mirrored: sites workwingman.atlassian.net (team: WW + FLEET) and
andrewjonesdev.atlassian.net (private, invite nobody) created by Andrew (30d Premium trials,
no card — auto-drop to Free). FLEET project = KAN-1..12 mirroring FLT-1..12 titles at
https://workwingman.atlassian.net/jira/software/projects/KAN/list. Pending: Andrew's OTP
step-up at id.atlassian.com → API token
fleet-harness-sync→ descriptions via REST + Rovo MCP wiring + project key rename KAN→FLT (cosmetic). - 2026-07-14 · Jira fully wired: API token
fleet-harness-sync(expires 2027-07-12) stored atC:\Users\fives\.fleet-secrets\jira.json; project key renamed KAN→FLT (FLT-1..12 aligned); full descriptions pushed via REST; 23 retro issues created (18 Delivered → Done, 5 In-Flight); Rovo MCPatlassian-rovoregistered user-scope — OAuth grant pending (run /mcp → authenticate). FLT-10 now ~70%: remaining = OAuth grant + agent statuses + custom fields. - 2026-07-15 · FLT-1 live run CLEAN on the designed path, first time (WT-f255, run
FLT-1-finalon765fa3b):codeximplemented on the first attempt (no escalation),claudereviewed blind,locked_pools: [], zero drift, validation reran pytest itself → 3 passed, branchwt/FLT-1-final/harness-b0d2e1d1. Every prior live run had reached the gate only via failover; this is the first where the intended implementation seat did the work. Codex'struncatealso handles what gemini's missed — rejects negative limits, clampslimit<=3, keeps the ellipsis inside the bound — and the blind reviewer still added value (flagged the clamp branch and exact-fit boundary as untested). - 2026-07-15 · Two codex-seat faults found, both invisible to mocks AND to a bad live probe (WT-f255). The codex seat — the designated implementation seat — failed in 4/4 live runs while the harness looked healthy, because the escalation ladder silently carried the work to claude/gemini/grok every time. Working escalation masked a dead seat; that is worth remembering as its own lesson.
0xC0000409crashes (empty output): codex retried a configured-but-dead Figma MCP at127.0.0.1:3845and intermittently died. Fixed by the spawned config task; codex now clean 3/3 with zero rmcp fatals.- The sandbox, a SEPARATE fault (
352e96d): codex reported "every filesystem operation failed because the Windows sandbox helper codex-windows-sandbox-setup.exe could not be launched." That helper ships only in the Store/AppX package, never the standalone CLI — so codex could not read or write a single file. Fixed with-c sandbox_mode="danger-full-access"(the override council-code-review already documents; safe because agents run in a disposable worktree on a trusted workstation). Pinned by a test so it cannot be "cleaned up". Why it hid, and the rule that follows: the earlier "verified live" probe asked codex to "print OK and do not edit anything" — a task needing ZERO filesystem access. It passed against a completely broken seat. A verification that cannot fail proves nothing. Re-verified by having codex write a real file and checking the DISK, not its claim (proof.txt, contents "WROTE"). This is the same family as the--jsonschema bug: mocks agreed with the author's guess, and a live probe agreed with the author's hope. Both only fell over on real work. - 2026-07-15 · Probe race found + fixed (WT-f255,
0491f9e): splitting agy into four seats madeprobe()fire four back-to-backagy --versioncalls, and ~1 in 4 lost the race — mis-marking a healthy lane DOWN and silently dropping it from the ladder (measured: 1 false DOWN per 4 probe runs, never the same lane;agy --versionalone is 6/6 clean at 0.3–2.2s). Probes are now cached per executable and shared across the seats fronting it, with one retry: a false DOWN costs a seat for a whole run, a retry costs a second. 5/5 clean probe runs after, all 8 seats UP. Whether a LANE is spendable is a pool/quota question, never a binary-presence one. - 2026-07-14 · FLT-1 LIVE end-to-end verified against a real repo (WT-f255) — first run with real
CLIs, real git worktrees, real pytest. Target: a purpose-built sandbox repo (
textkit, real git history + passing test); deliberately NOT a fleet repo for the first live outing. Task: addtruncate(text, limit)+ tests. Both runs completed to the human gate, exit 0. - Run 1 (all seats up): codex FAILED → ladder escalated → claude implemented → grok reviewed blind → validation reran pytest itself: 3 passed. Zero review drift.
- Run 2 (
--simulate-down claude): codex FAILED and claude down → ladder walked to gemini → grok reviewed → validation: 2 passed. This is a stronger acceptance result than the scripted test: two seats were unavailable at once and the ticket still landed. - The layered defense earned itself, live. Gemini's
truncateviolated the spec (text[:limit] + "..."exceedslimitby 3) AND its own test asserted the wrong behavior — so the FLT-3 validation gate PASSED it. The blind FLT-4 reviewer (grok) caught the length violation independently and setneeds_human_review=true. Validation alone would have shipped the bug; the reviewer alone had no test signal. Confirms the known FLT-3 gap in writing: an agent's own tests are not an independent oracle. Grok also flagged__pycache__in the diff and negative-limit handling in both runs. - Real bug found + fixed (
3b56a47): the codex--jsonparser guessed the event schema wrong (msg.text; real isitem.completed→item.text). Every mock agreed with the wrong guess, so 51 green tests hid it — on every real run_extract_textreturned None and results silently degraded to the "fields inferred" fallback. Now pinned bytests/fixtures/codex-events.jsonlcaptured verbatim from a real run, and verified live (codex returns a parsed contract, no inferred-fields warning). The C# FLT-2 session hit this same class of bug, also only on a real run — mocks agreeing with the author's guess is a pattern worth a standing rule, not a one-off. - Codex seat is flaky on this box: intermittent
0xC0000409(STATUS_STACK_BUFFER_OVERRUN) with empty output, correlated withrmcptransport fatals against a configured-but-dead MCP server athttp://127.0.0.1:3845/mcp(Figma dev MCP, not running). 2 crashes then 3/3 clean on retry. The harness handled it correctly every time (escalate, don't stall), but the codex seat is degraded fleet-wide until that dead MCP entry is removed from codex's config — worth its own ticket; it silently cost the implementation seat in BOTH live runs. RESOLVED 2026-07-14 (WT-f85a). Removed[mcp_servers.figma-desktop]from~/.codex/config.toml(backup:config.toml.pre-figma-fix.20260714-233257.bak); the remote[mcp_servers.figma]stays, since that is the cross-client hub FLT-13 actually uses and the desktop server is selection-aware only — useful solely while Figma is open and Dev Mode MCP is toggled on, which it was not. Verified 7/7codex exec --jsonruns: exit 0, zero0xC0000409, zero rmcp fatals. The rmcp fatal fired on every invocation pre-fix (crashing or not), so its disappearance is the deterministic evidence; 7 green runs alone would not be, given the crash was intermittent.- "Fleet-wide" was wrong: gaming/streaming/bedroom never had any figma entry
(verified by dumping their
mcp_serversblocks over SSH). Both entries were added on great-room earlier the same day by the Figma-MCP research session, which is why both live FLT-1 runs hit it. No fleet push was needed. - Deliberately did NOT add a retry on
0xC0000409. The loud failure is the detector that found this; a silent retry would turn seat degradation into an invisible tax, and the ladder already makes a flaky seat cheap (work landed via claude/gemini both times). Instead the crash is now named —crash: STACK_BUFFER_OVERRUN (0xC0000409)inknown_risks— while still FAILED + escalating.tests/test_codex_events.py:65stays as-is; 4 tests added around it. - Prevention:
fleet-dispatch mcp-healthprobes every url-backed[mcp_servers.*]entry and exits 3 on a dead one. Run against the pre-fix backup it reportsfigma-desktop DEAD, so the next stale entry gets caught by a gate instead of by a seat dying mid-run.
- "Fleet-wide" was wrong: gaming/streaming/bedroom never had any figma entry
(verified by dumping their
- Not yet proven: the interrupt/resume gate ran with
--yes(auto-approve) in both runs; a real human answering the gate, and a--simulate-downof the whole editing ladder, remain unexercised live. 56 tests green. - 2026-07-14 · FLT-1 scaffold built + council-gated (WT-f255). Repo
fleet-harnessgit-init'd, committed LOCAL ONLY at2863033(no remote, not pushed). Python 3.13 + uv, exact pins (langgraph 1.2.9, deepagents 0.6.12, langchain 1.3.13, langchain-core 1.4.9, langchain-ollama 1.1.0, httpx 0.28.1, pyyaml 6.0.3). Shipped: swappable brain (default ChatOllama → 10.0.0.7 gaming PC, localhost fallback, zero API keys required); deterministic router over routing.yaml (FLT-6) + probes + escalation ladder; graph route → implement (git worktree) → blind cross-vendor review (FLT-4, read-only sandbox) → validation that reruns tests (FLT-3) → humaninterrupt()gate; advisory branch for text-only roles; FLT-2 contract wrappers (docs/contract.md= canonical schema shared with the C#fleet-dispatch run-agentbuild); CLIpython -m fleet_harness run|probe. Acceptance met:--simulate-down claudecompletes route → implement(codex) → review(grok) → validate → human gate, covered bytest_acceptance_simulate_down_claude. 51 tests green (real graph + shipped routing.yaml, fakes only at vendor/git edges); all 5 seats probe UP live. Council gate: Codex chairman; seats Codex + Gemini + Grok substantive. DEGRADED — local Ollama seat (gemma4) returned spinner output only, and BOTH house-council seats (gaming, streaming) failed with MCP transport drops inside their courier subagents even though TCP to 10.0.0.7:37800 and 10.0.0.26:37878 was UP and Wi-Fi was on the house SSID (not drifted) — i.e. a subagent MCP-transport fault, not a box/network fault. Worth a follow-up ticket. Verdict: 0 Critical, 3 High, 9 Medium, ~11 Low, Kerr findings none, 4 dropped as false positives. All High and Medium fixed + regression-tested (notably: reviewer was running inside the implementer's worktree and could mutate the measured diff;approval_requiredran past the human control point; freeform mode bypassed isolation; cheap-bulk could never reach Ollama; secrets rode the diff to third-party reviewers). Next: point usage-governor + fleet-dispatch at routing.yaml (FLT-6 anti-fork property is unproven with one reader); swap wrappers tofleet-dispatch run-agentwhen the C# FLT-2 lands; decide repo remote + push; live end-to-end run against a real target repo (only fakes so far). - 2026-07-14 · Rovo MCP OAuth granted by Andrew — workwingman site ONLY (private site deliberately
excluded from agent reach; REST token remains the deliberate-use path for it).
claude mcp list= Connected. New sessions get Jira tools automatically. FLT-10 remaining: agent-oriented statuses + custom fields (Primary Agent, Review Agent, Risk, Branch, Run ID), then board-as-contract checklist evaluation. - 2026-07-14 · FLT-13 phase 1 (status wall) SHIPPED (WT-df2b): new repo
fleet-mission-control, net10.0 API + SignalR + Angular 22 NSwag PWA, verified live against real fleet-dispatch data, council gate Codex+Gemini+Grok+qwen3:8b+gaming:qwen3-coder:30b+streaming:llama3.3:70b (devstral seat FAILED/canceled), chairman list (1H/6M/5L) fully implemented, backend 20/20 + frontend 19/19. Local-only, not pushed. FLT-13 → In Progress (phases 2-4 remain); FLT-14 read-only panels unblocked. - 2026-07-15 · FLT-13 quota surface + tooling gates landed (WT-df2b, fleet-mission-control local commits 4-5): /api/quota + QuotaUpdated hub event reading agy-ledger.jsonl READ-ONLY (single-writer honored); agy-Claude rendered as remaining invocations + reserve intact/spent (units, never %), weekly counts as distinct no-refresh lines, weekly limit rows → hard-deny banner + reserve spent. Tooling: angular-eslint clean, Stryker.NET 39.19% baseline (hardening chip spawned; stryker-js blocked on Angular vitest builder), ReSharper InspectCode (1 fix), ZAP baseline+API scan 0 FAIL (CORP/CSP/referrer/permissions headers added), 0 vulnerable packages (Microsoft.OpenApi 2.7.5, npm qs override). Delta council gate: Codex+Gemini+qwen3:8b+gaming:qwen3-coder:30b, chairman 3H/4M/2L all implemented incl. Kerr fix (reserve gated on weekly, not 5h proxy). 30/30 + 24/24.
- 2026-07-15 · FLT-16 CI tooling pack rolled out to 11 C# repos (WT-df2b): vuln gate (enforcing)
- InspectCode (error-severity) + Stryker (report-only, staggered) + pinned tool manifests.
Council-gated on the pilot template (6 seats; 3 Highs caught — fail-open vuln gate, floating tool
installs, cron dogpile — all fixed before replication). Every repo's build/tests/gate re-run by the
orchestrator; 0 vulnerable packages fleet-wide. Codex implemented (governor RED). All branches
wt/WT-df2b/FLT-16, committed, NOT pushed — land decision pending. - 2026-07-15 · FLT-16 LANDED on origin/master, all 11 repos (WT-32b7). Backporting the stronger
clean-marker gate surfaced a deeper fail-open the council caught: a solution-wide scan proves only
that SOME project got a verdict — one clean marker satisfies the aggregate match even if another
project was never evaluated. Gate now enumerates projects and requires a per-project verdict;
DOTNET_CLI_UI_LANGUAGE=enpinned (marker is literal English text). Council 5/7 seats (Gemini found the multi-project hole, Grok the locale brittleness; qwen3-next:80b hit the 480s cap; streaming PC down — TCP+ping fail while gaming answered from the same host). Validation: extracted each workflow's real gate script and executed it — 11/11, enumerated == clean verdicts (WW 29/29). That caught a pilot bug nothing else did: one em-dash in arun:block =Missing closing '}'under WinPS 5.1 (GH Actions writes BOM-less UTF-8, 5.1 reads ANSI) — gate bodies now ASCII-only, seewinps-run-block-nonascii-parse-bomb. Landed per the multi-session FF-push edict (rebase in worktree → lease-pinned push straight to origin); origin was ancestor of every tip, 0 peer commits lost. membus now scans 4 projects (picked up MemBus.Contracts). - 2026-07-15 · FLT-16 follow-on: test-impact analysis RESEARCHED → REJECTED, premise was false (WT-975b).
Asked whether to scope the pack's Stryker runs to changed code via GHA/MCP. Council convened (opus, 5/5
seats) and answered well — but optimized a bottleneck that does not exist, because it was never given the
numbers. Measurement:
--coverage-analysis perTestis already Stryker.NET's default (all 11 configs leave it unset = already on, so the council's #1 win is a no-op); .NET mutation wall-clock is ~15 min across the fleet (2m35s–15m23s, running in parallel across separate repos); no MCP exposes a TIA selector today. Nothing to buy, nothing to build. Council log carries a correction block — the verdict is moot. Real defect surfaced and spun out separately: WorkWingman mutation CI produces no result because thelinuxrunner its workflows require was never built (b606a93, 07-08, routed 10 jobs at a label with nothing behind it; 17 mutation runs cancelled, 0 passed, ever). A peer session provisioned it at 07-15 23:11:49 CDT (0f787ef). See the FLT-16 section — this line was retracted once on a 34-minute-old observation and the retraction was itself wrong. Cleared while measuring: staggered crons are real (Mon 06/10/12/20),audio-loop-mcphasmutation.ymlon origin (local checkout was 2 behind). Method lesson: measure the bottleneck before convening a council about it — a council argues the premise rather than telling you it is false, and here chairman and top-ranked seat were the same lineage while both house councils were unreachable (FLT-63), so no independent lineage checked it. - 2026-07-16 · ~~Retraction: the WorkWingman "runner label" defect was not real.~~ THIS RETRACTION WAS
ITSELF WRONG — superseded, see below and the FLT-16 section. It claimed the backlog was "capacity". It was
not. The
linuxrunner the workflows require did not exist from 07-08 (b606a93) until a peer session provisioned it at 07-15 23:11:49 CDT (0f787ef) — 17 mutation runs cancelled, 0 passed, ever. The original "nothing answers that label set" claim was CORRECT for that entire window; it was retracted on an observation taken 34 minutes after the peer's fix landed. - 2026-07-16 · Post-mortem: four wrong diagnoses on WorkWingman CI in one night (WT-975b). Sequence: label
unanswered → runner wedged → orphaned processes → memory-starvation-dismissed → "capacity". Every one
published confidently; every one overturned within the hour. Root cause: sampling shared infra while a peer
session was actively repairing it, and reading their in-flight fixes as findings. The peer landed the runner
(
0f787ef, 23:11 CDT), raised its cap 5g→6g (228c3cf, 02:15 CDT), and rebuilt the image three times — each change silently invalidated a conclusion drawn minutes earlier. Contributing artifacts: (a) GitHub reports run status asqueuedwhile any job in it still waits, soruns?status=in_progressreads empty while a job runs — run status ≠ job status; query/actions/runs/<id>/jobs; (b) a cgroup OOM of a worker does not setOOMKilled(only PID 1 dying does), so "no OOM in the log +restarts: 0" does not rule out memory starvation — it is exactly what starvation looks like. Standing rule: before diagnosing shared infra,git logthe window for peer commits and date every observation against them. Cost: two false claims published to the board, pushed to a remote, and one handed to a spun-out session as its premise. - 2026-07-16 · Verified by spike, and it holds: the PR #21 shell fix survives a virgin runner (WT-975b).
Reproduced the original
PSSecurityExceptionon demand (process-scopePSExecutionPolicyPreference=Restricted) on greatroom + gaming + streaming. Per box: unfixed shell under Restricted exits 1 (control fires — the simulation is real), PR #21's membus-form shell exits 0 (survives), and a failing command through it still exits 7 (no green-washing). So a NEW runner needs no machine-policy change — the in-repo fix is the anti-drift property. v1 of this spike was contaminated and reported a false pass: it was launched with-ExecutionPolicy Bypass, which exportsPSExecutionPolicyPreferenceto every child, so the "unfixed" control ran under Bypass. Caught only because gaming — which had just thrownPSSecurityExceptionin CI — reported Bypass. Also: all runners execute asNT AUTHORITY\NETWORK SERVICE, and ExecutionPolicy CurrentUser is per-user, so probing your own policy proves nothing about the runner's. - 2026-07-16 · usage-governor CI is green-washing failures — measured, not theorised (WT-975b). Its
ci.ymlshell omits the trailingexit $LASTEXITCODEthat membus carries. Measured identically on three boxes: a body ofcmd /c "exit 7"returns 7 through membus's form and 0 through usage-governor's. A red suite renders as a green check. Any recent green on that repo is unverified. Spun out as its own task; the other 9 FLT-16 pack repos need the same audit (this is the same fleet config drift that left WorkWingman without the setup-dotnet fix its 11 siblings got).
Fleet Routines build tickets (FLT-34 fleet-routine) — spun 2026-07-17 from opus council¶
Council opus 2026-07-17 (ranking D/grok>A/claude>B/codex>C/gemini>E/local; report llm-council/reports/2026-07-17_191704_should-the-fleet-harness-flt-1-the-universal.md) re-ratified the delegate seam now that FLT-1 exists: fleet-routine = C# scheduling plane (WHEN+budget); fleet-harness = the ONLY orchestration engine (HOW+adapter). Runner invokes the graph, never re-selects adapters. C# runner + Python graph, process boundary a feature. House councils 5 AGREE / 2 DISSENT (both dissents = the rejected "absorb into FLT-1/Python" minority; both heaviest votes gpt-oss:120b + qwen3-next:80b confirm).
Blocks chain: FLT-104 → FLT-105 → FLT-106 → FLT-107 → FLT-108. All anchored to FLT-34.
| Key | Phase | Status | Summary |
|---|---|---|---|
| FLT-104 | Gate 0 | To Do | GO/NO-GO non-interactive auth smoke (fleet-routine doctor --noninteractive), 6/6 harnesses as Andrew user "whether logged on or not" (NOT SYSTEM). Blocks all scheduler code. |
| FLT-105 | P1 | To Do | run-now vertical slice through the C#↔fleet-harness seam: registry+tombstones, CLI add/list/delete/run-now+cap-validate, fire-time fail-closed governor (defer=skip-tick), fleet-harness routine-fire entrypoint, emit fleet.v1. run-now BEFORE WTS. |
| FLT-106 | P2 | To Do | WTS trigger via COM/API (trigger-only), StartWhenAvailable, reboot/sleep survival. |
| FLT-107 | P3 | To Do | multi-PC JetStream durable replay + Claude-native routine normalize. Open fork: subprocess/sync (P1) vs NATS-command/async (multi-PC) — decide here. |
| FLT-108 | P4 | To Do | Pavlok dedupe/escalation + full cap enforcement (maxTokens/cost/wallclock/concurrency/cooldown), missedRunPolicy=skip-retry-never-flush, immutable audit. |
2026-07-29 night — WT-c556 (Clahadore) session close¶
Landed + deployed. All services now run from reconciled WorkWingman master 9f96e1a1d.
| Ticket | State | What |
|---|---|---|
| WING-215 | Needs Human Review | board/docs.workwingman.ai behind Cloudflare Access; DNS migrated Google->Cloudflare (11 records preserved, yc untouched); tunnel + Pages; 8-email roster allowlisted |
| WING-225 | Needs Human Review | Vikunja standby replicas on gaming/streaming/bedroom; failover proven with primary down; link shares replicated to all replicas |
| WING-227 | Done | MPA mobile sweep (WT-ab3e) — deployed, verified 375/320px |
| WING-238 | Needs Human Review | branch topology reconciled: master IS the trunk again; 150 -> 70 branches |
| FLT-180 | Done | bedroom SSH restored, verified end-to-end |
| WING-228 | To Do | SPA Flow/Studio mobile epic — 3 open questions for Andrew |
Fleet-harness commits: 628364b lane buckets · 82ea9c0 rehydrate lanes + DR validation repair · 156d481 standby replicas · ae329cd BoardSurfacesWatch · e87bd4a DR dump guards · 42e24f3 link-share replication.
fleet-docs-hub: now a private repo in the tools org; ba10c61 Pages auto-publish; 42cd24a collector cwd + YAML escaping fixes.
Needs Andrew: (1) Vikunja primary 2.3.0 vs replicas 2.4.0 — upgrade primary deliberately, never downgrade replicas; (2) Access still One-time-PIN until WING-214 Google IdP; (3) nine fleet scheduled tasks were found disabled (incl. VikunjaNightlyBackup and VikunjaRestoreVerify) — re-enabled, but cause unknown and it can recur; (4) WING-228 open questions.
Incident, self-inflicted, recovered: testing a DR guard I passed -FromDump a 5-byte fake file; the .sql branch DROPs the database before reading input, so the primary board was wiped. Recovered in ~4 min from the Jul 23 dump + -FromJira. Real defect fixed in e87bd4a (refuses non-dumps and newer->older schema). Newest dump was 6 days old because the nightly backup was one of the disabled tasks — that is the finding worth acting on.
2026-08-04 — WT-3858 (Clahadore) · FLT-191 greatroom pagefile fault¶
FLT-191 · Greatroom pagefile on H: silently fails at boot — In Progress (WT-3858, 2026-08-04)¶
Symptom: H: pagefile config reverts every reboot; 08-04 commit exhaustion (error 1455) crashed grok.exe, agy.exe, pwsh, Claude Code.
Root-cause receipts (greatroom): PagingFiles = H:\pagefile.sys 32768 49152 but ExistingPageFiles = C:\pagefile.sys and TempPageFile = 1 — Windows failed to create the H: pagefile at boot and fell back to a temporary 81 GB C: pagefile. H: is internal NVMe (Samsung 990 EVO 4TB), Basic/GPT/NTFS/healthy, letter mapped in MountedDevices — not USB/dynamic/late-letter. BitLocker on H: = prime remaining suspect (elevated check dispatched fleet-wide). Continuous Resource-Exhaustion-Detector 2004 events; svchost ~55.9 GB commit (possible service leak, follow-up item).
Pending: elevated fleet diagnostic results (all 4 PCs); fix proposal to Andrew (C: primary pagefile system-managed or 64–128 GB; H: 48 GB max is undersized). Reboot = Andrew-only. System-settings change = Andrew approval first.
2026-08-05 — WT-290d (Clahadore) · FLT-204/205 MCP v2 migration + wingcms registration bug¶
FLT-204 · MCP v2 (spec 2026-07-28) migration: the 3 C# servers we own — To Do (WT-290d, 2026-08-05)¶
Question asked: can MCP's new stateless support make the MCP fleet stateless and fix RAM exhaustion?
Answer: no on RAM, yes on the protocol. Statelessness buys routing/safety properties, not bytes — process consolidation is the RAM lever, and they are orthogonal. Measured fixed floor is 62% of MCP commit (6.13 of 9.93 GB across 36 unique server identities), so the council's falsifier zero fired: consolidation concentrates the OOM rather than curing it. Physical pressure is 22 claude hosts (3.13 GB WS) + Chrome + WSL, not MCP.
Correction worth keeping: every process filter used node|python|uv and silently missed dotnet.exe, hiding two of the three servers in question. Corrected, the servers we own are 22 procs / 899 MB commit / 1.24 GB working set — consolidating them would recover ~1.0 GB physical. Real, but it does not move the fleet verdict: the bulk is plaud (18 procs/1.44 GB) + jdocmunch (35/1.04 GB) + jdatamunch (35/0.96 GB), all third-party and pinned mcp<2.0.0.
Scope collapsed from ~40 servers to 3: audio-loop, wingcms, workwingman-forms — all already on ModelContextProtocol 2.0.0-preview.1. Everything else is upstream or already remote HTTP.
Decision (Andrew): option 3 — v2 stdio now as the cutover target, HTTP behind an off-by-default flag, and the shared-daemon security suite built now so the flag stays flippable.
Proven on audio-loop (wt/WT-290d/mcp-v2-audio-loop, uncommitted pending gate): bump preview.1→2.1.0 builds 0 Warning(s) 0 Error(s); tests 22/22 passed; server/discover returns supportedVersions:["2026-07-28"]; legacy initialize (2025-06-18) still ACCEPTED and negotiates down, byte-identical to the current production build. Cutover cannot break Claude Code 2.1.222. Protocol work was one line, ~10 minutes — the audit's 6h was pre-existing hardening debt, not migration.
Two findings static analysis could not reach: (1) AddMcpServer() auto-advertises a logging capability despite zero logging code — and Logging is deprecated in 2026-07-28, so all three servers advertise a deprecated capability they do not implement; (2) ttlMs: 0, cacheScope: "private" means "do not cache", so the prompt-cache token benefit of stable tool lists is not realised by default — setting a real TTL is the one place this work touches the token bill.
FLT-205 · wingcms MCP registered fleet-wide from a stale, build-failing worktree — To Do (WT-290d, 2026-08-05)¶
~/.claude.json serves wingcms (31 tools, every session on the box) from _wt/ww-cms-merge — branch wt/WT-570b/wingcms-bucket-merge, 113 commits behind master and recorded in memory as build-failing. Compounding it, the registration ships "env": {} while WingCms.Cli/Program.cs:1079 resolves the content file by walking up from Directory.GetCurrentDirectory(), and WingCmsTools.cs:281-291 shells out without setting WorkingDirectory — so which site-content.json gets written depends on the launcher's CWD, across ~12 worktrees each holding a copy.
Blast radius: LATENT, not drifting. SHA256 across all copies shows one hash everywhere including canonical, and a second hash only in the registered tree explained by its own committed branch work; git status clean in both. No stray writes have happened yet.
Also noted: wingcms has no test project at all.
Standards debt, self-reported: this session ran ~10 turns of investigation before any ticket existed, and its board footer pointed at FLT-192, which was already Done. FLT-192's own description had already recorded "each session launches its own full MCP fleet" and named these servers — the measurement re-derived a documented cause. Tickets and board entry created retroactively on Andrew's prompt, which is the failure the standard exists to prevent.
audio-loop LANDED — 372f337 on wt/WT-290d/mcp-v2-audio-loop, pushed + fanned to gaming/streaming/bedroom. 1 of 3 servers. Receipts: dotnet build -c Release → 0 Warning(s) 0 Error(s); dotnet test -c Release → Passed! Failed: 0, Passed: 28, Total: 28; tools/call list_audio_devices returns text byte-identical to the preview.1 build (657 chars, 11 devices), differing only by resultType and _meta.serverInfo — both expected 2026-07-28 additions. Verdict: passed.
Gate: 4 seated / 1 skipped. Cedric (no findings, independently built + ran the suite) · Regular Jenny 4520 chars · Cyber Jenny 7564 chars · Gronktayvius 10375 chars · Clahadore skipped (codex-claude-admit denied; advisory-only since Claude authored). Clahadore chaired because Cedric appeared dead at synthesis time; Cedric's clean verdict arrived after and corroborated it.
Two silent seat deaths caught by the validation contract — both would have read as "no objections": Jenny attempt 1 exited 0 with empty stdout (jetski: no output produced — a tool required the "command" permission); Cedric attempt 1 exited 255 on rmcp ... Auth(AuthorizationRequired) because one of 10 configured mcp_servers demanded auth. Fixed with a no-tools instruction and -c mcp_servers="{}" respectively. This is exactly the failure mode the contract exists for.
The finding that mattered: Jenny and Gronktayvius independently spotted that AudioLoopMcp.Tests referenced Core only — 22 green tests proved domain logic and nothing about the wire. Fixed with McpProtocolContractTests (6 tests spawning the real server over stdio, pinned to verbatim captured payloads, including a negative assertion that top-level serverInfo stays absent). Negative control: pinned back to preview.1 → 3 of 6 FAIL. The tests have teeth.
Settled by decompile: Gronktayvius read McpServerImpl.ConfigureLogging in 2.1.0 — it sets Capabilities.Logging = new() unconditionally, which is why both of Clahadore's suppression attempts were no-ops on the wire while build and tests stayed green. Not an app defect, no public seam. FLT-204 acceptance criterion 3 is unmeetable as written and needs rewording.
Spun out: FLT-208 — transcribe opens any absolute path with no confinement (Cyber Jenny, HIGH). Pre-existing, not this diff, so it got its own ticket instead of expanding the commit or burying a HIGH in a line item.
Next: workwingman-forms (security-sensitive — _managedForms is the only control gating the forms.body grant), then wingcms (blocked on FLT-205).
2026-08-06 overnight — WT-1d04 (Clahadore) · FLT-201/202/203 built + FLT-206 opened¶
Andrew asked whether the deploy + branch-merge managers were ever built, and whether CLI-driven browser/app click-throughs could be fanned across the house PCs. Answer to the first: no, neither existed. Answer to the second: yes, but not via any vendor's own browser feature.
Shipped tonight — all committed and pushed, nothing merged to master¶
| Ticket | Branch / commit | Receipts |
|---|---|---|
FLT-201 fleet-uitest |
new private repo, wt/WT-1d04/FLT-201 @ 845d02c |
build 0/0 · 45/45 tests · displays verified live on greatroom |
FLT-202 fleet-merge |
new private repo, wt/FLT-202/init @ 88d8bda |
build 0/0 · 4/4 tests · 33 files, 1803 insertions |
| FLT-203 rc artifact lane | release-coordinator wt/FLT-203/installer-lane @ 0b66937 |
105 existing before → 105 after, +7 new = 112 · build 0 errors |
FLT-201 written by Clahadore on greatroom; FLT-202 and FLT-203 by Cedric (Codex gpt-5.5, xhigh) on gaming, dispatched over SSH via hidden scheduled tasks.
The measured thing that made FLT-201 possible¶
Headed UI testing across the fleet was blocked by two facts, both proven rather than assumed:
- SSH cannot see displays. The identical probe returns a phantom
WinDisc1024x768 over SSH and the real\.\DISPLAY1..3in session 1. Fix is a hiddenLogonType Interactivescheduled task. - On gaming, the 49in 32:9 ultrawide is the PRIMARY display. Every unpinned window defaults onto
the one monitor Andrew asked us to stay off. So "fall back to primary" is a critical bug, and
TargetSelectorthrows instead.
Exclusion is geometric, never by name: aspect >= 2.5 and width < 1280. Necessary — the two
G95SC units report different EDID ids (SAME028 on gaming, SAME019 on streaming), so an
allowlist would silently miss one. Both rules fired correctly and unprompted on two unlike layouts.
Two more traps encoded: DPI awareness must be set before reading bounds (4K panels read 1280x720 without it), and virtual-desktop origins are negative (gaming X=-2560, streaming X=-3584).
Fleet faults found by tripping over them — all feed FLT-206¶
- Codex sandbox is broken on 2 of 3 PCs. greatroom:
CreateProcessWithLogonW failed: 2. streaming:windows sandbox: timed out after 15000ms connecting runner pipe-in. Only gaming works. This silently removed two-thirds of offload capacity, for an unknown length of time. - gaming's
claudeCLI is not logged in —Not logged in - Please run /login, while exiting 0. Exit codes are worthless for auth checks. release-coordinatorwas inmanifest.jsonbut had never landed on gaming. Manifest presence is not evidence of on-disk presence; the sync is not reconciling.- Codex sandbox output is owned by
CodexSandboxOffline, not Andrew. Git refuses withdubious ownership; committing neededtakeown /R+icacls /Ton the repo (267 files) and on the parent's.git/worktreesmetadata (60 files). Any remote codex job leaves unusable output. - Codex sandbox blocks outbound network — a remote job cannot clone a missing repo. Repos must be pre-staged before dispatch.
- Dead Figma MCP entry on gaming and streaming, throwing
AuthRequiredinto every codex run. Same class as the deadfigma-desktop :3845that previously crashed seats. - greatroom at 0.7 GB free RAM of 29.4 GB, with 36
claude.exeprocesses against a cap of 2.
Standards debt, self-reported¶
- Review gate is thin and I am not calling it passed. FLT-201 got ONE seat (Gemini,
NO FINDINGSon the Core diff). Grok returned only a preamble and is counted FAILED. Codex was unavailable. FLT-202 and FLT-203 have had no independent review at all — Codex reviewing its own output is not a seat. None of this should land on master until a real gate runs. fleet-uitestandfleet-mergeare not yet infleet-repo-sync/manifest.json, so they will not reach the other PCs. Deferred deliberately: that edit needs the review gate, and the gate seats are mostly broken tonight.- FLT-201's
--via-sessionhangs,runwas never executed against a real browser, andinstall/uninstallwere never executed. All recorded on the ticket rather than glossed.
2026-08-06 — WT-fcc7 (Clahadore) · FLT-178 headless consoles¶
FLT-178 · Fleet-wide headless console enforcement — Done, with follow-ups (WT-fcc7)¶
Landed 79ac234 + afc21e9 on usage-governor master, fanned out to all peers.
Root cause was not what anyone assumed. LogonType=Interactive, not Settings.Hidden —
per Microsoft's docs Hidden only hides the task's row in the Task Scheduler UI. Every offending
task already had Hidden=$true and showed a console anyway. Control group on one machine:
UsageGovernorRaftAuthority (S4U) produced no window; UsageGovernorAdmitAuthority and
FleetDispatchServe (Interactive) did.
| Machine | Tasks flipped | Visible consoles after |
|---|---|---|
| greatroom | 17 | none (verified) |
| bedroom | 6 | none (verified) |
| streaming | 6 | none (verified) |
| gaming | queued | offline 16h at the time |
Two theories killed by measurement, so deliberately NOT built: a PATH shim for .NET
grandchildren (a 120 s trace over a full build + 582 tests caught zero windows from
dotnet/MSBuild/vstest/git) and a Claude desktop launcher (app.asar already ships windowsHide
+ conhost --headless + node-pty). The first detector, which reported "74 flashes", was itself
invalid — CREATE_NO_WINDOW still spawns a conhost.
Review: council (Cedric chair, Jenny, Cyber Jenny, Gronktayvius) → 9 findings, all fixed. A
second Cedric pass over the fixed code found 7 more, 3 P1 — including a StrictMode bug that made
every backup fail and so blocked both mutators entirely. That is precisely what the first commit's
unverified verdict was warning about.
Incidents, self-inflicted, recovered: (1) FMC API taken down on streaming — killing a stale
instance revealed Device Guard/WDAC now blocks the self-contained .exe; it had survived since
07-19 only because it was loaded before the policy. Repaired by repointing its launcher at the
dotnet.exe + DLL form bedroom already uses. (2) A stray unelevated FleetDispatch.exe
(Explorer-parented, since 08-04) had been serving in place of the elevated task, which had never
run.
Needs Andrew / follow-ups:
1. The usage-governor override never reaches fleet-dispatch. GovernorGate.ReadTier reads only
state.json's tier while UsageGovernor.exe override writes a separate override.json, so a
logged override still leaves every non-critical job deferred (governor RED). Only --critical
bypasses it. This defeated the overnight override fleet-wide.
2. S4U + RunLevel Highest is a recovery deadlock. An unelevated session cannot stop or restart
the session-0 listener — schtasks /End reports SUCCESS and does nothing. Dispatch is the
fleet's only no-UAC elevation path, so a wedged dispatch needs manual elevation. Mitigation:
register a FleetRestartDispatch task at RunLevel Highest that any session can Start.
3. FMC launchers differ per machine (one style WDAC-blocked) and append to a fixed log path with no
lock handling, so a stale instance silently blocks restarts behind a misleading error.
Standards debt, self-reported: -WhatIf row emission and the action sweep have still never been
executed on a real machine — both need elevation and dispatch would not accept jobs. Recorded on the
commit rather than glossed. gaming is unconverted.
Full write-up: usage-governor/docs/FLT-178-findings.md.
2026-08-06 ~02:45 — FLT-206 fleet-healthcheck VALIDATED against ground truth¶
fleet-healthcheck now detects real faults on the real fleet. Private repo
andrewjonesdev-tools/fleet-healthcheck, branch wt/FLT-206/init @ e60ca6d, 6 commits,
22/22 tests. Six live runs against all four PCs.
| Run | Result |
|---|---|
| 1 | 42 FAIL / 0 PASS — a 15s global timeout starved every probe |
| 2 | 16 PASS / 39 FAIL — timeouts calibrated; found 2 real fleet faults unprompted |
| 3 | 17 PASS / 22 FAIL / 16 INCONCLUSIVE — false alarms became honest unknowns |
| 6 | matches ground truth; CLI probes now 9-74s, i.e. real model round trips |
Faults it found on its own, all independently verified:
- release-coordinator listed in fleet-repo-sync/manifest.json but never landed on gaming —
manifest presence is not evidence of on-disk presence, the sync is not reconciling
- .git directories owned by a foreign account on all four machines
- greatroom RAM below threshold (WARN, correctly not FAIL)
- bedroom claude is logged out — nobody knew. Verified: Not logged in - Please run /login
on stdout, exit 1, governor banner on stderr
- agy is unauthenticated on all four machines — prints an OAuth consent URL and blocks for
60s. This is why the Gemini review seat could not be seated for most of the night
It also correctly classifies rather than just detecting: gaming claude reports needs re-auth, not a generic failure. Those have different fixes.
Not ready for email yet. agy needs an auth-error pattern (4 misclassified FAILs/night),
greatroom's broken codex sandbox is masked as INCONCLUSIVE by the duration heuristic, and
mcp-configs still errors on greatroom/bedroom.
The CLI-probe defect: four stacked causes, each of which alone reads as "the CLI is down"¶
- 15s global timeout starved every probe
ProcessStartInfo.FileNameset to a bare tool name withUseShellExecute=falsedoes no PATHEXT search, socodexresolved npm's extensionless bash shim- closing stdin is not the same as redirecting from NUL — an open pipe hangs, a closed pipe
errors (
stdin is not a terminal), only the device works - cmd.exe does not accept backslash-escaped quotes — the prompt shattered into tokens
(
error: unexpected argument 'with' found)
Standing memory codex-exec-stdin-hang corrected with all three stdin states measured. The old
rule ("ALWAYS < NUL") was being applied shell-blind; in PowerShell < is a parse error, and the
"obvious" C# substitute (RedirectStandardInput + Close()) is also wrong. Only
cmd /c "... < NUL" works.
Self-reported: round 4 shipped a fix built on my own wrong conclusion — I mistook "PowerShell
can't parse <" for "< isn't needed." Codex implemented my instruction faithfully and it failed.
What kept it converging was one invariant, not insight: the probe returns faster than PATH resolution takes. True every round regardless of what changed. That check is now permanent in the tool, so the next invocation defect announces itself instead of masquerading as a fleet outage.
The costly gap was diagnostic, not functional: the probe discarded stderr. Every failure
named itself there and had to be re-derived by hand outside the tool. Now always recorded.
2026-08-09 — WT-1283 · FLT-223 passive agent awareness — Needs Human Review¶
FLT-223 · Fleet-native passive AgentMessage/v1 and Mission Control shadow timeline¶
Landed and demo-ready. Fleet now has a versioned, local, durable AgentMessage/v1 producer and a
read-only Mission Control awareness timeline. The plane is fixed to
trust=peer_untrusted, authority=non_authoritative, deliveryMode=shadow, and
canAuthorizeActions=false. Raw message text stays out of REST, SignalR, browser state, the UI,
Fleet evidence, prompts, approvals, and landing authority.
Commits: fleet-harness a344e59 · worktree-identity 2d85ddb · fleet-mission-control
d98a4be · codex-harness-mirror 6f3fa14. FleetRepoSync triggered gaming, streaming, and
bedroom after all four fast-forward pushes.
Gates: harness 215 passed / 1 skipped; producer 300/300; Mission Control backend 711/711; frontend 305/305; warning-as-error builds, lint, production build, and diff checks passed. Council PASS: Cedric adjudication, Regular Jenny, Cyber Jenny, Gronktayvius General, and Gronktayvius Red Team. Clahadore is explicitly absent until Tuesday 2026-08-11 12:00 PM America/Chicago.
Pilot limits kept visible: claimed sender is unauthenticated telemetry; disk content must remain synthetic/public; production drain/retention and scan-truncation health are follow-ups; a golden cross-repo fixture and evidence writer are required before cross-host or active awareness. Any prompt injection, approval, landing, or secret-bearing use requires a new council gate.
2026-08-14 — WT-afdb · FLT-232 gh auth probes — Landed¶
FLT-232 · gh auth status is not a health probe — standardize on gh api user¶
Landed. fleet-mac-bootstrap master 02c2d3c, home-bootstrap master 2f88b33; both PRs MERGED.
The mac-bootstrap FF was refused on first attempt because master had moved to de9ca43 (WING-345
landing, new files only, no overlap) — rebased, re-verified, then fast-forwarded. All four Macs
verified at the merged HEADs per-repo; the fan-out's own ff= counter read 0 on three boxes and was
misleading. macmini4 picked up fleet-mac-bootstrap, which it had been missing, closing half of
FLT-234. gh auth status aggregates every configured gh account and exits
nonzero if any one fails, so a stale account fails the probe on a box whose auth is fine. In
fleet-mac-bootstrap that probe gated the entire fleet-repo clone loop — and macmini4, the one box
whose probe failed, is the one box missing fleet-mac-bootstrap. Root cause on that box: the token
sat in the macOS keychain, which non-interactive ssh cannot unlock (errSecInteractionNotAllowed),
so gh reported a live token as invalid. macmini4's hosts.yml was repaired first (backup kept).
PRs: fleet-mac-bootstrap#2 · home-bootstrap#2
Gates: Council 4/4 seats — Cedric (chairman), Regular Jenny, Cyber Jenny, Gronktayvius. Clahadore
skipped (governor RED; advisory-only regardless, Claude authored). Chairman ruled changes requested,
no Critical/High; all three in-scope findings fixed — hostname pinning at four call sites, a
$LASTEXITCODE sentinel that was letting a non-launching gh read as authenticated, and corrected
comments. Validation: bash -n 0, PS parse 0, repo regression suite PASS, cmd-block harness both
branches, sentinel proven live (old 0 → new -1), gh api user --hostname github.com exit 0 on
all five boxes. Neither repo has CI, so PR CI is N/A. Re-gated on the post-fix diff: 4/4 seats
clean, no findings (Regular Jenny's first round-2 attempt truncated on an agy response timeout and
was re-run rather than seated). No chairman pass on round 2 — nothing to synthesize over an empty
finding set.
Dissent on record: Gronktayvius argued for gh auth status --active --hostname github.com
(macOS only) and reverting the Windows sites. Chairman: sound but not disqualifying. Andrew can
overrule.
Also found: FLT-239 — sync-push.ps1 fails to
parse under Windows PowerShell 5.1 (BOM-less file, UTF-8 em-dash added by WING-345 018b917). pwsh 7
is fine. Scoped to that one script; the FleetRepoSync scheduled entrypoint parses clean, so automatic
reconciliation is unaffected.
Follow-ups: FLT-233 probes conflate transient
failure with a missing credential · FLT-234
macmini4 missing repo, and the GitHub token is cleartext in hosts.yml on three Macs (rotation is
Andrew's call).
2026-08-14 — WT-f0af · FLT-235 review-seat contamination — In Review¶
FLT-235 · A review seat edited the tree it reviewed, then reported its own edit as P1¶
The review gate produced the failure it exists to prevent. During WING-501, the Cedric/Codex
seat (codex review --base master) mutated worktree WorkWingman-wt-WT-ecb3-WING-501 after commit
40c4afb39 landed: seven files modified between 11:32 and 11:36, including a top-level zip block
added to electron/package.json — which the seat then reported back as its P1 finding,
"unsupported configuration blocks all installer builds". Its Contains("msedge") BrowserSession
finding was likewise about code it had just written. Cost a full investigation to prove the P1 was
not in the commit, plus a rebuild. Unnoticed, the seat's edits would have been committed as
reviewed work.
Root cause is structural, not a bug. -c sandbox_mode="danger-full-access" is mandatory on
Windows or Codex cannot inspect the diff and exits 0 with a blind "no findings" — and that same
override is what grants the write. There is no read-only Codex sandbox here. Only cwd constrains
the seat. Second occurrence: FLT-56
(2026-07-16) a Codex seat committed and pushed 3f48415. The skill also already contradicted the
standing memory rule "review seat must not write — seats run from SCRATCHPAD".
Fix: disposable detached worktree at the sha under review for any seat with filesystem reach
(git worktree add $rc $sha --detach, run, assert, remove --force); mandatory contamination
assert (git status --porcelain + git rev-parse HEAD byte-identical before/after, in the seat's
cwd and the live tree) on every seat every run; FAILED-CONTAMINATED as a status distinct
from FAILED and excluded from quorum; findings citing seat-modified paths quarantined before the
chairman pass (the chairman cannot tell seat-authored code from committed code — that is how the
self-edit got ranked P1); roster gains mandatory cwd and Clean after columns.
Landed: usage-governor/docs/review-seat-isolation-policy.md (branch wt/WT-f0af/FLT-235,
caa777e, pushed, not merged — council gate pending) · skills council-code-review,
codex-review, gemini-review updated in ~/.claude/skills · memory review-seat-must-not-write
refreshed with the second incident and the checkout mechanism.
Jenny / Gronktayvius: confirmed read-only, conditionally. Neither wrote. Gronk runs
--disallowed-tools "write,edit,bash,shell"; Jenny gets the diff inline and any tool call is
auto-denied headless. Both are read-only only because of a flag or a prompt line a future edit can
drop silently, so the contamination assert now applies to them anyway and the no-tools instruction
is stated as an invariant rather than a workaround.
Verified: disposable-checkout mechanism smoke-tested end to end on this box (add detached →
assert clean → worktree remove --force → 0 remaining). Not verified: a live Codex seat run
inside the checkout — the WING-501 workaround is the only evidence for that leg.
Follow-up: wrap checkout + assert + teardown in a script so a seat cannot be run without isolation; audit whether any past gate committed seat-authored edits as reviewed work.
2026-08-14 — WT-f37a · FLT-236 fan work off greatroom — In Progress¶
FLT-236 · No session work was fanning out, and no peer could run Gemini 3.7 Flash¶
The premise was false at every layer. The worktree-identity registry holds 1525 entries and
zero have host, model, or harnessKind set — the schema has the fields, nothing has ever
written them, so "which PC is this card running on, at which model?" was not an answerable question.
203 entries updated in the last 7 days, 42 with heartbeats under 24h, all effectively local to
ANDYGREATROOMPC.
Three independent breaks underneath that. (1) Dispatch to DESKTOP-D249KD4 returned The type
initializer for 'FleetDispatch.Core.RealJobExecutor' threw an exception. A TypeInitializationException
is cached for the life of the process, so one transient cctor failure in a serve process running since
8/8 poisoned every job kind on gaming for ~6 days; its outbox last wrote 8/6. Streaming and bedroom
ran the identical deployment (74e88fd) and were fine — the binary was never the variable, the process
was. (2) agy is unauthenticated on gaming and streaming; the CLI falls into interactive OAuth and
times out at 60s, so the entire Gemini leg only ever ran on greatroom. (3) bedroom ran agy 1.1.10,
whose catalog stops at Gemini 3.6 Flash — 3.7 was not selectable there at all.
Docker CI was pinned to the machine Andrew works on. home-ci carries no PC-specific label, so
generic fleet jobs could schedule anywhere — but greatroom-tools held the only docker label in
the org pool, so fleet-mission-control's actionlint and semgrep jobs landed on greatroom every time.
The workflow comments explained why ("Docker Desktop is per-user on Windows, so only the box proven to
serve it is labelled") — that proof had simply never been re-run against the peers.
Fixed and verified: gaming's FleetDispatchServe restarted, round-trip ok:true · bedroom agy
1.1.10 → 1.1.13 via winget, gemini-3.7-flash-medium returns through dispatch · docker label added
to DESKTOP-D249KD4-org-1 and DESKTOP-SCDT9HI-org-1 after proving NETWORK SERVICE is in
docker-users and the engine pipe is live on both · docker removed from greatroom-tools and
home-ci removed from both greatroom runners, so the pool is now 6 runners entirely on peers.
Proof: actionlint run 31830452479 executed on DESKTOP-SCDT9HI-org-1, conclusion success.
Uncommitted, council gate pending (branch wt/WT-f37a/FLT-236 in four repos): Flash 3.5 → 3.7
at the four worker-lane pin sites — fleet-harness/routing.yaml + cli_agents.py (a duplicate pin
of the same value, worth collapsing), fleet-dispatch AgyInvocation.DefaultMeterModel,
usage-governor/agy-wrap.ps1 (must move in lockstep with the previous — its own comment says so), and
llm-council/council.config.json sonnet/haiku tiers. Review seats deliberately not touched:
Regular Jenny stays 3.1 Pro High, Cyber Jenny stays 3.6 Flash High. AgyModels matches on
flash/pro/high substrings rather than version, so metering needed no change — verified at the
producer, not assumed. fleet-dispatch suite: 503 passed, 0 failed. Two tests asserted the 3.5 literal
while feeding DefaultMeterModel; they now interpolate the const so the pair cannot drift again.
Blocked on Andrew: agy needs interactive Google OAuth on gaming and streaming — browser login, not something an agent can or should complete. Until then only greatroom and bedroom can serve Flash 3.7.
Follow-up: nothing yet routes a card's work to a peer by default — fleet-dispatch is a manual
send, and routing.yaml is read by the fleet-harness rail, not by the sessions doing the work.
That gap is FLT-115 (auto-spawn engine, fan-out)
and needs a design decision before anything is built.
FLT-235 update — enforcement landed (council-seat)¶
The policy doc alone was a paper control, and the Grok seat reviewing it said so
("a standing policy with no check in this change is a paper control"). council-seat
(C# CLI, usage-governor/src/CouncilSeat.Cli, commit c954c96) is the check: it builds each
seat's command line and working directory itself — no --exec, no --cwd, so no argument can
point a seat at the tree under review. One call does checkout → snapshot (seat tree + live tree) →
launch with push disabled and credentials stripped → snapshot → validate → self-citation scan →
teardown. Exit 2 = FAILED-CONTAMINATED.
Two High findings from that Grok review, both fixed: (1) cwd is not a push boundary — FLT-56's
real damage was a push, and a seat that commits+pushes from the disposable checkout leaves the live
tree pristine, so prevention now precedes the assert: tokens/askpass removed, GIT_TERMINAL_PROMPT=0,
remote pushurls overridden via GIT_CONFIG_COUNT in the child env (doing it via repo config would
have disabled push in the real repo — a linked worktree shares .git/config; caught before shipping).
(2) a contaminated seat is dropped whole, not filtered — it can edit A and file a finding on B, and
the chairman cannot tell which half is trustworthy.
Four defects caught by the tests and by dogfooding: porcelain read through .Trim() ate the first
character of every unstaged filename (hello.txt → ello.txt, breaking every quarantine lookup); a
5145-char review scored "explicit no-findings" because one of its own findings said "no findings enter
quorum"; the default --out put a scratchpad seat's cwd inside the repo under review; and writing
the tool's own .out/.err before the after-snapshot made it report itself as contaminated.
Verified: dotnet build 0W/0E · dotnet test 711/711 (58 new, no regressions in the existing
653) · live Grok seat end-to-end through the CLI (174s, 5145 chars, Seated, clean-after yes) · --cwd
rejected exit 4 · checkout-parent inside the repo refused cleanly, no leaked dir. Integration tests run
against real git with a negative control on the push block. Not verified: a live Codex seat
through the tool. Not merged — council gate pending.
FLT-235 gate result — the tool reviewed itself and the premise was wrong¶
Ran the council gate on c954c96 through council-seat itself: 8 seat runs, Cedric over the
whole 109KB diff via its disposable checkout, Regular Jenny / Cyber Jenny / Gronktayvius over
chunks (chunking recorded as degradation). Every seat reported clean after: yes — the tool did
not contaminate anything while reviewing its own commit. Seats: 6/8 reported; Cyber Jenny
FAILED on both chunks by refusing the CWE framing, which the validator correctly caught as a
refusal rather than seating it as "no findings"; Clahadore skipped (governor, and advisory-only
since Claude authored).
Three independent security seats returned the same Critical: a git worktree is not an
isolation boundary. It shares the common gitdir — objects, refs, hooks and config — so a seat
could move a live branch, rewrite config, or plant a hook that fires on the next human commit,
none of it touching its own cwd, so the assert would call it clean. I had already hit one instance
of this (the push-url edit that would have disabled push in the real repo) and fixed the symptom
without asking what else was shared. Everything was. Now git clone --local --no-hardlinks, origin
removed, core.hooksPath pinned empty — which also deletes two earlier findings, since there is no
worktree registration to leak.
Also fixed (b6404df): push prevention was far too narrow — URL-form pushes and stored Windows
credentials both bypassed it, so every URL scheme is now rewritten via insteadOf, the credential
helper is emptied, and the repo under review is blocked as a local path too (proven with a negative
control). The containment guard was lexical and a junction defeated it — reparse points are now
resolved and the guard re-runs on the materialized path. A refusal could satisfy the no-findings
exemption and seat a non-review toward quorum. The assert had three blind spots (already-dirty file
rewritten, update-ref, planted hook) and now carries content hashes, the ref set and a hooks
digest. council-seat was not published by install.ps1 — a control nobody can invoke — so
deploy.ps1 now publishes and smoke-tests it, including asserting --cwd still exits 4 so a future
edit cannot quietly reintroduce an escape hatch.
The docs no longer claim more than the code does. "Only cwd constrains the seat" is gone; the policy states plainly that this is not a sandbox. ACLs on the main tree, Job Objects, and a restricted-token seat user are recorded as not-implemented rather than half-built.
Verified: dotnet build 0W/0E · dotnet test 717/717. Pushed, not merged.
FLT-235 MERGED — council-seat on master; OS boundary spun out as FLT-241¶
Fast-forwarded to master at 09c4988 (caa777e → c954c96 → b6404df → 5ce70f4 → 09c4988),
pushed, fanned out to all three PCs and all four Macs (ff=3 each). Worktree removed.
Three gate rounds, three Criticals — and the pattern mattered more than any of them: round 1
found the worktree shares objects/refs/hooks/config; round 2's Critical was caused by the round-1
fix (worktree→clone turned teardown into a recursive walk that followed junctions, so
mklink /J clone\x C:\repo would have deleted the live tree); round 3's was caused by the round-2
fix (the junction guard resolved only the deepest existing ancestor, leaving a junction one level up
unresolved). Every finding reduces to an in-process check cannot constrain a process running with
the user's full rights — spun out as FLT-241 rather than attempting a fourth round.
Verified end to end: dotnet test exit 0, 732/732 · deploy.ps1 publishes and smoke-tests
council-seat (5 seats declared, --cwd refused, exe stamp matches HEAD) — that last one was
Cedric's P1, a control nobody could invoke because nothing published it.
Re-gate receipts: 10/10 seats seated, every one clean after: yes. Cyber Jenny refused the
CWE framing on both chunks in round 1 (correctly scored FAILED, not seated as "no findings") and
seated 4/4 in round 2 after reframing to an engineering-standards ask. Gronktayvius took the whole
102KB post-fix diff in one run via --prompt-file, which was itself the first exercise of that fix.
Still true and written into the policy doc: this is not a sandbox. Restricted token, ACLs on the main tree, Job Objects and containers are recorded as NOT implemented rather than half-built. It raises the cost of an accident; it does not contain an adversary.
2026-08-15 — WT-afdb · FLT-239 fleet fan-out broken under PowerShell 5.1 — Landed¶
FLT-239 · sync-push.ps1 encoding, and scheduled tasks running detached copies¶
Landed. fleet-repo-sync master ed16d9a;
PR #3 merged.
Found while fanning out the FLT-232 merges. sync-push.ps1 failed to parse under Windows PowerShell
5.1, so the fleet fan-out silently did nothing for any caller using that host. Encoding, not syntax:
the file had no BOM, so 5.1 decoded it as ANSI; a U+2014 em-dash inside a string literal at line 56
destroyed the string terminator and the parser reported a bogus Missing closing '}' at line 55 —
nowhere near the cause. pwsh 7 was never affected. Introduced by WING-345 018b917.
Fixed by prepending the 3-byte UTF-8 BOM, not by re-saving through an encoder: every byte after the prefix is unchanged, so the diff is one line instead of an EOL-churn rewrite. BOM over ASCII-replacing the dash because that dash is runtime output text.
Also fixed: three of four peers ran FleetRepoSync from an unmanaged home-directory copy rather than
the repo, so repo fixes would never have reached the scheduled task. Repointed gaming, streaming and
bedroom at their repo paths, each verified by starting the task and confirming LastTaskResult=0.
Rollback files left on each box.
Gates: PS 5.1 PARSE_OK (was 4 errors), pwsh 7 PARSE_OK, body byte-identical, and the fixed
script run under 5.1 pushed and fanned out its own fix — EXIT=0, all peers triggered, macs
reconciled, failed=0. Council 3/3 seats approve: Cedric, Gronktayvius, Jenny. Seats split 2-1 on
sweeping five sibling scripts; resolved against by evidence — their non-ASCII is comment-only, so
latent rather than live, and one of them is the live scheduled-task entrypoint.
Corrections made during this work: an intermediate claim that streaming/bedroom had drifted was
wrong — same git blob, different checkout line endings (core.autocrlf is not uniform fleet-wide).
Compare the git blob, never raw bytes across boxes. An earlier claim that fleet reconciliation might be
dead fleet-wide was also wrong; the scheduled entrypoint parses clean under 5.1.
Still open on FLT-239: the Task Scheduler Operational log is disabled on all four Windows boxes,
which is why the original 0x800710E0 could not be diagnosed.
Follow-up: FLT-243 — repo-wide .ps1 encoding
standardization plus a parse-check guard under both hosts. The guard must PARSE files, not grep them
for non-ASCII. This bug bit twice in one session, the second time in an agent's own fix script.
2026-08-15 — WT-3594 · FLT-246 council-seat false FailedContaminated under peer sessions — In Review¶
FLT-246 · council-seat: live-worktree ref assert failed every seat when peers committed to sibling branches¶
PR: usage-governor#4 (branch wt/WT-3594/FLT-246).
Found during the WING-549 gate: four concurrent WorkWingman sessions pushed to their own wt/*
branches while the seats ran; the live-worktree assert fingerprinted ALL refs of the shared .git,
so every seat came back FailedContaminated (refs) with zero modified paths and an unmoved HEAD.
Fix (council-ruled over four rounds, Cedric chair): the live tree now asserts every ref EXCEPT a
peer set derived at the OPENING snapshot (PeerRefSet.Derive from git worktree list --porcelain -z
+ for-each-ref %(upstream)): branches sibling worktrees already had checked out plus their existing
upstreams; MINUS this worktree's own branch/upstream; MINUS trunk (master|main, origin/*,
origin/HEAD + target) which is never exemptible; prunable registrations exempt nothing; self must
match exactly one record or the capture aborts; strict porcelain grammar; symbolic refs carry
=> target in the fingerprint. Peer moves surface as PeerRefActivity (logged, never a verdict).
Reason strings are ASCII. rc-* seat clone unchanged (RefScope.All).
Gates: dotnet build UsageGovernor.sln -warnaserror exit 0; dotnet test 780/780. Every seat
in all five rounds ran through THIS branch's council-seat.exe against the worktree (30+ seat runs;
one Cedric seat caught writing to its own rc-* clone → FAILED-CONTAMINATED, dropped, re-run clean).
Round-5 roster: Cyber Jenny + Gronktayvius seated/pass, Clahadore advisory; Cedric + Jenny re-run
in flight at time of writing.
Incident during the gate: the SHARED usage-governor/.git/config lost all remotes and got a
core.hooksPath under ug-wt-f0af-flt241/tests/.../GLOBALROOT/Device/Null/nope/rc-* (12:15,
again ~12:44) — a peer FLT-241 test wrote to the live repo. Restored (remote add origin, unset
hooksPath, branch -u); FLT-241 session notified.
Follow-up: FLT-248 — shared-.git metadata threat model (config, worktree registrations, reflog), directional API hardening, extra coverage.
2026-08-15 — WT-1f12 · FLT-249 retired xAI model slugs — fleet-dispatch Done, odysseus In Review¶
FLT-249 · retired xAI slugs: two cosmetic leftovers, one of which was not cosmetic¶
A fleet-wide grep for retired xAI slugs (grok-4-fast, grok-4-1-fast-*, grok-4-0709,
grok-code-fast-1, grok-3, grok-imagine-image-pro) across ~/source/repos, ~/.claude,
~/.gemini, ~/.codex, ~/.grok and ~/.fleet-secrets found no live config carrying a retired
slug. Two leftovers remained.
1. fleet-dispatch — DONE, merged. PR #6,
branch wt/WT-a91c/FLT-249. HarnessRegistryTests.cs:305 used the literal grok-4-fast as its
example model; HarnessRegistry passes the string through and holds no default, so nothing was
broken — the dead id was just copyable. Now grok-4.6. dotnet test 503 passed / 0 failed; CI
build-test and inspectcode both green; merged and fanned out via fleet-repo-sync (3 PCs, 4 Macs).
2. odysseus — the row was stale AND the pricing model was wrong. Local branch
wt/WT-b73e/FLT-249, 4 commits. chatRenderer.js priced every xAI model from retired rows, so a
current model fell through longest-key matching to grok-4 at $3/$15. Refreshing the rows exposed a
larger defect the council caught: xAI doubles both rates at ≥200k prompt tokens and bills the
higher rate for the whole request, and the new models carry 256k–1M windows, so long-context turns
— ordinary traffic — were reported at half cost. Also grok-build-latest is a compatibility alias
for grok-4.5, not the latest grok-build; Cedric raised this in round 1, Clahadore overruled it
on absence of evidence, and Cedric was right.
MODEL_INFO moved to static/js/model/modelInfo.js and the cost path to modelCost.js, because
chatRenderer.js cannot be imported outside a browser — the tests had been scraping the table with
a regex and never executed the function the UI calls. getModelCost is now a one-line delegate.
Half-written tier rows fail closed rather than silently pricing at base.
NOT PUSHED — no write access. pewdiepie-archdaemon/odysseus is a third-party public repo where
Andrew has viewerPermission: READ, and local dev is diverged (ahead 1868 / behind 2028). The work
is committed locally only. Andrew's call: fork and PR upstream, keep it local, or drop it.
Gate: 4 council rounds. Round 1 (3/3 seats) → round 4. Cedric timed out on 3 of 5 attempts;
2 seats survived each round, which meets quorum but left the odysseus test files without a reviewer
in rounds 3–4. Two seats were marked FAILED-CONTAMINATED in round 2 by Clahadore's own concurrent
edits, not by the seats — the skill warns about exactly this and it was still done. Both re-ran clean.
FLT-260 · Meter real Grok spend into the governor ledger + availability-derived tier directive — Done (landed; pool flip deferred) (WT-ac40, 2026-09-24)¶
FLT-260 · PR usage-governor#8 · landed usage-governor master c418a42 · deployed + smoke-verified on greatroom, gaming, streaming, bedroom.
- Grok Build
--output-format jsoncarriesusage.total_tokens; newgrok-exec(metered replacement for baregrok -p) andgrok-spend(book/replay a receipt) verbs; council-seat Gronktayvius books its spend and fails closed without a receipt. - Hook directives name only lanes below RED (Cedric P2 from FLT-253); PreTool admission now fails CLOSED on missing/unreadable state (council ruling).
grokPoolTokensheld at null (UNKNOWN): llm-council and fleet-dispatch still call baregrok -p; flipping to 2.5M/24h is owned by the follow-up metering card.- Gate: 5 council rounds (Cedric chair) → READY TO MERGE. Gronktayvius FAILED every round (headless grok stalls on inherited MCPs/hooks on greatroom — separate card). Receipts: build 0/0, 833/833 tests, real-CLI smokes; live Grok end-to-end unverified (environment).
- Follow-up hardening: FLT-261.