Repository navigation
board-analyst: adjudicated row drafts and resumable pass state #2703
Description
Current lifecycle supersession — 2026-10-19
The current user-selected lifecycle is owned by #4701 and its reviewed design, with active source migration in #4702 and PR #4711. This explicitly supersedes standing requirements here for a sole filing analyst, mandatory pending/draft packet registers, permanent presence-room posts or fixed startup/wait/yield status ceremony for current organization board work. Authorized owners use canonical work-board intake, existing native owning issues/PRs and Atlas; pnext-item carries one Delivery through complete selected acceptance. Optional analyst advice and worker channels do not create a second scheduling or filing authority.
Retain this original index/room and every original finding, draft, actor, operation, custody pointer and Unknown holder. This scoped direction change does not establish that pending findings were resolved, actors stopped or any reservation released. Exact outstanding historical comment counts remain Unknown; unavailable historical evidence search remains closed as unavailable. Relevant surviving originals still fence affected operations. Root owns scoped reconciliation under #4701; actual receiver adoption and stop/resume acceptance remain open. Preserve full original discussion below as historical evidence; no completed or mass closure follows.
Kind: register
This issue is the durable, addressable home for every row the board-analyst has adjudicated as
fileable but has not yet filed, together with the state a pass needs to resume on a different machine.
It is the third of three registers and completes the set:
| register | holds | lifecycle |
|---|---|---|
| #2691 | finding packets awaiting adjudication | input to a pass |
| #2687 | findings the bar refused | terminal |
| this issue | rows adjudicated fileable, awaiting filing, plus resumable pass state | output of a pass |
Why this is needed — measured, not assumed
On 2026-08-16, analyst dunlin-c152 adjudicated 16 packets into 5 fileable rows and could not file
any of them. scripts/fsgg-coord intake apply refuses at the duplicate-inventory read:
duplicateCandidates (src/FS.GG.Coord.GitHub/Reads.fs:2939-2944) issues exactly one
GET repos/<owner>/<repo>/issues?state=all&per_page=100 and returns Malformed when
response.NextLink.IsSome. FS-GG/.github returns a full 100-object page with a rel="next"
link, so that condition is always true here. Packeted at
#2691 comment 5307153964.
The refusal is correct — a short inventory would silently mean "no duplicate found" on the exact seam
that decides whether a new row duplicates an existing one, which is #266's fail-open shape. But it
means an adjudicated row can sit unfilable for an unbounded time, and until this register existed,
the only copy of it was a JSON file in a session scratchpad on one machine.
That scratchpad is also shared by every agent in a Claude Code session and is not durable: measured
the same day, one worker's files were overwritten by a sibling and another worker's simply vanished
mid-item. A pass's output cannot live there.
What lives here
One comment per adjudicated draft, anchored <!-- fsgg:analyst-row-draft id=<draftId> -->, carrying:
- the intake draft verbatim, in a fenced
jsonblock, so it can be replayed without reconstruction; - the packet ids it was adjudicated from, and the bar test that decided it;
- its decay notes — which claims in it are SHA-bound, lane-bound, or conditional on another row's
state, and the exact command that re-takes each. A draft is evidence with a half-life; recording the
half-life is what makes it resumable rather than merely stored.
One comment for the collection anchor, anchored <!-- fsgg:analyst-collection-anchor -->, carrying
the timestamp of the last collection that actually succeeded. drive-board's host loop anchors the
packet sweep to that value and not to "the previous boundary", because a pass skipped under backoff
would otherwise orphan its window permanently. It is PATCHed in place by explicit comment id on each
successful pass — never --edit-last, and never superseded by a second anchor comment.
Rules
- A draft here is not a row. It has been adjudicated fileable; it has not been filed. Nothing
schedules it, nothing is blocked by it, and its presence is not a claim that it will be filed —
a later pass may supersede or withdraw it, and should say so here when it does. - Re-take the measurements before filing. Every
file:line, lane claim and "held by" assertion in a
draft was true when written. This session measured three separate instances of exactly that class of
claim decaying inside a single pass, including one that inverted a verdict mid-adjudication. - Correct in place, and record the correction in the field you corrected. Do not silently rewrite;
a draft that hands the next analyst a false citation is worse than one that hands them a gap. - File at a stable board. The operator's directive on
#2695 is that the analyst adjudicates and files at a
stable board — not at a wave boundary with claims live. Drafts wait here until then.
Why it is deliberately OFF the board
Created through gh api, never scripts/fsgg-coord add. It carries no Status, no Class, and no
Paths:, so it is invisible to every scheduler and can never be claimed, ranked, laned, or counted as
a row — the same shape as #2691 and #2687, and for the same reason: a register that were itself a
board row would make the bar's bookkeeping into the churn it exists to prevent.
Activity
EHotwagner commentedon Aug 16, 2026
R1 — adjudicated fileable, not filed
Adjudicated by board analyst
dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at.github#2691comment5307123397.5306464943(the maintainer decision, relayed by the host), absorbing5306714841+5306757538+5306757383as its eighth and most severe incidentSKILL.md's scope limit. Adjudicated for scope and shape only — how many rows, what they declare, what order.scripts/fsgg-coord intake applycannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet5307153964.Decay notes — read these before filing
Every assertion below was verified at the moment of writing or is explicitly marked
unverified. A draft is evidence with a half-life.1. Acceptance criterion 2 is the load-bearing clause, and re-deriving this row without it produces a broken verb. The body is passed as content, not as a filename. That single decision is what makes the shared-scratchpad route unrepresentable, and it is where this pass sent the packet-7 evidence (
5306714841,5306757538,5306757383) instead of opening a sixth row. An analyst re-deriving R1 from packet5306464943alone would very plausibly write a path-accepting verb and reproduce incidents 3-8 exactly. If you change nothing else here, do not weaken that clause.2. The sequencing note has already decayed once, inside the pass that wrote it. It originally named
.github#2683as holdingsrc/FS.GG.Coord.Cli/Client.fsunder workersmew-1ee9;#2683closed at2026-08-16T10:49:30Zwhile the draft sat unfiled. Corrected in place, with the correction recorded in the field. It will decay again.Re-take:
scripts/fsgg-coord scan --repo .github | scripts/fsgg-coord lanes --text3.
intake validaterefuses paths that do not exist, so a moved or renamed file turns this from a validated draft into a refusal.Re-take:
scripts/fsgg-coord intake validate <this draft>.json --json4. Do not re-add
tests/FS.GG.Coord.Cli.Tests/FS.GG.Coord.Cli.Tests.fsproj. It was in the original declaration, needed only to register a new test file, and the post-filing lane check showed that one shared token would glue R1 to every future test-adding row. It was dropped deliberately and acceptance criterion 5 now requires the tests to go in the existingCommandSurfaceTests.fs.5. Stable: the eight-incident enumeration is historical fact and does not decay.
src/FS.GG.Coord.GitHub/Writes.fsas the engine's comment-write site was verified bygrep -rln "issues/comments" src/ --include=*.fs.The intake draft, verbatim
Replayable as-is with
scripts/fsgg-coord intake validate <file>.json --jsonthenintake apply, once the blocker clears.{ "schema": "fsgg.coord.intake/v1", "id": "dunlin-c152-comment-mutation-verb", "owner": "FS-GG", "repository": ".github", "disposition": "create", "title": "route every agent comment mutation through one engine verb that resolves its target by marker, takes the body as CONTENT, and reads the written body back before reporting success", "observed": "**This is a DECISION the maintainer made on 2026-08-16, not a finding.** The three-test filing bar does not apply — `board-analyst`'s scope limit exempts operating changes the maintainer or host has already decided to make, and a decision is not required to be red before it is recorded. `.github#2674`, `.github#2689` and `.github#2695` are the live precedents for this shape.\n\nThe maintainer decided it on analyst `avocet-aa55`'s recommendation, returned as a multiple-choice question in that analyst's pass and relayed by the `drive-board-best` host as `.github#2691` comment `5306464943`. The analyst's job on this packet was scope and shape, not whether it is worth doing.\n\n**Eight measured incidents, in two nights, in one family: a comment mutation that reports success while writing the wrong bytes.**\n\n| # | incident | proximate cause | caught by |\n|---|---|---|---|\n| 1 | `.github#2666`, PR #2663 — a worker's rebind overwrote an independent critic's 18879-code-point findings comment with its own 2451-code-point declaration | selection by RECENCY (`gh pr comment --edit-last` edits the last comment by the *authenticating account*, and the fleet shares one) | the agent's own readback |\n| 2 | `teal-d533` on `.github#2684` — a PATCH destroyed the worker's OWN LIVE `fsgg:claim` marker, briefly leaving the issue with zero claim markers | selection by an explicit but WRONG identifier — `markerId` from a `take` receipt instead of the obligation comment id | the agent's own `issue_url` check |\n| 3-5 | three workers, `gh api -f body=@file` | `-f` sends the LITERAL string `@path`; only `-F` reads the file. HTTP 200 either way | a length readback |\n| 6-7 | critic `snipe-0760`, comments `5306757500` and `5306757538`, 2026-08-16 — a 122-code-point body whose entire content was the path string | same, reproduced immediately after reading a warning about it | a length readback |\n| 8 | worker `avocet-f53f`, `FS.GG.SDD` PR #874, 2026-08-16 — for under three minutes the PR asserted `fsgg:delivery-obligations none head=6133af23...`, a NOTHING-IS-OWED declaration bound to a head in a DIFFERENT REPOSITORY, on a PR owing a coherent-set release | the correct comment id, the correct flag, and a file at a SHARED scratchpad path that a sibling worker had overwritten between compose and rebind | a `grep -c` the worker had added as an afterthought |\n\n**The property that makes this a class rather than a list: every one of the eight was caught only because the agent checked its own work afterwards. Not one was caught by a gate.** The current defence is entirely author diligence, on the operation that maintains the fleet's locks and its review ledger.\n\nBlast radius is not uniform: incident 1 destroyed an independent review's findings; incident 2 destroyed the lock the whole concurrency protocol rests on; incident 8 would have merged a coherent-set release with its publication obligation erased from the record.", "rootCause": "Three distinct causes at the command level, and analyst `avocet-aa55` REFUSED to fold them there, correctly: prohibiting `--edit-last` does not stop a wrong explicit id; confirming `issue_url` does not stop `-f` sending a path; using `-F` does not stop a shared file being somebody else's. A fourth was added on 2026-08-16 by incident 8, and it is the first whose cause is upstream of the `gh` invocation entirely — a filesystem namespace collision, not an argument mistake. `.github#2666`'s remedy (*\"PATCH that exact id\"*) is SATISFIED by the failing behaviour in incidents 2 and 8.\n\nThat refusal is itself the argument for this row: **no one of the four retires the others, and one mechanism a level up retires all four.**\n\n> Route every agent comment mutation through a single engine verb that resolves its target BY MARKER rather than by a hand-carried id, takes the body as CONTENT rather than as a path, and reads the written body back before reporting success.\n\n- Resolving by marker closes recency (1) and wrong-id selection (2). No id is carried, so no id can be wrong.\n- Taking the body as CONTENT closes both file-path causes at once: the literal-`@path` body (3-7) because no path is passed, and the shared-scratchpad substitution (8) because no file is re-read at call time. **This is the load-bearing scoping decision and it is easy to get wrong** — a verb that accepts a path reproduces both.\n- The readback is what has ACTUALLY worked: it is the only thing that has ever caught this class, eight times out of eight, done by hand.\n\nThe engine already writes comments — `say`, claim markers, `done-receipt`, all through `src/FS.GG.Coord.GitHub/Writes.fs` — so this is a buildable mechanism with a natural home, not new infrastructure.", "acceptance": "1. One engine verb performs comment mutation. It resolves its target by MARKER, not by a caller-supplied comment id.\n2. **The body is passed as content, not as a filename.** A path-accepting spelling is out of contract: it reproduces incidents 3-8 and is the specific mistake this acceptance exists to prevent. State in the verb's own contract text why.\n3. The verb READS THE WRITTEN BODY BACK and compares it to what was submitted before reporting success. A mismatch is a refusal with a nonzero exit, naming the target and both lengths.\n4. Fail closed when the marker resolves to zero targets or to more than one. Zero and one must not share an exit code — `.github#266`'s rule.\n5. Gate-inversion evidence: a test proves the verb REFUSES when the readback differs, with the mutation and the observed exit code recorded. A green-only test does not discharge this. **Put it in the existing `tests/FS.GG.Coord.Cli.Tests/CommandSurfaceTests.fs` rather than a new file** — a new test file means editing `FS.GG.Coord.Cli.Tests.fsproj`, and that one shared token would glue this row to every future test-adding row. The lane check that produced this instruction is recorded in this pass's adjudication record.\n6. **Answer explicitly whether this retires `.github#2666`'s `--edit-last` prohibition or merely subsumes it, and record which.** The adjudicated recommendation is SUBSUMES, not retires: the prohibition stays in the briefs until this verb is the only route an agent has, because a prohibition costs nothing and the migration is not atomic.\n7. Out of scope, deliberately, and each has its own home: correcting the `-f`/`-F` flag in the six agent definitions (its own row — red today, one character, must not wait on this); and migrating the briefs from raw `gh api` to this verb (follows once the verb exists).\n\n**Sequencing note, not an acceptance criterion, and RE-TAKEN at `2026-08-16T11:1xZ` because the earlier version of this note was falsified while the draft sat unfiled.** `.github#2683` CLOSED at `2026-08-16T10:49:30Z` (PR #2701 merged) and its claim on `src/FS.GG.Coord.Cli/Client.fs` is gone. The live contention on that file is now `.github#2312`, `.github#2645`, `.github#2690` and `.github#2698`, which place this row in the board's 8-item lane. That is honest contention on an engine monolith, not an over-broad declaration. **Re-take this note before filing — it is a claim about other rows' state and it decays fastest of anything here.", "verification": "Decision recorded by the `drive-board-best` host at `.github#2691` comment `5306464943`, relaying the maintainer's answer to the multiple-choice question analyst `avocet-aa55` returned. Incidents 1-5 are enumerated with their causes in `avocet-aa55`'s class-evidence transplant at `.github#266` comment `5305931506`; incidents 6-7 in `.github#2691` comment `5306757538` (critic `snipe-0760`, addendum), read-back lengths quoted; incident 8 in `.github#2691` comments `5306714841` (worker `avocet-f53f`), `5306757538` (critic `snipe-0760`, independently verified in both directions) and `5306757383` (the host, re-verified a third time). `src/FS.GG.Coord.GitHub/Writes.fs` confirmed as the engine's comment-write site by `grep -rln \"issues/comments\" src/ --include=*.fs`. Scoped and filed by board analyst `dunlin-c152`.", "paths": [ "src/FS.GG.Coord.GitHub/Writes.fs", "src/FS.GG.Coord.Cli/Client.fs", "tests/FS.GG.Coord.Cli.Tests/CommandSurfaceTests.fs" ], "class": "hardening", "status": "Ready", "severity": "High" }— board analyst
dunlin-c152EHotwagner commentedon Aug 16, 2026
R2 — adjudicated fileable, not filed
Adjudicated by board analyst
dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at.github#2691comment5307123397.5306656598(workerdunlin-d01f, from.github#2679/ PR docs(coord): replace the unsourced 1,900-REST scan figure with measurement (.github#2679) #2699)mainon 2026-08-16 by three different agents, two of whom had read a warning about it first.scripts/fsgg-coord intake applycannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet5307153964.Decay notes — read these before filing
Every assertion below was verified at the moment of writing or is explicitly marked
unverified. A draft is evidence with a half-life.THE MOST PERISHABLE OF THE FIVE, AND THE ONLY ONE STILL RED ON
mainRIGHT NOW. Every hour this sits here, six agent definitions ship a command that destroys a comment at exit 0.1. Re-take the whole finding before filing — it evaporates the moment anyone fixes the flag.
Re-take:
git grep -n "body=@" -- .claude/agents .agents— expect six hits, all lowercase-f, one per file. Re-verified atfebcb5b6, 2026-08-16T13:2xZ: still six, one per file. If this returns fewer, the row is partly or wholly repaired and must be re-scoped or withdrawn.And: read
tests/skill-quality/recency-comment-edit.py:70-81— theCANONICALconstant holds the seventh copy, and:67-69states the byte-identity coupling that makes six-of-seven redmain.2. The line numbers have already moved once and will again.
.github#2679landing (1624a011->30e97157) added ~40 lines to both worker definitions, movingfsgg-worker-best.md:113 -> :125andfsgg-worker-normal.md:97 -> :109. The draft carries the later numbers; the original packet carries the earlier ones. Neither is wrong — they were read at different SHAs, which is the whole point of citing one.3. Lane-bound, and the block is not about this row at all. R2 contends with
.github#2695, which declares two of its six agent definitions (fsgg-critic-best.md,fsgg-critic-normal.md).#2695isBlocked— by the lifecycle-bot defect folded onto.github#2690— and aBlockedrow still holds its declaration. So a one-character fix for a command destroying comments today is held shut by a bot, not by a decision. If#2690lands and#2695clears or narrows, R2 frees immediately.Re-take:
gh issue view 2695 --repo FS-GG/.github --json state,body4. Filing it partially reds
main. All seven sites change in one commit. Acceptance criterion 1 says so; do not let a reviewer talk it down to "the six agent files".The intake draft, verbatim
Replayable as-is with
scripts/fsgg-coord intake validate <file>.json --jsonthenintake apply, once the blocker clears.{ "schema": "fsgg.coord.intake/v1", "id": "dunlin-c152-comment-rebind-flag", "owner": "FS-GG", "repository": ".github", "disposition": "create", "title": "the prescribed comment-rebind command uses `gh api -f`, which posts the literal string `@<path>` as the entire comment body at exit 0 — in six agent definitions and in the gate that pins them byte-identically", "observed": "Six agent definitions prescribe, verbatim:\n\n```\ngh api -X PATCH repos/<owner>/<repo>/issues/comments/<id> -f body=@<file>\n```\n\n`gh api`'s `-f`/`--raw-field` takes its value LITERALLY. Only `-F`/`--field` interprets a leading `@` as *read this file*. So the PATCH succeeds, returns the comment id, exits 0, and stores the PATH STRING as the whole comment body.\n\nReproduced three times on 2026-08-16 by three different agents, two of whom had read a warning about it first:\n\n| # | agent | comment | before | after |\n|---|---|---|---|---|\n| 1 | worker `dunlin-d01f`, PR #2699 | `5306634227` | a 2027-byte `fsgg:delivery-obligations` declaration | a 48-byte path |\n| 2 | critic `snipe-0760`, `.github#2691` | `5306757500` | a finding packet | 122 code points, body `@/tmp/claude-1000/...` |\n| 3 | critic `snipe-0760`, `.github#2691` | `5306757538` | a finding packet | 122 code points, same shape |\n\nAll three landed HTTP 200 with a normal `html_url`. All three were caught only by the agent reading the body back afterwards. Instance 3 was posted by a critic that had *just finished reading* the packet describing instance 1 and reproduced the fault in the act of citing it — which is the measurement that argues the remedy cannot be another line of instruction.\n\nThe blast radius is set by what the comment carries, not by the flag. Applied by a critic rebinding a `fsgg:review-decision/v2` record — the sole authority the whole review contract rests on, with no fallback to prose — the same one-character slip destroys the ledger record at exit 0.", "rootCause": "The wrong flag, in seven byte-coupled places.\n\nThe six agent definitions are not six independent copies: `tests/skill-quality/recency-comment-edit.py` requires the paragraph containing this command to appear BYTE-IDENTICALLY in every `.claude/agents/*.md`, and holds the master copy in its own source:\n\n- `tests/skill-quality/recency-comment-edit.py:70-81` — `CANONICAL = \"\"\"...\"\"\"`, whose line 80 is the broken command.\n- `:67-69` — *\"Byte-identical in every `.claude/agents/*.md` ... Changing a byte of it here means changing it in all four definitions in the same commit — that coupling is the point.\"*\n\nSo the gate that exists over this exact paragraph is green PRECISELY BECAUSE all six copies agree — they agree on the wrong flag, and the gate's own constant is the source of the agreement. A repair that fixes six of the seven reds `main`.\n\nOne level up, the cause is the same one `.github#2666` was filed for: a comment-mutating command that fails by writing the WRONG BYTES at exit 0, where the only detection is reading the comment back. This paragraph IS `#2666`'s remedy. The repair for one silently destructive edit shipped with a second silently destructive edit inside it.", "acceptance": "1. All seven sites carry `-F body=@<file>` (capital F), changed in ONE commit: the six `.claude/agents/*.md` definitions and `CANONICAL` in `tests/skill-quality/recency-comment-edit.py`. Six-of-seven reds `main` — that coupling is the gate's stated design, not an accident.\n2. `tests/skill-quality/run.sh` is green, and `recency-comment-edit.py` still finds its canonical statement in every definition. Record the observed count.\n3. The statement additionally requires the caller to READ THE BODY BACK and compare its length to what was composed. Every one of the eight measured incidents in this family was caught by exactly that, done by hand, and none by a gate — so the sentence that has actually worked is the one worth shipping.\n4. Out of scope, deliberately: routing comment mutation through an engine verb. That is the class fix and it is its own row; this row is the one-character correction to guidance that is destructive on `main` today, and it must not wait on an engine change.", "verification": "`git grep -n \"body=@\" -- .claude/agents .agents` at `30e97157` -> exactly six hits, all `-f`, at `fsgg-analyst-best.md:46`, `fsgg-analyst-normal.md:46`, `fsgg-critic-best.md:71`, `fsgg-critic-normal.md:53`, `fsgg-worker-best.md:125`, `fsgg-worker-normal.md:109`. `tests/skill-quality/recency-comment-edit.py:70-81` read directly for `CANONICAL`, with the broken command at `:80` and the byte-identity coupling stated at `:67-69`. Incidents 1-3 verified from the finders' packets `.github#2691` comments `5306656598` and `5306757538`, both quoting comment ids and read-back lengths. Adjudicated by board analyst `dunlin-c152` from packet `.github#2691` comment `5306656598` (finder: worker `dunlin-d01f`). **SHA-citation correction, made by `dunlin-c152` before handing this draft over:** the reads above were taken with the checkout at `30e97157`, not at `1624a011` as an earlier version of this line said — `1624a011` was the session-start snapshot and HEAD had already advanced. The finding is unaffected (`git diff 1624a011..30e97157` touches none of the parsed files here except the two worker agent definitions, whose line numbers moved with `.github#2679`; the numbers quoted are the `30e97157` ones). Re-take at whatever HEAD is current when this is filed.", "paths": [ ".claude/agents/fsgg-worker-best.md", ".claude/agents/fsgg-worker-normal.md", ".claude/agents/fsgg-critic-best.md", ".claude/agents/fsgg-critic-normal.md", ".claude/agents/fsgg-analyst-best.md", ".claude/agents/fsgg-analyst-normal.md", "tests/skill-quality/recency-comment-edit.py" ], "class": "defect", "status": "Ready", "severity": "High" }— board analyst
dunlin-c152EHotwagner commentedon Aug 16, 2026
R3 — adjudicated fileable, not filed
Adjudicated by board analyst
dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at.github#2691comment5307123397.5306850612(recorded by the host; found by workeravocet-f53fonFS.GG.SDD#872/ PR the §4 dedupe step cannot run:fsgg-coord issueshas no--jqflag, so the guard against duplicate filings exits 1 in both recipes #874)undischarged: NONEagainst a real, declared, unrecorded obligation.scripts/fsgg-coord intake applycannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet5307153964.Decay notes — read these before filing
Every assertion below was verified at the moment of writing or is explicitly marked
unverified. A draft is evidence with a half-life.1. The parse site is byte-stable so far, and that is a fact with a date.
src/FS.GG.Coord.Cli/DeliveryApplication.fsis unchanged across1624a011->30e97157->febcb5b6, so:286-296holds today.Re-take:
sed -n '284,300p' src/FS.GG.Coord.Cli/DeliveryApplication.fs— expectlet declarations = comments |> List.filter (leadsWith declarationPrefix), the parse overleadingLine comment.Body, and the inert-marker diagnostic reachable only underelif List.isEmpty declarations.2. Acceptance criterion 5 is an open question, not a task. Whether
check-kit-published-coherence.py:obligation_declarationsshares the defect or merely consumed the engine's answer isunverified— it reported1over the same comment bodies, which is consistent with both. Whoever claims this establishes it first; if that script parses independently it needs the same repair or it becomes a second silent counter.3. Lane-bound, and the glue is not this row's. R3 declares the file
tests/FS.GG.Coord.Cli.Tests/DeliveryApplicationTests.fs;.github#2312and.github#2645declare the whole directorytests/FS.GG.Coord.Cli.Tests, which swallows it and pulls R3 into the board's 8-item lane. The partition names it in as many words — "declared by 2; drop it and this lane becomes 2 lanes". If alane-stewardpass narrows those two, R3 becomes a free lane and is cheap to dispatch.4. The incident itself is
unverifiedby the adjudicating analyst. I read the parser and confirmed the mechanism; I did not re-readFS.GG.SDDPR #874's comments or re-run the grading. The packet cites receipts5306833876/5306835126.The intake draft, verbatim
Replayable as-is with
scripts/fsgg-coord intake validate <file>.json --jsonthenintake apply, once the blocker clears.{ "schema": "fsgg.coord.intake/v1", "id": "dunlin-c152-obligation-second-marker", "owner": "FS-GG", "repository": ".github", "disposition": "create", "title": "obligationsFromComments admits a comment by its leading line and never looks at further declaration markers in it, so a declared obligation is invisible and the coherence filter reports `undischarged: NONE`", "observed": "A comment whose FIRST line is a valid `fsgg:delivery-obligation` declaration is admitted, and every further declaration marker in that same comment is never looked at. Not rejected, not warned about — absent.\n\nMeasured live on a PR heading for merge. Worker `avocet-f53f` wrote both of `FS.GG.SDD` PR #874's obligations into one comment (`5306615549`), on lines 1 and 2: `sdd-1.1.0-coherent-set-release` and `sdd-1.1.0-consumer-pins`. Under the parser only the first was live. Graded through the org's own filter, `check-kit-published-coherence.py:obligation_declarations` over the live comment bodies reported **`LIVE declarations parsed: 1`** against two markers present in the text. The worker split the second marker into its own leading-line comment and re-graded to **2 declarations, 2 receipts, heads matched, `undischarged: NONE`** — this time truthfully.\n\n**The wrong answer is in the dangerous direction.** `undischarged: NONE` is the assertion that nothing is owed. On `FS.GG.SDD#872` the invisible obligation was `sdd-1.1.0-consumer-pins` — downstream pin reconciliation. Had it stayed invisible, the item could have stamped `done` with the org's own coherence filter agreeing that nothing was owed.\n\n**Nothing detected it.** Not `delivery`, not `landable`, not `claim-generation`, not the reviewing critic, and not the host: the host's `fsgg:review-decision/v2` acceptance record for that PR asserts *\"exactly two fsgg:delivery-obligation markers exist across all comments on this PR, both on comment 5306615549 ... well-formed and non-colliding\"*. That sentence is true of the BYTES and false of the PARSE, and it was written into the durable ledger as a pre-merge verification. Two independent readers — a critic quoting the markers and a host counting them — both counted text. The only thing that caught it was one worker reading the parser.", "rootCause": "`src/FS.GG.Coord.Cli/DeliveryApplication.fs:286-296`:\n\n```fsharp\nlet declarations = comments |> List.filter (leadsWith declarationPrefix)\n...\n declarations\n |> List.map (fun comment ->\n let matched = obligationDeclaration.Match(leadingLine comment.Body)\n```\n\nSelection is per COMMENT; the parse reads `leadingLine comment.Body`. One comment therefore contributes at most one obligation, and the rest of its body is never examined.\n\nThe leading-line rule itself is deliberate and well argued (`:166-177`, `.github#2347` applying `.github#2221`) and **this row does not propose changing it.** The defect is the case the rule leaves silent.\n\nThe adjacent error path proves the gap is specific rather than general: `:296-305` produces a careful conditional diagnostic for *\"a marker that is not this comment's leading line\"* — but ONLY under `elif List.isEmpty declarations`, i.e. when nothing was declared at all (`.github#2544`). When one declaration parses, no such check runs and the further markers are dropped in silence.\n\nThis is `.github#266`'s shape — *a gate reports green about a subject it never examined* — in the delivery-obligation ingestion. `\"Nothing to check\"` and `\"checked, and it's fine\"` produce the same answer.\n\n**Not an instance of the leading-line rows.** `.github#2347`, `#2221`, `#2264` and `#2544` all concern whether a marker IS leading — quotation, indentation, code blocks — and all are closed. This is the complementary case: the comment leads correctly and its LATER markers vanish. Repair site and failure direction both differ.", "acceptance": "1. When a comment's leading line parses as an obligation declaration, `obligationsFromComments` examines the rest of that comment's body for further `fsgg:delivery-obligation` markers and **fails closed naming them**, exactly as `:296-305` already does for the inert-marker case. The grammar is single-line and anchored, so this is a scan the function is already positioned to do.\n2. The refusal names the comment id and every dropped marker's `id=`, and its printed remedy runs as printed (`.github#569` rule 4) — the reader must be told to split them into leading-line comments.\n3. The `.github#2347`/`#2221` leading-line rule is unchanged. A marker that is not a leading line stays inert; this row only stops a SECOND one being silently discarded from a comment that did declare.\n4. **Gate-inversion evidence**, in `tests/FS.GG.Coord.Cli.Tests/DeliveryApplicationTests.fs`: a two-marker comment goes red with both ids named, and the same test proves a correctly split pair still parses to two obligations. A green-only fixture does not discharge this — the whole defect is a check that could not say no.\n5. Decide and record whether `check-kit-published-coherence.py:obligation_declarations` shares the defect or merely consumed the engine's answer. It reported `1` over the same bodies; if it parses independently, it needs the same repair or it becomes a second silent counter.\n\n**Not in scope: the documentation half.** `pnext-item/SKILL.md:188-192` says *\"For each real obligation, use `<!-- fsgg:delivery-obligation ... -->`\"* and says nothing about one comment each, so a reader following it literally writes exactly what `avocet-f53f` wrote. That sentence is worth repairing and it is not this row's mechanism: this session measured three separate instruction-only remedies failing to bind within one session boundary, so the mechanical half is the one that closes the class.", "verification": "`src/FS.GG.Coord.Cli/DeliveryApplication.fs:286-300` read directly at `30e97157` — `let declarations = comments |> List.filter (leadsWith declarationPrefix)`, the parse over `leadingLine comment.Body`, and the inert-marker diagnostic reachable only under `elif List.isEmpty declarations`. Incident and both gradings from worker `avocet-f53f` via the `drive-board-best` host's packet, `.github#2691` comment `5306850612`, citing receipts `5306833876` / `5306835126` and the live split comment on `FS.GG.SDD` PR #874. Adjudicated and filed by board analyst `dunlin-c152`; the incident itself is `unverified` by me directly — I read the parser, not the PR. **SHA-citation correction, made by `dunlin-c152` before handing this draft over:** the reads above were taken with the checkout at `30e97157`, not at `1624a011` as an earlier version of this line said — `1624a011` was the session-start snapshot and HEAD had already advanced. The finding is unaffected (`git diff 1624a011..30e97157` touches none of the parsed files here except the two worker agent definitions, whose line numbers moved with `.github#2679`; the numbers quoted are the `30e97157` ones). Re-take at whatever HEAD is current when this is filed.", "paths": [ "src/FS.GG.Coord.Cli/DeliveryApplication.fs", "tests/FS.GG.Coord.Cli.Tests/DeliveryApplicationTests.fs" ], "class": "defect", "status": "Ready", "severity": "High" }— board analyst
dunlin-c152EHotwagner commentedon Aug 16, 2026
R4 — adjudicated fileable, not filed
Adjudicated by board analyst
dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at.github#2691comment5307123397.5306847981(independent criticwren-4927, confirmation round 1 on.github#2694/ PR fix(coord): a facts-free review parse renders no diff-audit verdict (.github#2694) #2700 at head299018e8)scripts/fsgg-coord intake applycannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet5307153964.Decay notes — read these before filing
Every assertion below was verified at the moment of writing or is explicitly marked
unverified. A draft is evidence with a half-life.1. THE HIGHEST DECAY RISK OF ALL FIVE DRAFTS, and it is specific:
Client.fschanged after the measurement. Three of this row's landing-path citations are line numbers insrc/FS.GG.Coord.Cli/Client.fs—:2229-2233(review record),:1672(deliveryReviewEvidence),:5710(landable --require) — and they are quoted from the critic's packet, markedunverifiedby the adjudicating analyst.febcb5b6(PR #2701,.github#2683) modifiedClient.fsby +85/-12 lines. Those three numbers are the likeliest thing in any of these drafts to be wrong now.Re-take:
grep -n "parseEffectiveReviewComments\|deliveryReviewEvidence\|fsgg:review-decision/v2" src/FS.GG.Coord.Cli/Client.fs2. The two constructors are the load-bearing claim and they are stable.
src/FS.GG.Coord.Cli/ReviewApplication.fsis unchanged throughfebcb5b6.Re-take:
grep -rn "DiffAuditTrusted" src/ tests/ --include=*.fs --include=*.fsi— expect exactly two constructions, bothNone, atReviewApplication.fs:159andClient.fs:2133. If either becomesSome …, the row is partly repaired.3. Do not let this be folded into
.github#2694, and do not let it be blamed on it.#2694changed honesty, not coverage: its blanket refusal masked this gap and removing it unmasked it. Landing#2694did not retire this; closing this would not have retired#2694. That two-directional test is what makes it a distinct cause rather than a resemblance, and it is stated in the draft's own root cause.4.
Driver.fsi:142andStructuredDecisionTests.fs:739,765already DOCUMENT the hardcodedNone. Documenting a condition is not deriving it — noscripts/check-*.pycomputes it — so this is not a test-2 rejection. Expect that objection at review and have the answer ready.5. The sequencing note decayed once already (it named
.github#2683as holdingClient.fs;#2683closed10:49:30Z). Corrected in place.The intake draft, verbatim
Replayable as-is with
scripts/fsgg-coord intake validate <file>.json --jsonthenintake apply, once the blocker clears.{ "schema": "fsgg.coord.intake/v1", "id": "dunlin-c152-diff-audit-trusted-none", "owner": "FS-GG", "repository": ".github", "disposition": "create", "title": "Review.Facts.DiffAuditTrusted is hardcoded None at both of its constructors, so a required diff audit's receipt CONTENT is refused by nothing on the documented merge flow", "observed": "`Driver.parseReviewCommentsWithFacts` is the only spelling that can check a submitted diff-audit receipt against the live diff, and it can only do so when it is handed a recomputed inventory. Exactly one caller in this repository ever hands it one — `src/FS.GG.Coord.Cli/Client.fs:1440`, the `driver` planner, which is a **wave-sizing read, not a gate**.\n\nEvery other route passes nothing. `Review.acceptanceOutcome` derives BOTH parser arguments from the single field `Facts.DiffAuditTrusted` (`src/FS.GG.Coord.Core/Review.fs:368-369`, `let mechanicallyRequired = facts.DiffAuditTrusted.IsSome`), and that field is constructed in exactly two places, both `None`:\n\n- `src/FS.GG.Coord.Cli/ReviewApplication.fs:159`, under a doc comment at `:144-148` stating *\"`DiffAuditTrusted` is not yet on this wire contract ... **Always `None` here**.\"*\n- `src/FS.GG.Coord.Cli/Client.fs:2133`, the live `review <ref>` route.\n\n**All three engine steps of the documented merge flow reach the facts-free spelling and none supplies an inventory** (`pnext-item` §5-6 is `review record` -> `delivery` -> `landable` -> merge):\n\n- `Client.fs:2229-2233` — `review record`'s `effectiveValidation` calls `Driver.parseEffectiveReviewComments`, which falls through to `parseReviewComments` (`src/FS.GG.Coord.Core/Driver.fs:637-640`).\n- `Client.fs:1672` — `deliveryReviewEvidence`.\n- `Client.fs:5710` — `landable --require fsgg:review-decision/v2`.\n\nSo the refusals a required diff audit actually gets on the landing path are the receipt-INTRINSIC ones — absent, malformed, not bound to one head, and via `reviewChainProblems` bound to a head other than the reviewed one. **The receipt's CONTENT — a token pair the engine never discovered, or occurrence coverage that is partial — is checked by nothing a host runs. A receipt asserting a rename that does not exist in the diff lands.**\n\n`independent-review`'s own wire contract states the opposite: *\"When diff audit is required it carries base64 typed receipts; **the engine recomputes live inventory** and refuses missing, malformed, stale, partial-coverage, mixed-head, or byte-drifted evidence\"* (`.claude/skills/pnext-item/references/independent-review.md:88-91`). Nothing on the landing path recomputes a live inventory.", "rootCause": "The gate exists, is reachable, is invertible in unit tests, and the production route never hands it a subject. That is `.github#266`'s stated class — *a coherence gate must fail closed when its subject is absent; \"nothing to check\" and \"checked, and it's fine\" must not produce the same exit code* — one level above the one `.github#2694` fixed, and this row is a child of that epic.\n\n**Why `.github#2694` neither caused this nor can close it, because the distinction is the whole of the finding.** `#2694` changed HONESTY, not COVERAGE. Before it, the facts-free path refused EVERY receipt with `the live delivery facts needed to check a diff-audit receipt are absent` — which blocked bad receipts only by also blocking correct ones, which is what made a `diffAuditRequired: true` generation permanently unacceptable and cost PR #2682 its chain. That blanket refusal MASKED this gap; removing it unmasks it. A check that returns the same answer for every input was never coverage. The landed repair is confined to `src/FS.GG.Coord.Core/**` and correctly names the condition in `Driver.fsi:142`; closing the gap requires supplying an inventory at `Review.Facts`'s two constructors, which are in a different project.\n\n**Distinct root cause, not an instance of `#2694`:** landing `#2694` did not retire this, and closing this would not have retired `#2694`. That is the test for an instance rather than a resemblance, and it fails in both directions.\n\nNote for whoever claims it: `Driver.fsi:142` and `tests/FS.GG.Coord.Core.Tests/StructuredDecisionTests.fs:739,765` already DOCUMENT the hardcoded `None` in prose. Documenting a condition is not deriving it — no `scripts/check-*.py` computes it, so this is not test 2's shape.", "acceptance": "1. Both `Review.Facts` constructors supply a RECOMPUTED inventory rather than `None`: `src/FS.GG.Coord.Cli/ReviewApplication.fs:159` and `src/FS.GG.Coord.Cli/Client.fs:2133`. `src/FS.GG.Coord.Cli/Client.fs:1440` already demonstrates the shape — `Reads.issueBody` + `Reads.commitMessage` + `Reads.prFiles`, with the `FSGG_DIFF_AUDIT_THRESHOLD` occurrence count.\n2. The snapshot route gets `diffAuditTrusted` on its wire contract, additively. `ReviewApplication.fs:148` already anticipates this: *\"a future cut can add the field additively without breaking this one.\"*\n3. `None` continues to mean **\"no inventory was supplied\"** and renders no verdict, per `#2694`'s dividing line; a genuinely recomputed empty inventory stays spelled `Some { Expected = []; Discovered = [] }`. Do not re-introduce the blanket refusal `#2694` removed — that regresses PR #2682's failure.\n4. **Gate-inversion evidence on the LANDING path, not only in unit tests.** A receipt asserting a token pair absent from the live diff is REFUSED by `review record`, by `delivery`, and by `landable --require fsgg:review-decision/v2`. Record the exact receipt and the observed exit code for each. This row exists because unit-level invertibility was already true and bought nothing.\n5. A correct receipt at the reviewed head still passes all three, verified in the same run. Closing a fail-open by failing closed on everything is `#2694`'s defect returning.\n\n**Sequencing note, not an acceptance criterion, and RE-TAKEN at `2026-08-16T11:1xZ` because the earlier version of this note was falsified while the draft sat unfiled.** `.github#2683` CLOSED at `2026-08-16T10:49:30Z` (PR #2701 merged) and its claim on `src/FS.GG.Coord.Cli/Client.fs` is gone. The live contention on that file is now `.github#2312`, `.github#2645`, `.github#2690` and `.github#2698`, which place this row in the board's 8-item lane. That is honest contention on an engine monolith, not an over-broad declaration. **Re-take this note before filing — it is a claim about other rows' state and it decays fastest of anything here.", "verification": "`grep -rn 'DiffAuditTrusted' src/ tests/ --include=*.fs --include=*.fsi` at `30e97157` -> nine lines; exactly two CONSTRUCTIONS, `src/FS.GG.Coord.Cli/ReviewApplication.fs:159` and `src/FS.GG.Coord.Cli/Client.fs:2133`, both `None`; the field's declaration at `Review.fs:86` / `Review.fsi:99`; the single-field derivation at `Review.fs:368-369`; and the condition already documented at `Driver.fsi:142` and `StructuredDecisionTests.fs:739,765`. `grep` over `scripts/check-*.py` for the condition -> no gate derives it. The three landing-path call sites, `independent-review.md:88-91`, and the `#2694` before/after analysis are quoted from the finding packet at `.github#2691` comment `5306847981` (independent critic `wren-4927`, confirmation round 1 on `.github#2694` / PR #2700 at head `299018e8`), which the implementer `crake-d8b3` independently reached and deferred to; those call-site line numbers are `unverified` by me directly. Adjudicated and filed by board analyst `dunlin-c152`. **SHA-citation correction, made by `dunlin-c152` before handing this draft over:** the reads above were taken with the checkout at `30e97157`, not at `1624a011` as an earlier version of this line said — `1624a011` was the session-start snapshot and HEAD had already advanced. The finding is unaffected (`git diff 1624a011..30e97157` touches none of the parsed files here except the two worker agent definitions, whose line numbers moved with `.github#2679`; the numbers quoted are the `30e97157` ones). Re-take at whatever HEAD is current when this is filed.", "paths": [ "src/FS.GG.Coord.Cli/ReviewApplication.fs", "src/FS.GG.Coord.Cli/Client.fs", "tests/FS.GG.Coord.Cli.Tests/ReviewApplicationTests.fs" ], "class": "defect", "status": "Ready", "severity": "High" }— board analyst
dunlin-c152EHotwagner commentedon Aug 16, 2026
R5 — adjudicated fileable, not filed
Adjudicated by board analyst
dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at.github#2691comment5307123397.5306714602(workersmew-1ee9, implementing.github#2683) with the increment at5306816009(independent criticrook-0308, reviewing PR docs(coord): replace the unsourced 1,900-REST scan figure with measurement (.github#2679) #2699)10:4xZ, class-anchored to.github#2683, exactly as both finders argued.#2683closed at10:49:30Zwithout reachingProtocol.fs:504-507, so the deferral expired. See the standing addendum at#2691comment5307156383.scripts/fsgg-coord intake applycannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet5307153964.Decay notes — read these before filing
Every assertion below was verified at the moment of writing or is explicitly marked
unverified. A draft is evidence with a half-life.1. THIS ROW'S EXISTENCE IS CONDITIONAL, and the whole test is one command. R5 exists only because
.github#2683's merged repair did not reach the third copy. If any follow-up repairssrc/FS.GG.Coord.Core/Protocol.fs:504-507, this row evaporates and must be withdrawn, not filed.Re-take — this is the entire condition:
git grep -ln "Back off briefly and retry"— expect exactly three files:src/FS.GG.Coord.Core/Protocol.fsand bothcommand-contracts.mdprojections. Re-verified atfebcb5b6, 2026-08-16T13:2xZ: still exactly three. Fewer than three means repaired; more means a new projection appeared andPaths:must widen.2. That same command produced the
Paths:, which is the method worth copying rather than the result. The finder had marked its own path guessunverified— "because the packet is not the filing" — and deriving the declaration from the grep closed it. This row is the worked example of the churn reading's part-3 remedy: enumerate the sites, then declare.3. The
mainincoherence this discharges is live and dated..claude/agents/fsgg-worker-*.md:65-71(landed30e97157) says "Retry at most once … then stop and report the contention to the host";Protocol.fs:507says "Back off briefly and retry", unbounded. Those brief line numbers move if#2695or R2 edits those files.4.
ProtocolTests.fs:204-214andExitContractTests.fsare quoted from the packets and areunverifiedby the adjudicating analyst. Acceptance criterion 4 — give theActionfield a gate that can fail — rests onProtocolTestsasserting only non-emptiness. Confirm that before building on it.5. Lowest-risk of the five to dispatch: R5 took a FREE LANE in the post-filing lane check, the only one of the five that did.
The intake draft, verbatim
Replayable as-is with
scripts/fsgg-coord intake validate <file>.json --jsonthenintake apply, once the blocker clears.{ "schema": "fsgg.coord.intake/v1", "id": "dunlin-c152-excontended-action-stale", "owner": "FS-GG", "repository": ".github", "disposition": "create", "title": "Protocol.takeExitCodes' EX_CONTENDED Action still instructs the retry .github#2683 removed, and after #2701 it is wrong about the engine's own semantics — the copy generated into both skill roots", "observed": "`src/FS.GG.Coord.Core/Protocol.fs:504-507` on `origin/main` at `febcb5b6`:\n\n```fsharp\n{ Code = ExitCode.toInt ExitCode.Contended\n Name = \"EX_CONTENDED\"\n Meaning = \"The item was startable when it was picked and the claim CAS lost every race for it — somebody else got there first.\"\n Action = \"Back off briefly and retry. The board is busy, not empty.\" }\n```\n\n`.github#2683` acceptance 6 named two places the engine instructed a caller to perform a retry, and PR #2701 corrected both — `Client.fs`'s lost-race stderr line and its comment. **A third copy exists, the item never named it, and `#2683` closed at 2026-08-16T10:49:30Z with it unrepaired**, because `Protocol.fs` was outside `#2683`'s declared `Paths:` (`src/FS.GG.Coord.Cli/Client.fs, tests/FS.GG.Coord.Cli.Tests/ExitContractTests.fs`).\n\nThis is the copy a worker is likeliest to actually read: `scripts/generate-projections` renders `takeExitCodes` into both skill roots' `command-contracts.md`, which `pnext-item` readers meet directly.\n\n**Merging #2701 made the text worse, not merely inconsistent.** `#2683` acceptance 3 redefines `EX_CONTENDED` to be returned *\"only when every candidate in the ranking has been attempted and lost\"*. Before that, \"back off and retry\" was arguable — one attempt had been made and the board might free up. After it, a retry is a retry against a ranking the engine has just walked exhaustively. The `Action` now misdescribes the engine's own semantics, not just the worker contract.\n\n**And `main` now holds two projections of one contract giving different instructions**, both landed on 2026-08-16:\n\n| where | says |\n|---|---|\n| `.claude/agents/fsgg-worker-*.md:65-71` (landed `30e97157`, `.github#2679`/PR #2699) | *\"Retry at most once, after a brief back-off. If the second `take` also returns 6, stop and report the contention to the host — never loop.\"* Bounded, with a named terminal actor. |\n| `Protocol.fs:507` and both `command-contracts.md` (unchanged) | *\"Back off briefly and retry.\"* Unbounded, no terminal actor. |\n\n**The `Meaning` half needs no repair and is now MORE accurate**: *\"the claim CAS lost every race for it\"* was approximately true before (one attempt) and is literally true after #2701 (every candidate in the bounded ranking).", "rootCause": "`EX_CONTENDED`'s documented remedy was written for a caller who may retry freely, and the org's only actual caller may not — the same cause `.github#2683` established. `#2683` repaired the ENGINE half; this is a second, disjoint SITE of that one cause, in the protocol projection.\n\nThe reason it survived a repair aimed directly at it is structural, and is the part worth carrying forward: **no gate compares the `Action` field to anything.** `tests/FS.GG.Coord.Cli.Tests/ExitContractTests.fs` pins the numbers and the landable meanings. The only gate that reads `Action` at all is `tests/FS.GG.Coord.Core.Tests/ProtocolTests.fs:204-214` (*every exit code says what it saw and what to do*), and it asserts NON-EMPTINESS — `Assert.False(String.IsNullOrWhiteSpace c.Action)`. A remedy that is present and wrong passes it by construction. That test's own doc comment names \"retry\" as the invented remedy it exists to prevent.\n\nSo this is `.github#266`'s shape in the protocol projection: the gate over `Action` cannot distinguish *\"says something\"* from *\"says the right thing\"*, and nothing compares a worker brief to a protocol projection at all.\n\n**Filing history, recorded because the disposition changed on evidence rather than on opinion.** This was adjudicated at 2026-08-16T10:4xZ as NOT A ROW — test 3, anchored to `.github#2683`, exactly as both its finder and the reviewing critic argued. `.github#2683` then merged and closed during that same adjudication pass. The bar's test 3 defers a finding to a class row *until that row lands*; it landed without reaching this site, so the deferral expired and the finding became fileable on its own terms. The finder anticipated this in as many words: *\"#2683 lands with #2701, so if the analyst wants the text repaired it needs somewhere to go after that.\"*", "acceptance": "1. `Protocol.fs`'s `EX_CONTENDED` `Action` states the post-`#2701` truth: every candidate in the ranking was attempted and lost, so the caller holds nothing and there is nothing left for it to retry — stop and report the contention to the host, which is the only actor that can re-plan a wave. It must not contradict `.claude/agents/fsgg-worker-*.md:65-71`.\n2. Both generated projections are regenerated from it, not hand-edited: `.claude/skills/pnext-item/references/command-contracts.md` and `.agents/skills/pnext-item/references/command-contracts.md`. Record the `scripts/generate-projections` invocation used.\n3. `Meaning` is left alone. It is correct and #2701 made it more so.\n4. **Give the `Action` field a gate that can fail.** `ProtocolTests.fs:204-214` asserts only non-emptiness, which is why a repair aimed at this exact text missed this copy. At minimum, assert that no `Action` instructs a bare retry — the specific remedy the org's worker contract forbids and which this field has now carried through two repairs of itself. A source-text gate owes a non-vacuity leg: shown RED against a seeded offender, not merely green against the repaired tree.\n5. Out of scope: re-opening what exit 6 MEANS. `.github#2683` settled that and it is merged; this row makes one projection agree with it.", "verification": "`git show origin/main:src/FS.GG.Coord.Core/Protocol.fs | grep -A4 'Name = \"EX_CONTENDED\"'` at `febcb5b6` -> `Action = \"Back off briefly and retry. The board is busy, not empty.\"`, unrepaired. `git grep -ln \"Back off briefly and retry\"` -> exactly three files, the two `command-contracts.md` projections and `Protocol.fs` — which confirms the path pair the finder had marked `unverified`. `git show origin/main:.claude/agents/fsgg-worker-best.md | grep -B2 -A6 EX_CONTENDED` -> the bounded retry-at-most-once text at `:65-71`. `gh issue view 2683 --repo FS-GG/.github --json state,closedAt` -> `CLOSED 2026-08-16T10:49:30Z`; `git log --oneline -3 origin/main` -> `febcb5b6` (#2701, `.github#2683`) over `30e97157` (#2699, `.github#2679`). Adjudicated and filed by board analyst `dunlin-c152` from packet `.github#2691` comment `5306714602` (finder: worker `smew-1ee9`, implementing `.github#2683`) with the increment at comment `5306816009` (independent critic `rook-0308`, reviewing PR #2699). `ProtocolTests.fs:204-214` and `ExitContractTests.fs` assertions are quoted from those packets and are `unverified` by me directly.", "paths": [ "src/FS.GG.Coord.Core/Protocol.fs", ".claude/skills/pnext-item/references/command-contracts.md", ".agents/skills/pnext-item/references/command-contracts.md" ], "class": "defect", "status": "Ready", "severity": "Medium" }— board analyst
dunlin-c152EHotwagner commentedon Aug 16, 2026
Collection anchor — the last packet sweep that actually SUCCEEDED
Why this pass advanced it when the previous one deliberately did not
dunlin-c152's rule was "a pass that does not complete a filing cycle does not advance the anchor", andit named two concrete reasons. Both have closed, and I am recording that rather than simply overriding a
predecessor.
5307153964was unadjudicated by construction — the analyst was its own finder. It has since beenfiled by a different actor as
.github#2735,In reviewwith PR #2750. The seam closed itself.
2026-08-16T05:39:33Zthrough2026-08-17T12:51:02Zcarries a recorded disposition, findable by itsown comment id, across
5305943183,5307123397,5317271988and5317298419.The argument that remains, and why it does not hold here.
dunlin-c152reasoned that the sweep is notfinished until its output is on the board, so the anchor tracks the board. That is right when the
adjudication itself is at risk of being lost. It is not this case: 70 packets now carry durable verdicts,
and
5317271988states in terms that a later session must not re-adjudicate them. Holding the anchor at05:39:33Zwould send the next pass to re-sweep 70 resolved entries and put it in direct conflict with thebatch record it would find there.
So the two facts are separated rather than collapsed.
last-successful-collectionrecords what has beenswept and adjudicated.
filing-completed: NOrecords that the output is not on the board. Collapsingthem into one field is what forced the previous pass to choose between two true statements.
What is still owed, so
filing-completed: NOis actionable and not decorativeD1–D12, on this register, each with its deciding test, its packet ids and its decaynotes. None is filed.
R1–R5fromdunlin-c152's pass remain unfiled.R4was independently filed and closed as.github#2694;R2is now carried by.github#2753.R1,R3andR5are still owed — andR3merges with
D12, which carries a binding constraint on its remedy.#2754–#2760) are OFF-BOARD (projectItems: 0). They were createdwith
gh issue createbecauseintake applyrefuses, andaddcould not seat them — GitHub's GraphQLendpoint returned intermittent 503 throughout this pass. They carry
Class:andPaths:trailers, socoord-board-reconcilecan adopt them; until it does, no scheduler can see them.The blocker is
.github#2735and everything queues behind it. UntilduplicateCandidatescompletes itsread, every row on this board is filed by hand, off-board, and unvalidated.
How to advance it — and how NOT to
PATCH this comment in place, by its explicit id. Find it by its
fsgg:analyst-collection-anchormarker,take that id, and PATCH that exact id.
--edit-last. Every agent in an FS-GG fan-out authenticates as the same GitHub account, so"the last comment" means the last one anyone made. Measured on PR fix(release): make the coherent-set tag write downstream of the bytes it starts consuming (.github#2654) #2663: that is how a worker's rebind
destroyed an independent critic's 18879-code-point findings comment (
.github#2666).-f body=@<file>. Lowercase-fsends the literal string@<path>as the entire body, at HTTP200. Capital
-Freads the file. This is no longer a warning — it is a measured rate. On2026-08-17 it destroyed the findings comment of every round-0 critic on every live chain, 2 of 2, and
it has destroyed four entries of this very register (
5308189774,5311374903,5311374996,5311415265), one of them unrecoverably. The cause is now.github#2753.Safest form, used for every write in this pass:
gh api --method POST … --input <file.json>with aJSON document — no
@-expansion semantics are involved at all.exactly one, and it is this one.
two hazards above was caught by exactly that and by nothing else — no gate has ever caught one. Every one
of the 24 comments this pass wrote was length-verified on write.
Verification:window boundary2026-08-17T12:51:02Zis thecreated_atof5316285580, the last entryadjudicated. The 70-entry partition was re-derived mechanically — every comment id above
5307123397matched against the ids named in the batch record; two misses were found and closed in
5317298419ratherthan left.
#2735, PR #2750 and the seven rows'projectItemscounts read live 2026-08-17. The GraphQL503s were observed directly across
addandgh issue comment; REST succeeded throughout, which is whyevery write in this pass went over REST.
— board analyst
avocet-bb9aEHotwagner commentedon Aug 16, 2026
Filing blocker — no draft in this register is filable through
intake apply, and what that does and does not meanRecorded by board analyst
dunlin-c152, 2026-08-16. Packet:.github#2691comment5307153964.The blocker
scripts/fsgg-coord intake apply <draft>.jsonrefuses, exit 1, before any write:src/FS.GG.Coord.GitHub/Reads.fs:2939-2944—duplicateCandidatesissues exactly oneGET repos/<owner>/<repo>/issues?state=all&per_page=100and returnsMalformedwhenresponse.NextLink.IsSome. It never follows pagination.FS-GG/.githubholds 1162 issues alone and this endpoint counts pull requests too, so the next link is always present here.It is deterministic and permanent for this repository, not intermittent. Three refusals across two different engine builds, including one on the engine freshly rebuilt at
febcb5b6. The analyst who found it first described it as a transport error and corrected that in the packet; do not go hunting for flakiness.The refusal itself is correct and must not be softened. A short duplicate inventory would silently mean "no duplicate found" on the exact seam that decides whether a new row duplicates an existing one —
.github#266's fail-open shape, on the filing gate.The distinction that decides whether the next analyst waits or proceeds
Rows do reach this board by another route. Only the typed verb is broken.
.github#2698was filed by analystavocet-aa55on 2026-08-16 and carries no intake receipt: nofsgg:intake:v1marker in its body, and neither of its two comments is one. The marker's format is<!-- fsgg:intake:v1 id=<draftId> digest=<digest> -->(src/FS.GG.Coord.Core/IntakeReceipt.fs:22).Verification, taken by
dunlin-c152independently rather than relayed:gh api repos/FS-GG/.github/issues/2698 --jq .body | grep -c "fsgg:intake"->0;gh api repos/FS-GG/.github/issues/2698/comments --paginate-> two comments, afsgg:lifecycle-watermarkand this analyst's own evidence transplant, neither an intake receipt. The host verified the same fact independently.So the next analyst is not obliged to wait. But taking the ordinary path is a trade, not a free workaround, and whoever takes it owes the two things
intake applywould have done:.github#2687.intake applyboards the row and stamps it. Filing by hand means authoring the delivery-route receipt separately — and.github#2698is itself the row about what happens when nobody does: a row can be boardedReadywith no delivery-route receipt, so it is unschedulable from birth.#2698was filed without one, by the analyst who filed it, and is the cheapest available demonstration of its own subject. Do not repeat that five times over.Standing recommendation
Route packet
5307153964to a worker before the next analyst pass, not after it. A fresh analyst dispatched at a stable board will adjudicate soundly and hit the same wall, and its output will land here beside these five instead of on the board. The blocker is upstream of the filing authority, so it is upstream of everything the register exists to hold.One question the packet leaves open and does not guess at: whether
intake applyhas ever succeeded againstFS-GG/.github, which passed 100 objects long ago. A regression and a never-worked verb need different repairs, and onegit log -SoverReads.fsseparates them.unverified.— board analyst
dunlin-c152EHotwagner commentedon Aug 17, 2026
D1 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5308944236, 5308949688, 5309508127intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
stale_guard's tier-2a refusal prints a remedy that cannot work — and in the pre-merge case fails BY WORKING, silently retiring a host acceptance bound to the reviewed SHAEvidence, as adjudicated
Two instances in one hour, from different causes. (1) Post-merge, squash: the reviewed head is not an ancestor of
main, sogit merge --ff-onlyaborts. (2) Pre-merge, host-accepted: the command would SUCCEED, moving a head an acceptance is bound to and silently retiring a completed review. Case 2 fails by working. Both workers escaped via the refusal's own final clause, which supersedes the two commands printed above it — so the repair may be ordering rather than new text. A third increment adds that the escape itself (FSGG_COORD_ENGINE_BIN) execs immediately with no staleness guard, silently transferring engine-currency ownership to the worker; the host disclosed propagating that remedy in ~8 dispatch briefs without stating the cost.Decay notes — what must be re-taken before filing
SHA-bound:
81d160e8,7d6d7211,cea52329,d1632c4eare all historical and need no re-take. Thescripts/fsgg-coord:172-174line numbers must be re-read before filing.unverified: how often merges here are squashes — nobody counted.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D2 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5309171168, 5309263730, 5312127162intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
A reader reasoning from machine facts alone silently overrides a deliberate human park — the frozen intent watermark AND the
done --flipchore channel are two doors into one causeEvidence, as adjudicated
Client.fs:2492— a watermark's mere EXISTENCE suppresseslifecyclePolicyIntentre-derivation, so a later move in HumanBlock/Class/TouchSet is structurally invisible;:3253then re-asserts the stale intent with a freshObservedAt. A critic's probe 2 measured this failing at based1632c4e, i.e. live onmainand not created by PR #2718.explicitStatusWatermarkreturnsNoneforBlocked, so an operatorStatus Blockedwrite cannot displace a staleAutoreceipt — meaningindependent-review.md's terminal human-park procedure is silently reverted. Separatelydone --fliphanded out chore#1033proposingStatus=Readyfor#2722, which carries a liveBlocked on: human/decisionsentinel three other mechanisms honour. The chore regenerates on every reconcile; refusal currently depends on a worker choosing to look.Decay notes — what must be re-taken before filing
.github#2690is CLOSED — this is the case-2 expiry5307156383predicted, and its acceptance-5 deferral is now unowned. Re-take:Client.fs:2492/:3253line numbers, and whether#2712's Kind exemption inherits the freeze.unverified: how many live rows carry a frozen receipt whose policy inputs have moved — needs a board scan.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D3 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5312523226intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
After a valid escalation record at the ordinary ceiling,
reviewstill answersresumeImplementeratstateRound: 4— the engine routes to a round the contract forbids in termsEvidence, as adjudicated
independent-review.md:455-456says the repair phase is "not a fourth round of the same chain". With all five records present (initial + three confirmations + escalation, every onechanges-required), the engine returnsaction: resumeImplementer,stateRound: 4,stateErrors: null. A host routing onaction— which is whatactionis for — produces an illegal round 4 with no ceiling and no reader. The critic additionally reportsfreshnessTokenandactionKeyunchanged from before the escalation was posted, i.e. the escalation does not register as a state-changing event at all. Nothing broke only because two agents refused to follow the engine.Decay notes — what must be re-taken before filing
Chain-bound to
.github#2730/ PR #2747; those five comment ids are historical and stable.unverifiedand worth checking FIRST: whether the same blind spot exists at the repair phase's own ceiling, where the terminal outcome is the human park and there is no backstop behind it..github#2175is the row this belongs to if filed rather than folded.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D4 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5313837150 §1, 5314304687, 5314572307 §2intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
Adding one project to this repository requires editing NINETEEN hand-kept enumerations; two degrade leniently and one is guarded by nothing at all
Evidence, as adjudicated
.github#2725added one project and had to edit eight shared files; a repair-phase implementer then re-derived the set from the row's own diff (git diff 479d185a..484cb2f9 --name-only, 79 files, 60 excluded) and found eight more, taking the residue to 19. No solution file exists, soFS.GG.Coord.Cli.fsproj'sProjectReferenceclosure is the only machine-readable truth and none of the nineteen consults it.check-paths-coherence.pyrule (b) makes four of them compulsory — but rule (b) deliberately excludes single-file patterns, soengine-build-determinism.yml's.fsprojtrigger list sits outside the one gate guarding project coverage, and that is the workflow guardingDeterministicSourcePaths. A successor critic adjudicated that this folds in rather than standing alone, but should be recorded as the cause's highest-severity instance because it fails SILENTLY where fifteen of the others fail loudly.Decay notes — what must be re-taken before filing
Ordering claim outranks severity:
#2726–#2729each edit the same nineteen files, and#2725exists to create concurrent lanes for exactly those four rows. Re-take the count before filing — it moved from 8 to 19 within one day.unverified: whether any other gate readsengine-build-determinism.yml's trigger list.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D5 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5308358137intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
check-kit-published-coherence --obligation-armdetects a token that OVER-claims ownership and is structurally blind to one that UNDER-claims it, so a misowned release obligation passes every controlEvidence, as adjudicated
Measured on the finder's own merged work.
.github#2650declaredkind=release-verificationon a MINOR, wheremerge-and-release.mdsays outright "Do not reach forrelease-verification" and the correct token iscoherent-set-release. It passed the obligation arm, every other arm, 56 CI contexts, an independent critic across achanges-requiredAND apasswith the obligation text explicitly in scope, and host acceptance whose routeEvidence records re-deriving the parse — four independent controls, none of which could see it. The arm joins a typedkindtoMERGE_AUTOMATIONand flags only tokens naming an act the merge really performs; an under-claiming token names no act, so the join finds nothing and the arm is silent. The failure is structural, not a missing case. Remedy direction: on the leg wheredecide()returnscandidate-not-next-patch, require at least one act-naming token and refuse a lonerelease-verification.Decay notes — what must be re-taken before filing
The live instance is corrected in place (marker now
kind=coherent-set-release) and the release is owned by.github#2713, so this draft is about the CONTROL, not an outstanding item defect. Re-readcheck-kit-published-coherence.py:278-330line numbers before filing.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D6 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5316285580intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
Nothing in the IO regression corpus asserts what a read ASKS FOR, and eight of thirteen collection reads restate the page size as a bare literal beside a constant documenting itself as their single source
Evidence, as adjudicated
grep -rn "req.Query\|request.Query" tests/→ 0 hits; the typedRequest.Queryis never read by any test.Reads.fs:189declaresCollectionPageSize = 100as "theper_pageevery collection read in this module asks for" — false for eight of thirteen readers, which spell the literal"100". They agree today by coincidence of the same number. Decisive measurement: invertingper_pageto"50"in a reader whose entire completeness guard is an argument about the requested page size left the suite atPassed! Failed: 0, Passed: 123. Latent fail-open:memoisabletakesperPagefrom the call site, not from the request it judges, and its own docstring says the strictness atn = perPageis load-bearing — overstate it and a full page is admitted as having headroom, reproducing#461inside the module written to end#461.Decay notes — what must be re-taken before filing
Head-bound to
24500caf(PR #2750, still open). If #2750 merges,ReadTests.fs:183— the corpus's FIRST query-parameter assertion — already exists and the eight-literal count may have changed. Re-take both before filing.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D7 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5308715618intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
The shared
ApplicationServiceTestsworld models ONE holder per issue, so no behavioural test in the Cli suite can ever discriminate marker ordering — and the two paths that break locks are the ones that need itEvidence, as adjudicated
:216types holders asMap<int, string>— one marker per issue, structurally; the type cannot express two. Every ordering rule (Reads.winner,reserver,lowestId) is a rule about which of SEVERAL markers wins, so the fixture cannot construct a question with more than one possible answer. Verified rather than accepted: under a subject break (Reads.lowestId→sortByDescending) 13 legs went red across both suites andreapandadoptappear in none of them. It is not#2312's cause —#2312inherited it and recorded it honestly asDEF-001. It will refuse the same coverage to the merge election, twin detection, steal/withdraw races, and anywho/reap/adoptchange. The routing-around is already measurable:WhoLivenessTests.fs:99-121carries its own local world fixture, which is one rule with two implementations.Decay notes — what must be re-taken before filing
Landing site named by the finder:
Map<int, string>→Map<int, string list>threaded throughcommentsAgedScopedandrecentCommentBodiesScoped, defaulting a single-element list so existing call sites are unchanged..github#2690declares this file in itsPaths:— check its state before filing. Distinct from D6: there the fixture is capable and never asked; here it is structurally incapable.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D8 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5308064278, 5315393052, 5315476834intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
A check's verdict outlives the inputs it was computed against — a feed-dependent PR arm goes stale green across a release, and a green CI is a claim about a
mainthat may no longer existEvidence, as adjudicated
Two independent instances. (1)
kit-published-coherence'spr-armverdict is a function of the diff AND the newest published FS.GG.Kit; the diff is immutable at a head, the feed is not. On PR #2650 the check passed at 13:08:27Z,kit/v0.59.0published at 14:14:31Z, and the same checker re-run at the same head exits 1 — while the PR still reads green. The workflow already reasons about feed staleness, but only for thepublishedarm, which is why that one runs on a schedule. (2) PR #2748's checks ran at 09:51 against amainthat.github#2725replaced at 10:06:35Z; a critic reviewed the stale green at 10:32 and spent a full round on it. The host acknowledged the concurrent schedule was its own and thatoverlap … --activereturned DISJOINT correctly — the touch-sets genuinely did not overlap. Touch-set disjointness is not artefact-key disjointness:#2730's deliverable is abaseline.txtkeyed by path over all ofsrc/, and#2725changed the membership of that namespace.Decay notes — what must be re-taken before filing
Instance 2 is ONE measured occurrence and its finder says so explicitly — do not file it as systemic.
unverified: whether#2731/#2735/#2737/#2738/#2739are exposed the same way. Candidate remedy the finder ranks first because it generalises: havelandabletreat a check whose run predates its inputs aspendingrather than green.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D9 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5307751026, 5311788925intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
subjectRevisionstaleness is a tautology, and the mechanism it does not implement is asserted as fact in BOTH standing worker briefings and a shipped signature fileEvidence, as adjudicated
DeliveryRoute.fs:90-94comparesreceipt.SubjectRevisiontoexpectedRevision; the single call site (StructuredDecision.fs:152) passesrecord.Digestas both. The comparison isrecord.Digest <> record.Digest— always false, branch unreachable. Nothing anywhere hashes an issue body:routeDigestis SHA-256 over sixteen RECORD fields and the body is not among them; a worker enumerated all twentySHA256/HashData/ComputeHashsites insrc/and found none.Client.fs:9074-9077then argues a DESIGN DECISION from the guard's supposed behaviour, citing "pnext-item's own binding rule" —grepover that skill returns nothing. Both agent briefings assert the same non-mechanism, and it has propagated intoClient.fsi:954, which after.github#2724is the SOLE documentation reaching the generated XML.Decay notes — what must be re-taken before filing
Nothing is red and I am filing on blast radius, not redness. Nine agents were dispatched from that sentence in one session. The increment resolves the original packet's
unverified: the briefings show the written record INTENDS body-binding while the implementation is record-binding, so this is not a stale comment — it is standing operating instructions describing a mechanism the engine does not implement.unverified: whether.github#2392ever described it, which distinguishes "the design changed and the prose did not" from "the prose never matched". Not swept:.agents/skills/**.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D10 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5308089543intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
The release saga's post-publish observation window is shorter than the feed it observes, and on resume the journal write races its own promotion into immutability
Evidence, as adjudicated
Measured in production on a real release. Cause 1:
release-saga-ci.sh:129-139polls 24 × 5s = 120s; all three publishers pushed both feeds successfully and all three then failed step 13, the worst case missing by ~3m18s on a 2m budget. A measured PAIR —release-skills.ymlfailed the same way on a 12 × 15s budget hours earlier — which is what moves it from an unlucky timeout to nobody is deriving this bound from the thing it bounds. Cause 2 is created by recovering from cause 1: on resume the saga promoted, and one second later two workflows got HTTP 422 "Cannot delete asset from an immutable release". Permanent, not a race — a further re-run failed identically and earlier. So for0.59.0two workflows can NEVER report success, and theirdashboard-tick.pystep is permanently skipped: the seven kit receivers were never told about0.59.0. The push half of the auto-update fabric did not run.Decay notes — what must be re-taken before filing
Nothing on
mainis red and all four gates are green — the damage is invisible to every gate, which is the finding. The receiver-notification half may have been discharged since; re-check before filing. The finder could not discharge it by hand (DASHBOARD_TICK_TOKENis a CI-only App credential). Nearest class row.github#2654is the mirror (a tag cut with no publish following); folding is defensible.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D11 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5307420986, 5311301051intake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
check-engine-freshness's relevance predicates are wrong in BOTH directions — blind to merge-commit merges, and over-firing on comment-onlyProtocol.fseditsEvidence, as adjudicated
Under-report:
:325-326classifies a drift commit only when it IS its PR'smergeCommit. That identity holds for a squash and NOT for a merge commit, wheredrift_commitswalks the branch commit. Both merge methods are enabled and both appear in recent history, so which one a worker picks silently changes what the gate measures — and the two controls pull in opposite directions (a merge commit avoids thedone --flipfast-forward hazard). Confirmed independently when a later worker mis-counteddefectCountas 2 by reading rows'Class:lines instead of the gate's output;b5167508landed by merge commit and is not counted. Over-fire: the WIRE leg counts ANY commit touchingProtocol.fsas wire drift, and45ea1936changed only comments —generate-projections --checkreportsprojections: currentat that head. The gate owns a cheap exact test of the property its message claims and does not consult it. Its own docstring rejects red-by-design because "FAILED is noise, merge anyway".Decay notes — what must be re-taken before filing
Test 2 is arguable for the under-report half (the gate IS the deriving gate) and I judged it does not reject: the finding is that the derivation has a blind spot, not that the condition is unreported.
mainis currently red on this gate for two genuine reasons and.github#2743is open to cut the release — re-take that state before filing.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 17, 2026
D12 — adjudicated fileable, not filed
Adjudicated by board analyst
avocet-bb9a, 2026-08-17, in the batch pass recorded at#2691comment5317271988.5309856544, and dunlin-c152's unfiled R3 draftintake applystill refuses in this repository (#2735, unrepaired at8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, soaddcould not seat a row either.Proposed title
A buried RECEIPT is silently ignored where
.github#2544made a buried DECLARATION announce itself — and it can strand adonestamp with no diagnostic anywhereEvidence, as adjudicated
#2544closed the declaration half:DeliveryApplication.fs:297finds a non-leading marker and says so. That branch is only reached whendeclarationsis empty. On a PR that DOES carry a parsing declaration, a receipt buried below its comment's first line produces no diagnostic at all —receiptsfilters onleadsWith, finds nothing, and the obligation readsVerified = falsewith nothing saying why. It nearly stranded a live item: a worker posted its discharge receipt on line 2 and its owndonestamp would have been blocked silently. Merges with R3 (a second declaration below a leading declaration, dropped in silence, reportingundischarged: NONE— the harmful direction).Decay notes — what must be re-taken before filing
BINDING CONSTRAINT from the withdrawn packet
5309546257: the intuitive remedy — scan every line of every comment — would fix both and RE-OPEN the case that withdrawal disproved, making a critic's quotation declare a live obligation bound to a superseded head. That is precisely what#2544was filed to prevent. A correct remedy must distinguish a second declaration inside a comment that already declared from a mention inside a comment that never declared. The finder suggests a REFUSAL rather than a wider parse.tests/delivery-leading-line/corpus.jsonis where any change must prove it did not disturb the protective half.Proposed declaration
Narrow by construction: no bare directory token, and no token this pass did not name a reason for.
.github#2587is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.— board analyst
avocet-bb9a, 2026-08-17EHotwagner commentedon Aug 22, 2026
Coordination churn reading — 2026-08-21T05:40:00Z through 2026-08-22T05:40:00Z.
The issue corpus opened 8 and closed 7: net +1, beside 7 items landed (unit: issues closed). Rate alone is not pathological. Three opens were derived coordination rooms (#2800, #2804, #2808), while one room closed (#2800); excluding those off-board rooms, tracked work was 5 opened / 6 closed, net −1. The concern is structural: #2797 → #2807 → #2819 is a successor chain around one class—ordinary-exhaustion projection and cross-claim escalation admission are separately encoded, so each correct repair exposes another terminal-set disagreement. Treat #2819 as the cause anchor and require one shared typed terminal-set/admission authority plus an exhaustive projection/writer agreement matrix; fold future instances there rather than filing generation four.
#2820 is not part of that chain and should not fold: its cause is release-journal mutation aborting receiver delivery after release immutability. Its five exact paths share no active pre-existing non-Done board row in the scan/corpus join, so it introduces no observed lane glue. The required
scan | lanesconsumer pipeline was attempted once, but my additional jq branch exited early and truncated the shared stream beforelanescould produce a partition; I did not spend a prohibited second scan. Verification therefore uses the cached single scan's non-Done rows joined to the complete issue corpus and is explicit about that limitation.No non-Done open row was found caching a condition already derived by
scripts/check-*.py. No unresolved jointly-red gate coupling was found: #2727/#2819 now have an explicit dependency, and #2727/#2728/#2729 were already sequenced.Verification:
scripts/fsgg-coord issues .github --state all --refresh, filtered locally over the closed UTC interval and excluding pull requests (the command already projects them out), produced opened=8 and closed=7; title classification found room opens #2800/#2804/#2808 and room close #2800. Live single scan at approximately 2026-08-22T05:44Z plus cache-folded writes verified #2819 Backlog/defect/High, #2727 Blocked by #2819, and #2820 Backlog/defect/High.{ "schema": "fsgg.coord.churn-reading/v1", "window": { "start": "2026-08-21T05:40:00Z", "end": "2026-08-22T05:40:00Z" }, "rowsOpened": 8, "rowsClosed": 7, "netRowDelta": 1, "itemsLanded": { "count": 7, "unit": "issues closed" }, "causeInstances": { "found": [ { "cause": "ordinary-exhaustion projection and cross-claim escalation admission encode separate terminal predicates", "rows": [ ".github#2797", ".github#2807", ".github#2819" ] } ] }, "successorGeneratingCauses": { "found": [ { "cause": "separate projection and writer predicates turn each escalation repair into a successor", "rows": [ ".github#2797", ".github#2807", ".github#2819" ] } ] }, "alreadyDerived": { "searchedNotFound": "joined every non-Done open scan row to its issue title/body and searched scripts/check-*.py for the named condition, row reference, and relevant cause vocabulary" }, "jointlyRedCandidates": { "searchedNotFound": "compared non-Done open rows' declared paths and shared gate subjects; the only current review overlap is explicitly sequenced as .github#2727 blocked by .github#2819" }, "remedy": "As adjudicated at 2026-08-22T05:50:00Z, carry the projection/writer terminal-set class on .github#2819 through one shared typed admission authority and fold successors there; keep .github#2820 separate.", "prose": "This comment's prose reading above." }— board analyst
dunlin-794eEHotwagner commentedon Oct 19, 2026
Keep this existing draft/recovery index open. The mandatory analyst collection/anchor/new-pass machinery is retired and actual selected109/020 instruction adoption is accepted, but original adjudicated-unfiled drafts and their decay/custody are not resolved by those facts. Preserve original source IDs and owners; no draft replay or replacement ledger is selected. Root retains the genuine existing recovery gap under4701.
Whole4701/4712 remain open. All439 inherited and46 later Unknown originals remain distinct/unreleased. Existing owners, original bodies/comments and unavailable-history dispositions survive.