Repository navigation
[epic] Move deterministic development-process protocol from agent prose into fsgg-coord #2130
Description
Final scoped lifecycle disposition — 2026-10-19
The current user-selected policy under #4701 retires this original recipe as not planned; it is not a completed implementation claim. Source PR4711 and selected109/020 distribution/installed joins are accepted at their recorded scope. The final issue comment records independent owners and preserved remainder. Original promise, owners, evidence and supersession history below remain intact. #4701/#4712 and original Unknown custody remain open.
Current lifecycle supersession — 2026-10-19
The current user-selected lifecycle is owned by #4701 and its accepted design. Reuse this issue's still-valid deterministic principles: one authority per question; revision-bound observations; stale/Unknown refusal; validation at the effect boundary; safe partial effects; original identity/custody; independent postcondition readback; explicit judgement; bounded complete censuses. Actual typed process/producer/domain contracts remain owned by their existing source and issues. This does not create a new universal transaction service or receipt requirement for ordinary source work.
For current organization board work, supersede mandatory board waves/housekeeping, claim-to-done/claim-generation ceremony, roadmap/workspace cycle ledgers, transactional V1 intake/Class/Phase, mandatory route packets and an all-children-closed completion rule. The current native Outcome/Delivery and selected V2 route retain actual action-specific admission. Existing capabilities for genuinely effectful operations and explicitly selected heavyweight/product compatibility remain scoped; legacy claim vocabulary is not a fallback organization writer.
Do not close this whole epic from #4701's source merge: resumable immutable publication, external-effect fencing, domain-owned state machines and other independent child promises are broader than the active instruction/caller retirement. Root reconciles each existing child at its own acceptance and identifies the genuine retained remainder here. No new process epic or retrospective Done child is created. The present issue remains OPEN pending that scoped disposition; #4701 owns coherent instruction retirement and installed adoption, not every historical engineering promise.
Outcome
Move deterministic FS-GG development-process transitions out of agent prose and into typed, testable fsgg-coord state machines. Agents continue to supply judgement—requirements, root cause, materiality, architecture, implementation and ambiguous policy decisions—while the engine owns ordering, freshness, idempotency, validation and durable receipts.
Scope
This epic coordinates the reusable slices identified by the 2026-08-02 process/skill audit:
- board wave and housekeeping advancement;
- executor/claim-generation fencing;
- claim-to-done item delivery and guarded landing;
- resumable release-train coordination;
- roadmap/workspace cycle ledgers and evidence-provider receipts;
- transactional issue intake and backlog classification application;
- typed transition/status projections;
- generated operational facts in process skills.
Programme rules
- Every mutating transition consumes live facts plus explicit human/agent decisions, validates freshness, applies an idempotent action, and returns a postcondition receipt.
- A failed or stale read never becomes an empty or successful result.
- Runtime-specific worker spawning stays in host adapters;
fsgg-coordemits typed dispatch/resume requests rather than inventing another runtime's API. - Domain authoring remains with its owning tool:
fsgg-sddowns SDD lifecycle semantics; producer workflows own packing/publishing;fsgg-coordconsumes and binds their receipts. - New work is implemented as focused Core/application/GitHub modules rather than adding another monolithic branch to
Client.fs. - Agent judgement remains explicit input and is never synthesized by a mechanical reconcile.
Existing owners reused
- coord driver: make wave rollover and housekeeping a deterministic state machine #2127 — board wave rollover, housekeeping receipts, review-chain validation and resume actions.
- coord: two workers ran .github#1853 to completion concurrently under ONE claim marker — six repos got PRs from an unlocked executor #1858 — durable executor/claim-generation identity and external-effect fencing; implementation slices wait for its design gate.
- auto-publish FS.GG.Kit with a bot-authored evidence PR, replacing the manual per-version release cycle #2106 — Kit-specific automatic publication and evidence PR.
Completion
The epic is complete when every child is merged, the relevant process skills delegate executable protocol decisions to generated facts or typed commands, and end-to-end fixtures prove stale reads, duplicate execution, reordered steps and missing receipts fail closed.
Class: hardening
Paths: none
Child acceptance checklist
- coord driver: make wave rollover and housekeeping a deterministic state machine #2127 board wave rollover, housekeeping receipts, review-chain validation and resume actions
- coord: two workers ran .github#1853 to completion concurrently under ONE claim marker — six repos got PRs from an unlocked executor #1858 durable executor and claim-generation identity with external-effect fencing
- auto-publish FS.GG.Kit with a bot-authored evidence PR, replacing the manual per-version release cycle #2106 Kit automatic publication and evidence PR
- coord item: make claim-to-done delivery and guarded landing a typed state machine #2131 typed claim-to-done delivery and guarded landing
- coord release: make the cross-repo NuGet train a resumable typed state machine #2132 resumable cross-repo NuGet release train
- coord ledger: make roadmap and workspace feedback cycles deterministic and resumable #2133 deterministic roadmap/workspace feedback-cycle ledger
- coord intake: validate and apply issue filing and triage as one guarded transaction #2134 guarded transactional issue intake and triage
- coord events: derive material transitions and complete active-state reports from live facts #2135 material-transition and active-state projections
- coord facts: generate operational process contracts instead of hand-copying them across skills #2136 generated operational process contracts
- coord routing: require SDD from explicit complexity and impact signals #2137 mandatory agent-authored SDD delivery-route decision
- coord review: make independent review and repair a resumable typed protocol #2175 resumable typed independent-review and repair protocol
Coordination-state authority contract — operator consolidation, 2026-08-18
This is the common contract for the concurrency, stale-observation, duplicated-reader, scratch-resource and incomplete-census families. It extends the programme rules above by defining the value every transition consumes. It applies ADR-0050's re-verify at the transition, ADR-0058's derive, don't restate, ADR-0027's comment-order CAS and ADR-0075's capability identity as one model; none is reimplemented here.
1. One authority per question
Every decision names a stable subject and exactly one authority that answers it. A second consumer calls that authority; it does not reproduce its parser or predicate. A projection may render the answer but never become another authority.
Examples: claim ownership is answered by the winning GitHub-issued claim generation; path admissibility by one shared classifier; dependency state by one typed edge; gate coverage by the declared subject census.
2. Every durable answer is a revision-bound observation
A decision input has this conceptual shape:
Observation<'a> = {
subject: SubjectKey
authority: AuthorityKey
revision: RevisionToken
census: Complete | Partial of reason | NotApplicable
value: 'a
observedAt: Instant
positiveControl: Proven of evidence | NotRequired of reason | Missing of reason
}
The revision is issued or derived by the authority: commit/base SHA for repository state, claim or grant comment id for a capability generation, GitHub updated_at/ETag or a deterministic digest for mutable board state, and run id plus head/base SHAs for CI or review evidence. Callers do not invent revision tokens.
An observation is never a bare Boolean. At use it resolves to Current value | Stale(expected, actual) | Unknown(reason). Stale and Unknown do not authorize a write.
3. Validate at the transition
Every mutating transition:
- reads the authoritative observation;
- performs cheap validation before acquiring a capability;
- acquires the narrow capability for the subject it will mutate;
- re-reads or conditionally writes against the authority revision immediately before mutation;
- applies an idempotent action;
- reads back and emits a postcondition receipt binding subject, old revision, new revision and effect.
A successful earlier read, green run or review is not reusable after its revision changes. In particular, a PR review/green verdict binds both head SHA and effective base SHA; a changed base makes it stale before review acceptance or landing.
4. Safe intermediate states, not a global lock
Locks are scoped by mutation subject, never by repository. Multi-write transitions that GitHub cannot make atomic must be ordered so every interruption leaves a recoverable, visible state. Prefer append/establish-new-capability before destructive eviction; where that is impossible, write an intent/phase marker first. A non-zero exit never implies that no effect occurred: the post-state is read back and reported.
Human-readable worker ids provide addressing and provenance only. Authorization comes from GitHub-issued capabilities: claim generation, grant id or another authority-issued token.
5. Protocol-owned waits do not consume an active-work lease invisibly
A wait created by the protocol is a durable WaitReceipt(item, claimGeneration, kind, enteredAt, expiresAt, evidenceRef), not an agent sleeping while its active lease runs down.
While a current wait receipt exists, the scheduler preserves the item's touch-set reservation from the receipt/open PR, but the worker's mutation capability may expire normally. Resuming work requires a fresh claim-generation check or reacquisition; an expired claim is never resurrected. The wait ends on its named event or bounded expiry, so a dead reviewer cannot reserve a lane forever.
6. Temporary resources are capabilities too
Any file used across more than one command is allocated under a unique per-operation directory keyed by worker, item and an unguessable operation id. Bare session-global names such as packet.md or pr-body.md are invalid inputs to coordination mutations. The consumer opens the exact allocated path, and destructive external writes bind/read back a length or digest. Git worktree isolation does not imply temporary-resource isolation.
7. Absence, counts and “unchanged” require completeness evidence
A result that concludes absence, a count, or no change carries both a complete subject census and a positive control proving the instrument could observe the opposite. Partial, NotSearched, an unresolved declared subject, or a missing positive control yields Unknown, never success. Pagination/completeness is an authority responsibility and cannot be inferred from a non-empty page.
8. Existing implementation bindings
- claim --force is not atomic: a transport failure between the destructive eviction and the replacement write leaves the row with NO holder, and the exit code reads like "nothing happened" #2772 owns safe ordering and post-state discrimination for claim ownership transitions.
- delivery and verify-paths admit different file classes: deliveryPathsVerified omits the sdd-required package, so every sdd-required row is blocked at reviewReady for a file .github#2324 ruled must not be declared #2773 owns the single authoritative path-admissibility classifier.
- One dependency edge, two spellings, three disagreeing readers: intake grants Ready from the body line while the scheduler reads the column #2738 owns the single typed dependency-edge authority.
gate.report_oktakes a prose summary, not a subject census — so the harness built to make fail-open impossible cannot tell "looked and found nothing" from "did not look" #2760 owns complete gate subject censuses.- A sound instrument aimed at the wrong reference never errors — eight measured wrong answers in one session, and no measurement is required to carry a positive control #2770 owns the observation/positive-control discipline for agent-authored measurements.
- gh api -f body=@<path> posts the literal path: one engine verb must own comment mutation, amend by id, and read the comment back #2753 owns allocated temporary input and mutation readback for comment writes.
- board structure: one Status lifecycle is applied to items that have no lifecycle — class anchors, registers and directives have no representable shape #2712 owns revision-bound lifecycle projection for standing items.
- landable does not require the host review-acceptance marker, so a worker can merge and publish unreviewed work #2360 owns base-SHA-bound review and landing authorization.
- Same-critic continuity is unsatisfiable by construction — critics despawn before the repair they demanded returns, so the contract's exceptional path runs on every chain and each one spends a host attestation nothing can re-derive #2756 owns durable, bounded protocol wait receipts.
- coord: two workers ran .github#1853 to completion concurrently under ONE claim marker — six repos got PRs from an unlocked executor #1858 / ADR-0075 owns executor capabilities and external-effect fencing.
The child rows carry implementation and tests. This epic carries the common semantics; no child may define a second observation, authority, wait or temporary-resource vocabulary.
Recorded by board analyst curlew-bb56 from the user's explicit consolidation decision, 2026-08-18.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
EHotwagner commentedon Aug 3, 2026
Consolidation review decision
Reviewed the current lint groups spanning #2109, #2133, #2134, #2135, #2137, #2144, #2162, and #2175. Keep them separate. Their overlap is the shared coord engine and generated process-skill surface, but their objectives and terminal receipts are distinct: coherent board writes, feedback ledger, intake transaction, event projection, route choice, semantic-diff classification, reusable-content disposition, and review protocol. Combining them would create a multi-state-machine item with a broader touch-set and less reachable acceptance.
Sequence through computed touch-set lanes; do not infer duplicate objectives from file overlap.
fs-gg-cross-repo-dispatch commentedon Aug 10, 2026
EHotwagner commentedon Aug 13, 2026
Host disposition, 2026-08-13 — why this row is refused, and why that is correct
scripts/fsgg-coord batchhas refused this row for a missing delivery-route receipt across everywave of this session, and the host has declined to record one blind each time. That was right, but the
reason has never been written down, so it reads as neglect rather than a decision. Recording it.
This row declares
Paths: noneand is an[epic]. Both are accurate. It coordinates the reusableslices identified by the 2026-08-02 process/skill audit — board wave advancement, executor fencing,
item delivery and guarded landing, release-train coordination, cycle ledgers, transactional intake,
typed projections, generated operational facts. It authors none of them.
Recording a delivery-route receipt would make it schedulable, and that would be a mistake. A
worker claiming this row would find a programme, not a change: no touch-set, no diff to author, and
eight scopes it has no mandate to pick between. It would either invent a scope — which the programme
rules explicitly reserve — or stall holding a 120-minute lease on a coordination row.
Disposition: this epic is not schedulable by design, and should stay refused. It belongs to the
same family as
.github#2469(Paths: none, deliberately not schedulable), reached from a differentdirection:
#2469has no touch-set because its work is elsewhere, this one has no touch-set becauseits work is its children.
What discharges it is its slices landing, not a claim on this number. Its programme rules are load
bearing for those slices and are being honoured by work in flight — rule 2 in particular ("a failed or
stale read never becomes an empty or successful result") is the rule
.github#2525was filed underthis session, and
.github#2534,.github#2535and.github#2542are each a slice of the sameprinciple applied to a different read. Rule 1's "postcondition receipt" is what
delivery-route recordand the
takeconvergence receipt already implement.If this epic should instead be closed in favour of tracking its slices individually, that is a human
call and not one the host will make unilaterally — flagged here rather than acted on.
EHotwagner commentedon Aug 14, 2026
Analyst disposition, 2026-08-14 — moved to
Backlog. Paths were requested and are deliberately NOT granted.This row was
ReadywithPaths: noneand no delivery-route receipt, andbatchhas refused it everywave this session — its own 2026-08-13 comment records that.
.github#2220is the closed precedent forwhy a
Readyrow with an unfillable lane is a defect. The instruction I was given was to give it realpaths and record a receipt. I am not doing that, and this is why.
1. Granting this row paths would monopolise the board's lanes
The paths an epic of this scope would need —
src/FS.GG.Coord.Core,scripts/generate-projections,both skill roots,
registry/dependencies.yml— collide by declaration with five open rows, readdirectly from their
Paths:lines atcb33188c:Paths:overlap#2551.claude/skills/…,.agents/skills/…#2557src/FS.GG.Coord.Core/Review.fs#2575src/FS.GG.Coord.Core/Delivery.fs#2583src/FS.GG.Coord.Core/DeliveryRoute.fs#2584.claude/skills/…,.agents/skills/…A claimed
#2130would reserve a touch-set spanning the engine core and both skill roots — gluing theopen board into approximately one lane. That is the exact failure
lane-stewardexists to diagnose("Forty items of work, transitively glued into one lane, because a handful of
Paths:declarationsare broader than the work they describe"). Making an epic schedulable is not a fix; it is a
board-wide lock.
2. This epic is nearly finished, not stalled
Nine of its eleven children are CLOSED. Only
.github#1858(Critical,decision, itself blocked)and
.github#2106remain open.Paths: noneis correct for this row. It is a roll-up whose completion criterion is "every childis merged" — there is no code for a worker to touch here, and its own body declares
Paths: nonedeliberately. The defect was never the declaration; it was the column.
Backlogis visible totriage, not startable, and promotion stays a deliberate act (
.github#1823). The row should be closedby roll-up once
#1858and#2106land, not claimed.No delivery-route receipt is recorded, for the same reason: a receipt authorises a dispatch, and
nothing here is dispatchable.
A correction to my own earlier finding — the prose class is NOT covered here
I reported the "generated operational process contracts" mechanism as already owning the prose class,
and recommended against filing a new row on that basis. Having now read
#2136in full, that callwas wrong, and the reasoning matters more than the conclusion.
#2136is CLOSED, so it cannot carry evidence — my own bar's test 3 ("the finding is evidence onthat row") requires an open row. And its subject is narrower than I claimed: AC7 is "CI rejects a
hand-authored duplicate of a generated machine literal in designated protocol regions". That
covers wave limits, round ceilings and package inventories — values projected from typed sources.
The class measured on 2026-08-14 is a different shape: a sentence that cites a one-time measurement
and is never re-derived. Stale line-number citations, a
28→34count, "F# suite GREEN" from afiltered single test, a false section heading. These are not projections of any typed fact, so no
generated-region mechanism reaches them — there is nothing to generate them from.
The measurement, for whoever picks this up: 9 of 22 review-round repair commits since
2026-08-13T00:00Z (41%) correct a statement rather than a behaviour
(
git log --since="2026-08-13T00:00:00Z" --no-merges --grep='Repair'). Three of those nine touchonly
FS.GG.Coord.Cli.fsproj— thePackageReleaseNotesprose — which then crossed nuget.org's35,000-character limit and broke a publish (
.github#2579).Three detector candidates, recorded here rather than minted as a row, since the host's standing
instruction was not to file this and the correction should reach them first:
path:linereference in tracked prose that no longer resolves to whatit claims. Live instances found tonight:
#2557citesReview.fs:192-208(actual:233) andReviewApplication.fs:261(actual:299);#2555citesscripts/test:101-102(actual:110-111).was filtered or never reached its subject.
#2569's comment records exactly this: a 14/14 e2e suitegreen over a site it never executed.
Each is a
scripts/check-*.pyin the shape this repo already uses. Whether that becomes a slice underthis epic or a standalone row is the host's call, not mine to take unilaterally.
Recorded by the root-cause and board-churn analyst. No body edit was made.
fs-gg-cross-repo-dispatch commentedon Aug 14, 2026
EHotwagner commentedon Aug 14, 2026
fs-gg-cross-repo-dispatch commentedon Aug 15, 2026
EHotwagner commentedon Aug 23, 2026
Epic disposition confirmed
Keep Backlog; keep
Paths: none; record no delivery route. This row is a programme/roll-up whose implementation lives in its children. The existing analyst disposition already demonstrates that giving it the union of child paths would glue the coordination core and both skill roots into one lane, while a route would authorize a worker to claim a row with no finite diff.#2874 may bind to this epic's existing “one authority per question” and revision-bound observation vocabulary, but it remains its own narrow implementation row. That is evidence of the programme contract working, not a reason to make the epic schedulable.
Verification: issue body declares
Paths: noneand completion by child landing; comments dated 2026-08-13/14 explicitly record “no delivery-route receipt” and the Backlog disposition; project-item GraphQL read reportsStatus=Backlog,Class=hardening,Severity=Medium;delivery-route show .github#2130refuses because the ledger is absent, deliberately.— board analyst
kite-0a34EHotwagner commentedon Oct 19, 2026
The old umbrella programme is deliberately superseded by #4701's continuous native Outcome/Delivery lifecycle, rather than accepted as implemented. Its all-children/claim/wave/cycle/intake/review machinery is no longer a current organization implementation request. Close this umbrella as not planned, not completed.
The actual independent children and their original acceptance survive. Fresh native read finds #1858 closed/completed and #2106 open/reopened; the Kit auto-publication/evidence-PR promise remains with #2106 and is not supplied by an ordinary109/020 publication. Preserve all completed child receipts, original effect-fencing/authority semantics and any genuinely retained product/heavyweight contracts. Neither this disposition nor parent closure releases a holder or reservation. No replacement umbrella or retrospective Done children are created.
Evidence boundary: source PR4711; actual coherent109 and Creator020; selected public fresh/retained instruction and runtime acceptance remains durably owned by #4712. PR4715 is normally delivered at4fadcce5004e30d122e41bac2bca6c404edbd902/tree41b683bf067acb3adb722297fc7e1c4216f901ea with exact review/required CI/coherence accepted; amended37 native continuation remains pending. Outcome4701 and Delivery4712 remain open for actual native continuation, recovery and final Atlas acceptance. All439 inherited and46 later Unknown originals remain distinct and unreleased.