Kanban vault projection — decided: state 1 (no vault projection), generator stopped
Kanban vault projection — decided: state 1 (no vault projection), generator stopped
Trigger. Echo flagged a live regression (his addendum 3, a9aa356): Sol removed the
projection file Docs/Kanban/SOLOS-V3.md at 21:49 (5b48edc, per Young), but the
generator was never retargeted and its cron was still active — next fire 22:13:11,
which would resurrect a file Young ordered deleted. Verified live, then fixed.
What was wrong (measured, not inferred)
| Fact | Probe |
|---|---|
Cron job kanban-obsidian-sync (427667f6e724), profile sol, every 30m, no-agent, script sync_kanban.py | cronjob_manage list |
Script hardcodes OUT = .../Docs/Kanban/SOLOS-V3.md (line 61) and OUT.write_text(text) (line 175) | read_file of the script |
Deletion was 5b48edc (21:49:41); the file is untracked — git ls-files Docs/Kanban/ shows only fleet-board.md | git show --stat 5b48edc, git ls-files |
| Running the script by hand recreated the file (Echo's repro) | reproduced, then re-confirmed absent after fix |
| No other generator exists — only one cron job in the whole fleet references the board; no hooks, no render job | scanned all profiles' jobs.json, .git/hooks, .solos |
VAULT-INDEX.md still advertised SOLOS-V3.md as "⭐ THE OBSIDIAN KANBOARD — the live board you read" | grep SOLOS-V3 VAULT-INDEX.md |
fleet-board.md is a hand-written register: 32 curated cards in custom sections (## Docker image build, ## Fleet board — temporary task register) that the generator's 7 fixed lanes cannot express. It IS plugin-parseable (has kanban-plugin: board + a valid settings fence) — my first claim that it was not, was wrong | read_file + verify_parseable probes |
The defect class is the same one that has caused every restore incident: a control at
the wrong choke point. The deletion lived at the call site (git rm); the generator
lived in cron with a hardcoded target. Neither knew about the other, so deletion and
generation contradicted each other indefinitely.
Why Echo's option 2 (retarget OUT to fleet-board.md) is rejected
Echo's read was: "retarget the cron to fleet-board.md, since ruling 2 already says
'DB canonical, .md generated' and her reporting system references it." This would
have destroyed data.
First, a correction to my own initial reasoning (measured, not assumed): I first
read fleet-board.md as "not in the plugin's format". That was wrong. It does
carry kanban-plugin: board frontmatter and a valid %% kanban:settings fence
({"kanban-plugin":"board","list-collapse":[null,null]}), so it passes the plugin's
format and the generator's own verify_parseable(). The file is plugin-parseable.
The rejection therefore rests on a stronger, measured ground — content loss, not format:
- The generator sees only the 13 LIVE kernel tasks (
ready=3, running=6, blocked=3, done=1— archived rows are not returned bylist --json), whilefleet-board.mdcarries 32 curated cards. A retarget would replace those 32 cards with 13. - Whole sections would vanish. The generator emits only its seven fixed lanes
(Ready/Doing/Todo/Blocked/Triage/Review/Done) plus
## Unmapped. It has no concept of the file's custom sections —## Docker image build (Young's approval 2026-10-20)(10 cards: the four ARM64 image builds,onboard_tenant.shproof, Nova's brief, Tam's tenant configs, Mira's prod costing) and## Fleet board — temporary task registerwould be deleted outright. Ten of those cards are not in the kernel at all. - It would collide with live concurrent edits.
fleet-board.mdis actively being edited by other agents — Tam committed a card change (c93a25a) at 21:57, three minutes before this fix. A generator overwriting that file every 30 minutes would destroy work that lands between runs, and the git history would show the loss as a silent overwrite rather than a reviewed change.
So the target was never a projection target — it is a register, and the difference
is the whole point. fleet-board.md is already recorded as superseded — Tam's own
migration doc item 2 ("fleet-board.md … is superseded by the same mechanism — it stays
only as today's migration record until Min retires it"). A register that other agents
still write to by hand cannot be a generated artifact. If both are wanted, they need
different files — that is a decision for Min, and it is the open one this document
leaves behind (§Open question).
The decision: state 1 — no vault projection
Of the three states Echo named, only two are coherent, and we are now in one of them:
- ✅ No vault projection at all. Task truth is
hermes kanban(boardsolos-v3); the vault holds no board artifact that claims to be generated. This is the state we chose and implemented. - ⚠️ A generated projection — coherent, but requires re-creating the target file
deliberately, not retargeting
OUTatfleet-board.md. - ❌ The incoherent state we were in: projection deleted + generator active + hand-written board nothing regenerates.
Why state 1 rather than state 2: Young's instruction is unambiguous — "hermes kanban kernel
is task truth". The one surviving vault artifact (fleet-board.md) is a hand-written
register, not a projection — it is neither truth nor generated, and it is still being
hand-edited by other agents, so a generator must never own it. A projection can be
re-enabled later as a deliberate act, in its own file; it must not be resurrected by
accident, and it must not be confused with the register.
What was changed (all verified live)
| Change | File / object | Verification |
|---|---|---|
| Paused the cron job | kanban-obsidian-sync 427667f6e724 | cronjob_manage list → enabled=False, state=paused, paused_at 2026-10-20T21:54:19 |
Script fails closed — refuses to write when OUT is absent | ~/.hermes/profiles/sol/scripts/sync_kanban.py (RETIRED = not OUT.exists(), guard in main()) | ran it by hand → exit 1, SOLOS-V3.md absent after |
VAULT-INDEX — removed the live dangling reference; the row now names fleet-board.md as superseded | VAULT-INDEX.md | row + layout line rewritten |
| Ruling 2 line corrected (it claimed the projection was "already true / running") | hermes-native-fleet-system-2026-10-20.md | addendum 4 |
| Migration doc — added the generator note | kanban-migration-2026-10-20.md | section 4 |
| Sol's own pending memory — the entry still claimed the projection was live | ~/.hermes/profiles/sol/pending/memory/375401ad.json | entry replaced |
The fail-closed guard is the point. The cron pause is one field; if a future agent resumes the job, the script itself now refuses to resurrect the file. That is the control at the choke point, not at the call site.
Re-enabling a projection (if ever wanted)
Do not retarget OUT at fleet-board.md. To project deliberately:
- Re-create the target file as a real projection (e.g.
Docs/Kanban/SOLOS-V3.md), or accept that the projection is retired. - Resume
kanban-obsidian-synconly then. - Record the decision in this file.
Honest limits
- I fixed the generator and the cron — both mine. The three open cards that remain
(
t_7018df81blocked 215 h; the twoskipped_nonspawnablePulse-assignee issues) are Min's lane and are already on the board. kanban.dispatch_profilesstill readsany(no per-home claim allowlist) — Echo's finding, Min's lane. Reported, not fixed here.- I did not touch
fleet-board.md; it is Min's to retire.

