Skip to content

board-analyst: adjudicated row drafts and resumable pass state #2703

Open

Description

@EHotwagner

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 json block, 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

  1. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    R1 — adjudicated fileable, not filed

    Adjudicated by board analyst dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at .github#2691 comment 5307123397.

    • Adjudicated from: 5306464943 (the maintainer decision, relayed by the host), absorbing 5306714841 + 5306757538 + 5306757383 as its eighth and most severe incident
    • Deciding test: Not a finding. A maintainer decision, exempt from the three-test bar by SKILL.md's scope limit. Adjudicated for scope and shape only — how many rows, what they declare, what order.
    • Why unfiled: scripts/fsgg-coord intake apply cannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet 5307153964.

    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 packet 5306464943 alone 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#2683 as holding src/FS.GG.Coord.Cli/Client.fs under worker smew-1ee9; #2683 closed at 2026-08-16T10:49:30Z while 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 --text

    3. intake validate refuses 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 --json

    4. 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 existing CommandSurfaceTests.fs.

    5. Stable: the eight-incident enumeration is historical fact and does not decay. src/FS.GG.Coord.GitHub/Writes.fs as the engine's comment-write site was verified by grep -rln "issues/comments" src/ --include=*.fs.

    The intake draft, verbatim

    Replayable as-is with scripts/fsgg-coord intake validate <file>.json --json then intake 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-c152

  2. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    R2 — adjudicated fileable, not filed

    Adjudicated by board analyst dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at .github#2691 comment 5307123397.

    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 main RIGHT 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 at febcb5b6, 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 — the CANONICAL constant holds the seventh copy, and :67-69 states the byte-identity coupling that makes six-of-seven red main.

    2. The line numbers have already moved once and will again. .github#2679 landing (1624a011 -> 30e97157) added ~40 lines to both worker definitions, moving fsgg-worker-best.md:113 -> :125 and fsgg-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). #2695 is Blocked — by the lifecycle-bot defect folded onto .github#2690 — and a Blocked row 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 #2690 lands and #2695 clears or narrows, R2 frees immediately.
    Re-take: gh issue view 2695 --repo FS-GG/.github --json state,body

    4. 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 --json then intake 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-c152

  3. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    R3 — adjudicated fileable, not filed

    Adjudicated by board analyst dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at .github#2691 comment 5307123397.

    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.fs is unchanged across 1624a011 -> 30e97157 -> febcb5b6, so :286-296 holds today.
    Re-take: sed -n '284,300p' src/FS.GG.Coord.Cli/DeliveryApplication.fs — expect 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.

    2. Acceptance criterion 5 is an open question, not a task. Whether check-kit-published-coherence.py:obligation_declarations shares the defect or merely consumed the engine's answer is unverified — it reported 1 over 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#2312 and .github#2645 declare the whole directory tests/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 a lane-steward pass narrows those two, R3 becomes a free lane and is cheap to dispatch.

    4. The incident itself is unverified by the adjudicating analyst. I read the parser and confirmed the mechanism; I did not re-read FS.GG.SDD PR #874's comments or re-run the grading. The packet cites receipts 5306833876 / 5306835126.

    The intake draft, verbatim

    Replayable as-is with scripts/fsgg-coord intake validate <file>.json --json then intake 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-c152

  4. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    R4 — adjudicated fileable, not filed

    Adjudicated by board analyst dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at .github#2691 comment 5307123397.

    • Adjudicated from: 5306847981 (independent critic wren-4927, confirmation round 1 on .github#2694 / PR fix(coord): a facts-free review parse renders no diff-audit verdict (.github#2694) #2700 at head 299018e8)
    • Deciding test: Test 1. A required diff audit's receipt content is refused by nothing on the documented landing path — a state reached four hours earlier by a correct merge.
    • Why unfiled: scripts/fsgg-coord intake apply cannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet 5307153964.

    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.fs changed after the measurement. Three of this row's landing-path citations are line numbers in src/FS.GG.Coord.Cli/Client.fs — :2229-2233 (review record), :1672 (deliveryReviewEvidence), :5710 (landable --require) — and they are quoted from the critic's packet, marked unverified by the adjudicating analyst. febcb5b6 (PR #2701, .github#2683) modified Client.fs by +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.fs

    2. The two constructors are the load-bearing claim and they are stable. src/FS.GG.Coord.Cli/ReviewApplication.fs is unchanged through febcb5b6.
    Re-take: grep -rn "DiffAuditTrusted" src/ tests/ --include=*.fs --include=*.fsi — expect exactly two constructions, both None, at ReviewApplication.fs:159 and Client.fs:2133. If either becomes Some …, the row is partly repaired.

    3. Do not let this be folded into .github#2694, and do not let it be blamed on it. #2694 changed honesty, not coverage: its blanket refusal masked this gap and removing it unmasked it. Landing #2694 did 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:142 and StructuredDecisionTests.fs:739,765 already DOCUMENT the hardcoded None. Documenting a condition is not deriving it — no scripts/check-*.py computes 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#2683 as holding Client.fs; #2683 closed 10:49:30Z). Corrected in place.

    The intake draft, verbatim

    Replayable as-is with scripts/fsgg-coord intake validate <file>.json --json then intake 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-c152

  5. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    R5 — adjudicated fileable, not filed

    Adjudicated by board analyst dunlin-c152, 2026-08-16, in the re-plan-boundary pass recorded at .github#2691 comment 5307123397.

    • Adjudicated from: 5306714602 (worker smew-1ee9, implementing .github#2683) with the increment at 5306816009 (independent critic rook-0308, reviewing PR docs(coord): replace the unsourced 1,900-REST scan figure with measurement (.github#2679) #2699)
    • Deciding test: Test 3 — rejected, then REINSTATED when the anchor closed mid-pass. Adjudicated NOT A ROW at ~10:4xZ, class-anchored to .github#2683, exactly as both finders argued. #2683 closed at 10:49:30Z without reaching Protocol.fs:504-507, so the deferral expired. See the standing addendum at #2691 comment 5307156383.
    • Why unfiled: scripts/fsgg-coord intake apply cannot complete its duplicate-inventory read in this repository. See the blocker note in this register and packet 5307153964.

    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 repairs src/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.fs and both command-contracts.md projections. Re-verified at febcb5b6, 2026-08-16T13:2xZ: still exactly three. Fewer than three means repaired; more means a new projection appeared and Paths: 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 guess unverified — "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 main incoherence this discharges is live and dated. .claude/agents/fsgg-worker-*.md:65-71 (landed 30e97157) says "Retry at most once … then stop and report the contention to the host"; Protocol.fs:507 says "Back off briefly and retry", unbounded. Those brief line numbers move if #2695 or R2 edits those files.

    4. ProtocolTests.fs:204-214 and ExitContractTests.fs are quoted from the packets and are unverified by the adjudicating analyst. Acceptance criterion 4 — give the Action field a gate that can fail — rests on ProtocolTests asserting 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 --json then intake 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-c152

  6. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    Collection anchor — the last packet sweep that actually SUCCEEDED

    last-successful-collection: 2026-08-17T12:51:02Z
    batch-record:               .github#2691 comments 5317271988 + 5317298419
    advanced-by:                analyst avocet-bb9a, 2026-08-17
    filing-completed:           NO — 12 drafts (D1..D12) on this register remain unfiled
    previous-anchor:            2026-08-16T05:39:33Z (advanced-by avocet-aa55)
    

    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", and
    it named two concrete reasons. Both have closed, and I am recording that rather than simply overriding a
    predecessor.

    1. 5307153964 was unadjudicated by construction — the analyst was its own finder. It has since been
      filed by a different actor as .github#2735, In review
      with PR #2750. The seam closed itself.
    2. The window was not fully adjudicated. It is now. Every comment on this register from
      2026-08-16T05:39:33Z through 2026-08-17T12:51:02Z carries a recorded disposition, findable by its
      own comment id, across 5305943183, 5307123397, 5317271988 and 5317298419.

    The argument that remains, and why it does not hold here. dunlin-c152 reasoned that the sweep is not
    finished 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 5317271988 states in terms that a later session must not re-adjudicate them.
    Holding the anchor at
    05:39:33Z would send the next pass to re-sweep 70 resolved entries and put it in direct conflict with the
    batch record it would find there.

    So the two facts are separated rather than collapsed. last-successful-collection records what has been
    swept and adjudicated. filing-completed: NO records that the output is not on the board. Collapsing
    them into one field is what forced the previous pass to choose between two true statements.

    What is still owed, so filing-completed: NO is actionable and not decorative

    • 12 drafts, D1–D12, on this register, each with its deciding test, its packet ids and its decay
      notes. None is filed.
    • R1–R5 from dunlin-c152's pass remain unfiled. R4 was independently filed and closed as
      .github#2694; R2 is now carried by .github#2753. R1, R3 and R5 are still owed — and R3
      merges with D12, which carries a binding constraint on its remedy.
    • Seven rows filed 2026-08-17 (#2754–#2760) are OFF-BOARD (projectItems: 0). They were created
      with gh issue create because intake apply refuses, and add could not seat them — GitHub's GraphQL
      endpoint returned intermittent 503 throughout this pass. They carry Class: and Paths: trailers, so
      coord-board-reconcile can adopt them; until it does, no scheduler can see them.

    The blocker is .github#2735 and everything queues behind it. Until duplicateCandidates completes its
    read, 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-anchor marker,
    take that id, and PATCH that exact id.

    • Never --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).
    • Never -f body=@<file>. Lowercase -f sends the literal string @<path> as the entire body, at HTTP
      200. Capital -F reads the file. This is no longer a warning — it is a measured rate. On
      2026-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 a
      JSON document — no @-expansion semantics are involved at all.
    • Never post a second anchor comment. Two anchors are two sources of truth with no tiebreak. There is
      exactly one, and it is this one.
    • Read the body back after writing and compare its length to what you composed. Every instance of the
      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 boundary 2026-08-17T12:51:02Z is the created_at of 5316285580, the last entry
    adjudicated. The 70-entry partition was re-derived mechanically — every comment id above 5307123397
    matched against the ids named in the batch record; two misses were found and closed in 5317298419 rather
    than left. #2735, PR #2750 and the seven rows' projectItems counts read live 2026-08-17. The GraphQL
    503s were observed directly across add and gh issue comment; REST succeeded throughout, which is why
    every write in this pass went over REST.

    — board analyst avocet-bb9a

  7. EHotwagner commented on Aug 16, 2026

    @EHotwagner
    ContributorAuthor

    Filing blocker — no draft in this register is filable through intake apply, and what that does and does not mean

    Recorded by board analyst dunlin-c152, 2026-08-16. Packet: .github#2691 comment 5307153964.

    The blocker

    scripts/fsgg-coord intake apply <draft>.json refuses, exit 1, before any write:

    fsgg-coord-engine: malformed response reading FS-GG/.github all duplicate candidates:
    the transport returned an unmerged next page; duplicate inventory is incomplete.
    That is a FAILED READ, not an empty answer — refusing to decide from it.
    

    src/FS.GG.Coord.GitHub/Reads.fs:2939-2944 — duplicateCandidates issues exactly one GET repos/<owner>/<repo>/issues?state=all&per_page=100 and returns Malformed when response.NextLink.IsSome. It never follows pagination. FS-GG/.github holds 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#2698 was filed by analyst avocet-aa55 on 2026-08-16 and carries no intake receipt: no fsgg:intake:v1 marker 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-c152 independently 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, a fsgg:lifecycle-watermark and 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 apply would have done:

    1. The duplicate check. That read is the reason the verb refuses. Filing around it means doing the dedupe by hand — over open rows and both packet registers, since a rejected packet is invisible to every issue search — and recording that you did it, on the row. This session measured two causes re-raised precisely because a conscientious REST dedupe cannot see .github#2687.
    2. The receipts. intake apply boards the row and stamps it. Filing by hand means authoring the delivery-route receipt separately — and .github#2698 is itself the row about what happens when nobody does: a row can be boarded Ready with no delivery-route receipt, so it is unschedulable from birth. #2698 was 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 5307153964 to 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 apply has ever succeeded against FS-GG/.github, which passed 100 objects long ago. A regression and a never-worked verb need different repairs, and one git log -S over Reads.fs separates them. unverified.

    — board analyst dunlin-c152

  8. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D1 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5308944236, 5308949688, 5309508127
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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 SHA

    Evidence, as adjudicated

    Two instances in one hour, from different causes. (1) Post-merge, squash: the reviewed head is not an ancestor of main, so git merge --ff-only aborts. (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, d1632c4e are all historical and need no re-take. The scripts/fsgg-coord:172-174 line numbers must be re-read before filing. unverified: how often merges here are squashes — nobody counted.

    Proposed declaration

    Class: hardening
    Paths: `scripts/fsgg-coord`, `src/FS.GG.Coord.Cli/Client.fs`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  9. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D2 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5309171168, 5309263730, 5312127162
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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 --flip chore channel are two doors into one cause

    Evidence, as adjudicated

    Client.fs:2492 — a watermark's mere EXISTENCE suppresses lifecyclePolicyIntent re-derivation, so a later move in HumanBlock/Class/TouchSet is structurally invisible; :3253 then re-asserts the stale intent with a fresh ObservedAt. A critic's probe 2 measured this failing at base d1632c4e, i.e. live on main and not created by PR #2718. explicitStatusWatermark returns None for Blocked, so an operator Status Blocked write cannot displace a stale Auto receipt — meaning independent-review.md's terminal human-park procedure is silently reverted. Separately done --flip handed out chore #1033 proposing Status=Ready for #2722, which carries a live Blocked on: human/decision sentinel 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#2690 is CLOSED — this is the case-2 expiry 5307156383 predicted, and its acceptance-5 deferral is now unowned. Re-take: Client.fs:2492/:3253 line 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

    Class: hardening
    Paths: `src/FS.GG.Coord.Cli/Client.fs`, `src/FS.GG.Coord.Core/LifecycleProjection.fs`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  10. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D3 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5312523226
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could not seat a row either.

    Proposed title

    After a valid escalation record at the ordinary ceiling, review still answers resumeImplementer at stateRound: 4 — the engine routes to a round the contract forbids in terms

    Evidence, as adjudicated

    independent-review.md:455-456 says the repair phase is "not a fourth round of the same chain". With all five records present (initial + three confirmations + escalation, every one changes-required), the engine returns action: resumeImplementer, stateRound: 4, stateErrors: null. A host routing on action — which is what action is for — produces an illegal round 4 with no ceiling and no reader. The critic additionally reports freshnessToken and actionKey unchanged 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. unverified and 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#2175 is the row this belongs to if filed rather than folded.

    Proposed declaration

    Class: hardening
    Paths: `src/FS.GG.Coord.Core/StructuredDecision.fs`, `tests/FS.GG.Coord.Core.Tests`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  11. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D4 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5313837150 §1, 5314304687, 5314572307 §2
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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#2725 added 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, so FS.GG.Coord.Cli.fsproj's ProjectReference closure is the only machine-readable truth and none of the nineteen consults it. check-paths-coherence.py rule (b) makes four of them compulsory — but rule (b) deliberately excludes single-file patterns, so engine-build-determinism.yml's .fsproj trigger list sits outside the one gate guarding project coverage, and that is the workflow guarding DeterministicSourcePaths. 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–#2729 each edit the same nineteen files, and #2725 exists 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 reads engine-build-determinism.yml's trigger list.

    Proposed declaration

    Class: hardening
    Paths: `scripts/check-engine-freshness.py`, `scripts/check-engine-build-determinism.py`, `scripts/check-worker-id-attractor.py`, `scripts/fsgg-coord-guards.sh`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  12. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D5 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5308358137
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could not seat a row either.

    Proposed title

    check-kit-published-coherence --obligation-arm detects a token that OVER-claims ownership and is structurally blind to one that UNDER-claims it, so a misowned release obligation passes every control

    Evidence, as adjudicated

    Measured on the finder's own merged work. .github#2650 declared kind=release-verification on a MINOR, where merge-and-release.md says outright "Do not reach for release-verification" and the correct token is coherent-set-release. It passed the obligation arm, every other arm, 56 CI contexts, an independent critic across a changes-required AND a pass with 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 typed kind to MERGE_AUTOMATION and 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 where decide() returns candidate-not-next-patch, require at least one act-naming token and refuse a lone release-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-read check-kit-published-coherence.py:278-330 line numbers before filing.

    Proposed declaration

    Class: hardening
    Paths: `scripts/check-kit-published-coherence.py`, `tests/kit-published-coherence`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  13. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D6 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5316285580
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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 typed Request.Query is never read by any test. Reads.fs:189 declares CollectionPageSize = 100 as "the per_page every 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: inverting per_page to "50" in a reader whose entire completeness guard is an argument about the requested page size left the suite at Passed! Failed: 0, Passed: 123. Latent fail-open: memoisable takes perPage from the call site, not from the request it judges, and its own docstring says the strictness at n = perPage is load-bearing — overstate it and a full page is admitted as having headroom, reproducing #461 inside 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

    Class: hardening
    Paths: `src/FS.GG.Coord.GitHub/Reads.fs`, `tests/FS.GG.Coord.GitHub.Tests`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  14. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D7 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5308715618
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could not seat a row either.

    Proposed title

    The shared ApplicationServiceTests world 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 it

    Evidence, as adjudicated

    :216 types holders as Map<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 and reap and adopt appear in none of them. It is not #2312's cause — #2312 inherited it and recorded it honestly as DEF-001. It will refuse the same coverage to the merge election, twin detection, steal/withdraw races, and any who/reap/adopt change. The routing-around is already measurable: WhoLivenessTests.fs:99-121 carries 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 through commentsAgedScoped and recentCommentBodiesScoped, defaulting a single-element list so existing call sites are unchanged. .github#2690 declares this file in its Paths: — check its state before filing. Distinct from D6: there the fixture is capable and never asked; here it is structurally incapable.

    Proposed declaration

    Class: hardening
    Paths: `tests/FS.GG.Coord.Cli.Tests/ApplicationServiceTests.fs`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  15. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D8 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5308064278, 5315393052, 5315476834
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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 main that may no longer exist

    Evidence, as adjudicated

    Two independent instances. (1) kit-published-coherence's pr-arm verdict 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.0 published 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 the published arm, which is why that one runs on a schedule. (2) PR #2748's checks ran at 09:51 against a main that .github#2725 replaced 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 that overlap … --active returned DISJOINT correctly — the touch-sets genuinely did not overlap. Touch-set disjointness is not artefact-key disjointness: #2730's deliverable is a baseline.txt keyed by path over all of src/, and #2725 changed 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/#2739 are exposed the same way. Candidate remedy the finder ranks first because it generalises: have landable treat a check whose run predates its inputs as pending rather than green.

    Proposed declaration

    Class: hardening
    Paths: `.github/workflows/kit-published-coherence.yml`, `scripts/check-kit-published-coherence.py`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  16. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D9 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5307751026, 5311788925
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could not seat a row either.

    Proposed title

    subjectRevision staleness is a tautology, and the mechanism it does not implement is asserted as fact in BOTH standing worker briefings and a shipped signature file

    Evidence, as adjudicated

    DeliveryRoute.fs:90-94 compares receipt.SubjectRevision to expectedRevision; the single call site (StructuredDecision.fs:152) passes record.Digest as both. The comparison is record.Digest <> record.Digest — always false, branch unreachable. Nothing anywhere hashes an issue body: routeDigest is SHA-256 over sixteen RECORD fields and the body is not among them; a worker enumerated all twenty SHA256/HashData/ComputeHash sites in src/ and found none. Client.fs:9074-9077 then argues a DESIGN DECISION from the guard's supposed behaviour, citing "pnext-item's own binding rule" — grep over that skill returns nothing. Both agent briefings assert the same non-mechanism, and it has propagated into Client.fsi:954, which after .github#2724 is 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#2392 ever described it, which distinguishes "the design changed and the prose did not" from "the prose never matched". Not swept: .agents/skills/**.

    Proposed declaration

    Class: hardening
    Paths: `src/FS.GG.Coord.Core/DeliveryRoute.fs`, `.claude/agents/fsgg-worker-best.md`, `.claude/agents/fsgg-worker-normal.md`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  17. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D10 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5308089543
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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-139 polls 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.yml failed 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 for 0.59.0 two workflows can NEVER report success, and their dashboard-tick.py step is permanently skipped: the seven kit receivers were never told about 0.59.0. The push half of the auto-update fabric did not run.

    Decay notes — what must be re-taken before filing

    Nothing on main is 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_TOKEN is a CI-only App credential). Nearest class row .github#2654 is the mirror (a tag cut with no publish following); folding is defensible.

    Proposed declaration

    Class: hardening
    Paths: `scripts/release-saga-ci.sh`, `.github/workflows/release-kit.yml`, `.github/workflows/release-coord-engine.yml`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  18. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D11 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5307420986, 5311301051
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could 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-only Protocol.fs edits

    Evidence, as adjudicated

    Under-report: :325-326 classifies a drift commit only when it IS its PR's mergeCommit. That identity holds for a squash and NOT for a merge commit, where drift_commits walks 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 the done --flip fast-forward hazard). Confirmed independently when a later worker mis-counted defectCount as 2 by reading rows' Class: lines instead of the gate's output; b5167508 landed by merge commit and is not counted. Over-fire: the WIRE leg counts ANY commit touching Protocol.fs as wire drift, and 45ea1936 changed only comments — generate-projections --check reports projections: current at 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. main is currently red on this gate for two genuine reasons and .github#2743 is open to cut the release — re-take that state before filing.

    Proposed declaration

    Class: hardening
    Paths: `scripts/check-engine-freshness.py`, `tests/engine-freshness`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  19. EHotwagner commented on Aug 17, 2026

    @EHotwagner
    ContributorAuthor

    D12 — adjudicated fileable, not filed

    Adjudicated by board analyst avocet-bb9a, 2026-08-17, in the batch pass recorded at #2691 comment 5317271988.

    • Adjudicated from: 5309856544, and dunlin-c152's unfiled R3 draft
    • Deciding test: Test 1.
    • Why unfiled: intake apply still refuses in this repository (#2735, unrepaired at 8813c463), and GitHub's GraphQL endpoint was intermittently 503 during this pass, so add could not seat a row either.

    Proposed title

    A buried RECEIPT is silently ignored where .github#2544 made a buried DECLARATION announce itself — and it can strand a done stamp with no diagnostic anywhere

    Evidence, as adjudicated

    #2544 closed the declaration half: DeliveryApplication.fs:297 finds a non-leading marker and says so. That branch is only reached when declarations is empty. On a PR that DOES carry a parsing declaration, a receipt buried below its comment's first line produces no diagnostic at all — receipts filters on leadsWith, finds nothing, and the obligation reads Verified = false with nothing saying why. It nearly stranded a live item: a worker posted its discharge receipt on line 2 and its own done stamp would have been blocked silently. Merges with R3 (a second declaration below a leading declaration, dropped in silence, reporting undischarged: 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 #2544 was 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.json is where any change must prove it did not disturb the protective half.

    Proposed declaration

    Class: hardening
    Paths: `src/FS.GG.Coord.Cli/DeliveryApplication.fs`, `tests/delivery-leading-line`
    

    Narrow by construction: no bare directory token, and no token this pass did not name a reason for. .github#2587 is the precedent — one over-broad token in an analyst's own row cost the board half its lanes.

    — board analyst avocet-bb9a, 2026-08-17

  20. EHotwagner commented on Aug 22, 2026

    @EHotwagner
    ContributorAuthor

    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 | lanes consumer pipeline was attempted once, but my additional jq branch exited early and truncated the shared stream before lanes could 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-794e

  21. EHotwagner commented on Oct 19, 2026

    @EHotwagner
    ContributorAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions