CB-638: the wiki describes a system that no longer exists — audit index of pages to revise, build and retire #168
Closed
opened 2026-08-24 18:44:37 +02:00 by kevin
·
5 comments
No Branch/Tag Specified
main
worker/fleetd-612-unita-87807e-1
worker/612-b3-mcpwirings-da2b58-3
worker/612-b2-cb185-176d3a-2
worker/612-b1-completion-457459-1
worker/612-agaps-73a926-2
worker/608-sleeps-3a64ff-3
worker/621-b4520b-1
worker/618-b83894-2
worker/fleetd-615-e05481-5
worker/lead-autocompact-5f1ab2-3
worker/fleetd-613-f85deb-3
worker/fleetd-608-flaky-nudge-test-d0c2d1-3
worker/lead-context-gauge-ad404f-1
worker/gauge-wiring-9158c1-4
worker/redeploy-slowstart-ead0e5-5
worker/charter-bytes-13668c-6
worker/rollover-outcome-291483-2
worker/589-f64303-2
worker/593-1a8025-5
worker/589-fcd2aa-1
worker/568-9fdaa2-3
worker/571-attempted-outcome-5739f7-2
worker/581-completionresolver-cas-sites-0542b7-6
worker/562-loop-health-wiring-test-99611c-5
worker/562-surface-loop-health-7df5cc-4
worker/575-waiter-cleanup-sites-62ad80-1
worker/572-answer-lock-release-46a9ae-5
worker/567-probe-channel-leak-a38fc5-6
worker/551-record-before-send-7cbf56-1
worker/561-listener-fanout-survives-a-throw-61d538-2
worker/555-redeploy-main-flow-seam-65c2f5-2
worker/556-injector-owns-registration-e027a5-1
worker/552-post-restart-mktemp-abort-bc2672-4
worker/553-onstatus-completion-leak-0da881-2
worker/550-shasum-linux-196132-1
worker/538-loop-dies-on-error-4a5eeb-6
worker/426-health-coverage-ef1fd4-4
worker/504-failed-reported-clean-3cfd66-3
worker/537-capturedlog-close-e4c437-2
worker/459-broken-link-targets-cadc17-5
worker/535-appender-leak-fe74c1-1
worker/512-part2-shutdown-detection-434701-9
worker/529-logger-level-sweep-2a5533-8
worker/528-drain-gate-call-site-5de83d-7
charter/forge-mcp-vs-token
worker/521-swap-guard-unpinned-28e931-5
worker/519-probe-test-harness-d25ab8-4
worker/525-logger-level-leak-1b4eb0-6
worker/518-fleetmcp-resolver-wiring-8ef96c-1
worker/512-drain-complete-line-7edd71-3
worker/517-abort-branch-and-jar-id-41b641-2
worker/500-9e52c9-3
worker/509-4912f4-2
worker/511-9a4b23-1
worker/493-479f45-2
worker/505-03f8b2-1
worker/492-followup-detect-unclear
worker/501-a31fa0-7
worker/498-451d1c-5
worker/494-1015ce-2
worker/492-209647-1
worker/489-001902-2
worker/480-relative-handover-path-906323-1
worker/480-b-handover-skill-45bf1f-5
worker/474-followup-source-pin-f54a55-17
worker/474-charter-check-on-reload-f54a55-17
worker/466-quarantine-repeatcount-report
worker/393-opencode-skill-seeding-71854b-13
worker/469-canonical-tool-names-2a472a-16
worker/466-quarantine-escalation-5ae9c1-15
worker/446-hot-exhausted-pattern-0af580-6
worker/464-charter-tool-name-guard-a85635-12
worker/463-listfleet-default-fails-open-f1c76c-11
worker/458-invariant-5-by-purpose-862f9a-10
worker/439-coordinator-row-gate-bc032a-8
worker/449-herdr-protocol-576015-4
worker/450-abstract-spawn-599e1c-5
worker/437-ack-refuses-177d91-1
worker/444-placement-window-feb56a-2
worker/440-helddurable-derived-d462d7-13
worker/425-rework-placement-resolve-c58ba1-9
worker/421-lead-peek-held-msgs-cdbad2-10
worker/435-fixed-policy-cap-fe11de-12
worker/422-gate-state-observability-9e79d6-11
worker/431-memberregistry-live-readers-cdbad2-10
worker/424-architect-slot-hot-038b41-7
worker/422-model-gate-spawn-c29f48-6
worker/425-default-profile-live-f55534-8
worker/415-coverage-wording-2cbf9c-5
worker/416-3ad1da-1
worker/418-588283-3
worker/deterministic-stamp-race-409-3cb7b6-10
worker/armed-reads-live-config-404-ed931f-9
worker/reply-peer-refusal-391-5a34bd-7
worker/models-allowlist-aa9e9b-3
worker/ttl-stamp-race-399-f1122f-8
worker/scrub-receipt-400-316b3e-5
worker/exhaustion-detection-395-105105-6
worker/scrub-abort-394-316b3e-5
fix/scrub-uid-abort
worker/task-scrub-517574-2
worker/t386-clock-bd5b78-4
worker/t384-scrub-813790-5
worker/t381-cc-748314-2
worker/t373-336973-2
worker/t365-3920c5-3
worker/t358-6e989b-1
worker/t355-8b321c-1
worker/fleetd-369-hermetic-git-tests-e8b19a-3
worker/fleetd-368-stale-lead-binding-f5682e-2
worker/fleetd-360-deploy-units-0d3793-1
worker/359-dead-lead-tabs-f1253b-4
worker/362-worktree-skills-c03e51-3
worker/361-coord-visibility-655144-1
362-plugin-visibility-and-drift
worker/errscan-bed2ca-2
worker/amqp-log-identity-bed2ca-2
worker/withdefaults-guard-561704
worker/sleepguard-82076d-1
worker/fd334-9ee1b6-5
worker/fd348-f1ab27-4
worker/fd335-a71c35-1
worker/fd342-174a17-2
worker/fd345-490d0f-3
worker/fleetd-337-5ec7d4-21
worker/fleetd-341-af5a6b-24
worker/fleetd-339-5ca0a2-23
worker/fleetd-338-83a4a1-22
worker/fleetd-333-281f46-18
worker/fleetd-329-11bdbb-16
worker/fleetd-330-2770fb-17
worker/fix-326-50506e-15
worker/fix-324-3e9bbf-14
worker/fix-323-b8287d-13
worker/fix-316b-bd0860-11
worker/fix-318-76ca36-9
worker/fix-317-486aec-8
worker/fix-315-ce47c5-6
worker/fix-307-275890-6
worker/fix-308-b4f664-7
worker/fix-309-ec3939-8
worker/fix-310-7a3974-9
worker/fix-302-52ad0e-9
worker/fix-298-ce1acb-8
worker/fix-297-66bd11-7
worker/fix-296-104622-6
worker/fix-293-bare-closetab-eb22b5-3
worker/fix-280-gone-ask-lapse-bca98e-2
worker/fix-290-reapidle-guard-coverage-9b0dd1-1
worker/fix-285-trust-seed-8f3565-10
worker/fix-284-backend-error-seat-85912c-11
worker/fix-282-chained-ask-e6d0bb-8
worker/fix-283-teardown-leaks-f40dfa-9
worker/fix-281-pin-handler-actions-4921ac-7
worker/audit-rendezvous-lifecycle-d072ae-2
worker/audit-health-placement-1a2476-6
worker/audit-teardown-exits-e207a5-3
worker/audit-launcher-asymmetry-27e370-4
worker/audit-rest-authz-6ca53c-5
worker/investigate-275-abandon-asking-fdef52-8
worker/fix-274-worktree-leak-b0095d-7
worker/fix-273-exhausted-pattern-9665b5-6
worker/fleetd-267-model-check-bd8068-1
worker/fleetd-131-archunit-18b834-7
worker/fleetd-266-sshagent-rename-a014ff-6
worker/fleetd-184-uid-claim-8e1f31-4
worker/fleetd-184-warn-b381ee-10
worker/fleetd-184-docs-be1d12-9
worker/fleetd-257-9bf010-7
worker/fleetd-103-23a113-6
worker/fleetd-247-342356-5
worker/fleetd-116-04dea8-4
worker/fleetd-252-a830e0-3
worker/fleetd-111-7e8673-9
worker/fleetd-155c-f8ef4b-8
worker/fleetd-176-b928ca-3
worker/fleetd-249-7a7878-2
worker/cb248-composition-root-b-9acdf7-15
worker/cb148-envrc-default-fa6c82-12
worker/cb201-unit5-wiring-6c12e6-8
worker/cb241-fallback-echo-1175e9-11
worker/cb149-trust-dialog-2392a5-9
worker/cb134-148-overlay-visible-c9b986-10
worker/cb234-session-id-keyed-04e1fc-1
worker/cb201-unit3-nudge-abdf5c-6
worker/cb201-unit2-policy-c1102c-5
worker/cb201-unit4-outcome-a13bfa-7
worker/cb201-unit1-classifier-91b9b1-4
worker/cb201-227-refine-831980-3
worker/cb175-model-readback-0f085f-1
worker/cb222-charter-tmpdir-17f013-1
worker/cb226-architect-slot-race-cd3aa8-3
worker/cb224-worktree-root-group-024523-2
worker/cb-123-role-demotion-c600f7-2
worker/cb-219-opencode-roots-1f677e-1
worker/cb214-claude-session-id-b9eab4-4
worker/cb213-zdotdir-wrong-process-dd6de4-3
worker/cb211-exhaustion-classification-9546e0-2
worker/cb137-ambiguous-task-4df3d8-4
worker/cb209-agentsessionid-4dfdb6-2
worker/cb185-hostenvnames-2692b5-3
worker/cb206-opencode-sqlite-128718-2
worker/cb185-worktree-group-fc0c99-1
worker/cb-137-ask-ticket-e7760c-2
worker/cb-172-broker-uri-d36ae4-4
worker/cb-175-model-readback-76ead6-3
worker/cb-161-pane-ancestry-293510-1
worker/cb-164-rebase-885863-8
worker/cb-164-empty-scrape-false-success-1a80af-3
fix/cb-197-ticket-ttl-from-completion
worker/cb-189-remote-url-coverage-4692f3-1
worker/cb-185-blockers-027756-4
worker/cb-192-gap-log-11b631-2
worker/cb-633-fix-5f4396-3
worker/cb185-router-d6436d-3
worker/cb185-router-routing-gaps-9e9d33-3
worker/cb185-paneids-992586-2
worker/cb-633-allow-list-union-ed374b-1
worker/cb-157-credential-in-remote-url-496e44-2
worker/cb-641-health-herdr-evidence-8f1f54-6
worker/cb-640-health-msg-evidence-99c9cd-1
worker/cb-642-fleets-status-skill-bbbc40-5
cb-634-ide-mcp
worker/lead-comms-wiring-c014b9-7
worker/lead-mailbox-c19577-6
worker/autocompact-window-82bc2f-5
worker/cb-634-probe-18056f-4
worker/cb635-broker-urienv
worker/cb-632-config-retry-8e0efa-7
lead/cb-622e-claude-md
lead/cb-622-followup
worker/cb-622a-165dff-1
lead/cb-622d-opencode-mount
worker/cb-622b-717c67-2
worker/cb-622c-ab7759-3
worker/cb-617b2-20ca4b-3
worker/cb-617a-5c2f4a-1
worker/cb596-4e49ef-3
worker/cb586-10500c-1
worker/cb-606-b9343a-25
worker/cb604-1445f8-24
worker/cb582-477374-21
worker/cb584-8c2281-22
worker/cb600-e6b9a9-20
worker/cb602-ce257f-19
worker/cb601-b42837-18
worker/cb598-6c7ba7-17
worker/cb599-740fe4-16
worker/cb597-282224-15
worker/cb590fix-185e9a-10
worker/cb528-recovery-race
worker/cb594-96bead-8
worker/cb590-916766-2
worker/cb527-997d99-3
worker/cb592-env-leak-3cbf9c-1
worker/cb588-async-ticket-nudge-3218f7-5
worker/cb578b-9dcb13-6
worker/cb581-d24826-5
worker/m2-u5-ef8c42-15
worker/cb578a-516499-2
worker/cb576-01a04b-17
worker/cb579-lead-tab-acba06-20
worker/cb580-terminal-health-ed6058-21
worker/cb577-f36fdc-18
worker/cb573b-3db06f-16
worker/cb568c-f36fdc-18
worker/cb568-drop-cause-c3ac1c
worker/cb575-cancelled-notification-c3ac1c
worker/m4-sol-a2cbec-3
worker/cb574-async-ask-c3ac1c
worker/cb573-health-model-8ca857-14
worker/cb572-unknown-target-7f2e35-13
worker/u4-700706-9
worker/u3-b9fcb6-6
worker/u2-ef5b68-4
worker/u1-469dce-1-clean
worker/u1-469dce-1
worker/cb-564-health-events-70cf7e-2
worker/cb-565-recycle-drops-role-98e58f-3
worker/cb-563-missing-reply-df2866-1
worker/cb-562-readiness-gate-silent-6c23c9-3
worker/cb-560-architect-presence-da8155-1
worker/cb-561-architect-silent-off-a71cab-2
worker/cb-548-bind-architect-slot-fe1b8c-1
worker/parity-overlay-settings-5fb711-1
secrets-central-store
cb-559-hot-key-correction
cb-557-fleet-role-pools
worker/cb-553-maxload-explicit-spawn-305ee3-6
worker/cb-551-idle-lead-heartbeat-f1633c-1
worker/cb-544-drain-preserves-worktree-925fad-3
worker/cb-552-docs-sync-1cb9cf-4
worker/cb-548-rendezvous-guard-rebased
worker/cb-548-rendezvous-guard-116b53-10
worker/cb-548-authz-v2-586df6-8
worker/cb-548-authz-264363-5
salvage/cb-528b-codex-home
salvage/cb-528a-codex-launcher
CB-518-primary-flow
feature/peer-launcher-spi
cb-103-injector
v1.1.0
v1.0.0
Labels
Clear labels
blocked
needs-live-proof
ready-to-delegate
silent-default
Cannot start until something else lands. The body says what.
Merged and green, but never shown working on the running daemon. Not the same as done.
Scope, files and acceptance criteria are written. A worker can be briefed from the body alone.
A feature that compiles, passes tests, and ships turned off. Nine recurrences and counting.
No Label
ready-to-delegate
Milestone
No items
No Milestone
Projects
Clear projects
No project
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: fleet/fleetd#168
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The wiki has drifted behind the code. This ticket is the index of what to fix: which pages to revise, which to build, which to retire.
Found during a full architecture review of
fleetd+fleet-manageron 2026-08-24. Every count below was produced by grepping a fresh clone of the wiki against the currentmain(3f4ac2b), and the "still current" list was checked against the code rather than assumed.Rule for this work
The code is authoritative. The wiki is not. Where a page and the source disagree, the page is wrong until proven otherwise — and the fix is to read the code, not to reword the page.
Rename map — what actually changed
bridge_*MCP tools (11)fleet_*(11) —fleet_sendfleet_replyfleet_askfleet_ackfleet_statusfleet_pollfleet_listfleet_spawnfleet_stopfleet_profilesfleet_whoamiGET/POST/DELETE /workers/membersbridged_spawns/bridged_sends/bridged_pushmetricsfleet_spawns_total/fleet_sends_total/fleet_push_nudges_totalollama.ltms.dev,gx00llm.ltms.devGET /eventstext/event-streamhandler anywhere inbridged/src/main/javaDo NOT blind find-and-replace
bridgedSeveral
bridged*names are still correct and a sweep would break them:BRIDGED_MEMBER,BRIDGED_API,BRIDGED_WORKER_TOKEN— live env var names in the sourcescripts/redeploy-bridged.sh,scripts/bridged-launchd-wrapper.sh— real filenamesdeploy/dev.ltms.bridged.plist,dev.ltms.bridged.service— real filenamesbridged.jar— the artifact's realfinalNamebridged.yaml— still accepted as a fallback;Fleetd.java:85-94notes the operator's live file is still named thisOnly the tool names, metric names, and route paths in the table above are renames. Everything else needs a per-hit judgement.
A. Pages to revise
Ranked by how wrong they are. Counts are stale-token hits, verified today.
bridge_*/workersGET /eventsas a real SSE endpoint (line 45) and "REST + SSE (OpenAPI, AgentAPI-shaped)" (line 222). Worst page in the wiki./workers. Historical entries may legitimately keep old names — mark them as history explicitly rather than silently updating.bridge_*hits. Also the only page with stale metric names. Note its CLAUDE.md block must stay byte-identical with the repo copy.send_text · events.subscribe; the code usesagent.promptand polls —events.subscribeis deferred (UnixSocketHerdrClient.java:28-30)./workers. Package count/protocol were fixed 2026-08-15 but the tool and route names were not.B. Pages to build
fleet-managerhas zero coverage in the wiki —grep -ril 'fleet-manager|fleets.json'returns nothing across all 15 pages. It is a separate repo, a separate build, and the operator-facing entry point for multi-fleet work.fleet-manager/README.md,probe.py, issues #160 and #156Fleetd.java:492-506), so REST behaviour cannot be inferred from the MCP contract.fleet_ackandfleet_whoamihave no REST route at all.rest/FleetApp.java:115-131,docs/MCP-Contract.mdguard/SubscriptionGuard.java,auth/,member/MemberEnvAllowList.javaC. Pages to retire — decide, don't drift
4-Setup (25 lines) and 5-Operations (35 lines) are honest redirect stubs pointing at 13-User-Guide. They are not broken and the "what this page predicted vs what shipped" table in 5-Operations has real archival value.
Decision needed: keep them as redirects, or delete and renumber. Either is fine — but leaving it undecided is how they rot again. If kept, fix the two stale technical claims still inside them (protocol 14 in 4-Setup, port 8080 in 4-Setup).
Acceptance criteria
_SidebarandHomelink to them.Notes
bridge_*occurrences across 12 pages is the single largest mechanical sweep, but it is not purely mechanical — the daemon still answers thebridge_*names for one release, so a page describing the deprecation window should keep both, labelled.fleetdrepo and is not fetched by default —fleetd/wiki/is empty on a fresh clone while README.md and CLAUDE.md link into it 10 times. Worth fixing alongside this, or the revised pages stay invisible to anyone who clones the repo.Filed from an architecture review on 2026-08-24 against
main@3f4ac2b.Proposed structure — research, diagnosis, and a target layout
The page list above says what is wrong. This comment proposes how to organise it so it does not rot again, based on the established frameworks rather than invention.
What the field actually recommends
Diátaxis (Procida; adopted by Canonical, Django, Gatsby) is the dominant structural framework. It says documentation serves four distinct needs, generated by two axes — action vs. cognition, and study vs. work:
Its central claim is the one that matters here: "crossing or blurring the boundaries described in the map is at the heart of a vast number of problems in documentation." A page that mixes types cannot be maintained, because no single change is ever scoped to it.
arc42 §9 and ADRs (Nygard format: Title / Context / Decision / Status / Consequences) cover the part Diátaxis does not: decisions. The load-bearing rule is that an ADR is immutable — when a decision changes you write a new record with
Status: superseded by ADR-000N, you never edit the old one. That preserves the rationale instead of letting it rot in place.Docs-as-code / generated reference is the consensus anti-rot mechanism: derive reference material from the source, review doc changes with the code change, and run freshness checks in CI. The recurring finding is that the most accurate documentation is generated from code, because then it cannot drift.
Diagnosis — why this wiki rotted
Applying that lens to the audit findings, the 265 stale tokens are symptoms of three specific structural causes:
1. Every page mixes Diátaxis types, so nothing has a maintainable scope.
13-User-Guideis the clearest case — one page covering install (how-to), configure (reference), delegate (tutorial + how-to) and troubleshooting (how-to). It was written accurately on 2026-08-17 and was stale eight days later, because any change to any of those four concerns invalidates "the page" and nobody wants to re-audit 473 lines.11-Featureshas the same problem at 2203 lines.2. The wiki restates facts the code owns — that is the drift engine.
Tool names, route paths, metric names, protocol numbers and ports are all reference facts with an authoritative home in the source. The wiki keeps a hand-copied second copy. 265
bridge_*occurrences exist only because CB-632 renamed a thing in one place and the copy in twelve pages could not follow. This will happen again on the next rename unless the copy stops being hand-maintained.3. Design decisions live in prose in living pages instead of frozen records.
This directly explains the
Home.mdcontradiction found in the audit. The AgentAPI decision is stated in at least three places (Home,1-Architecture,3-Approaches,2-Message-Server). The 2026-08-17 audit corrected one paragraph and missed the rest, so the same page now says both "never built — a discarded option" (line 73) and "retained as a fallback injector" (line 103). One immutable ADR would have one answer.Proposed structure
Four sections by Diátaxis type, plus decisions and meta. Prefix by section rather than a flat sequence, so adding a page never renumbers its neighbours:
What changes, concretely:
13-User-Guidesplits into H-1…H-5. It is the best page in the wiki and this is not a demotion — splitting it is what lets each half be re-verified independently instead of annually.3-ApproachesbecomesD-0001: herdr-centric message server, statusaccepted, and is then never edited again. The AgentAPI/Redis/NATS content stops being "stale" the moment it is correctly framed as a 2026-07-11 decision record. Same for the design-era half of2-Message-Server→D-0002, and thebridged→fleetdrename →D-0003.8-Roadmapsplits: shipped history →M-2(frozen), future plans → Gitea issues and milestones, not the wiki. A roadmap in a wiki is a page that is wrong by default.11-Features(2203 lines) splits: the capability list is reference, the rationale is explanation. Its CLAUDE.md block must stay byte-identical with the repo copy — that constraint moves with it.R-*pages are generated, not written.The anti-rot mechanism — the part that matters most
Structure alone will not stop this recurring. The concrete proposal:
1. Generate the reference pages from source. This is feasible today with no new dependency. The MCP tools are already declared as
McpSchema.Toolvalues built bysendTool(),replyTool()…whoamiTool()(FleetMcp.java:282-292), so a small emitter can walk them and render name + description + JSON schema. Same shape for routes (FleetApp.java:115-131), metrics (FleetMetrics.java) and config keys (fleetd.example.yaml).2. Make it a golden-file test, not a build step. Regenerate into a committed file and fail the build when it differs — the idiom this repo already uses heavily, and it inverts the incentive: after this, CB-632 could not have been merged without updating the docs, because the rename would have broken the build. That is the whole fix in one sentence.
3. Run the audit grep from the ticket body in CI, scoped to the non-generated pages, allowing tokens inside
D-*records (where old names are correct, because a decision record describes the world at its date).4. Adopt the "freeze vs. auto-update" distinction explicitly.
D-*andM-2are frozen — old names there are correct and must not be swept. Everything else is live and must matchmain. Marking this per-page is what stops the next audit from "fixing" history.Migration order
Diátaxis explicitly recommends against a big-bang restructure — "identify one small improvement, implement it, repeat." Suggested order, each step shippable alone:
R-1…R-4generated + golden test. Highest leverage: kills the largest category of drift permanently and makes ~200 of the 265 stale tokens unreachable.D-0001–D-0003. Cheap — mostly relabelling existing pages — and immediately resolves theHome.mdcontradiction plus most of the AgentAPI/Redis/NATS noise, without rewriting the prose.13-User-GuideintoH-1…H-5, re-verifying each againstmainas it moves.H-7(fleet-manager) andE-4(trust boundary) — the two genuine coverage gaps.E-*prose sweep, last, because by then only genuine explanation text remains.Home+_Sidebarrewritten as routers, once the destinations exist.One cost to accept deliberately
Renaming pages breaks every inbound link — from
README.md,CLAUDE.md, prior issues and commit messages. Two options: keep the old page as a one-line redirect stub (the pattern4-Setupalready uses, which works), or accept the breakage and fix the repo's own links in the same PR. Recommend redirect stubs forHome,13-User-Guideand11-Features(the three with real external inbound traffic) and clean renames for the rest.Sources
Audit done and merged —
docs/wiki-audit.md(PR #193)All 15 pages have a verdict with quoted lines and
file:lineevidence for every claim.I spot-checked the evidence rather than taking it on trust
Everything I sampled held up:
fleet_readis not a registered tool. The full set isfleet_ack,ask,list,poll,profiles,reply,send,spawn,status,stop,whoami. Chapters 1 and 2 both document it.GET /eventsroute.FleetApp.build()registers 15 routes and none is/events.Chapters 1 and 2 both document an SSE stream that does not exist.
fleet_send's real parameters aresessionId,content,timeoutMs,wait,turnId,coordId. Chapter 6 teaches{role, prompt}and chapter 7 teaches{to, kind, body, block}.Neither would work.
fleet_whoamialso returnsarchitect, which chapter 11 omits.mcp/BridgeMcpandconfig/FleetdConfig. Neither resolves.The one wrong finding turned out to be my bug, not the auditor's
The audit reported
memberHerdrSocketas entirely undocumented. That is wrong — the section is at11-Features.md:2174. But checking it showed the real gap: it has no row in chapter 11's indextable, and that table is how the page is meant to be read. I added that section on 2026-08-31 and
forgot the row.
Fixed in the wiki (
b24965c), and the audit file corrected on merge (2d55b0b) to state thedistinction rather than quietly deleting the finding. "Undocumented" and "documented but unindexed"
are different jobs and should not be collapsed.
Honest coverage
The auditor reported checking 11 pages claim-by-claim (Home, Sidebar, 1, 2, 4, 5, 6, 7, 9, 11, 13)
and skimming the four long historical pages (3, 8, 10, 12) before checking the specific claims that
set their verdicts. Worth weighing when acting on those four.
What I would do next, and why not now
The obvious follow-up is to rebuild chapters 1, 2 and 9 first — they are the ones an agent reads to
learn the system, so their errors propagate into work. But 6 REBUILDs is more rewriting than is
worth committing to before the current code settles: #185, #189 and #192 are all in flight and two
of them change what chapters 11 and 13 must say. Rewriting now means rewriting twice.
Leaving this issue open with the audit merged as its work list.
Pages 4 and 5: keeping them, not retiring them — the audit was wrong here
The audit marked
4-Setup.mdand5-Operations.mdRETIRE, describing them as redirect-only stubs. I checked both before acting, and that is not what they are.5-Operations.mdcarries real content that exists nowhere else:recycle()never existed, that per-session authorization did ship, and that the broker is optional rather than required;write:repositoryforge token rather than the admin one.Deleting the page would throw that away. A correction record is worth keeping precisely because someone will otherwise re-derive the wrong version.
4-Setup.mdis shorter, but it still carries the subscription-boundary rule and an explicit list of what had gone wrong on it — a decommissioned model host, port 8080, herdr protocol 14, a systemd unit that does not exist here, and Redis Streams / NATS that were never built. That list is useful: it tells a reader which specific wrong facts used to be published.Also, four pages link to them. Retiring them would break those links or force edits across the wiki for no gain.
Decision: both stay as superseded pages that point at 13 User Guide. They already carry a ⚫ status banner naming the section that replaced them.
_Sidebar.mdmarks both as superseded, and1-Architecture.md's related-pages section now sends a reader to chapter 13 for the procedure instead of to these two.This is recorded rather than quietly done, because "retire" and "keep as a redirect with its corrections intact" are different outcomes and the difference matters to anyone reading the audit later.
Done — all 15 pages handled
Every page the audit listed has been rewritten, revised, or explicitly kept, and all of it is pushed to the wiki.
798d3a848c8a1e06cceeee9c4f96426f5a27962e69Pages 4 and 5 are kept as superseded pages — reasoning in the comment above.
The claims that were removed, and are now gone from every page
Three false claims were spread across several pages, which is why fixing one page at a time would not have worked:
fleet_readtool. It has never existed. The registered set is 11 tools (FleetMcp.java:301-327).GET /eventsroute. No such route is registered.FleetApp.build()(FleetApp.java:143-158) is the complete list, and the pages now say so explicitly so the claim cannot come back.agentapiunderfleetd/src/main/javareturns nothing, and bothProfile.kindvalues run throughHerdrPeerLauncher. It is kept on 3-Approaches as discarded research, never in the present tense.Also removed:
ccsprofiles and commands,fleet_sendparameters that were never shipped (role,prompt,to,kind,body,block), Redis Streams and NATS JetStream as the queue, and every hardcoded backend hostname — the guard's allowlist is a config value that defaults to empty, so no page names one.Two things worth recording for the next audit
1. Reviewer voice leaked onto the pages. My shared brief asked each writer to say what it had verified, and three pages came back saying "I checked this in the code" and "I did not verify X in this pass" on the page itself. A reference page states the fact and cites the line; who read what belongs in the report. I stripped about 25 of these by hand and added a rule to the shared brief. Worth writing into the brief from the start next time.
2.
Home.mdcarried a release number, a ticket count and a test total. Those were accurate when written and stale within two weeks, and by then they read as current facts. The page no longer carries any of them; 8-Roadmap holds the delivery record instead, and it deliberately drops exact test counts for the same reason.One correction to the audit itself
The audit's own coverage note says it checked 11 pages claim-by-claim and skimmed four. The skim is where the pages-4-and-5 error came from — both were called redirect-only stubs, and neither is. Every verdict on a skimmed page is worth re-reading before acting on it.
Closing this.
mmdcrendered every diagram on every page before each push.§B is done too — correcting my earlier close
I closed this an hour ago against §A and §C only, and reopened it straight away: §B asks for three pages that did not exist, and acceptance criterion 3 names two of them explicitly. That was my error, not a scope decision. All three now exist.
4912b7aHomeand_Sidebarcd3a12fevents.subscribewas never builtThe three new pages
14 Fleet Manager.
fleet-managerhad zero coverage, so an operator had no way to learn it exists. Written from its own source — thefleets.jsonshape taken from the parser rather than the example file, and the probe's real progress test, which compares worktree modification times twice four seconds apart and reportsstalledwhen nothing changed. It also carries the two limits that come fromfleetdrather than from the tool: two daemons sharing one herdr session tear down each other's members, and a session inside a pane is resolved as a worker, which is why the manager sits outside a pane and speaks REST.15 REST API Reference. All 14 routes in one table with the
Authz.Actioneach handler checks, plus per-route bodies taken from the handlers. It leads with the fact that makes the page necessary: MCP and REST are siblings over one sharedMessageService, so REST behaviour cannot be inferred from the MCP contract.fleet_ackandfleet_whoamihave no route at all.16 Security & Trust Boundary. The guard, the role table, the member credential scrub and token scope, collected. The limits are stated rather than glossed — see below.
Two things found while writing these
1. A live inconsistency:
GET /membersreturns its rows under aworkerskey (FleetApp.java:322). The route was renamed/workers→/membersin CB-557 and the body key was left behind. A caller that readsbody["members"]gets an empty list and sees an idle fleet — not an error.fleet-managerreadsbody["workers"]and is correct (fleet_manager/probe.py:134). Documented on page 15; not changed, because changing it would breakfleet-manager. Worth its own ticket if anyone wants the names to agree.2. The security page had to state four limits, not three. A page that overstates protection is worse than no page, so it records: the effective allow-list is a union and therefore a strict superset of what an operator writes under
allow:; theZDOTDIRscrub is zsh-only; blockingSSH_AUTH_SOCKdoes not stop a member reaching a passphrase-free key file on disk; andargvis world-readable, which bypasses every environment control on the page.fleetditself is clean there — it hands a member's environment to herdr as its own field — but nothing stops another program on the host leaking through its own argv.Acceptance criteria
BRIDGED_MEMBERandbridged.yamlstill present.bridged.jaris legitimately gone: the artifact really was renamed tofleetd.jarin CB-634, so that entry on the protect-list is itself out of date.Homeand_Sidebar— 16 as well.workerskey above.Closing.