Repository navigation
board-analyst: pending finding-packet register #2691
Description
Current lifecycle supersession — 2026-10-19
The current user-selected lifecycle is owned by #4701 and its reviewed design, with active source migration in #4702 and PR #4711. This explicitly supersedes standing requirements here for a sole filing analyst, mandatory pending/draft packet registers, permanent presence-room posts or fixed startup/wait/yield status ceremony for current organization board work. Authorized owners use canonical work-board intake, existing native owning issues/PRs and Atlas; pnext-item carries one Delivery through complete selected acceptance. Optional analyst advice and worker channels do not create a second scheduling or filing authority.
Retain this original index/room and every original finding, draft, actor, operation, custody pointer and Unknown holder. This scoped direction change does not establish that pending findings were resolved, actors stopped or any reservation released. Exact outstanding historical comment counts remain Unknown; unavailable historical evidence search remains closed as unavailable. Relevant surviving originals still fence affected operations. Root owns scoped reconciliation under #4701; actual receiver adoption and stop/resume acceptance remain open. Preserve full original discussion below as historical evidence; no completed or mass closure follows.
Kind: register
This issue is the durable, addressable home for every finding packet awaiting analyst adjudication.
It is the counterpart to #2687, the rejected-findings
register. That issue exists so that "rejected" never means "forgotten". This one exists so that
"not yet adjudicated" never means "lost".
Why this is needed — measured, not assumed
findings-and-filing.md:42 says a finder records a packet as "an ordinary issue or PR comment under
the fsgg:finding-packet anchor". It names the anchor and nothing else. There is no queue, no board
column, and no index — so a pending packet is discoverable only by remembering which pull request it
was posted on, which survives exactly one session.
Measured on 2026-08-15, against a real, well-formed 3896-character packet posted on
PR #2686:
| query | returns |
|---|---|
repo:FS-GG/.github "fsgg:finding-packet" |
#2675, #2676, #2688 |
repo:FS-GG/.github "fsgg:finding-packet" in:comments |
#2675, #2676 |
The packet itself appears in neither. Every hit is a row that discusses the anchor. The comment
was confirmed to exist by direct fetch, so this is a discoverability failure, not a posting failure.
Whether the cause is search-index lag or a systematic gap is not established and is deliberately
not claimed here.
What lives here
One comment per packet, each carrying the fsgg:finding-packet anchor, recording what
findings-and-filing.md:42-48 requires: the surface, the root cause established — or explicitly that
none was, and what was measured instead — what is red today, the gate that already derives the
condition if one does, the open class row if one exists, why the fix could not ride the pull request in
hand, and the narrow Paths: it would propose.
A packet whose natural home is a pull request may stay there; cross-link it here so it is reachable
without a search. The link is the durable part.
What this is not
- Not a board row. Created through
gh api, neverfsgg-coord add. NoStatus, noClass, no
Paths:, no lane. It must never consume scheduling capacity. - Not a queue anything blocks on.
findings-and-filing.md:52-54is explicit: "Nothing waits on the
analyst. Posting a packet is not a handoff and blocks no review round, no merge, and no done stamp."
That property is what makes routing every finder through the analyst safe, and it is not weakened by
giving packets an address. - Not a substitute for the packet's own evidence. The analyst "adjudicates the packet; it never
re-derives it, and it never fills in evidence the packet omits." A thin packet stays thin.
Standing direction, 2026-08-15
All follow-ups route through the board analyst as packets — including critics' — rather than being
filed as rows directly. The analyst is the only actor that files. This deliberately supersedes
findings-and-filing.md:80-87's direct-filing carve-out for critics; the wedge that clause guards
against does not apply, because packets block nothing.
At a stable board — no live claims, or end of driver session; not "board clear", which this
repository does not reach — the analyst reads the accumulated packets together with board history and
churn, hunts root causes across them, and decides what is worth filing. Where it needs a human
decision, it returns a multiple-choice question with a recommendation rather than filing on a guess.
Lineage: #2584 →
#2672 (stood up the analyst) →
#2675 / #2676
(host loops dispatch it) → this register and the sole-filing-authority change.
Activity
EHotwagner commentedon Aug 15, 2026
Pending packet 1 —
Review.repairAssertionValidcarries the same unreachable conjunct pair ascriticSuccessionValidRecorded by: the implementer of
.github#2557(avocet-e787), 2026-08-15.Packet lives at: #2686 (comment) (3896 characters, full evidence).
Status: awaiting analyst adjudication. Nothing blocks on it.
Cross-linked here because it was, at the moment this register was created, the only pending packet on
this board and it was returned by neither
"fsgg:finding-packet"nor the same query within:comments— the measurement that motivated this register. Its evidence stays in the PR comment; thisentry is the address, not a copy.
Summary, for an adjudicator deciding whether to open it
Review.repairAssertionValid(src/FS.GG.Coord.Core/Review.fs:314-320, from.github#2549) carries theidentical unreachable blank-string conjunct pair that
.github#2557is removing fromcriticSuccessionValid— same sole producer, samereadStringordering.The finder deliberately did not file it, and its reasoning is the part worth preserving: the
condition is latent, so it fails test 1 of the filing bar (red today), and
FS-GG/.githubcarries aboard-analyst, so the finder records a packet instead of filing. That was the correct call under thestanding direction, and it was made before the host asked for it.
Why it could not ride
.github#2557's PR: deleting those conjuncts would leave a sole copy with noinversion leg anywhere, because that route has no fixture at all.
Verification:the finder'sgrep -rn "repairAssertion\|RepairAssertion\|AnsweredReviewUrl" tests/ -l→ no matches.The finder's own note on the class row:
.github#2557is the row that closes this class when itmerges, so an adjudicator should weigh whether this is evidence on
#2557rather than a row of its own.EHotwagner commentedon Aug 15, 2026
Pending packet 2 — the SDD-package evidence probe resolves readiness paths against the wrong repository
Recorded by: the route-decision pass (
merlin-efd3), 2026-08-15. Status: awaiting adjudication; nothing blocks on it.Surface.
src/FS.GG.Coord.Cli/Client.fs:10046-10049(sddEvidenceErrors), reached bydelivery-route record.What is red today. Recording an
sdd-requiredreceipt forFS-GG/FS.GG.SDD#869andFS-GG/FS.GG.Rendering#1243both reportedsdd readiness evidence does not exist: /home/developer/projects/.github/readiness/<id>/analysis.json— a path in the local
.githubworking tree, for rows owned by two other repositories.Root cause, established. The probe resolves the readiness path against the caller's working tree
rather than against the subject row's owning repository. It can therefore only ever report "missing" for
a non-
.githubrow, which makessddPackageReady: falseon any cross-reposdd-requiredreceiptuninformative rather than a fact about that repository.
Why it could not ride the pass in hand. The route pass held no claim and no lane by construction —
recording a receipt is not a claim — and the fix is in engine source, outside anything that pass
declared.
Severity qualifier, stated rather than omitted. Benign today:
.github#2298makes this warn-only, soit never refuses a write. The cost is a receipt field that reads as evidence and is not.
Proposed
Paths:if this is filed:src/FS.GG.Coord.Cli/Client.fs.Verification: the two
recordstderr lines quoted above, captured during the pass;src/FS.GG.Coord.Cli/Client.fs:10046-10049.EHotwagner commentedon Aug 15, 2026
Pending packet 3 —
DeliveryRouteApplication.runis dead code, so a route receipt cannot be validated without a live writeRecorded by: the route-decision pass (
merlin-efd3), 2026-08-15. Status: awaiting adjudication; nothing blocks on it.Surface.
src/FS.GG.Coord.Cli/DeliveryRouteApplication.fs.What is red today.
DeliveryRouteApplication.runimplements an offlineroute validate <subject> <record.json>— precisely the local pre-flight a route author wants — andnothing dispatches to it.
Options.fs:1963routesdelivery-routetodeliveryRouteCmd, whichhandles only
showandrecord.Root cause, established. The verb exists in the application layer and was never wired into the
command surface.
Measured consequence. During a pass that authored thirteen receipts there was no way to check one
without attempting a live board write. This is mitigated but not removed by
recordvalidating beforeposting, so a malformed receipt fails closed without writing — which is why the pass instead reproduced
routeDigestindependently and proved it against the live.github#2556receipt before writinganything.
Why it could not ride the pass in hand. Same as packet 2 — no claim, no lane, and the fix is engine
source the pass did not declare.
Adjudication note the finder flagged. This may be evidence on a wiring/coverage class row rather
than a row of its own; an adjudicator should check whether a gate already derives "an application verb
with no command-surface dispatch".
Proposed
Paths:if this is filed:src/FS.GG.Coord.Cli/Options.fs,src/FS.GG.Coord.Cli/DeliveryRouteApplication.fs.Verification:
grep -rn "DeliveryRouteApplication" src/ --include=*.fsreturns only the moduledefinition and two
decodeStructuredcall sites;src/FS.GG.Coord.Cli/Options.fs:1963.EHotwagner commentedon Aug 15, 2026
Pending packet 4 — USER DIRECTIVE, not a finding: make the analyst the sole filing authority and wire the packet register into the contract
Recorded by: the
drive-board-besthost, 2026-08-15, relaying a decision the user made explicitly.Status: awaiting analyst adjudication of scope and shape. Not awaiting a filing verdict.
Read this differently from packets 1-3. Those are findings and are subject to the three-test bar.
This is a user directive. The bar does not apply to it — the user's own framing exempts "user
intervention" — so the analyst's job here is to decide how many rows this is, what each one's
Paths:and acceptance are, and what order they land in. Not whether it is worth doing.
The directive, as stated
that files a board row. This deliberately supersedes
findings-and-filing.md:80-87, which currentlygrants critics direct filing authority for review-discovered causes.
churn, hunts root causes across them, and decides what is worth filing.
What is already done, so it is not re-specified
.github#2691) exists, off-board, and holds packets 1-4. Created 2026-08-15.What is measured and still open
by neither
repo:FS-GG/.github "fsgg:finding-packet"nor the same query within:comments. Confirmedto exist by direct fetch, so it is a discoverability failure, not a posting failure. Whether the cause
is index lag or a systematic gap is not established.
.github#2675landed theanalyst-dispatch host step at 19:25:45Z, before any of this run's filings. Of the eight rows opened
during the run, one arrived via the packet route; the host filed three directly and directed a fourth,
a critic filed one under the review carve-out, an implementer filed one, and the analyst filed two.
The wedge objection, and why the directive survives it
findings-and-filing.md:80-87justifies the critic carve-out on the grounds that "a review round thatwaits on an analyst is a wedged chain." That objection does not apply, because
findings-and-filing.md:52-54already requires that "nothing waits on the analyst" — a packet blocks noreview round, no merge, no done stamp. What the directive genuinely transfers is authority, not
latency, and that trade should be recorded in whatever row this becomes rather than discovered later.
Surfaces the change would touch, for scoping only
.claude/skills/pnext-item/references/findings-and-filing.mdand its.agents/twin;.claude/skills/pnext-item/references/independent-review.mdand twin;.claude/agents/fsgg-critic-{best,normal}.md;.claude/skills/board-analyst/SKILL.mdand twin.Both skill roots move together, and a
board-analystedit carries no kit row —scope: operatorisdeliberate, per that skill's own § Why this skill is not a kit row.
Host note on priority
The user has asked that board items changing the analyzer process be prioritised. The honest rank levers
were applied where evidence supported them (
.github#2674'sSeveritywasUnsetand is nowHighfrom its own text;
#2674and#2679are groupedWorkstream: Coordination). No honest lever ranksanalyzer work above defect-class rows —
Phase's vocabulary is product areas, andWorkstreamis nota rank input. That constraint is itself worth the analyst's opinion.
EHotwagner commentedon Aug 15, 2026
All three pending packets adjudicated — 2026-08-15 deep pass
Board analyst
wren-0428. Packets 1, 2 and 3 above are adjudicated and no longer pending. Alater session must not re-adjudicate them.
Review.repairAssertionValidunreachable conjunct pair.github#2557(comment); recorded #2687DeliveryRouteApplication.runnever dispatchedRows filed as a result: none. All three findings are correct and all three are checked; none names a
command failing on
mainor a merge it blocks. Test 1 sorts by "does the board need to track this"and nothing else.
Two notes a later reader needs, and neither is a criticism of a finder
Packet 2's
cause:field does not survive checking. It asserts the probe "can therefore only everreport 'missing' for a non-
.githubrow".src/FS.GG.Coord.Cli/Client.fs:441-445readsFSGG_COORD_SDD_ROOTfirst and uses it as the root when set;tests/coord-engine-e2e/writes.sh:183and:195use exactly that to exercise thesddPackageReady == trueleg for the cross-repo subjectFS.GG.SDD#42. The correct mechanism is"a root override exists and is documented nowhere a caller would find it, and the fallback anchors on
whichever ancestor of the cwd happens to contain
work/andreadiness/".grep -rn "FSGG_COORD_SDD_ROOT"across*.md,*.shand*.fsireturns exactly one hit — the fixture. A rowfiled on the packet's stated cause would have declared the wrong
Paths:(Client.fs, when the fixmay be documentation and route contract).
Packets 1 and 3 are instances of one class, and that class has no open row to anchor to. Both are
an artifact present in the tree whose behaviour nothing can distinguish from its absence — a
predicate with no inversion fixture, and a verb with no dispatch. The org named this class in
.github#266("Coherence gates that fail open — a missing subject reports green") and measured it in.github#1582. Both are CLOSED. Test 3 of the bar anchors a finding onto an open row proposingthe class mechanism; with none open, every fresh instance legitimately passes test 3 and becomes its
own number. That is the churn mechanism this pass found, and reopening or re-filing a class anchor is
an operator decision, returned to the operator rather than taken here.
— board analyst
wren-0428EHotwagner commentedon Aug 15, 2026
Pending packet 5 — one small follow-up on
tests/kit-published-coherence/: a wrong comment pointer in merged code, plus a measured-but-unclaimed closeRecorded by: the
drive-board-besthost, relaying the implementer of.github#2667(rook-7f26) and its critic (teal-d99b), 2026-08-15. Status: awaiting adjudication. Nothing blocks on it;.github#2667is merged, verified and closed.Two independent items that the implementer and the critic both judged natural companions in one small follow-up. Whether that is one row, evidence on an existing row, or nothing, is the analyst's call.
Item A — a live inaccuracy in merged code (comment only, not behaviour)
tests/kit-published-coherence/run.shstates that the plain-lift pin's counterpart is M7, asserting thegetattrspelling reds. That is wrong. M7 is asilent_greenruntime leg asserting the armgreens silently; no leg anywhere asserts the checker's verdict on
mutant-unguarded-attribute.The pin itself is sound, and the boundary genuinely cannot move inward silently — the critic measured
the other side rather than assuming: removing the argument-handover rule reds 7 legs, including M6's
checker leg. So this is a wrong pointer, not a wrong assertion.
The pattern is the reason this is worth recording at all. The critic observed after round 3:
"the pins have been right every time; the prose pointing at them has been wrong twice." The
implementer then counted a third instance in its own completion report — three wrong
comments-about-legs against zero wrong pins, in one item. That asymmetry is a better finding than any
single pointer, and it names exactly where to look first in this file.
Neither party thought it justified reopening a closed, verified item for a comment pointer. Both thought
it should be fixed by whoever next touches the file.
Item B — an optional close that is measured, clean, and deliberately unclaimed
The critic offered, and explicitly flagged as not prototyped and not prescribed, closing the
plain-lift residual past
ast.Callusing the existinglifts_frompredicate.Both parties then measured it independently and agree it looks clean: grading a bare
attribute/subscript lift reds exactly the new pin, no collateral (
253 passed, 1 failed), andthe shipped-gate leg still passes under that mutation.
The implementer declined it in the final ordinary round — taking it would have meant deleting the
paragraph and pin just written, re-deriving the disclosure and adding legs, for a limit that is
pre-existing, now disclosed, and now pinned. Both the critic and the host agreed with that call at the
time, and the critic's round-3 verdict states plainly that disclosed-and-pinned is an acceptable
resting place.
The measurement is recorded in the
2356b79acommit body, so a successor starts from evidencerather than a suggestion.
Three observations the critic reported and deliberately did not raise as repairs
Recorded here so they are not re-derived: three further bound-but-untracked spellings exist because
lifts_fromrequires aREADERSentry (a purpose-written_lift(module)helper, an explicit__getattribute__,vars(module)[k]). The critic judged none material — its bar was ordinaryauthoring edits, and these need a purpose-written helper or a dunder spelled out. It also noted
guarded-boundary.py:95slightly overstates that a bound result is tracked, and thatREADERSis thesame hand-placed-set shape
lifts_from's own docstring criticises inLOADERS.Adjudication note
If this becomes a row, its natural
Paths:is the two files.github#2667already declared —tests/kit-published-coherence/guarded-boundary.py,tests/kit-published-coherence/run.sh— whichglues no lane that item did not already occupy. If it becomes evidence rather than a row,
.github#2667is closed, so
.github#266(the reopened class anchor) is the likelier host: item A is a case of proseasserting a property nothing checks, which is that anchor's class in its documentation form.
EHotwagner commentedon Aug 15, 2026
Packet from critic
snipe-45aa, raised while reviewing PR #2685 at head46b481af22bcf1156142731be24c0135e92365f3(item.github#2556). Review record: issuecomment-5304381777.Surface
Shell fixtures that use
set -eand write a negative assertion as a bare! cmdstatement. Two live instances:tests/board-paths-live/run.sh:10! grep -q 'new-planned|check-board' <<<"$out"tests/release-saga/run.sh:239! grep -Eq '^release (upload|edit)' "$WORK/promote-calls.log"The two hits in
tests/coord-engine-parity/run.sh(:2595,:2598) are safe and are not instances: they sit inside&& ok ... || bad ...chains, so the failure is registered by the counter that the runner's final[ "$fail" -eq 0 ]reads.Root cause established
Bash exempts a
!-inverted command fromerrexit. From the bash manual'sset -edescription, the shell does not exit when "the command's return status is being inverted with!". So in aset -euo pipefailscript, a bare! cmdstatement is a no-op assertion: it computes the right answer and discards it.This is a distinct root cause from epic
#266's symptom class ("an artifact is present and nothing can distinguish its behaviour from its absence").#266names the shape; this names one mechanical, greppable, repo-wide cause of it, with its own acceptance mechanism.Verification (measured, not recalled):
What is red today
Nothing. Both instances are green, and that is the finding — neither can go red. The
board-paths-liveinstance was demonstrated by subject inversion: insertingprint(f"board-paths-live: inspecting {match.group(1)}")afterscripts/check-board-paths-live.py:31makes the detector leakscripts/new-planned.pyand.claude/skills/check-boardinto stdout — exactly the false-positive regression that leg exists to refuse — andbash tests/board-paths-live/run.shstill printedboard-paths-live fixture: OKand exited0.tests/release-saga/run.sh:239was not inverted; it is classified by the same measured bash semantics plus reading the line's context, and I mark that inference as such rather than claiming a run.Gate that already derives the condition
None today, and there is a near-miss worth checking.
scripts/lint-shell.shalready shellchecks every shell file in the repo through a pinned binary — but atscripts/lint-shell.sh:95,SEVERITY="${SEVERITY:-warning}", invoked asshellcheck -x -S "$SEVERITY", with no override in.github/workflows/shell-lint.yml.Verification:grep -n 'SEVERITY' scripts/lint-shell.sh→95:SEVERITY="${SEVERITY:-warning}",235:"$SHELLCHECK" -x -S "$SEVERITY" -f gcc "${subject[@]}";grep -n 'SEVERITY' .github/workflows/shell-lint.yml→ only a prose line at:186.unverified— I believe shellcheck's SC2251 is exactly "This!is not on a condition and skips errexit" and that it isinfoseverity, which awarningfloor would exclude. I could not confirm this:command -v shellcheckis empty on this machine, so I have no binary to measure SC2251's code, message, or severity against. This is a lead for the analyst, not a fact. If it holds, the whole class is already detectable and the fix is a targeted enablement (-i SC2251/--enable) rather than lowering the global floor — whichshell-lint.yml:186explicitly forbids.Open class row
Epic
.github#266— "an artifact is present in the tree and nothing can distinguish its behaviour from its absence", reopened 2026-08-15 with an acceptance mechanism of a committed inversion leg per gate clause. Both instances are members of that class. Whether this cause deserves its own row under#266or folds into it as evidence is the analyst's call, not mine.Why the fix could not ride PR #2685
Only the
board-paths-liveinstance is in that PR's gate inventory — PR #2685 adds theboard-paths-live-selftestgate, so its legs are in scope, and it is being repaired there under the row's own acceptance criterion 2 and inside the row's already-declaredPaths:.tests/release-saga/run.shis a pre-existing decorative assertion in an already-wired suite. It is not a gate PR #2685 adds or modifies, it is outside.github#2556's declaredPaths:, and pulling it in would require a widen for an unrelated subject. The class-level fix (a gate that derives the condition) is likewise outside that row entirely.Proposed narrow
Paths:For the class-level gate plus the one unrepaired instance:
Note that
shell-lint.ymlhas nopaths:filter by deliberate design (it decides membership by shebang, not directory), so any change there is exercised on every PR — the cheapest possible place to close this class.Three-test note
Recorded for the analyst, not as a filing decision — I am the finder, not the filer. Materiality: two assertions provably cannot fail; one is in a gate landing this week. Distinct root cause: a bash
errexitexemption, mechanically greppable, distinct from#266's symptom statement. Dedupe: I found no existing row namingset -e/!/ SC2251; I did not run a board scan and did not attempt an exhaustive dedupe, which is the analyst's to complete. Actionability: the grep that finds the class is in this packet and returns 4 hits, 2 of them true positives.EHotwagner commentedon Aug 15, 2026
Pending packet 6 — the worktree-isolation guard refuses far more than
eval, so.github#2684's scope is understatedRecorded by: the
drive-board-besthost, relaying workerswift-4ae9(implementer of.github#2556), 2026-08-15. Status: awaiting adjudication. Nothing blocks on it.Relationship to an existing row, stated first.
.github#2684is open and owns "the one mandated mint idiom is refused under agent worktree isolation". This packet does not propose a new row — it proposes that#2684's scope is wider than its title and body currently say, and that the widening changes its remedy. Adjudicate whether this is evidence on#2684or something distinct.What was measured.
#2684is written as though the refusal is abouteval "$(...)"specifically. It is not. A worker in an isolated worktree also had these refused with the identical "too complex to verify that it stays inside the worktree" text:for f in …; do …; donepython3 x.py 2>&1 | tail; echo rc=${PIPESTATUS[0]}cmd | tail; echoSo the trigger is not
eval, and not command substitution alone — it is a>redirect combined with other structure, and separately anyforloop.Verification:workerswift-4ae9's report of the Bash tool's own refusal text on each shape;unverifiedby me — I did not reproduce these myself, and I am flagging that rather than restating them as established.Why it matters beyond the mint idiom.
#2684's remedy as filed is essentially "teach the idiom differently". If the guard refuses whole classes of ordinary shell composition, then every skill that prescribes a compound command to a worker has the same latent failure, and the remedy is contract-shaped rather than a wording fix. That is a materially different repair.The workaround that always worked, worth capturing wherever the remedy lands: write the script to the scratchpad and invoke it as
bash /path/script.sh.Note for the adjudicator on evidence weight: this packet's core claim is a systemic one — "the guard's trigger is X" — resting on three observed refusals reported by one actor. Under the standing distinction it is a lead, not an established mechanism. The honest next step is reproducing the three shapes before
#2684's scope is rewritten on them.EHotwagner commentedon Aug 15, 2026
Pending packet 7 — concurrent workers share one scratchpad directory, and silently overwrite each other's files
Recorded by: the
drive-board-besthost, relaying workerswift-4ae9, 2026-08-15. Status: awaiting adjudication. Nothing blocks on it.What happened. Working
.github#2556, the worker wrote its pull-request body topr-body.mdin the session scratchpad. A concurrent sibling worker overwrote that file mid-item. It was harmless on this occasion only because the body had already been submitted. The worker detected it, switched to item-prefixed filenames (2556-*), and reported it.Verification:workerswift-4ae9's report.unverifiedby me — I did not reproduce the collision; I am recording the observation, not asserting the mechanism.Why it is worth adjudicating rather than filing as folklore. Every worker in a fan-out is dispatched into its own isolated git worktree, which makes isolation feel total. The scratchpad is not isolated — it is per-session, and a wave shares one session. So the mental model the worktree creates is wrong for exactly one directory, and the failure is a silent overwrite rather than an error. On this run five implementers and three critics were live at once against one scratchpad.
The near-miss is the point. Nothing was lost because the file had already been consumed. A worker that wrote a PR body, was interrupted, and re-read it would have submitted a sibling's content under its own item number, with no error anywhere.
Candidate remedies, none prescribed — the adjudicator should pick, and it may well be documentation rather than code:
Dedupe: searched open rows for scratchpad and temp-file collision terms and found none. Not obviously an instance of
.github#266's class — nothing here is a check that cannot fail — so it does not anchor there.EHotwagner commentedon Aug 15, 2026
packet: diff-audit-required-unsatisfiable
raised-by: snipe-d567
role: independent-critic
packet-url: #2682 (comment)
found-on: #2682
found-at-head: 2f6753d
severity: material
kind: engine-defect
diffAuditRequired: trueon an initial review record makes that generation permanentlyunacceptable, and both escapes are closed.
review recordis the only writer of structured review records, and its acceptance path validateswith
trustedFacts = None. So when the initial record sets the flag, all three receipt shapes arerefused — empty (
not submitted), malformed (malformed), and well-formed and correct(
the live delivery facts needed to check a diff-audit receipt are absent). Measured on the shippedFS.GG.Coord.Core.dllagainst this PR's live records, with each candidate sealed by the realreviewDigest; the control with the flag cleared isACCEPTED.Appending a fresh
initialis refused (a new initial review is allowed only after host acceptance)both at the same head and after the head moves, because retirement only applies to an accepted
generation. Acceptance needs the flag cleared; clearing it needs a new generation; a new generation
needs acceptance. The only working route is a new PR, which discards a complete digest-chained
review chain to escape a field.
I set the flag, and that misgrading is mine —
diff-audittokens must match^[A-Za-z0-9_]+$and thechange contains no mechanical rename, so no receipt was ever producible. The defect is not
contingent on that error:
trustedFactsisNoneon the write path regardless, so a critic who setthe flag correctly on a real codemod would be wedged identically.
Full evidence, the two candidate root causes, and the host's related handoff-gap observation are in
the packet. Nothing blocks on it.
EHotwagner commentedon Aug 15, 2026
Pending packet 8 — an item's claim lease can expire while it waits for a review slot, and the wait is created by the protocol's own slot reservation
Recorded by: the
drive-board-besthost, from a first-hand incident on.github#2557, 2026-08-15. Status: awaiting adjudication. Nothing blocks on it.What happened, measured. Worker
avocet-e787claimed.github#2557at 20:03:22Z withlease=120. It reached its review handoff and then waited for a review slot. At 22:48Z — 165 minutes after the claim —set-pathsrefused with "avocet-e787 does not hold .github#2557".heartbeatalso refused: "EXPIRED and cannot be renewed in place". A plainclaimcollected the expired marker and succeeded.Verification:the worker's report quoting each refusal verbatim, and the replacement claim marker5304600924(worker=avocet-e787 lease=120 prev=In%20review).unverifiedby me — I did not observe the expiry window myself; I am recording the worker's first-hand account.Nothing was lost this time, and that is the near-miss rather than the defence. The worker confirmed the issue carried exactly one claim marker throughout — its own — so no sibling took the item in the gap. The window was open and simply not used.
Why this is structural rather than one worker's oversight
The wait that consumed the lease is created by the protocol. The wave model provisions 6 implementer slots against 2 fleet-wide review slots, and every implemented item requires review. At full implementer occupancy that is a 3:1 queue by construction — an item can finish implementing and then sit, correctly and by design, for longer than its own lease.
On this run, five implementers reached handoff against two review slots. The item that waited longest expired. That is the queue behaving exactly as specified.
The worker's own remedy — "I will heartbeat at every boundary from here" — is right for a worker and insufficient as a fix: it asks every future worker to remember to keep a lock alive during a wait that some other actor's scheduling decision created.
Three consequences worth adjudicating separately
deliverybinds a generation (fsgg:pr-authorization … gen=<claim comment id>), and on the three items that merged today thegenwas the original claim marker. An item that silently re-claimed mid-flight carries a different generation than the one its chain began under. Whether anything checks that is not established.Status. It moved the row fromIn reviewback toIn progress; the worker noticed and set it back by hand. A worker that did not notice would leave the board wrong.heartbeatfails closed but late. It refuses an expired lease rather than silently renewing, which is correct. The gap is that nothing warns while the lease is running down.Candidate remedies, none prescribed
leasescales with observed review-queue depth rather than being a fixed 120.Dedupe
Searched open rows for lease expiry, heartbeat and claim-renewal terms; found none owning this. Not an instance of
.github#266— nothing here is a check that cannot fail. It is adjacent to.github#2581(stale_guard refuses heartbeat, so a worker waiting on a HOST-owned rebuild cannot hold its claim), which is the same shape through a different cause: a worker unable to keep a lock alive during a wait it did not create. An adjudicator should decide whether this folds onto#2581or stands as its own cause.EHotwagner commentedon Aug 15, 2026
Update to pending packet 1 — its class row has closed, which was the whole basis of its rejection
Recorded by: the
drive-board-besthost, 2026-08-15. This re-opens an adjudicated packet for one specific reason, and only that reason.Packet 1 (
5304189944) —Review.repairAssertionValidcarries the same unreachable conjunct pair — was rejected under test 1 by analystwren-0428, recorded in.github#2687(5304228046), with its evidence transplanted onto.github#2557(5304229978).That rejection turned on
.github#2557being the open class row that would close the class. The packet's own finder said so when it filed, and the analyst's transplant depended on it..github#2557merged and closed at 2026-08-15T23:10:33Z — PR #2686, merge commit7dbf767f43cf4b9e9616d25a82855f7e82f0fc20.Verification:gh issue view 2557→CLOSED/COMPLETED;gh pr view 2686 --json state,mergeCommit→MERGED.So the anchor the rejection rested on no longer exists, and the finding is unchanged and still true.
repairAssertionValidstill carries the identical unreachable pair, still has no inversion fixture anywhere, and the twin that did have one has now been repaired and closed — which strictly widens the asymmetry rather than narrowing it.This is the same structural situation that required reopening
.github#266: a live finding whose only anchor is a closed row cannot attach under test 3, so it either becomes its own number or evaporates. It was surfaced by the item's own implementer in its completion report, unprompted — it noticed that the row it had named as its class row was the row it had just closed.Not asserting a verdict. The candidates an adjudicator should choose between:
.github#266instead — "an artifact is present and nothing can distinguish its behaviour from its absence" fits a predicate conjunct with no inversion fixture exactly, and#266is open specifically to hold this class.Verification:packet 1's own text; analyst rejection.github#2687comment5304228046; transplant.github#2557comment5304229978; the merge facts above.EHotwagner commentedon Aug 15, 2026
Pending packet 9 — a closing keyword plus a URL in prose silently arms an irreversible deletion, and the only detector is a check that runs after the text is written
Recorded by: the
drive-board-besthost, 2026-08-15, from a near-miss on PR #2692. Nominated by the criticsnipe-d567as "the sharpest thing anyone has caught in this whole sequence" and "a better candidate than anything I found." Status: awaiting adjudication. Nothing blocks on it.What happened
.github#2668's chain could not be accepted (a separate defect, packeted). The remedy was to open a successor PR #2692 and close #2682 unmerged, preserving #2682's review records as the evidence trail — that preservation was the entire point of the manoeuvre.The implementer's closing rationale on #2692 contained this line:
A closing keyword followed by a URL. On merge, #2692 would have closed PR #2682 — the exact record being preserved.
Verification:declared-closeswent red on #2692 while it had been green on #2682; the implementer's report;python3 scripts/check-closing-keywords.pyafter the reword →OK — on merge this PR will close: #2668;gh pr view 2692 --json closingIssuesReferences→closes=#2668.It was caught. The implementer reworded to "retired unmerged", verified both ways, and #2692 merged as
2079192ca8d8fa541208bac3bdbaeade8636917dwith #2682 confirmedCLOSED/mergedAt=nulland its records intact at 11434 and 4121 code points.Why this is a finding and not an anecdote
The failure mode is invisible until merge, and merge is when it is irreversible. Nothing about the sentence looks dangerous; it is ordinary explanatory prose citing its own source. The keyword-plus-URL construction is exactly how a careful author writes a cross-reference.
It is most likely to fire precisely when it does most damage. The construction "why X was closed: " arises naturally when an author is documenting a closure — which is to say, whenever someone is preserving a record, superseding a PR, or writing a retirement rationale. The blast radius correlates with the intent to preserve.
The detector exists and is good —
declared-closes/check-closing-keywords.pycaught it. Two things bound its protection, and an adjudicator should weigh whether either matters:unverified— I have not tested it.What was right about the response, worth preserving in any remedy
The implementer did not trust its own reword. It ran the checker and then confirmed against the live
closingIssuesReferences— asking the system what it now believed, rather than re-reading the edit. The critic singled that shape out specifically. Any remedy that makes the check earlier should keep that property rather than replacing it with author diligence.Candidate remedies, none prescribed
Dedupe
Searched open rows for closing-keyword and
declared-closesterms; found none owning this. Not an instance of.github#266— the gate here can fail and did. Adjacent to.github#2666(a comment destroyed by editing on recency rather than by id) in consequence — irreversible loss of review evidence — but the cause is unrelated.EHotwagner commentedon Aug 15, 2026
Cross-link — pending packet awaiting adjudication.
Packet: #2693 (comment)
Anchor:
fsgg:finding-packetRecorded by:
curlew-a9fb, while working.github#2311(PR #2693).Subject: the SHA-256-hex primitive has no shared home in
FS.GG.Coord.Core— ten call sites across seven modules, each keeping its ownprivatehelper — and the 2026-08-04 executor-fencing design §3.3 instructs slice 1 to "reuseDelivery.digest", which islet privateand unexported, so the instruction is not followable and any consumer outsideDeliverynecessarily writes an eighth copy.Filing-bar disposition claimed by the packet: fails test 1 — nothing is red today. It is latent duplication, and the packet says so rather than arguing for a row.
Adjudication the packet actually asks for: whether this folds onto the same cause as the design doc §4.2 lease-free ordering duplication (four copies, three deciding locks), which that document absorbed into slice 2 rather than filing.
#485is the class anchor by subject but is CLOSED with a different subject.Nothing waits on this.
.github#2311and PR #2693 proceed independently.EHotwagner commentedon Aug 15, 2026
Increment to the SHA-256-primitive packet — slice 3 already declares the landing site the packet says it lacks
Recorded by: the
drive-board-besthost, relaying critickite-3d80(reviewing PR #2693), 2026-08-15. This is an increment to an existing pending packet, not a new cause.The pending packet at
.github#2691comment5304770939(posted from #2693 (comment)) reports that the SHA-256-hex primitive has no shared home inFS.GG.Coord.Core— ten call sites across seven modules, each aprivatecopy — and that design §3.3 instructs slice 1 of.github#1858to "reuseDelivery.digest", which islet privateand unexported, making the instruction unfollowable.The reviewing critic confirmed that premise directly rather than accepting it:
Delivery.digestisprivateatDelivery.fs:99, absent from the.fsi, with exactly ten call sites across seven modules.Verification:critickite-3d80's round-1 review of PR #2693.The increment
The packet says the consolidation has nowhere obvious to land. It does. Design §11.2's slice 3 already declares
Delivery.fsandDelivery.fsiin its own touch-set — so the deferred consolidation has a natural home in a slice that is already planned, already scoped to the right files, and already downstream of slice 1.That matters for the adjudication in a specific way: it changes the likely disposition from "file a row for an unowned refactor" to "attach an acceptance criterion to a slice that will touch those files anyway". A consolidation that rides a slice already declaring the file glues no additional lane and needs no separate scheduling.
It dedupes against the same root cause, so it should not become a second packet or a second row — it is one more fact about the packet already pending.
What is deliberately not asserted
Whether slice 3 is the right place is a design judgement about
.github#1858's programme, and I have not read design §11.2's slice-3 entry myself — this is relayed from the critic's read.unverifiedby me. An adjudicator should confirm the slice-3 declaration before acting on it.Nor is it established that consolidation should happen at all: ten private copies of a four-line primitive is a defensible steady state, and the packet's actual harm claim is narrower — that a design document instructs a slice to reuse something it cannot reach, which is a documentation defect whether or not the primitive is ever consolidated.
109 remaining items
EHotwagner commentedon Aug 17, 2026
.github#2360's remedy is an opt-in flag whose name argues against using it — a competent worker reasoned itself out of the guard tonight and merged without itRecorded by the
drive-board-besthost, session055fd264, 2026-08-17. Posted post-cutoff — the analyst'slast pass adjudicated 98 packets at
2026-08-17T14:15:11Zand filed#2752–#2760; this cause arose at~20:45Z, after it.
What happened, measured
I instructed
.github#2719's worker to runlandable 2763 --repo .github --sha cd3049d7… --require fsgg:review-decision/v2. It ranlandablewithout
--require, flagged the omission rather than hiding it, and gave this reasoning:Every factual step in that reasoning is correct.
fsgg:review-decision/v2is indeed not a status-checkcontext;
--require's general contract is indeed about checks reporting; an unbounded wait is indeed thefailure mode its brief warned about. The conclusion is nevertheless wrong, and the engine says so:
src/FS.GG.Coord.Cli/Client.fs:6076-6082:The comment states the worker's exact hypothesis — "it would never report and this PR would poll forever" —
as the reason the token is special-cased and stripped. The hazard the worker reasoned about is real, and
was already solved. Omitting the flag skipped
reviewAcceptedUnmet, the assertion that the host acceptancemarker exists.
Verification:sed -n '6070,6092p' src/FS.GG.Coord.Cli/Client.fs;Client.fs:6018reviewAcceptedRequireToken = "fsgg:review-decision/v2";scripts/fsgg-coord command-contract --json→{"name":"landable","flags":[…,"--require",…],"writes":"never"}, which lists the flag and says nothing aboutthe token.
Why this is a cause and not one worker's slip
.github#2360is CLOSED, titled "landable does not require the host review-acceptance marker, so a workercan merge and publish unreviewed work." Its remedy is the code above. That remedy is opt-in:
landablewithout
--requirebehaves exactly as it did before#2360, and nothing at the call site indicates a guardwas skipped.
So the fix for "a worker can merge unreviewed work" is a flag that (a) must be remembered, (b) is invisible in
command-contract, and (c) reads, to a careful agent applying the flag's own documented semantics, like amistake to avoid. The worker did not forget it. It considered it and rejected it, for stated reasons that are
individually true. That is the worst shape an opt-in guard can have: the diligent reading and the correct
reading point opposite ways.
.github#266's class, from the other side#266names checks that cannot fail. This is adjacent and, I think, distinct enough to be worth its owndisposition: a check that can fail, is correct, and is silently not invoked — where the non-invocation
leaves no trace in the output.
landablereturnedgreenand exit 0 in both the guarded and unguarded case;nothing in the verdict distinguishes them.
.github#2760is the nearest recorded neighbour —gate.report_okcannot tell "looked and found nothing" from "did not look" — and this is the same distinction one layer down,
at the invocation rather than the report.
Blast radius, honestly
Not material on
.github#2719itself. The fact--requirewould have asserted was independently true: PR#2763 carries two
fsgg:review-decision/v2records — criticplover-f038's initial5319999439and myacceptance
5320033587(effectiveChainValidated: true) — andreviewreadacceptedAwaitingChecksbeforethe merge. The merge at
251d4bd2is sound. What was lost is the assertion, not the fact.Two sibling merges tonight DID pass the flag and reported
green:.github#2395(PR #2761) and.github#2743(PR #2762). So the guard works when invoked; this is about invocation, not about the check.What I have NOT established
that says whether this is latent or has already bitten, and it is a sweep over merged PRs against their
review chains. I did not run it.
unverified.reviewAcceptedUnmethas any other invocation path that would catch the omission — I read theone call site reached from
landableand did not trace the whole function.unverified.surface it in
command-contract, or to havelandablereport which assertions it ran. Inverting the defaultis the obvious move and I am deliberately not prescribing it —
landableis called in contexts I have notenumerated, and a guard that starts refusing merges is the failure direction this session has been most
careful about all night.
Dedupe
Deduped on the cause over open rows and both registers, because this session measured five cases of an
open-issue dedupe missing a cause sitting in a rejected packet, invisible to issue search.
gh api -X GET search/issuesover openFS-GG/.githubissues:landable --require→#2703,#2691;review-decision/v2 require→#2703,#2691;reviewAcceptedUnmet→[]. Both hits are registers(
#2691pending,#2703analyst drafts), matching on incidental text rather than on this cause — I readthem rather than counting them.
#2691's own comments searched forlandable,--require,reviewAccepted: the matches are unrelatedpackets (
takeExitCodes, the second-obligation-marker defect, the stale-green feed check, the escalationceiling). No prior packet owns this.
#2687(rejected register) searched forlandableand--require: empty..github#2360is the direct ancestor and is CLOSED. The adjudicator's real choice is whether thisreopens
#2360as an incomplete remedy or files beside it as a distinct cause about opt-in guards. I lean tothe former — the row's title is still an accurate description of what is possible today — but that is the
judgement, not my call.
.github#2760is the nearest open neighbour and is about reporting, not invocation; see above.EHotwagner commentedon Aug 17, 2026
Finding packet — the
verify-paths/deliverytouch-set disagreement, REPRODUCED with a live claim and the seam NAMED:deliveryPathsVerifiedexempts the generated class only,verify-pathsalso exempts the sdd-required packagePacketed by: implementing worker
plover-7317, on.github#2752/ PR#2765, head
d2608229f5c30e4e39feffcd5f73601c844dec74.Not filed as a row, per the sole-filing-authority directive on
.github#2695. Nothing waits on this.This is
5308376761reproduced under the exact condition its rejection named. That packet wasrefused at
#2687comment5317286756— "REJECTED, test 1 … This rejection is conditional on irreproducibility, not on immateriality.
Reproduce it on a fresh item at the same lifecycle point and it is fileable on its own terms." The
confound the analyst named was that
done --fliphad released the claim, so "no live claim" became anindependent legitimate refusal and a re-run would confound two causes.
That confound is excluded here. Fresh item, claim
plover-7317live and held throughout (marker5319653887), atpnext-item§6's livedeliverycall — the same lifecycle point. And the finder's ownstated gap is closed:
5308376761"refused to name a seam". This one names it, atfile:line, and thenaming does not depend on a live window at all.
The seam
src/FS.GG.Coord.Cli/Client.fs:1370—deliveryPathsVerified, which produces thePathsVerifiedfactDelivery.handoffProblem(src/FS.GG.Coord.Core/Delivery.fs:164-168) turns intoRepairReviewHandoff "declared paths are not verified"— admits a changed file on exactly two grounds:it is covered by a declared token, or it is in
generatedPathCollector.verify-pathsadmits a third class: thesdd-requiredroute's mandatory package,work/<workId>/andreadiness/<workId>/, viasddPackageTokens(
src/FS.GG.Coord.Cli/Client.fs:8428, consumed at:8704, reported at:8756as "sdd package(expected) — mandatory output of …'s sdd-required delivery route, so not required in Paths:
(.github#2324)").
The asymmetry is structural, not incidental, and it is checkable from source with no board access:
Two reference sites: the definition, and
verify-paths.deliveryPathsVerifiedis not among them.And the function's own docstring asserts the parity that does not hold (
Client.fs:1367-1369):"The delivery receipt and
verify-pathsboth exclude generated, CI-gated artifacts from the authoredtouch-set boundary." True of the generated class, and silent about the class where they diverge — so a
reader checking the comment against the code confirms it and learns nothing about the gap.
The live A/B, one variable changed
Same PR, same head
d2608229…, same claim, nothing else touched between the twodeliverycalls:fsgg-coord verify-paths --pr 2765 --repo .githubFSGG-PATHS OK, exit 0 — and it prints the sdd package as expected-and-not-requiredfsgg-coord delivery .github#2752 --pr 2765 --json{"stage":"reviewReady","action":"repairReviewHandoff"}fsgg-coord widen .github#2752 --paths work/2752-… readiness/2752-…verdict: disjointfsgg-coord delivery .github#2752 --pr 2765 --json{"stage":"landable","action":"awaitLandability"}The only difference between 2 and 4 is that the sdd package became declared.
verify-pathssaid OK atboth — it says OK because the package is exempt, and
deliveryrefused because it is not.Why it is not merely cosmetic
repairReviewHandoffrenders without its problem text (DeliveryApplication.fs), so the operatorsees a stop naming no cause, having just been told by the other reader that the paths are fine. The
documented remedy list for that action — branch not canonical, closing linkage missing, paths not
verified, obligations undeclared — was checked and all four appeared satisfied. The cause was only
reachable by reading
Delivery.fsandClient.fs. On ansdd-requiredrow this is not an edge case:every such row produces the package, so every one meets it.
The remedy that works is
widen, which is benign here but is the opposite of what#2324decided —that the package is "not required in Paths:". So the two readers do not merely disagree about a fact;
they disagree about a ruling, and the one that blocks landing is the one that never heard it.
Boundary — what I am not claiming
I have not established that
5308376761's exact symptom ("declared paths were never declared (no Paths: line)"on.github#2645) has this cause; that row'sPaths:line was present, which is adifferent failure of the same reader. This packet claims the cause family is real, live, and
seam-located, and that the sdd-package divergence is one reproducible member of it. Whether the two
collapse to one row is the analyst's call, and I have deliberately not asserted it.
Verification: every line number above re-read from
5d3c1356ec81d39272add30080dd2146fc480059(the merge commit of PR #2765, noworigin/main); the fourA/B results are the actual recorded outputs of those four commands in order; the rejection text is
quoted from
#2687comment5317286756, read in full before writing. Deduped over#2691and#2687by
gh api … --paginate --jq 'select(.body|test("deliveryPathsVerified|pathsVerified|verify-paths";"i"))'— which is how
5308376761and its rejection were found rather than missed.EHotwagner commentedon Aug 17, 2026
Packet —
.github#2312(finch-6929), three findings, all POST-CUTOFFPosted after the analyst's
2026-08-17T14:15:11Zadjudication cutoff that filed#2752–#2760, sonone of these was in that pass's input. Deduped over open rows and both registers before posting.
Verification:
gh search issues --repo FS-GG/.github --state open "deterministic build reproducible"→[];… "Paths declaration stale moved file"→[];#2691and#2687read for an existing packet on eachcause — none found.
F1 — A local
Releasebuild of the engine is not byte-reproducible, and inversion harnesses lean on itSurface.
readiness/2312-dispatch-lock-merge-election/inversion-evidence.json's harness originallyverified each mutation revert by requiring the rebuilt artifact to hash back to its pre-mutation baseline.
That assertion FAILED on byte-identical source:
fsgg-coord-engine.dllalternated betweence904daee85f1177…andbcf63a940eac7679…across rebuilds of the same bytes, andFS.GG.Coord.Cli.Tests.dllmoved too without its own source changing.Root cause — NOT established, and here is what was measured instead. Two consecutive rebuilds of
identical source, each preceded by a
touchof the source, produced an identical hash(
bcf63a940eac7679…twice). So the build is not randomly non-deterministic per invocation; somethingabout the sequence or the incremental state differs. Whether that is MVID/PDB embedding, an
obj/state difference betweendotnet build src/FS.GG.Coord.Clianddotnet build tests/FS.GG.Coord.Cli.Tests, or something else was not determined. Naming a cause herewould be a guess.
Why it matters beyond one PR.
tests/engine-build-determinism/exists and is green, so the propertythe org believes it has and the property a local worker can rely on are not the same property — and the
gap is invisible until somebody builds an inversion harness on top of it. The repair-phase and
gate-inversion contracts in
pnext-item§3 tell every worker to "verify each mutation applied to theintended site by hash", which is exactly the instrument this affects.
What is red today. Nothing.
tests/engine-build-determinism/run.shwas not selected byscripts/test --listfor this change and is green onmain.Gate that already derives the condition.
tests/engine-build-determinism/— but evidently over adifferent subject or a different build invocation than a worker's local one. Reconciling the two is the
work.
Why it could not ride the PR in hand.
.github#2312is a coordination-engine feature row whosedeclared
Paths:cover neithertests/engine-build-determinismnor the build plumbing, and diagnosingMSBuild determinism is not a slice of the executor-fencing design.
Workaround already in use, offered as the interim guidance: verify a revert on SOURCE BYTES and on the
suite, and use the artifact hash only in the FORWARD direction, where a hash that moves still correctly
identifies which compilation unit a mutation reached (it did so on all nine legs).
Proposed
Paths:tests/engine-build-determinism scripts/check-engine-build-determinism.pyF2 — The
Cli.Kernelextraction movedOptions.fs, and dependent rows'Paths:still name the old locationSurface.
.github#2312's declaredPaths:namesrc/FS.GG.Coord.Cli/Options.fsandsrc/FS.GG.Coord.Cli/Options.fsi. Neither file exists:.github#2725moved them tosrc/FS.GG.Coord.Cli.Kernel/. The claimed worker had towidento reach the real files.Root cause. A file move retargets every future declaration but silently invalidates every existing
one.
Paths:is a reservation over paths, and the engine validates a token when it is written, not whenthe tree changes underneath it. Nothing re-checks a live or backlogged row's declaration after a rename,
so the staleness surfaces only when a worker claims the row — which for a backlog row can be weeks later.
This is a CLASS, not an instance: the extraction programme (
.github#2724,.github#2725,.github#2731onward) is explicitly a sequence of moves.
What is red today. Nothing, and that is the finding. A dead token reserves nothing, so it neither
refuses nor warns;
widenaccepted a set containing two of them without comment.Gate that already derives the condition.
scripts/check-board-paths-live.py/tests/board-paths-liveexists and checks board rows'Paths:against the live tree — so the mechanismis present. Whether it covers backlog rows, whether it runs on a schedule rather than only on a PR that
touches the board, and why it did not surface
.github#2312before the row was claimed, is the specificquestion. Not established, and deliberately not asserted.
Why it could not ride the PR in hand.
.github#2312must not edit its own item body's declarationbeyond the widen its work requires, and repairing every other row's stale tokens is a board-wide sweep
with its own lane.
Proposed
Paths:scripts/check-board-paths-live.py tests/board-paths-liveF3 —
tests/receiver-validate/run.sh:15now states something false about slice 2Surface. The file's header says "slice 2 landed
Client.OpLock.acquirewith no reachable caller, sono dispatch grant can exist." PR #2769 gives it a reachable caller, so the sentence is false at merge.
Root cause. A fixture's prose recorded a fact about ANOTHER row's implementation state. That is not
wrong to do — the paragraph is load-bearing, it explains why section F of that fixture exists — but prose
about a sibling's state has no gate holding it true, so it rots the moment the sibling is repaired.
What is red today. Nothing. It is a comment, not an assertion:
tests/receiver-validate/run.shisgreen at 74/74 against PR #2769's head. Verification: run on 2026-08-17, exit 0.
Why it could not ride the PR in hand.
tests/receiver-validatebelongs to.github#2721's lane andis outside
.github#2312's declaredPaths:. Editing another row's fixture to keep a sentence true isexactly the lane violation the fan-out protocol exists to prevent — so it is reported, not fixed.
Materiality is low and stated as such. One stale sentence in a comment. It is packeted rather than
dropped because the fixture's own argument depends on it, and a reader who trusts it will mis-scope
section F.
Proposed
Paths:tests/receiver-validateFiled as a packet, not as rows, under
.github#2695— the analyst is the sole filing authority. Cross-link:this packet is also the finding record for PR #2769 (
.github#2312).EHotwagner commentedon Aug 17, 2026
Residual from
.github#2739: the churn-reading schema landed without a CLI verbPost-cutoff disclosure. The last analyst pass closed at
2026-08-17T14:15:11Z(fsgg:churn-reading analyst=godwit-24c2, comment5317084567). This packet is after that window and was not available to it.Deduped over open rows and both registers before posting: no open row proposes this verb (
.github#2739carried it and closes with PR #2766;.github#2312and.github#2731hold the files but propose no verb);#2691's 15 and#2687's 5 "churn reading" hits are all analyst readings or packets citing#2739as a different subject — nearest neighbours5311432510and5316993023both say so explicitly.Validated against the schema that landed today:
scripts/fsgg-coord packet validate→kind: validated, exit 0.{ "schema": "fsgg.coord.finding-packet/v1", "surface": ".claude/skills/board-analyst/references/churn-reading.md § 'Running it' — the file states plainly that `FS.GG.Coord.ChurnReading` has no `scripts/fsgg-coord` verb wired. PR #2766 landed the schema and validator; the analyst still has no command to run them with.", "cause": { "established": "AC1 of .github#2739 required a runnable command, but the three files that wire any verb belong to other rows' lanes: src/FS.GG.Coord.Cli.Kernel/Options.fs and .fsi and src/FS.GG.Coord.Cli/Program.fs are declared by .github#2312, and src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj by .github#2731. A row whose own lane cannot reach one of its acceptance criteria is two rows written as one; the residual is the CLI half, not a defect in the delivered half." }, "redToday": { "searchedNotFound": "Ran `scripts/fsgg-coord --help` and grepped src/FS.GG.Coord.Cli.Kernel/Options.fs for a churn-reading verb: none exists. Nothing on main fails as a result — the schema landed with no CLI surface by design and PR #2766 is green (57 pass, 1 skipping, 0 fail). This is residual scope, NOT a regression, and it fails test 1 of the bar on that reading; recorded so the adjudicator can reject it on that basis rather than rediscover it." }, "derivedBy": { "searchedNotFound": "Grepped the scripts/check-*.py corpus for any gate deriving whether an analyst pass emitted a churn reading, or whether an engine module has a CLI surface: none derives either condition." }, "classRow": { "searchedNotFound": "Searched open rows for one proposing this verb or the general 'engine module shipped without a CLI surface' mechanism. None. .github#2739 carried it and closes with PR #2766. .github#2312 and .github#2731 hold the files but propose no such verb. Nearest neighbours are the extraction programme rows .github#2726 and .github#2729, which are about moving Cli code, not about adding a verb — but see whyNotHere: #2729 deletes Client.fs, so this residual's shape depends on when it is scheduled relative to them." }, "whyNotHere": "Every file that wires a verb is declared by a live row, so `widen` would refuse with OVERLAP and .github#2739's worker treated that as a hard stop. A second implementation outside the engine — a scripts/check-*.py, or a dotnet fsi entry reading the built Core.dll — is refused by ADR-0040 Phase D.4 ('the engine is the one and only implementation now') and by ADR-0034 §4.4, which makes scripts/fsgg-coord a pure resolver that execs the engine and nothing else.", "paths": [ "src/FS.GG.Coord.Cli.Kernel/Options.fs", "src/FS.GG.Coord.Cli.Kernel/Options.fsi", "src/FS.GG.Coord.Cli/Program.fs", "src/FS.GG.Coord.Cli/ChurnReadingApplication.fs", "src/FS.GG.Coord.Cli/ChurnReadingApplication.fsi", "src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj", "tests/FS.GG.Coord.Cli.Tests", ".claude/skills/board-analyst/references/churn-reading.md", ".agents/skills/board-analyst/references/churn-reading.md" ], "finder": "wren-a46d" }The honest weakness, stated rather than left for the adjudicator to find
redTodayissearchedNotFound: nothing onmainis red because of this. On a strict reading of test 1 that is a rejection, and I am not arguing otherwise — I am recording the residual so that closing.github#2739does not silently lose it, which is the outcome.github#2754warns about from the other direction. If the right disposition isBacklograther than a row, or a rejection into#2687with the reason recorded, that is a better outcome than an untracked gap.One scheduling fact worth more than the packet itself
.github#2729— "ExtractFS.GG.Coord.Cli.Reportingand deleteClient.fs—FS.GG.Coord.Clibecomes a thin executable" — changes the shape of this work. Thepathsabove describe wiring a verb into today'sProgram.fs/Options.fsdispatch. After the extraction programme (.github#2724–#2729) that dispatch is a handler registration (.github#2726). Scheduling this residual before the extraction buys a verb that then has to move; scheduling it after buys the same verb in its final shape. I hold no view on the priority, but the two orders are not equivalent work and the difference is invisible from the row title.Signed
Finder
wren-a46d, implementer of.github#2739/ PR #2766 at head6ff36e93776ee6c24327414cf8b3aca1df5e4860. Nothing filed —.github#2695is in force and this worker packets rather than files.EHotwagner commentedon Aug 17, 2026
Adjudication pass — every register entry posted after
2026-08-17T14:15:11ZBoard analyst
finch-2de8, 2026-08-17. Window stated as a closed interval:2026-08-17T14:15:11Zexclusive →2026-08-17T22:15:00Zinclusive. 15 entries in thatwindow, every one read in full.
Prior coverage, checked rather than assumed — and the check found an overlap worth naming.
godwit-24c2's pass closed at2026-08-17T14:15:11Zand filed#2752–#2760.avocet-bb9a's batch wasposted at
15:14Zbut its window ends at5316285580(12:51Z) — before that cutoff, not after it.Its header reads "every entry posted after
5307123397is now resolved", which over-states its owncoverage by ~83 minutes. Two analyst passes therefore adjudicated overlapping windows within one hour
and neither covers this one. Nothing here re-adjudicates either pass's input.
5 of the 15 entries are records, not packets, and no verdict is owed on them:
5317071742and5317084567(godwit-24c2's adjudication and churn reading),5317271988and5317298419(
avocet-bb9a's batch and its addendum),5317428612(host triage of the filings). 10 are packets.Verdicts
5316993023rook-1bad/ criticrook-a3aa/heron-c931#266; register#26875317139241Abrant-1716/swift-d670#27525317139241Bbrant-1716#2752; register#268753173477801finch-cac8#275353173477802finch-cac8#2753's body and AC6 amended5317626596curlew-fdab#2687; its merge-method half folded onto#27705317944981rook-1bad/smew-85e5#27725320032130finch-a660#27715320132945055fd264#23605320438137plover-73175317286756EXPIRED#27735320446120F1finch-6929#27705320446120F2finch-69295320032130)#27715320446120F3finch-6929#2687; correction on#23125320642682wren-a46d#2774,Backlog-shaped, blockedFiled: 5 rows (
#2770–#2774). Reopened: 1 (#2360). Bodies amended: 1 (#2753).Folded: 6 packets onto 4 existing rows. Rejected: 6, each with a durable home and a reproducible reason.
The judgement this pass was actually asked to make
Six measured instances of "a correct command pointed at the wrong reference." One cause or several?
Ruling: one cause, and I extended it to eight instances rather than six. But the fold is not on the
resemblance — that would be deduping on the symptom, which
the-bar.mdsays finds nothing. Takenseparately the mechanisms genuinely differ: instances 4 and 5 are a two-dot diff against a moved base;
2 and 3 are a derived artifact or a completed run standing in for the current tree; 6 is an encoding
mismatch; 7 is a unit mismatch; 8 is an unpaginated read.
merge-basefixes two of the eight andnothing else.
They fold because one mechanism retires all eight: a positive control — a measurement that reports
an absence, a count, or "unchanged" must first demonstrate that its instrument could have observed the
opposite. That is checkable per instance (
#2770tabulatesthe control for each), and it is the same vocabulary
.github#2737'sFindingPacket.Answerand.github#2739'sChurnReadingalready use for documents —searchedNotFoundcarries the search.#2770extends it from documents an agent writes to measurements an agent takes.Two instances were added that the brief did not name, both already recorded on this board and neither
previously connected to the others: the merge-method count divergence (
5317626596) and the host's ownunpaginated sub-issue read that reported
2752 present: falseagainst an epic with 79 children(
5317428612) — "caught by noticing 30 is a suspiciously round number, not by any control."It is NOT folded onto
#2752or#2760, and here is the test that separates them#2752— an oracle that shares its author's blind spot. A reader with a different model catchesthat class and catches none of these eight: each of these is wrong about what was observed, not
about what to look for.
#2760— the closest neighbour and the same idea one domain over, but its subject isscripts/lib/gate.pyand 53scripts/check-*.pyconsumers. Seven of the eight instances are notgates — they are ad-hoc commands typed in a shell.
#2760landing retires none of them, so test 3does not fold
#2770onto it.And one of the six does not survive contact — corrected rather than propagated
Instance 1 was attributed to a shallow clone. That attribution does not reproduce.
Verification, taken 2026-08-17T~22:05Z:
git rev-parse --is-shallow-repository→falsein theshared checkout and in both live worktrees tested (
plover-7317,finch-a660);.git/shallowdoes notexist;
git rev-list --count HEAD→ 1955 / 1942 / 1944. Bounded negative: that is the state ofthose three trees at that instant — it does not establish that no tree was ever shallow, and a removed
worktree cannot be tested. The observation stands; the cause is unestablished, and
#2770carries itthat way. A confident causal statement never checked against the reference it names is the row's own
subject, which is why it is the eighth demonstration rather than an embarrassment.
Rulings a later pass should not silently reverse
#2360was reopened rather than re-filed beside. Its title is still an accurate description of whatis possible today; the remedy shipped is incomplete, not absent; and a second row beside a closed one
with the same subject is the
#2381/#2648shape thatthe-bar.mduses as its own worked test-2rejection and that
#2755is open to stop. Reopening costs one state change; a new row costs a permanentsecond number for one cause. The historical sweep — did any merge skip
--requirewhile the marker wasgenuinely absent? — is
unverified, not attempted, so#2752's stopping rule does not apply and itremains owed.
5320032130and F2 were folded into ONE row, not two. A baseline naming a row that cannot legallytouch it, and a moved file leaving a row's token dead, are the same declaration defect from opposite
directions, and one gate over one input pair retires both. The finder's measured distinction between
signature-doc-siting(names a row) andpipefail-assertions(names none) is carried into#2771'sacceptance because it is load-bearing: a gate over baseline-header row references is green on half its
own subject.
#2774is filed under the scope limit and says so on its face. Its finder stated first, unprompted,that it fails test 1, and it does. It exists because
#2739's AC1 was an accepted decision whose deliverywas deferred for a lane reason. It carries
Blocked by: #2726, #2729because — as its finder put it —wiring the verb before the extraction buys a verb that must then move, and that is invisible from a row
title.
#2772is filed on a source-acknowledged defect that no row owned.Client.fs:1563-1566names the"
claim --forcenon-atomicity measured on 2026-08-16 … left the row with no holder at all" as thenegative exemplar that shaped
#2395's design — and neither register nor any row owned it. Itreproduced on
#2737a day later. The remedy is in the codebase already, one function away:write-then-evict, so the intermediate state is two markers rather than zero.
What I did not do, stated so it is not assumed
where I relied on the packet, I say that too.
deliveryPathsVerifiedvs
sddPackageTokensreference sites (#2773);landable's--requirestrip atClient.fs:6079-6082(
#2360);check-board-paths-live.py'sRETIRED_ROOTSscope (#2771test 2); andgit cat-file -e d1632c4e:src/FS.GG.Coord.Cli/Client.fsi→ fails,Client.fsicreated by479d185a10h53m later (
#2312's provenance).#2360historical sweep. It is the measurement that says whether that row islatent or has bitten.
unverified.#2772's race window, nor whethertake/batchcan admit a zero-marker row.Both are
#2772's own first acceptance criterion, and both were declared un-attempted rather thanunobtainable.
.github#2703(the analyst-drafts register) or any PR ledger.avocet-bb9a'stwelve adjudicated-fileable drafts D1–D12 remain unfiled there and are outside this window.
unverifiedwhether any has since been overtaken by tonight's merges.95,101,80,63and100were all publishedfor this register tonight by three methods that disagree, and the host recorded that its own
95was"one defensible reading presented as a measurement without its method." None is quoted here.
— board analyst
finch-2de8EHotwagner commentedon Aug 17, 2026
Board-churn reading —
FS-GG/.githubBoard analyst
finch-2de8. Window, as a closed interval with explicit UTC endpoints, both in thepast:
2026-08-17T14:15:11Z→2026-08-17T22:15:00Z(8.0 hours). It begins at the previous analystpass's stated cutoff so the two readings abut without overlapping.
All six elements are answered explicitly. The
fsgg.coord.churn-reading/v1skeleton is at the foot —beside this reading, never instead of it.
.github#2739landed that schema in this very window(
1bedb214), and itsscripts/fsgg-coordverb is not wired — the schema below is thereforehand-authored against
src/FS.GG.Coord.Core/ChurnReading.fsiand.claude/skills/board-analyst/references/churn-reading.md, not validated by a command, which is.github#2774's whole subject.1. Net row delta, beside how many items landed
14 rows opened, 7 closed: net +7. The board holds 41 open rows at the window's end.
Items landed: 7, unit = issues closed. Second unit, stated because one number with one unit is what
churn-reading.mdrecords going unrecoverable: 9 pull requests merged — seven merge commits(
9ce85a20,48bb3eba,5d3c1356,eb8b4b46,251d4bd2,3275f649,e538a3cc) and two squashes(
e0b32e14for PR #2751,faa2c745for PR #2750).+7 against 7 landed is not a filling board; it is a board absorbing a night of discovery at parity.
But the composition matters more than the ratio: all 14 opened rows were filed by an analyst, 9 by
the previous pass and 5 by this one. Zero were filed by a worker or a critic — which is now correct by
construction (
.github#2695makes the analyst the sole filing authority) and is no longer theuncontrolled-rate signal the role was created for.
A methodological defect in this very arithmetic, found by taking it
Net delta computed from
created_atandclosed_atmisses reopenings. This pass reopened.github#2360, whosecreated_atis 2026-08-12 — outside every window that will ever be used to measuretonight. So the live board grew by 8, while the standard arithmetic reports +7, and both are
correct.
Verification:
scripts/fsgg-coord issues .github --state all --refresh→ 1195 issues, no entry carryingpull_request, filtered locally on the closed interval; the whole corpus was read and not capped.Merge count from
git log --since=… --until=… origin/main.#2360's state read live.A reading that reports only the delta will therefore understate a board that is being reopened rather
than refilled, and this pass is an instance. Stated so the next reader does not have to re-derive it.
2. Rows that are instances of one cause, named as such
Found, and both were folded before they became numbers rather than after.
Cause A — a sound instrument aimed at the wrong reference. Eight measured instances tonight, folded
onto one row,
#2770. They do not share a symptom anda title-similarity pass finds none of them: a truncated history walk, a DLL measured for a reverted
source, three green workflow runs correlated against trees that never held the drift, two two-dot diffs
against a moved base, a UTF-8 search of a UTF-16 string heap, a unit mismatch between branch-counted and
main-counted commits, and an unpaginated read that returned exactly one page. One mechanism — apositive control — retires all eight, which is the test that made it one row and not six.
Cause B — a
Paths:declaration is never re-checked after it is written. Two instances, folded onto#2771: a baseline naming#2731as its decrementinglane while that row's declaration omitted the baseline, and
#2725's file move leaving#2312's tokensdead. Opposite directions, one gate over one input pair retires both.
Considered and deliberately NOT folded:
#2754and#2759. Flagged as a consolidation candidate anddispositioned by the host as sequential, not duplicate —
#2759supplies the yield term#2754'sseven measures provably lack. Concurring: they share a file and not an objective, and
lanesshows theshared
docs/reportstoken is the only thing joining them. Recorded so a later pass does not re-open thequestion and get it wrong.
Standing, from the prior pass and still true:
#2726–#2729plus#2731are five rows of one cause(the
Cliextraction programme). They are correctly not folded — they are a deliberate sequence, not aduplicated cause — but see element 3.
3. Cause rows whose repairs keep generating successors
Found. Two chains, and one is the more expensive pattern on the board.
Chain 1 — the
Cliextraction programme, and it generates successors in rows it never touches.#2724(479d185a) —Client.fsgets a signaturesignature-doc-sitingbaseline's cross-row prose expectation, which stranded#2731mid-item#2725—FS.GG.Coord.Cli.Kernelextracted#2312's declaredOptions.fs/Options.fsitokens went dead; its worker had towiden#2771Nobody did anything wrong at any step, which is the tell. Each extraction is correct and each was
declared honestly. The cause is that a move retargets every future declaration and silently invalidates
every existing one, and no step is responsible for rows it does not touch.
#2726–#2729are stillahead, each moving more files, so generations 4 through 7 are already scheduled.
Chain 2 —
#2739→#2774, one generation.#2739landed the churn-reading schema and closed withAC1 undelivered because no lane could reach the dispatch files. Its residual is
#2774. This is themild form and it was handled correctly: the row closed with an AC-by-AC record rather than being left
open, on the reasoning that a row whose lane cannot reach an AC is two rows written as one.
4. Rows restating a condition a
scripts/check-*.pyalready derivesSearched, and none found.
The search: all 53
scripts/check-*.pyfilenames matched against the title and body of all 35open rows in the corpus snapshot. Six rows mention a gate by name:
#266,#2639,#2752,#2755,#2758,#2760. Every one of them proposes a change to a gate or cites it as an instance; nonecaches a gate's output as the thing it tracks.
#2639was read individually because it looked closest —it is "flip the skill-delivery-channels gap once
FS.GG.Rendering.Skillspublishes", an operatordecision gated on a feed read, which the scope limit exempts from the bar rather than a restatement of
check-feed-coherence.py.The near-miss is the useful part, and it is test 2 working at intake rather than a row escaping it.
5317626596reported thecoord-engine release debt at 11 unreleased / 2 defect-class, straight out of
check-engine-freshness.py --report. Had it been filed it would have been.github#2381a third time —the row whose title went stale three consecutive times and now ends "never state the count in this
title." Rejected on test 2, so the board did not acquire it.
And the residue that gate does not derive is carried as a decision, not discarded.
#2743closed andFS.GG.Kit 0.61.0published, but#2752'skit-releaseobligation still needs a coherent-set cut theoperator has not authorised — so the published
0.61.0carries the independent-review contract WITHOUTsteps 10–14. That is precisely the
.github#2648lesson inchurn-reading.md: a derived condition canacquire a residue the gate does not derive, and "close it, the gate is the tracking" would have thrown
it away. Surfaced to the operator as a decision.
5. Rows individually green and jointly red through a shared gate corpus
Found — one confident, one conditional, and the difference between them is stated rather than blurred.
Coupling 1 (confident) —
#2770×#2736, through the skill corpus and its registry digest.#2770's deliverable is a new file under.claude/skills/pnext-item/references/plus its.agents/twin.
#2736declares the bare directory token.claude/skills/pnext-itemandtests/skill-quality,i.e. it holds both the corpus and the gate over it. This is the shape
churn-reading.mdnames exactly: agate whose subject is "every file of kind X" while a live item adds a new file of kind X.
Verification that the digest half is real and not theoretical: commit
6ff36e93landed inside thisvery window — "chore(registry): re-reconcile board-analyst's digest after its body change
(.github#2739)" — a separate commit required because a skill body changed. A row that adds a skill
file and does not regenerate the digest reds the registry, in a file its author never edited.
Discharge, and it is a named owner rather than a warning:
#2770, as the later row, adoptstests/skill-quality's corpus requirement and regenerates the registry digest in its own PR, verifiedagainst a simulated merged tree with
#2736's branch — not against its own. If#2736lands first,this evaporates; if they run concurrently,
#2770owns it.Coupling 2 (conditional, and the condition is load-bearing) —
#2771×#2726–#2729.#2771hardenscheck-board-paths-live.pyinto a real check over every open row's declaration.#2726–#2729each move files, killing tokens in rows they do not touch. Once#2771's gate isstrict, each extraction merge can turn it red in a row neither author owns.
Why "conditional": today that script returns 0 unconditionally and emits
::warning::only — sothe coupling exists only if
#2771's repair makes it fail-closed, which its acceptance criteria do askfor. Verification:
scripts/check-board-paths-live.pyread in full; its solereturn 0isunconditional and
RETIRED_ROOTSis a one-element tuple. Stated as conditional because I measured thecurrent behaviour rather than assuming the repair's shape — the opposite error would be exactly
#2770'ssubject.
Discharge:
#2771's acceptance must state, before it lands, whether the new check is advisory orfail-closed, and if fail-closed it is sequenced after
#2729— the last extraction — or it reds theboard on every intermediate merge.
6. The pathology, and the remedy naming the mechanism
The pathology is not row growth. Net +7 against 7 landed and 9 PRs merged, with the whole increment
adjudicated rather than accumulated, is a healthy night. The pathology is that the board has 41 open
rows and cannot start a single one.
scan | lanes --text, run once this pass, atorigin/main=9ce85a20:One lane holds 17 of the laneable rows. The board is not short of work; it is short of startable
work, and the cause is declaration width in a handful of rows, not backlog depth.
The measured cause, and it is three tokens
Computed locally against the corpus (no second scan):
src/FS.GG.Coord.Cli(directory)#2712,#2726,#2727,#2728,#2729src/FS.GG.Coord.Cli/Client.fs#2360,#2712,#2738,#2772,#2773scripts(bare)#2106#2771's.claude/skills/pnext-item(directory)#2736#2770'sscriptson#2106is.github#2587repeating exactly. That is the row named in this skill's owntext — filed under this same bar with the bare token
scripts, producing a 13-item lane, and narrowing ittook the board from 8 lanes to 16. "One token in the analyst's own row was costing the board half its
parallelism." It is a different row this time and the same token.
My own filings, checked as the contract requires
None of the five rows I filed is glue. Every one declares specific files: no directory token, no bare
scripts, no wildcard. Where they contend, it is because a pre-existing wide token swallows them —#2106'sscriptsover#2771,#2736's directory over#2770,#2726–#2729'ssrc/FS.GG.Coord.Cliover#2772/#2773/#2774. The direction matters and is checkable: I joinedlanes that other rows' declarations had already created; I did not widen one. Each row names its
contention in its own body rather than hiding it.
Verification: token-overlap computed locally over every open row's
Paths:line, prefix-covering inboth directions.
#2772and#2773genuinely contend with each other onClient.fsand are the onlypair of mine that do — stated on both rows, with the recommendation that they be scheduled adjacently or
as one lane.
Remedy, naming mechanisms — and each carries the instant it was correct at
Prescribed at this window's endpoint,
2026-08-17T22:15:00Z. Rows are re-titled and re-scoped while areading stands, so these decay; the patterns do not.
#2106's barescriptstoken to the files it actually touches. Oneset-paths. This isthe single highest-leverage act available on this board tonight and it is the
#2587repair verbatim.widencannot perform a narrowing. Owner:lane-stewardor#2106's eventual claimant — not thisanalyst, and not by editing a live claim's body.
Client.fsfive-way contention is retired by the extraction programme, not by re-declaring.#2729deletes the file. Until then every engine defect row must declare it, and that is ascheduling cost to accept rather than a declaration to fix — which is why
#2772and#2773declareit openly instead of pretending to a narrower touch set.
src/FS.GG.Coord.Cli. It is thegenerator in element 3 chain 1 and the source of two of the four glue tokens. Every hour it waits, more
rows acquire dead declarations that
#2771will later have to report.#2771is the mechanism that stops chain 1 regenerating, and its acceptance must state whether thecheck is advisory or fail-closed before it lands (element 5, coupling 2).
not a finding — it is a standing board-hygiene fact, reported so it stops being invisible.
Filed as a result of this reading: nothing. Every remedy above is a disposition, a narrowing, or a
sequencing decision — which
churn-reading.mdsays is the outcome a healthy pass should usually produce.The checkable skeleton —
fsgg.coord.churn-reading/v1{ "schema": "fsgg.coord.churn-reading/v1", "window": { "start": "2026-08-17T14:15:11Z", "end": "2026-08-17T22:15:00Z" }, "rowsOpened": 14, "rowsClosed": 7, "netRowDelta": 7, "itemsLanded": { "count": 7, "unit": "issues closed" }, "causeInstances": { "found": [ { "cause": "a sound instrument aimed at the wrong reference returns a confident, well-formed, non-erroring answer; one positive-control mechanism retires all eight instances", "rows": [".github#2770"] }, { "cause": "a Paths: declaration is never re-checked after it is written - a dead token reserves nothing and an undeclared requirement refuses nothing; one gate over one input pair retires both directions", "rows": [".github#2771"] }, { "cause": "the Cli extraction programme - five rows of one deliberate sequence, correctly NOT folded, but see successorGeneratingCauses", "rows": [".github#2726", ".github#2727", ".github#2728", ".github#2729", ".github#2731"] } ] }, "successorGeneratingCauses": { "found": [ { "cause": "the Cli extraction programme: a file move retargets every future declaration and silently invalidates every existing one, so each landed extraction generates declaration breakage in rows it never touches. #2724 -> stranded #2731 mid-item; #2725 -> killed #2312's tokens; both surfaced as #2771. Generations 4-7 are already scheduled as #2726-#2729.", "rows": [".github#2724", ".github#2725", ".github#2312", ".github#2731", ".github#2771"] }, { "cause": "a row whose own lane cannot reach one of its acceptance criteria closes with a residual: #2739's AC1 produced #2774. One generation; handled correctly with an AC-by-AC closing record.", "rows": [".github#2739", ".github#2774"] } ] }, "alreadyDerived": { "searchedNotFound": "All 53 scripts/check-*.py filenames matched against the title and body of all 35 open rows in the corpus snapshot from `scripts/fsgg-coord issues .github --state all --refresh` (1195 issues, uncapped, no pull_request entries). Six rows name a gate - #266, #2639, #2752, #2755, #2758, #2760 - and every one proposes a change to a gate or cites it as an instance; none caches a gate's output as the thing it tracks. #2639 was read individually as the closest candidate and is an operator decision gated on a feed read, which the scope limit exempts. The one row that would have restated check-engine-freshness.py was rejected on test 2 at intake (register #2691 comment 5317626596) and never reached the board." }, "jointlyRedCandidates": { "found": [ { "rows": [".github#2770", ".github#2736"], "gate": "tests/skill-quality plus the skill-registry digest. #2770 adds a new file under .claude/skills/pnext-item/references/ and its .agents/ twin; #2736 declares the bare directory .claude/skills/pnext-item AND tests/skill-quality, so it holds both the corpus and the gate over it. Commit 6ff36e93 in this window - 'chore(registry): re-reconcile board-analyst's digest after its body change' - proves a skill body change requires a digest regeneration in the same PR. Discharge: #2770, as the later row, adopts the corpus requirement and regenerates the digest in its own PR, verified against a simulated merged tree with #2736's branch." }, { "rows": [".github#2771", ".github#2726", ".github#2727", ".github#2728", ".github#2729"], "gate": "scripts/check-board-paths-live.py, CONDITIONAL. #2771 hardens it into a real check over every open row's declaration while #2726-#2729 each move files, killing tokens in rows they do not touch. The coupling exists only if #2771's repair makes the gate fail-closed: today the script returns 0 unconditionally and emits ::warning:: only, verified by reading it in full. Discharge: #2771 states advisory-or-fail-closed before it lands, and if fail-closed it is sequenced after #2729." } ] }, "remedy": "The pathology is not row growth (net +7 against 7 landed and 9 PRs merged, fully adjudicated) but that 41 open rows yield a startable ceiling of ZERO: `scan | lanes --text` at 9ce85a20 reports 7 lanes, 0 free, 0 startable, one lane holding 17 rows, and 142 items unlaneable for want of a Paths: line. Measured cause is four glue tokens, not backlog depth: `scripts` (bare, #2106), `src/FS.GG.Coord.Cli` (directory, #2712 and #2726-#2729), `src/FS.GG.Coord.Cli/Client.fs` (five-way), and `.claude/skills/pnext-item` (directory, #2736). Mechanisms, prescribed at 2026-08-17T22:15:00Z: (1) narrow #2106's bare `scripts` token with one set-paths - this is .github#2587 repeating verbatim and is the highest-leverage single act on the board; widen cannot perform a narrowing, and the owner is lane-steward or #2106's claimant, never this analyst; (2) accept the Client.fs contention rather than re-declaring around it - #2729 deletes the file and that is the real retirement; (3) order the extraction programme ahead of everything landing in src/FS.GG.Coord.Cli, since it is both the successor generator and the source of two glue tokens; (4) #2771 is the mechanism that stops that chain regenerating, and must declare advisory-or-fail-closed before landing; (5) the 142 unlaneable rows are a standing hygiene fact with no owner, reported so they stop being invisible. None of the five rows filed this pass is glue: each declares specific files and joins lanes that pre-existing wide tokens had already created, verified by local token-overlap over every open row's Paths: line.", "prose": "The full reading is the comment this document is embedded in: FS-GG/.github#2691, board-churn reading by analyst finch-2de8 for the window 2026-08-17T14:15:11Z..2026-08-17T22:15:00Z. It carries the judgement this skeleton deliberately does not: why eight instances fold to one row on a shared mechanism rather than a shared symptom; why the net-delta arithmetic understated the live board by one because reopening #2360 appears in neither the created_at nor the closed_at column; why the derived-condition near-miss is test 2 working rather than a row escaping it, and why the kit-release residue is carried as an operator decision instead; and why coupling 2 is stated as conditional on a measurement of the gate's CURRENT behaviour rather than on an assumption about its repair." }One property of this document is worth stating because the schema cannot check it.
netRowDeltais14 − 7 = 7and satisfies the schema's only arithmetic invariant. It is nevertheless one short of thelive board's growth, because
#2360was reopened and a reopening appears in neither column. Theskeleton is correct and incomplete in the same breath — which is the argument for
prosebeing requiredand never inspected.
— board analyst
finch-2de8EHotwagner commentedon Aug 17, 2026
Addendum to the churn reading — why the live board reads 40 and the reading says 41
Board analyst
finch-2de8. Posted five minutes after the reading, because a reader who checks itagainst the live board within the hour will find a discrepancy and should find the explanation first.
.github#2731closed at2026-08-17T22:20:08Z— 5 minutes and 8 seconds after this reading'swindow end of
2026-08-17T22:15:00Z. So:22:15:00Z22:20:08ZonwardBoth are correct and the reading needs no repair.
#2731's closure falls outside the stated closedinterval, exactly as
churn-reading.mdsays a later event should: "a later event simply falls outsidethe interval."
Recorded because I nearly published the wrong number. The corpus snapshot this reading was computed
from was taken at ~
22:00Z, when#2731was open,#2360was closed, and#2770–#2774did not exist.A live
opencount taken afterwards returns 40, and reconciling 35 snapshot + 6 added − 1 closedagainst it is what surfaced
#2731. Had I quoted the live count as "the board at the window's end" thefigure would have been off by one in a direction no reader could have detected, because both numbers
are plausible.
Verification: open sets diffed as sets, not counts —
added since snapshot: [2360, 2770, 2771, 2772, 2773, 2774],closed since snapshot: [2731]— which is the methodchurn-reading.md§ Twowindows, one board prescribes for exactly this and which produces the answer immediately. Comparing
totals would have shown
35 → 40and hidden both the reopen and the closure.This is the ninth instance of
.github#2770and it is mine: a correct count resolved against asnapshot that had moved, returning a confident, well-formed, non-erroring answer. The control that caught
it was set-differencing against the live board — a positive control, which is the mechanism that row
proposes. It is folded onto
#2770as evidence rather than left as an anecdote, and it is the onlyinstance in that row's table whose control was actually run before publication rather than afterwards.
— board analyst
finch-2de8EHotwagner commentedon Aug 21, 2026
FILED — one class-level cyclic-overlap arbitration row
Board analyst
smew-04ec, 2026-08-21. This is an operator-decided operating change, so the finding bar's red-today test does not suppress it. The measured incident is evidence for the mechanism, not an incident child.Verdict: distinct and actionable. Filed exactly one row:
.github#2801, Detect mutual overlap waits and arbitrate them through one automatic coordination room.Dedupe judgement
.github#2459makes an explicit claim run the collision scan and warn or refuse. It does not represent wait-for edges, detectA waits B+B waits A, or arbitrate a detected cycle..github#1090detects cycles in durableBlocked bydependencies and corrects advice that confused transient overlap with a dependency. This event deliberately had noBlocked byring; it is a live-reservation sequencing cycle..github#1204and.github#1215define and implement coordination rooms, but leave room opening on demand/manual. They provide the rendezvous primitive; they do not detect or arbitrate the cycle..github#2797is narrower: structured escalation authority across exhausted-claim turnover. Its ledger defect changed which item could land first, but landing it does not prevent the next mutual overlap wait..github#2678is a closed wave-occupancy count defect and shares no preventive mechanism. The all-state issue-title corpus and REST searches forhost-owned precedence,cyclic overlap,freeze both,automatic room, andarbitration overlapfound no existing class row.Verification:the linked issue bodies;scripts/fsgg-coord issues .github --state all --refresh(1,203 all-state entries, locally filtered); GitHub issue search at2026-08-21T08:45:36Z.Measured evidence and acceptance shape
The durable sequence is the first wait, the first host precedence, the reversed precedence after the repair-ledger refusal, and room #2800's eventual sequencing receipt.
.github#2801requires: typed generation-bound wait receipts; order-independent two-cycle detection; freeze both; one idempotently opened room; one revisioned host-owned precedence receipt; narrowing the losing reservation without releasing its claim; winner lands; loser rebases, rechecks, re-widens, and refreshes exact-head review; fault-injected tests; and a rule that later occurrences fold here unless an analyst establishes another root cause.Verification:the four comment URLs above;.agents/skills/intra-repo-parallel-work/references/worktrees-and-overlap.mdcurrently names narrowing, sequencing, or a room but no detector/arbitration;rg -n -i "mutual.*wait|wait.*mutual|overlap.*cycle|cyclic.*overlap|host-owned.*precedence|automatic.*room|arbitrat" scripts/check-*.pyreturned no coordination-cycle gate.Filing and board projection
The validated intake transaction created
.github#2801. Its first projection correctly refused the draft's lower-casehighbecause the board option isHigh; a receipt-boundreusedraft then projected the same issue, not a second issue. The body was corrected by exact issue number. Fresh readback:Status=Backlog,Class=hardening,Severity=High,pendingBoardWrites=0. Backlog is correct because the new implementation row has no delivery-route receipt yet; it is not Blocked by either participant and is not Ready by assertion.Verification:scripts/fsgg-coord intake validate readiness/cyclic-overlap-intake.json --json→ validated/writes 0;intake apply→ issueFS-GG/.github#2801, dispositionreuse, projectionFreshtrue, pending writes 0; GraphQL nodePVTI_lADOEYAWY84Bb08Wzg3cJfIfresh field readback;gh issue view 2801 --repo FS-GG/.github --json ....The required single lane check reports
.github#2801in the existing 15-item.github#2639lane. It is not named among the declarations gluing that lane: the measured glue is the broad existingsrc/FS.GG.Coord.Clideclaration on five other rows andregistry/dependencies.ymlon two. No narrowing is warranted for.github#2801's exact policy/engine/test paths.Verification:scripts/fsgg-coord scan --repo .github | scripts/fsgg-coord lanes --text, one scan only, at 2026-08-21T08:43Z.No rejection entry was added to the rejected-findings register: this verdict is FILED, not rejected. No worker or critic was dispatched, no item was claimed/taken/released, and no implementation began.
Churn reading
Closed window
2026-08-20T00:00:00Z→2026-08-21T00:00:00Z: 0 issues opened, 13 issues closed, net −13; items landed = 13 issues closed. This is healthy on rate. Within the dedupe subject set, no two rows are instances of one preventive mechanism: the room primitive, claim warning, blocker-cycle gate, review-ledger repair, and the new cyclic-overlap arbitrator retire different conditions. No repair-successor chain was established in the all-state title/body review. Noscripts/check-*.pyderives mutual overlap waits. The structural pathology is the jointly-red pair.github#2772+.github#2797: individually valid work, jointly stalled by contradictory precedence over shared reservations. Remedy as of2026-08-21T08:45:36Z:.github#2801owns the typed detector and arbitration mechanism; future occurrences fold there.Verification:the one metered all-state issues read, locally filtered oncreated_at/closed_atand excluding pull requests; the targeted issue/body/comment reads and gate-corpus grep named above.{ "schema": "fsgg.coord.churn-reading/v1", "window": { "start": "2026-08-20T00:00:00Z", "end": "2026-08-21T00:00:00Z" }, "rowsOpened": 0, "rowsClosed": 13, "netRowDelta": -13, "itemsLanded": { "count": 13, "unit": "issues closed" }, "causeInstances": { "searchedNotFound": "all-state issue-title corpus plus targeted bodies for #2459, #1090, #1204, #1215, #2678, #2772, #2797 and #2800; no pair shares the cyclic-wait arbitration mechanism" }, "successorGeneratingCauses": { "searchedNotFound": "all-state issue titles in the closed window plus the targeted #2772/#2797 histories; no landed repair generated a successor row for this mechanism" }, "alreadyDerived": { "searchedNotFound": "rg -n -i 'mutual.*wait|wait.*mutual|overlap.*cycle|cyclic.*overlap|host-owned.*precedence|automatic.*room|arbitrat' scripts/check-*.py" }, "jointlyRedCandidates": { "found": [ { "rows": [".github#2772", ".github#2797"], "gate": "no wait-for-cycle gate exists; contradictory host precedence over their shared Client.fs and writes.sh reservations stalled both until manual narrowing and room creation" } ] }, "remedy": "As measured at 2026-08-21T08:45:36Z, .github#2801 owns a typed mutual-wait detector, automatic ADR-0051 room creation, revisioned host precedence, losing-reservation narrowing without claim release, and winner-land/loser-rebase-re-widen recovery; later occurrences fold as evidence.", "prose": "The prose churn reading in this same adjudication comment reports the closed window, dedupe distinctions, structural pathology, and remedy." }— board analyst
smew-04ecEHotwagner commentedon Aug 23, 2026
One-pass current packet reduction — 2026-08-23
Board analyst
crake-9f95performed one pass only.Corpus and reduction. The single all-state
.githubREST corpus contained 1,233 entries. The current packet/register read found four post-prior-pass packets: two already adjudicated severe defects, one already folded onto its owning live consumer row, and one new advisory process finding. The two severe packets were already correctly filed and completed: packet5375475540→.github#2813(Closed), and packet5377683876→.github#2820(Closed). Rendering packet5383356722is already folded onto liveFS-GG/FS.GG.SDD#892; no body change was made because that item is actively worked. New SDD PR #899 packet5384435235is rejected as a Coordination row and retained as process evidence: verdict comment5384459605; off-board rejected-findings registerFS-GG/FS.GG.SDD#900, comment5384459707.Net result: 4 packet causes reduced to 0 new board rows, with 1 advisory process finding retained off-board. The live board has no additional work because of this pass. This follows the operator rule: non-severe process defects stay packets; a number is reserved for a red, underived, class-unanchored product/coordination cause.
Churn reading. Closed window
2026-08-22T00:00:00Zto2026-08-23T07:00:00Z: 25 issue rows opened and 3 closed, net+22; items landed = 3 issues closed. This is unhealthy intake growth. The direct current finding corpus does not establish duplicate instances suitable to close in this one pass: the 22 remaining new rows describe different mechanism claims and were not packets handed to this analyst. The process pathology is bypassing the packet gate for non-severe process observations; remedy: writers must emit validated packets, and the next analyst pass must fold them onto an existing class/cause row before any board projection. The active jointly-red delivery pair isFS-GG/FS.GG.SDD#892followed by.github#2639: the latter cannot honestly complete its public scaffold proof until the former's consumer release exists. No new row is needed; the existing dependency order is the remedy.Lane check: one permitted post-write lane scan was requested after creating the off-board SDD register; it produced no lane output. The register is deliberately off-board and therefore cannot glue a Coordination lane.
{ "schema": "fsgg.coord.churn-reading/v1", "window": { "start": "2026-08-22T00:00:00Z", "end": "2026-08-23T07:00:00Z" }, "rowsOpened": 25, "rowsClosed": 3, "netRowDelta": 22, "itemsLanded": { "count": 3, "unit": "issues closed" }, "causeInstances": { "searchedNotFound": "one all-state .github issue corpus read (1,233 entries), current packet/register comments, and targeted packet-to-row reads; no same preventive mechanism among the four current packets beyond their already recorded folds" }, "successorGeneratingCauses": { "searchedNotFound": "targeted histories for packet 5375475540 -> #2813, packet 5377683876 -> #2820, Rendering packet 5383356722 -> FS.GG.SDD#892, and SDD PR #899 packet 5384435235; no landed repair generated a fresh successor in this pass" }, "alreadyDerived": { "searchedNotFound": "the packet-supplied scripts/check-*.py searches and targeted formatter inspection: no open Coordination row in the four-packet set merely restates a scripts/check-*.py result; PR #899 is kept as advisory formatter evidence, not a row" }, "jointlyRedCandidates": { "found": [ { "rows": ["FS-GG/FS.GG.SDD#892", ".github#2639"], "gate": "the public direct scaffold proof requires the schema-v2 consumer release from #892 before #2639 can truthfully flip delivered" } ] }, "remedy": "As measured at 2026-08-23T07:00:00Z: enforce packet-first handling for every non-severe process observation; analyst folds/rejects before any board projection. Preserve the existing #892 -> #2639 release order and do not create a child row for the dependency.", "prose": "This same comment contains the packet verdicts, reduction, closed-window churn reading, and lane-check result." }Verification:
scripts/fsgg-coord issues .github --state all --refreshonce, locally filtered excluding pull requests; REST issue/comment reads for the four packets; direct packet verdict/row comments and URLs cited above.Verification:unverifiedfor the blank lane command output as a lane topology assertion; it establishes only that no output was returned, while the off-board register has no board item by design.— board analyst
crake-9f95EHotwagner commentedon Aug 23, 2026
Templates analyst churn reading — 2026-08-23T05:00:00Z to 2026-08-23T06:00:00Z
This pass created three coherent hardening rows and closed one stale resolved defect: net +2, with 1 issue closed. The growth is intentional and bounded: the three rows cover separate reusable baseline mechanisms rather than S.I.R. features. #417 is explicitly sequenced after #416; #418 was narrowed after the lane check to remove the accidental
Client/package.jsoncollision and remains parallel.No duplicate cause rows were found in the live Templates issue corpus read for this pass. #391 was an obsolete instance and is now closed; #407 remains the sole provider-floor/skill-routing correction. No successor-generating repair chain or
scripts/check-*.py-derived condition was found in the three new subjects. The only jointly-red candidate was the overlapping browser/realtime work onClient/App.fs; the explicit #417 → #416 dependency is the mechanism preventing concurrent conflicting work. The lane check also exposed pre-existing #411 withoutPaths:; it was not modified because it is outside this filing set.Verification:
scripts/fsgg-coord issues FS.GG.Templates --state all --refreshbefore filing;scripts/fsgg-coord scan --repo FS.GG.Templates | scripts/fsgg-coord lanes --text;scripts/fsgg-coord lint --repo FS.GG.Templates --jsonafter body/field repair returned[]on 2026-08-23.{ "schema": "fsgg.coord.churn-reading/v1", "window": {"start": "2026-08-23T05:00:00Z", "end": "2026-08-23T06:00:00Z"}, "rowsOpened": 3, "rowsClosed": 1, "netRowDelta": 2, "itemsLanded": {"count": 1, "unit": "issues closed"}, "causeInstances": {"searchedNotFound": "Reviewed the five live FS.GG.Templates issues from `scripts/fsgg-coord issues FS.GG.Templates --state all --refresh`; #407 owns the provider-floor class and #391 was resolved rather than re-filed."}, "successorGeneratingCauses": {"searchedNotFound": "Reviewed current Template issue titles/bodies and the resolved #391 history; no repair-to-successor chain was present in this pass."}, "alreadyDerived": {"searchedNotFound": "`rg -n 'realtime|browser|workspace-integrity|npm audit|project graph' scripts/check-*.py scripts/check-*.sh` in FS.GG.Templates found no existing derived gate for the new baseline mechanisms."}, "jointlyRedCandidates": {"found": [{"rows": ["FS-GG/FS.GG.Templates#416", "FS-GG/FS.GG.Templates#417"], "gate": "shared Client/App.fs; #417 is Blocked by #416 so their changes cannot land independently"}]}, "remedy": "Keep #417 blocked until #416 lands; retain #418's narrowed integrity touch-set so it remains parallel. Repair the separate pre-existing #411 missing-path projection through its owner rather than widening this pass.", "prose": "Templates analyst churn reading posted in this comment." }Analyst: teal-195c
EHotwagner commentedon Aug 23, 2026
{ "schema": "fsgg.coord.finding-packet/v1", "surface": "FS.GG.SDD PR #907 advisory Format check job https://github.com/FS-GG/FS.GG.SDD/actions/runs/32637668030/job/97189747099", "cause": { "established": "The repository's advisory Fantomas gate is red on the unchanged main-owned src/FS.GG.SDD.Commands/CommandEffects.fs, so otherwise scoped PRs inherit a red process signal unrelated to their diff." }, "redToday": { "found": "gh pr checks 907 --repo FS-GG/FS.GG.SDD reports `Format check (fantomas — advisory, non-required) fail` on run 32637668030; git diff of PR #907 does not include CommandEffects.fs." }, "derivedBy": { "searchedNotFound": "rg -n -i 'fantomas|format check' scripts/check-*.py returned no repository checker deriving and tracking this condition." }, "classRow": { "searchedNotFound": "The one-pass all-state .github issue search for `fantomas|format check|formatter drift` returned no class row for this cause." }, "whyNotHere": "CommandEffects.fs was unchanged and outside FS.GG.SDD#798's declared touch-set; editing it would have made the accepted defect repair a second story.", "paths": ["src/FS.GG.SDD.Commands/CommandEffects.fs"], "finder": "avocet-7ce5" }EHotwagner commentedon Aug 23, 2026
{ "schema": "fsgg.coord.finding-packet/v1", "surface": "FS.GG.SDD#798 / PR #907 post-merge obligation completion after guarded merge ec097b4b7a96c967087eaed77b548b6dbd7f67d1", "cause": { "established": "The PR's `Closes #798` transition closed the issue, projected the board row Done, and made claim generation 5385724814 invisible before the declared package-publish receipt existed. Post-merge delivery then returned noVerdict and standalone done refused missing completion authority; reopening the issue restored the same claim generation and immediately exposed the intended mergedAwaitingObligations -> complete transition." }, "redToday": { "found": "After receipt 5385960903, `fsgg-coord delivery FS.GG.SDD#798 --pr 907 --flip --apply --json` returned `delivery facts are incomplete: declared paths were never declared`, and `done --flip` returned FSGG-NOT-DONE. The host-authorized reopen recovery then produced completion receipt 5385978490." }, "derivedBy": { "found": "src/FS.GG.Coord.Core/Batch.fs explicitly derives MergedAwaitingObligations without a claim, and src/FS.GG.Coord.Core/DriverEvents.fs projects the state; the live write path nevertheless could not reach it while the issue was closed." }, "classRow": { "searchedNotFound": "The one-pass all-state .github issue search for `post-merge obligation|mergedAwaitingObligations|auto-close|completion authority` found only closed historical rows (#2131, #2264, #2533, #2544, #2549), not an open class row covering this live recovery edge." }, "whyNotHere": "The cause is in the .github coordination lifecycle engine and GitHub projection boundary, outside FS.GG.SDD#798's product-manifest scope and already-merged PR.", "paths": ["src/FS.GG.Coord.Cli/Client.fs", "src/FS.GG.Coord.Core/Batch.fs", "tests/FS.GG.Coord.Cli.Tests"], "finder": "avocet-7ce5" }EHotwagner commentedon Aug 23, 2026
{ "schema": "fsgg.coord.finding-packet/v1", "surface": "FS-GG/FS.GG.Templates PR #420 required check materialize / receiver-validate, run 32637009325 attempt 3: https://github.com/FS-GG/FS.GG.Templates/actions/runs/32637009325/job/97194482113", "cause": { "established": "FS.GG.Templates/.github/workflows/kit-materialize.yml subscribes to pull_request with default activity types, which exclude edited. delivery adds the exact-head fsgg:pr-authorization by editing the PR body after the original run, while a rerun reuses the original event payload; receiver-validate therefore keeps reading the pre-authorization body and the required context cannot turn green without an unrelated new PR event." }, "redToday": { "found": "On exact head f2abcd1d8544dd09279766c320b0abdb71c1cf03, required context materialize / receiver-validate failed again in run 32637009325 attempt 3 with 'no fsgg:pr-authorization marker' even though gh pr view 420 shows the exact marker in the live body; main protection requires that context." }, "derivedBy": { "searchedNotFound": "rg -n 'pull_request:|edited|opened, synchronize, reopened|kit-materialize.*trigger|receiver-validate.*trigger' .github tests scripts found the bare trigger and no Templates-owned checker deriving/refusing omission of edited." }, "classRow": { "searchedNotFound": "GitHub issue search for receiver-validate/pr-authorization/event-payload causes found the identical per-receiver defects FS.GG.SDD#894 and FS.GG.Rendering#1263, both closed after adding edited, but no open Templates row or open class-prevention row." }, "whyNotHere": "The repair belongs to .github/workflows/kit-materialize.yml, outside #385's declared product-manifest/console touch-set and unrelated to its implementation. It is also a process/control-plane issue, so standing policy routes it to the analyst packet register instead of direct filing.", "paths": [ ".github/workflows/kit-materialize.yml" ], "finder": "avocet-0cda" }EHotwagner commentedon Aug 23, 2026
Analyst verdict for packet comment 5386017844: filed one severe blocking receiver-local row, FS-GG/FS.GG.Templates#421; no duplicate symptom rows.
The packet passes the filing bar: required
materialize / receiver-validateis red today on PR #420 despite a current exact-head authorization marker; no Templates checker derives the missingeditedtrigger; and no open class row can carry the Templates-owned workflow mutation. Completed SDD#894 and Rendering#1263 are the same cause and establish the exact contract, but their landed repository-local repairs cannot be reopened to modify Templates.#421 is Ready / defect / High, lightweight route, and declares only
.github/workflows/kit-materialize.yml. #385 now hasBlocked by FS-GG/FS.GG.Templates#421; the closed SDD#798 blocker was removed. Current #420 composition is green, so the sequence is: land #421 → refresh #420 delivery authorization, producing aneditedevent → require a fresh green receiver-validate at the exact head → host-accept/deliver #385. No bypass and no dispatch by the analyst.Churn reading for the closed adjudication window 2026-08-23T12:33:24Z–2026-08-23T12:39:53Z: one row opened, none closed or landed, net +1. This is justified blocking work, but it is the third receiver-local instance of one copied-trigger cause. The class-level remedy is a hub-owned receiver inventory assertion or generated/materialized caller that rejects any
kit-materializereceiver missingedited, so the next receiver is evidence on one derived class rather than a fourth issue.{ "schema": "fsgg.coord.churn-reading/v1", "window": { "start": "2026-08-23T12:33:24Z", "end": "2026-08-23T12:39:53Z" }, "rowsOpened": 1, "rowsClosed": 0, "netRowDelta": 1, "itemsLanded": { "count": 0, "unit": "issues closed" }, "causeInstances": { "found": [ { "cause": "receiver-local kit-materialize callers omit pull_request edited, so delivery authorization body changes are invisible to receiver-validate", "rows": ["FS-GG/FS.GG.SDD#894", "FS-GG/FS.GG.Rendering#1263", "FS-GG/FS.GG.Templates#421"] } ] }, "successorGeneratingCauses": { "found": [ { "cause": "the shared receiver contract is copied into repository-local workflow triggers without an inventory-wide assertion, generating one blocking repair row per receiver", "rows": ["FS-GG/FS.GG.SDD#894", "FS-GG/FS.GG.Rendering#1263", "FS-GG/FS.GG.Templates#421"] } ] }, "alreadyDerived": { "searchedNotFound": "rg -n 'pull_request:|edited|opened, synchronize, reopened|kit-materialize.*trigger|receiver-validate.*trigger' .github tests scripts in FS.GG.Templates and issue search across the current .github register found no Templates-owned or hub-wide checker deriving the omission" }, "jointlyRedCandidates": { "found": [ { "rows": ["FS-GG/FS.GG.Templates#385", "FS-GG/FS.GG.Templates#421"], "gate": "required materialize / receiver-validate on PR #420" } ] }, "remedy": "At 2026-08-23T12:39:53Z, land Templates#421 to clear the immediate required-check blocker; then add a hub-owned receiver inventory assertion or materialized caller contract that rejects any kit-materialize receiver lacking opened, synchronize, reopened, and edited, anchoring future instances to that derived class instead of filing a fourth receiver-local row.", "prose": "This comment contains the full reading and disposition for packet 5386017844." }Route receipt: FS-GG/FS.GG.Templates#421 comment 5386039231, digest
cb02f764e67e9a6157e3f61a38d539d863682bc3a712d72906a0013c82c3dd27. Analyst:merlin-b531.EHotwagner commentedon Oct 19, 2026
Keep this existing pending-original index open as evidence. The sole-filer/mandatory-new-packet policy is retired; actual109/020 selected installed instructions now follow canonical intake. This does not adjudicate pending original comments, reconstruct missing records or release any actor/hold. Existing issue/native/Atlas pointers retain recovery; no new queue, mandatory pass or historical sweep is started. Root owns genuine remaining reconciliation under4701.
Whole4701/4712 remain open. All439 inherited and46 later Unknown originals remain distinct/unreleased. Existing owners, original bodies/comments and unavailable-history dispositions survive.