feat(seatpost): post-only seat-verdict endpoint in ld-runtime (LR-20261111-025) #939

Merged
pi-landing merged 5 commits from lr-20261111-025/seatpost into live 2026-11-11 17:31:59 +00:00
Collaborator

Spec 025 (part 1 of 3): the post-only seat-verdict endpoint in ld-runtime

Seats anchor when they can read a PR's comments before posting their verdict
(seat B4 on #934 listed the comments and read seat A's verdict). This PR is the
post-only half of the fix: a seat gets the diff/tests/guard as a prepared local
bundle (part 3) and posts through this endpoint, which has no list/read verb
for comments or reviews
— closing homelab-88's N5 (verdict-cli printed
other comments' open findings) by construction, not by prompt.

Head shape: three stacked commits (brief rule 5) — the endpoint
(955ab6b3), the AMENDMENT-2 rework answering homelab-88's review
(ef493ca1), and two review-round fix commits (2fac01a2, ac105cd0). Seats
review the full base..head diff.

What is here (final shape)

  • lab-director/dispatcher/seatpost/: ONE exact write route /v1/seat-post,
    PUT = register, POST = post. Every other method → 405 (audited);
    every other path → 404.
  • N1 — the server mints the bundle id (128-bit, never caller-chosen;
    crypto/rand, injectable in tests). Register pins {sid, repo, pr, head};
    the 200 returns the minted id, which the seat-bundle tooling (part 3)
    carries to the seat's folder.
  • N3 — the body is bound to the pin. The verdict's first block (the
    leading run of non-blank lines — exactly what the census reads) must declare
    the pinned sid (SESSION: line or relay sid=) and a head that equals the
    pin. The first DECLARING line decides (bold statement with a stance word —
    AGREE/APPROVE/REQUEST_CHANGES/HOLD/…, the ## Verdict — <sha> heading form,
    or the relay LD-VERDICT line); a decoy above the real statement refuses
    instead of passing. A body the census cannot attribute is not transported.
  • B2 — claim before post. The endpoint INSERTs a claimed row (its own
    partial unique index) BEFORE calling Forgejo and refuses on ANY insert
    error without posting. A failed post burns the bundle — the claim blocks
    every later post, is logged for a human, and re-registering a fresh bundle
    is the recovery. A posted-row insert failure still answers 200 (the comment
    exists; lying would invite a duplicate) and the claim keeps the one-post
    guarantee.
  • Head mismatch against the LIVE PR head (re-read at post time) is
    refused; no response to an unauthenticated caller echoes shas.
  • Every call on the route — register and post, including every refused
    one
    — is audited to the insert-only seat_posts table (refused register
    rows can never be read back as the pin: the read filters
    result='registered').
  • N7 — the wiring asserts both partial unique indexes at boot and refuses
    posts with a named 503 while the migration is absent.
  • N8 — the listener binds the pod IP only. An empty OR explicit wildcard
    host (:8098, 0.0.0.0, ::, [::]) resolves the pod IP via HOSTNAME;
    failure refuses the listener. Never a wildcard bind.
  • Posting uses the pod's existing LD_FORGEJO_TOKEN — the pi-landing copy
    held only in ld-fleet. No new identity. The token is never logged;
    refusals are fixed one-line sentences, upstream error text goes to the pod
    log only.

B1 — provenance, mounted on 8097 only

seat_posts records the seat's sid and the Forgejo comment_id of the
post. The census counts a gated-repo verdict by provenance, not author:
GET /v1/seat-post/provenance?repo=&pr=&comment_id= → {head, sid, result}
or 404 — strict params, no list verb, mounted only on the 8097
landing-only listener
. The seat-facing 8098 handler 404s it (tested), and
it has its own rate allowance so census sweeps can't 429 a real verdict.
When 8097 is off, one named boot line says the read is absent and gated-repo
landings fail closed.

Done-when flows (fixed at hand-over)

  1. seat-bundle <repo> <pr> <head> — not this PR (part 3: the sandbox
    tooling + seat template).
  2. seat-post posts one verdict on the bundle's pinned PR/head — PROVEN
    (endpoint half): TestPostTransportsTheVerdictVerbatim,
    TestSecondPostIsAConflict, TestClaimConflictRefusesWithoutPosting,
    TestStaleClaimBurnsTheBundle,
    TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond; the client
    script lands with the bundle in part 3.
  3. Seat pane gets no FORGEJO_API_KEY and no git credential — endpoint half
    PROVEN
    : the seat's only Forgejo route is this route and the runtime
    holds the only copy of the posting token (TestNilPosterRefusesPerCall,
    wiring tests in cmd/ld-runtime/seat_post_test.go). The env-scrubbing
    wrapper lands with the template (part 3).
  4. Tests — PROVEN:
    • a seat can't GET /comments or /reviews: TestNoReadVerbAtTheHTTPSurface
      (405s on the route; 404s on /comments, /reviews, every other path);
    • a second post is refused: TestSecondPostIsAConflict,
      TestClaimConflictRefusesWithoutPosting, and
      TestConcurrentPostsCannotBothReachForgejo (exactly one Forgejo write
      under racing posts);
    • a wrong head is refused: TestPostRefusals subtests incl.
      head-mismatch;
    • homelab-88 N5 by construction: the Poster seam has no comment/review
      read method — no code path can print another seat's findings.
    • N3 binding: TestBodyPinBinding (decoy-first-block refused, both fleet
      grammars, backtick forms, first-declaration-wins);
    • N1: TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle;
    • N4: TestRegisterInsertFailureRefuses, TestNoShaInAnyRefusalBody;
    • N7: TestSchemaAbsentRefusesPosts, TestSeatPostSchemaMissingRefusesPosts;
    • B1: TestProvenanceHandler, TestProvenanceIsMountedOnTheLookupListener,
      TestProvenanceIsNotOnThePostHandler, TestProvenanceHasItsOwnAllowance;
    • F1 sid wiring: TestRegistrationReadCarriesTheSid,
      TestSeatPostWiringCarriesTheSid.
  5. The seat-template PR — not this PR (part 3).

Deferred per El Director (follow-up, named here as ruled)

  • N2 — a repo allowlist (today any owner/repo pi-landing can comment on
    is accepted at register).
  • N5 — per-caller rate limiting / bundle expiry (today one limiter per
    listener).

Honest scope (per AMENDMENT 1)

This endpoint buys no comment/review read path (anchoring closed by
construction) and a target pinned by the implementer's registration.
It does not stop anything in sbx-lab from posting a fake verdict through
it, because a seat and an implementer are the same Unix user. The gateway
sid check (relay and census) is what makes a fake verdict worthless
— and
B1's provenance read is what lets the census count only verdicts that
actually travelled this route. Full isolation (single-use pods) is queued
separately and deliberately not built here.

Proof

  • go vet ./... — clean.
  • go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ — ok
    (seatpost 29 tests / 100+ subtests incl. the concurrency test at
    -race -count=25; record 33; ld-runtime 57).
  • go test -race -count=1 ./run/ — ok except 7 pre-existing sandbox-only
    failures (TempDir RemoveAll cleanup: … gomodcache … permission denied),
    reproduced identically on a clean origin/live checkout here; zero
    assertion failures. Includes TestPostIssueCommentPostsTheBodyVerbatim.
  • Guard (scripts/gits-sbx-epic-test.sh, full run, same runner): live FAIL
    list = 20, head FAIL list = 20, NEW FAILURES: 0 (identical modulo
    per-run tmp-path text). The guard predates the stacked commits; the
    dispatcher is not a guard surface.

Roll-out order (per the lead)

  1. This PR (endpoint) → CI builds the dispatcher image.
  2. Prod PR (after spec 017's pin lands): image pin rebased on 017's, the
    8098 Service port + a CNP scoped to sbx-lab by namespace and app label,
    and the seat_posts migration (sid column, both partial unique indexes)
    via the 023 auto-sync. Provenance rides 017's 8097 exposure.
  3. Seat template + seat-bundle/seat-post sandbox tooling.

Gate-adjacent: this changes the seat/verdict tooling — homelab-88's
independent file review (BLOCKED the first head; AMENDMENT-2 answered B1/B2
and took N1/N3/N4/N7/N8) plus two fresh seats per head, before El Director's
go.

no independent walk: implementer-run checks only

Lab-Run: LR-20261111-025

# Spec 025 (part 1 of 3): the post-only seat-verdict endpoint in ld-runtime Seats anchor when they can read a PR's comments before posting their verdict (seat B4 on #934 listed the comments and read seat A's verdict). This PR is the post-only half of the fix: a seat gets the diff/tests/guard as a prepared local bundle (part 3) and posts through this endpoint, which has **no list/read verb for comments or reviews** — closing homelab-88's N5 (`verdict-cli` printed other comments' open findings) by construction, not by prompt. **Head shape:** three stacked commits (brief rule 5) — the endpoint (`955ab6b3`), the AMENDMENT-2 rework answering homelab-88's review (`ef493ca1`), and two review-round fix commits (`2fac01a2`, `ac105cd0`). Seats review the full base..head diff. ## What is here (final shape) - `lab-director/dispatcher/seatpost/`: ONE exact write route `/v1/seat-post`, `PUT` = **register**, `POST` = **post**. Every other method → 405 (audited); every other path → 404. - **N1 — the server mints the bundle id** (128-bit, never caller-chosen; `crypto/rand`, injectable in tests). Register pins `{sid, repo, pr, head}`; the 200 returns the minted id, which the seat-bundle tooling (part 3) carries to the seat's folder. - **N3 — the body is bound to the pin.** The verdict's first block (the leading run of non-blank lines — exactly what the census reads) must declare the pinned sid (`SESSION:` line or relay `sid=`) and a head that equals the pin. The first DECLARING line decides (bold statement with a stance word — AGREE/APPROVE/REQUEST_CHANGES/HOLD/…, the `## Verdict — <sha>` heading form, or the relay `LD-VERDICT` line); a decoy above the real statement refuses instead of passing. A body the census cannot attribute is not transported. - **B2 — claim before post.** The endpoint INSERTs a `claimed` row (its own partial unique index) BEFORE calling Forgejo and refuses on ANY insert error without posting. A failed post burns the bundle — the claim blocks every later post, is logged for a human, and re-registering a fresh bundle is the recovery. A posted-row insert failure still answers 200 (the comment exists; lying would invite a duplicate) and the claim keeps the one-post guarantee. - **Head mismatch** against the LIVE PR head (re-read at post time) is refused; no response to an unauthenticated caller echoes shas. - Every call on the route — register and post, **including every refused one** — is audited to the insert-only `seat_posts` table (refused register rows can never be read back as the pin: the read filters `result='registered'`). - **N7 — the wiring asserts both partial unique indexes at boot** and refuses posts with a named 503 while the migration is absent. - **N8 — the listener binds the pod IP only.** An empty OR explicit wildcard host (`:8098`, `0.0.0.0`, `::`, `[::]`) resolves the pod IP via HOSTNAME; failure refuses the listener. Never a wildcard bind. - Posting uses the pod's existing `LD_FORGEJO_TOKEN` — the pi-landing copy held only in ld-fleet. **No new identity.** The token is never logged; refusals are fixed one-line sentences, upstream error text goes to the pod log only. ## B1 — provenance, mounted on 8097 only `seat_posts` records the seat's `sid` and the Forgejo `comment_id` of the post. The census counts a gated-repo verdict by provenance, not author: `GET /v1/seat-post/provenance?repo=&pr=&comment_id=` → `{head, sid, result}` or 404 — strict params, no list verb, **mounted only on the 8097 landing-only listener**. The seat-facing 8098 handler 404s it (tested), and it has its own rate allowance so census sweeps can't 429 a real verdict. When 8097 is off, one named boot line says the read is absent and gated-repo landings fail closed. ## Done-when flows (fixed at hand-over) 1. `seat-bundle <repo> <pr> <head>` — **not this PR** (part 3: the sandbox tooling + seat template). 2. `seat-post` posts one verdict on the bundle's pinned PR/head — **PROVEN** (endpoint half): `TestPostTransportsTheVerdictVerbatim`, `TestSecondPostIsAConflict`, `TestClaimConflictRefusesWithoutPosting`, `TestStaleClaimBurnsTheBundle`, `TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond`; the client script lands with the bundle in part 3. 3. Seat pane gets no FORGEJO_API_KEY and no git credential — **endpoint half PROVEN**: the seat's only Forgejo route is this route and the runtime holds the only copy of the posting token (`TestNilPosterRefusesPerCall`, wiring tests in `cmd/ld-runtime/seat_post_test.go`). The env-scrubbing wrapper lands with the template (part 3). 4. Tests — **PROVEN**: - a seat can't GET /comments or /reviews: `TestNoReadVerbAtTheHTTPSurface` (405s on the route; 404s on `/comments`, `/reviews`, every other path); - a second post is refused: `TestSecondPostIsAConflict`, `TestClaimConflictRefusesWithoutPosting`, and `TestConcurrentPostsCannotBothReachForgejo` (exactly one Forgejo write under racing posts); - a wrong head is refused: `TestPostRefusals` subtests incl. `head-mismatch`; - homelab-88 N5 by construction: the `Poster` seam has no comment/review read method — no code path can print another seat's findings. - N3 binding: `TestBodyPinBinding` (decoy-first-block refused, both fleet grammars, backtick forms, first-declaration-wins); - N1: `TestRegisterMintsTheBundleID`, `TestRegisterRefusesACallerChosenBundle`; - N4: `TestRegisterInsertFailureRefuses`, `TestNoShaInAnyRefusalBody`; - N7: `TestSchemaAbsentRefusesPosts`, `TestSeatPostSchemaMissingRefusesPosts`; - B1: `TestProvenanceHandler`, `TestProvenanceIsMountedOnTheLookupListener`, `TestProvenanceIsNotOnThePostHandler`, `TestProvenanceHasItsOwnAllowance`; - F1 sid wiring: `TestRegistrationReadCarriesTheSid`, `TestSeatPostWiringCarriesTheSid`. 5. The seat-template PR — **not this PR** (part 3). ## Deferred per El Director (follow-up, named here as ruled) - **N2** — a repo allowlist (today any `owner/repo` pi-landing can comment on is accepted at register). - **N5** — per-caller rate limiting / bundle expiry (today one limiter per listener). ## Honest scope (per AMENDMENT 1) This endpoint buys **no comment/review read path** (anchoring closed by construction) and a **target pinned by the implementer's registration**. It does **not** stop anything in sbx-lab from posting a fake verdict through it, because a seat and an implementer are the same Unix user. **The gateway sid check (relay and census) is what makes a fake verdict worthless** — and B1's provenance read is what lets the census count only verdicts that actually travelled this route. Full isolation (single-use pods) is queued separately and deliberately not built here. ## Proof - `go vet ./...` — clean. - `go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/` — ok (seatpost 29 tests / 100+ subtests incl. the concurrency test at `-race -count=25`; record 33; ld-runtime 57). - `go test -race -count=1 ./run/` — ok except 7 pre-existing sandbox-only failures (`TempDir RemoveAll cleanup: … gomodcache … permission denied`), reproduced identically on a clean `origin/live` checkout here; zero assertion failures. Includes `TestPostIssueCommentPostsTheBodyVerbatim`. - Guard (`scripts/gits-sbx-epic-test.sh`, full run, same runner): live FAIL list = 20, head FAIL list = 20, **NEW FAILURES: 0** (identical modulo per-run tmp-path text). The guard predates the stacked commits; the dispatcher is not a guard surface. ## Roll-out order (per the lead) 1. This PR (endpoint) → CI builds the dispatcher image. 2. Prod PR (after spec 017's pin lands): image pin rebased on 017's, the 8098 Service port + a CNP scoped to sbx-lab by namespace and app label, and the `seat_posts` migration (sid column, both partial unique indexes) via the 023 auto-sync. Provenance rides 017's 8097 exposure. 3. Seat template + `seat-bundle`/`seat-post` sandbox tooling. Gate-adjacent: this changes the seat/verdict tooling — homelab-88's independent file review (BLOCKED the first head; AMENDMENT-2 answered B1/B2 and took N1/N3/N4/N7/N8) plus two fresh seats per head, before El Director's go. no independent walk: implementer-run checks only Lab-Run: LR-20261111-025
feat(seatpost): post-only seat-verdict endpoint in ld-runtime (LR-20261111-025)
All checks were successful
CI Review / receiver-test (pull_request) Successful in 5s
CI Review / runner-manifest-test (pull_request) Successful in 6s
Build Lab Director Dispatcher Image / preflight (pull_request) Successful in 4s
CI Review / helm-validate (pull_request) Successful in 10s
Lint & Validate / shellcheck (pull_request) Successful in 6s
CI Review / alert-receiver-test (pull_request) Successful in 20s
Lint & Validate / yaml-lint (pull_request) Successful in 23s
CI Review / record-sql-test (pull_request) Successful in 1m3s
Build Lab Director Dispatcher Image / build-and-push (pull_request) Successful in 2m5s
Lint & Validate / terraform-validate (pull_request) Successful in 2m21s
CI Review / cockpit-e2e (pull_request) Successful in 2m49s
CI Review / cockpit-test (pull_request) Successful in 2m51s
CI Review / dispatcher-test (pull_request) Successful in 3m9s
955ab6b334
Seats anchor when they can read a PR's comments before posting (seat B4,
infra-core #934). This endpoint is the post-only half of spec 025's fix:
the implementer registers a bundle (PUT: repo/pr/40-hex head), the seat
posts its verdict (POST), and the route has NO read verb at all - it can
never list or fetch comments or reviews, so it closes homelab-88's N5
(verdict-cli printed other comments' open findings) by construction.

- seatpost: one exact path /v1/seat-post, PUT=register POST=post, every
  other method 405/audited, every other path 404; one post per bundle
  (in-process claim + documented partial unique index as the durable
  arbiter); live-head check against the registered pin; fixed refusal
  sentences that are also the audit row's result; rate limit first;
  verdict body transported verbatim (transport, not judgement).
- record: seat_posts insert-only ledger (registrations and posts, refused
  calls included); the registration read filters result='registered' so a
  refused register can never be read back as the pin.
- run: PostIssueComment + exported PullHead, strictly additive.
- cmd/ld-runtime: LD_SEAT_POST_ADDR gates the fifth listener; posting uses
  the pod's LD_FORGEJO_TOKEN (the pi-landing copy held only in ld-fleet);
  no new identity, token never logged.

HONEST SCOPE: this buys no read path and an implementer-pinned target; it
does NOT stop a same-Unix-user process in sbx-lab from posting a fake
verdict through it - the gateway sid check (relay and census) is what
makes a fake verdict worthless. Full isolation (single-use pods) is
queued separately.

The seat_posts table's migration rides this run's prod PR; until it
applies, the endpoint logs and answers (record.ErrSeatPostsAbsent is the
named, expected roll-out case), exactly like the seat-lookup ledger.

Lab-Run: LR-20261111-025
Collaborator

REQUEST_CHANGES — ld-reviewer — head 955ab6b334
SESSION: LR-20261111-025-seatA-20261111T1534Z
MODEL: omniroute/deepseek-flash

VERDICT: HOLD
MODEL: omniroute/deepseek-flash · SESSION: LR-20261111-025-seatA-20261111T1534Z
HEAD: 955ab6b334
FINDINGS:
PR body "Done when" flow 2 cites TestPostPostsVerbatimBody: no function of that name exists at this head (grep -rn "func TestPostPostsVerbatimBody(" lab-director/dispatcher -> no match); the behaviour is proven as TestPostTransportsTheVerdictVerbatim (lab-director/dispatcher/seatpost/post_test.go:429).
PR body "Done when" flow 3 cites TestNilPosterRefusesNamingTheVariable: no function of that name exists (grep -rn "func TestNilPosterRefusesNamingTheVariable(" lab-director/dispatcher -> no match); the behaviour is proven as TestNilPosterRefusesPerCall (seatpost/post_test.go:816).
PR body "Done when" flow 4 cites TestNoReadVerb: no function of that exact name exists (grep -rn "func TestNoReadVerb(" lab-director/dispatcher -> no match; only the prefix of TestNoReadVerbAtTheHTTPSurface, seatpost/post_test.go:702).
PR body "Done when" flow 4 cites TestPostRefusesWhenLiveHeadMoved: no function of that name exists (grep -rn "func TestPostRefusesWhenLiveHeadMoved(" lab-director/dispatcher -> no match); the wire-level head-mismatch case is the subtest TestPostRefusals/head-mismatch (seatpost/post_test.go:620).
Consequence (checkable): 4 of the 9 test names carried by the "Done when" proof block do not resolve at this head, so "PROVEN (test name)" cannot be verified by name as written. The fix is the PR body (cite the real test names, or mark the flows endpoint-half proven), not the code.
No code defect found against step-5 claims: one exact route with PUT/POST only and 405+Allow otherwise (seatpost/post.go:373-393); Poster seam is only PostIssueComment+PullHead with no comment/review list or fetch (post.go:167-173); repo/pr/head come only from the registration (post.go:549, body struct in post() has bundle+body only); verdict body forwarded unmodified (post.go:528, 612); token never logged (cmd/ld-runtime/seat_post.go:111-135, and LD_FORGEJO_TOKEN is absent from configNames in cmd/ld-runtime/main.go, so it is not in runtimeConfig); every call on the path audited, refusals included, one row per call (post.go:738-790).
TEST: cd lab-director/dispatcher && go vet ./... && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0

**REQUEST_CHANGES — ld-reviewer — head 955ab6b3342deefe3864c5bd9b92bf404f737dc9** SESSION: LR-20261111-025-seatA-20261111T1534Z MODEL: omniroute/deepseek-flash VERDICT: HOLD MODEL: omniroute/deepseek-flash · SESSION: LR-20261111-025-seatA-20261111T1534Z HEAD: 955ab6b3342deefe3864c5bd9b92bf404f737dc9 FINDINGS: PR body "Done when" flow 2 cites `TestPostPostsVerbatimBody`: no function of that name exists at this head (`grep -rn "func TestPostPostsVerbatimBody(" lab-director/dispatcher` -> no match); the behaviour is proven as `TestPostTransportsTheVerdictVerbatim` (lab-director/dispatcher/seatpost/post_test.go:429). PR body "Done when" flow 3 cites `TestNilPosterRefusesNamingTheVariable`: no function of that name exists (`grep -rn "func TestNilPosterRefusesNamingTheVariable(" lab-director/dispatcher` -> no match); the behaviour is proven as `TestNilPosterRefusesPerCall` (seatpost/post_test.go:816). PR body "Done when" flow 4 cites `TestNoReadVerb`: no function of that exact name exists (`grep -rn "func TestNoReadVerb(" lab-director/dispatcher` -> no match; only the prefix of `TestNoReadVerbAtTheHTTPSurface`, seatpost/post_test.go:702). PR body "Done when" flow 4 cites `TestPostRefusesWhenLiveHeadMoved`: no function of that name exists (`grep -rn "func TestPostRefusesWhenLiveHeadMoved(" lab-director/dispatcher` -> no match); the wire-level head-mismatch case is the subtest `TestPostRefusals/head-mismatch` (seatpost/post_test.go:620). Consequence (checkable): 4 of the 9 test names carried by the "Done when" proof block do not resolve at this head, so "PROVEN (test name)" cannot be verified by name as written. The fix is the PR body (cite the real test names, or mark the flows endpoint-half proven), not the code. No code defect found against step-5 claims: one exact route with PUT/POST only and 405+Allow otherwise (seatpost/post.go:373-393); Poster seam is only PostIssueComment+PullHead with no comment/review list or fetch (post.go:167-173); repo/pr/head come only from the registration (post.go:549, body struct in post() has bundle+body only); verdict body forwarded unmodified (post.go:528, 612); token never logged (cmd/ld-runtime/seat_post.go:111-135, and LD_FORGEJO_TOKEN is absent from configNames in cmd/ld-runtime/main.go, so it is not in runtimeConfig); every call on the path audited, refusals included, one row per call (post.go:738-790). TEST: cd lab-director/dispatcher && go vet ./... && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0
Collaborator

APPROVE — ld-reviewer — head 955ab6b334
SESSION: LR-20261111-025-seatB-20261111T1534Z
MODEL: omniroute/deepseek-flash

VERDICT: APPROVE
MODEL: omniroute/deepseek-flash · SESSION: LR-20261111-025-seatB-20261111T1534Z
HEAD: 955ab6b334

FINDINGS (none blocking; each checkable):

  1. NON-BLOCKING (PR-body doc drift): the four cited proof names do not exist as written. Body says TestPostPostsVerbatimBody (actual: seatpost/post_test.go:429 TestPostTransportsTheVerdictVerbatim), TestNoReadVerb (actual: :702 TestNoReadVerbAtTheHTTPSurface), TestNilPosterRefusesNamingTheVariable (actual: :816 TestNilPosterRefusesPerCall, and it is in seatpost/, not cmd/ld-runtime/), TestPostRefusesWhenLiveHeadMoved (actual: subtest "head-mismatch" of :612 TestPostRefusals). Substance is proven; only the citations are stale.
  2. NON-BLOCKING (scope wording): "every call audited" is true for every method on /v1/seat-post, but an off-path request (404) writes no row by design (post.go Handler comment). Recommend the body say "every call on the route".
  3. NON-BLOCKING (asymmetry, test-wiring only): a nil Store is a 500 on the post path but an unguarded 200 on the register path (register skips its read when g.Store == nil and record() returns nil). newSeatPostServer refuses a nil store, so no live runtime reaches it.

CLAIMS CHECKED (all hold at this head):

  • no read verb: seatpost.Poster has only PostIssueComment/PullHead; Store only Insert/Registration/Posted; Handler 404s every path != Path and 405s every method != PUT/POST. No comment/review fetch anywhere in seatpost/, seat_post.go or the new run/forgejo.go funcs. TestNoReadVerbAtTheHTTPSurface passes (25 subtests incl. /comments, /reviews, /v1/seat-posts).
  • one post per bundle: per-bundle claim (waits, then re-reads Posted) + partial unique index contract documented in record/seat_posts.go; conflict mapped to 409. TestSecondPostIsAConflict, TestConcurrentPostsCannotBothReachForgejo (asserts exactly 1 Forgejo write, 1x200 + 1x409), TestRegisterConflict pass.
  • head-mismatch refusal: live head re-read via run.PullHead and compared to the registered pin before any write; 409 with short shas. TestPostRefusals/head-mismatch passes; head-read failure is a fixed 502 with detail only in the pod log.
  • repo/pr/head only from registration: post() takes no target from the seat; c.Repo/c.PR = reg.*, and both Forgejo calls use reg.Owner()/reg.RepoName()/reg.PR. Post 200 body is {posted, comment_id} only.
  • verdict verbatim: body := req.Body, posted and audited unchanged (no grammar check). run.PostIssueComment wire test asserts "body":"<verdict>" and the returned id.
  • token never logged: seatPostPoster keeps the token in a field only; every refusal sentence is a constant/fixed one-liner, upstream text is oneLine'd into Logf, and Forgejo error strings name the path, not headers.
  • unsafe values excluded: repoPattern + dot-segment check, isHex40 pin, capBundle for the audit column only, pr parsed as a real JSON integer.
  • "no independent walk: implementer-run checks only" — present at the end of the body, so the proof is correctly scoped to the implementer's own runs.

TEST: cd lab-director/dispatcher && go vet ./... -> 0
TEST: cd lab-director/dispatcher && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0 (all three packages ok)
NOTE: ./run/ not in the required command; its 7 pre-existing sandbox TempDir/gomodcache cleanup failures are untouched by this diff, and the added run/forgejo_test.go TestPostIssueCommentPostsTheBodyVerbatim asserts no cleanup.
Method: fresh clone, checked out 955ab6b3 (rev-parse confirms it, head did not move), diffed against base 35a336157d. No PR comments or reviews read; verdict-cli not run.

**APPROVE — ld-reviewer — head 955ab6b3342deefe3864c5bd9b92bf404f737dc9** SESSION: LR-20261111-025-seatB-20261111T1534Z MODEL: omniroute/deepseek-flash VERDICT: APPROVE MODEL: omniroute/deepseek-flash · SESSION: LR-20261111-025-seatB-20261111T1534Z HEAD: 955ab6b3342deefe3864c5bd9b92bf404f737dc9 FINDINGS (none blocking; each checkable): 1. NON-BLOCKING (PR-body doc drift): the four cited proof names do not exist as written. Body says `TestPostPostsVerbatimBody` (actual: seatpost/post_test.go:429 TestPostTransportsTheVerdictVerbatim), `TestNoReadVerb` (actual: :702 TestNoReadVerbAtTheHTTPSurface), `TestNilPosterRefusesNamingTheVariable` (actual: :816 TestNilPosterRefusesPerCall, and it is in seatpost/, not cmd/ld-runtime/), `TestPostRefusesWhenLiveHeadMoved` (actual: subtest "head-mismatch" of :612 TestPostRefusals). Substance is proven; only the citations are stale. 2. NON-BLOCKING (scope wording): "every call audited" is true for every method on /v1/seat-post, but an off-path request (404) writes no row by design (post.go Handler comment). Recommend the body say "every call on the route". 3. NON-BLOCKING (asymmetry, test-wiring only): a nil Store is a 500 on the post path but an unguarded 200 on the register path (register skips its read when g.Store == nil and record() returns nil). newSeatPostServer refuses a nil store, so no live runtime reaches it. CLAIMS CHECKED (all hold at this head): - no read verb: seatpost.Poster has only PostIssueComment/PullHead; Store only Insert/Registration/Posted; Handler 404s every path != Path and 405s every method != PUT/POST. No comment/review fetch anywhere in seatpost/, seat_post.go or the new run/forgejo.go funcs. TestNoReadVerbAtTheHTTPSurface passes (25 subtests incl. /comments, /reviews, /v1/seat-posts). - one post per bundle: per-bundle claim (waits, then re-reads Posted) + partial unique index contract documented in record/seat_posts.go; conflict mapped to 409. TestSecondPostIsAConflict, TestConcurrentPostsCannotBothReachForgejo (asserts exactly 1 Forgejo write, 1x200 + 1x409), TestRegisterConflict pass. - head-mismatch refusal: live head re-read via run.PullHead and compared to the registered pin before any write; 409 with short shas. TestPostRefusals/head-mismatch passes; head-read failure is a fixed 502 with detail only in the pod log. - repo/pr/head only from registration: post() takes no target from the seat; c.Repo/c.PR = reg.*, and both Forgejo calls use reg.Owner()/reg.RepoName()/reg.PR. Post 200 body is {posted, comment_id} only. - verdict verbatim: body := req.Body, posted and audited unchanged (no grammar check). run.PostIssueComment wire test asserts `"body":"<verdict>"` and the returned id. - token never logged: seatPostPoster keeps the token in a field only; every refusal sentence is a constant/fixed one-liner, upstream text is oneLine'd into Logf, and Forgejo error strings name the path, not headers. - unsafe values excluded: repoPattern + dot-segment check, isHex40 pin, capBundle for the audit column only, pr parsed as a real JSON integer. - "no independent walk: implementer-run checks only" — present at the end of the body, so the proof is correctly scoped to the implementer's own runs. TEST: cd lab-director/dispatcher && go vet ./... -> 0 TEST: cd lab-director/dispatcher && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0 (all three packages ok) NOTE: ./run/ not in the required command; its 7 pre-existing sandbox TempDir/gomodcache cleanup failures are untouched by this diff, and the added run/forgejo_test.go TestPostIssueCommentPostsTheBodyVerbatim asserts no cleanup. Method: fresh clone, checked out 955ab6b3 (rev-parse confirms it, head did not move), diffed against base 35a336157df27578698b50e0f21f69b1aa71c564. No PR comments or reviews read; verdict-cli not run.
Collaborator

APPROVE — ld-reviewer — head 955ab6b334
SESSION: LR-20261111-025-seatA-20261111T1534Z
MODEL: omniroute/deepseek-flash

resolved TestPostPostsVerbatimBody — citation fixed and verified resolving: PR body "Done when" flow 2 now cites TestPostTransportsTheVerdictVerbatim, which resolves at head 955ab6b3 in lab-director/dispatcher/seatpost/post_test.go:429.
resolved TestNilPosterRefusesNamingTheVariable — citation fixed and verified resolving: flow 3 now cites TestNilPosterRefusesPerCall, resolving at seatpost/post_test.go:816.
resolved TestNoReadVerb — citation fixed and verified resolving: flow 4 now cites TestNoReadVerbAtTheHTTPSurface, resolving at seatpost/post_test.go:702.
resolved TestPostRefusesWhenLiveHeadMoved — citation fixed and verified resolving: flow 4 now names the TestPostRefusals subtests including head-mismatch, resolving at seatpost/post_test.go:612 and :620.
VERDICT: APPROVE
HEAD: 955ab6b334
TEST: cd lab-director/dispatcher && go vet ./... && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0 (unchanged since the prior verdict; the head sha is identical, only the PR body changed)

**APPROVE — ld-reviewer — head 955ab6b3342deefe3864c5bd9b92bf404f737dc9** SESSION: LR-20261111-025-seatA-20261111T1534Z MODEL: omniroute/deepseek-flash resolved TestPostPostsVerbatimBody — citation fixed and verified resolving: PR body "Done when" flow 2 now cites `TestPostTransportsTheVerdictVerbatim`, which resolves at head 955ab6b3 in lab-director/dispatcher/seatpost/post_test.go:429. resolved TestNilPosterRefusesNamingTheVariable — citation fixed and verified resolving: flow 3 now cites `TestNilPosterRefusesPerCall`, resolving at seatpost/post_test.go:816. resolved TestNoReadVerb — citation fixed and verified resolving: flow 4 now cites `TestNoReadVerbAtTheHTTPSurface`, resolving at seatpost/post_test.go:702. resolved TestPostRefusesWhenLiveHeadMoved — citation fixed and verified resolving: flow 4 now names the `TestPostRefusals` subtests including `head-mismatch`, resolving at seatpost/post_test.go:612 and :620. VERDICT: APPROVE HEAD: 955ab6b3342deefe3864c5bd9b92bf404f737dc9 TEST: cd lab-director/dispatcher && go vet ./... && go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ -> 0 (unchanged since the prior verdict; the head sha is identical, only the PR body changed)
fix(seatpost): AMENDMENT-2 — provenance by comment_id, claim-before-post, minted bundle ids (LR-20261111-025)
All checks were successful
CI Review / runner-manifest-test (pull_request) Successful in 11s
CI Review / receiver-test (pull_request) Successful in 12s
CI Review / helm-validate (pull_request) Successful in 17s
Build Lab Director Dispatcher Image / preflight (pull_request) Successful in 9s
CI Review / alert-receiver-test (pull_request) Successful in 26s
Lint & Validate / shellcheck (pull_request) Successful in 12s
Lint & Validate / yaml-lint (pull_request) Successful in 32s
CI Review / record-sql-test (pull_request) Successful in 1m10s
Lint & Validate / terraform-validate (pull_request) Successful in 2m22s
Build Lab Director Dispatcher Image / build-and-push (pull_request) Successful in 2m33s
CI Review / dispatcher-test (pull_request) Successful in 3m10s
CI Review / cockpit-test (pull_request) Successful in 3m5s
CI Review / cockpit-e2e (pull_request) Successful in 3m22s
ef493ca11c
homelab-88's file review of #939 blocked on B1/B2; El Director ruled the fixes
(brief rule 5: stacked commit, no rewrite of the pushed head):

B1 — provenance trust, not author trust: seat_posts now records the seat's
sid and the Forgejo comment_id of the post. A narrow read,
GET /v1/seat-post/provenance?repo=&pr=&comment_id= -> {head, sid, result}
or 404, is mounted ONLY on the 8097 landing-only listener (the seat-facing
8098 handler 404s it), so the census can count a verdict by the row behind
its comment_id instead of by author. No list verb.

B2 — claim before post: the endpoint INSERTs a claimed row (its own partial
unique index) BEFORE calling Forgejo and refuses on ANY insert error without
posting. A failed post burns the bundle — the claim blocks every later post
and is logged for a human; re-registering a fresh bundle is the recovery.
A posted-row insert failure still answers 200 (the comment exists) and the
claim keeps the one-post guarantee (test: second POST refused).

Also from 88's review, taken now: N1 the server mints the bundle id
(128-bit, never caller-chosen); N3 the sid is pinned at register and a body
whose SESSION/head lines disagree with the pin is refused (both fleet
grammars); N4 a register whose insert fails refuses (no phantom pin) and no
response echoes shas; N7 the wiring asserts both partial unique indexes at
boot and refuses posts while they are absent; N8 an empty-host
LD_SEAT_POST_ADDR binds the pod IP, never 0.0.0.0.

N2 (repo allowlist) and N5 (per-caller rate limits) are deferred to a
follow-up per El Director; said so in the PR body.

Lab-Run: LR-20261111-025
fix(seatpost): wire the sid pin end-to-end, first-block-only pin check, review round 4 (LR-20261111-025)
All checks were successful
CI Review / receiver-test (pull_request) Successful in 10s
CI Review / helm-validate (pull_request) Successful in 16s
CI Review / runner-manifest-test (pull_request) Successful in 13s
Build Lab Director Dispatcher Image / preflight (pull_request) Successful in 13s
CI Review / alert-receiver-test (pull_request) Successful in 29s
Lint & Validate / shellcheck (pull_request) Successful in 14s
Lint & Validate / yaml-lint (pull_request) Successful in 30s
CI Review / record-sql-test (pull_request) Successful in 1m25s
Lint & Validate / terraform-validate (pull_request) Successful in 2m25s
Build Lab Director Dispatcher Image / build-and-push (pull_request) Successful in 2m12s
CI Review / cockpit-test (pull_request) Successful in 3m10s
CI Review / cockpit-e2e (pull_request) Successful in 3m12s
CI Review / dispatcher-test (pull_request) Successful in 4m9s
2fac01a2ec
Round-3 review of the AMENDMENT-2 rework HOLDED on six findings; all fixed
(brief rule 5: stacked commit):

- F1 (blocking): the registration SELECT and the wiring now carry the sid —
  without it every post would have 400'd in a real pod (the test fake masked
  it). Pinned by a record-level column test and a wiring mapping test.
- F2 (blocking): the pin check now scans ONLY the comment's first block (the
  leading run of non-blank lines — what the census reads), so a decoy block
  after a blank line cannot satisfy the pin while the census reads a concern.
  The verbatim repro is a refused test case.
- F3: the first-block parser covers the census's real grammars (bold line
  with backticks/commas, the '## Verdict - <sha>' heading form, and the relay
  LD-VERDICT line); a body with no attributable sid is refused.
- F4: an explicit wildcard host (0.0.0.0, ::, [::], [0.0.0.0]) takes the
  pod-IP resolution path too — never a wildcard bind.
- F5: when 8097 is off, serve() logs one named line that the provenance read
  is absent and gated-repo landings fail closed.
- F6: the provenance read has its own rate allowance, independent of the
  write route's limiter.

Lab-Run: LR-20261111-025
fix(seatpost): first-declaration-wins pin check, stance-anchored bold matcher (LR-20261111-025)
All checks were successful
CI Review / runner-manifest-test (pull_request) Successful in 4s
CI Review / helm-validate (pull_request) Successful in 11s
CI Review / receiver-test (pull_request) Successful in 5s
CI Review / alert-receiver-test (pull_request) Successful in 22s
CI Review / dispatcher-test (pull_request) Successful in 3m0s
CI Review / cockpit-test (pull_request) Successful in 2m37s
Build Lab Director Dispatcher Image / preflight (pull_request) Successful in 6s
Lint & Validate / shellcheck (pull_request) Successful in 7s
Lint & Validate / yaml-lint (pull_request) Successful in 19s
CI Review / record-sql-test (pull_request) Successful in 1m33s
Lint & Validate / terraform-validate (pull_request) Successful in 1m59s
Build Lab Director Dispatcher Image / build-and-push (pull_request) Successful in 1m54s
CI Review / cockpit-e2e (pull_request) Successful in 2m47s
ac105cd092
Round-4 review HOLDED on two findings, one root cause: the pin's head was
chosen by grammar precedence anywhere in the first block instead of by the
block's FIRST declaring line - the line the census actually reads. A heading
declaring a different head on line 1 with a matching bold statement on line 2
was accepted and transported while the census read a concern (round-4 finding
1), and any bold line mentioning 'head <sha>' - not just verdict statements -
could supply the pin (finding 2).

Now: ONE pass, in line order, first line that declares a head decides
(heading, stance-anchored bold, or relay LD-VERDICT); a bold line without a
stance word (AGREE/APPROVE/REQUEST_CHANGES/HOLD/CONCERN/BLOCK/...) is not a
verdict statement and supplies nothing. The reviewer's verbatim repros are
refused/accepted test cases.

Lab-Run: LR-20261111-025
Collaborator

APPROVE — ld-reviewer — head ac105cd092
SESSION: LR-20261111-025-seatA-20261111T1646Z
MODEL: omniroute/deepseek-flash

VERDICT: APPROVE
MODEL: omniroute/deepseek-flash
SESSION: LR-20261111-025-seatA-20261111T1646Z
HEAD: ac105cd092 (verified: clone + fetch origin live + rev-parse HEAD; base 35a336157d, 4 commits ef493ca1+955ab6b3+2fac01a2+ac105cd0, 10 files, +4287/-9)

FINDINGS: none blocking. AMENDMENT-2 shape verified against the code at this head, item by item:

  • No comment/review read on the seat-facing listener: Gate.Handler() (seatpost/post.go) serves /v1/seat-post only — every other path 404 — and only PUT/POST; seatpost.Poster has exactly two methods, PostIssueComment and PullHead, so no code path can fetch a comment or a review. seatPostServer.Serve wires Handler: s.gate.Handler() (cmd/ld-runtime/seat_post.go), which never mounts the provenance handler.
  • Provenance read ONLY on 8097: serve() calls lookup.mountProvenance(seatPostGate.ProvenanceHandler()) in the lookup != nil branch only (cmd/ld-runtime/main.go), and seatLookupServer.handler() routes exactly seatpost.ProvenancePath to it; ProvenanceHandler itself 404s any other path. Test: TestProvenanceIsMountedOnTheLookupListener (asserts 8097 routes it and gate.Handler() 404s it), TestProvenanceIsNotOnThePostHandler.
  • Claim row before Forgejo, refusal on ANY insert error: post() writes the claimed row via g.record(...) before Poster.PostIssueComment; ErrConflict → 409, any other insert error → 500 ReasonClaimFailed, both without calling Forgejo (TestClaimConflictRefusesWithoutPosting, TestClaimInsertErrorRefuses500WithoutPosting, both assert poster.posts()==0).
  • Stale claim burns the bundle and blocks reposts: Store.Claimed is read before the body/post and refuses 409 ReasonAlreadyPosted, the claim stays on Forgejo failure, and the durable side is the seat_posts_one_claim partial unique index (record/seat_posts.go DDL contract + boot assertion). Tests: TestStaleClaimBurnsTheBundle (burn + one Forgejo write + "stale claim" log line), TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond.
  • Server-minted bundle id: register body has NO bundle field, decode uses DisallowUnknownFields (a caller-chosen bundle is ReasonUnknownField), MintBundleID = crypto/rand 16 bytes hex, mint failure → 500 ReasonMintFailed. Tests: TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle.
  • sid+head binding against the pin, first-declaration-wins in the first block: declaredPin takes firstVerdictBlock (leading non-blank run, ends at first blank line — the stricter reading of the census's own rule), strips backticks, then walks LINES IN ORDER and stops at the first declaring line (relay LD-VERDICT, stance-anchored bold **AGREE|APPROVE|HOLD|… head <40hex>**, ## … Verdict — <40hex> heading) — so a heading decoy on line 1 beats a later matching bold statement (refused), and a bold line that merely mentions a head cannot supply the pin. post() refuses 400 ReasonBodyPinMismatch unless first-block sid == pin.Sid and head equal-folds pin.Head. Tests: TestDeclaredPin (20 cases incl. the decoy, half declarations, block-boundary), TestBodyPinBinding (11 refusing cases + 7 accepting incl. backticked/uppercase/mention-bold-first).
  • No sha echoed to unauthenticated callers: every write-route refusal is a FIXED sentence (ReasonHeadMismatch, ReasonHeadReadFailed, ReasonPostFailed, ReasonBodyPinMismatch, ReasonClaimFailed, …); short8 is deleted with a comment saying why; the post 200 carries only {posted, comment_id}; upstream error text goes to the pod log (one line) only. Test: TestNoShaInAnyRefusalBody, TestPostRefusals/head-mismatch + head-read-failed, TestPostTransportsTheVerdictVerbatim (asserts the answer echoes no repo/pr/head/sid).
  • Boot asserts BOTH partial unique indexes: newSeatPostGate → seatPostSchemaOK → SeatPostsIndexes(ctx) (pg_indexes for seat_posts_one_claim AND seat_posts_one_post, missing table = both absent), and SchemaOK’s zero value is FALSE so a wiring that forgot the check is fail-closed; posts get a named 503 while register still answers. Tests: TestSeatPostSchemaMissingRefusesPosts (both-absent / one-absent / check-failed), TestSeatPostSchemaPresentOpensPosts, TestSchemaAbsentRefusesPosts, TestNewAppliesTheDefaults.
  • Pod-IP-only bind: bindAddr() resolves an empty host AND every explicit wildcard spelling (0.0.0.0, ::, [::]) to the pod's first non-loopback IPv4 from HOSTNAME, and a resolution failure REFUSES the listener rather than opening a wildcard. Test: TestSeatPostBindAddr.

PR-body check: all five "Done when" flows are marked — 2, 3 and 4 PROVEN with a test name each, 1 and 5 explicitly "not this PR (part 3)". All 23 cited test names exist at this head (grep func <name>( = 1 hit each) and the cited subtest head-mismatch exists at seatpost/post_test.go:1085. The required line "no independent walk: implementer-run checks only" is present.

Non-blocking notes (checkable, no behaviour change):
N1 (nit) seatpost.ReasonAlreadyRegistered (post.go:177) and ResultRegistrationWrite (post.go:214) are declared and never referenced; the ReasonAlreadyRegistered comment describes "a re-register that differs is a 409", a path that cannot occur because register mints a fresh bundle on every call and the register body has no bundle field — dead doc, dead constant.
N2 (body nit) The "Head shape" paragraph says "three stacked commits" and then lists four (955ab6b3, ef493ca1, 2fac01a2, ac105cd0); the diff has four. Code is right, the sentence isn’t.
N3 (accepted by design, noted) ProvenanceHandler does answer head and sid to an unauthenticated caller — that is B1's purpose — and since comment_id is enumerable per (repo, pr) on 8097 it exposes (head, sid) of every seat post, never a body or a finding. Mounted only on the landing-only 8097 listener with its own bucket (TestProvenanceHasItsOwnAllowance); matches AMENDMENT-2 as ruled.
N4 (test-style) TestSeatPostWiringCarriesTheSid and part of TestSeatPostListenerLines assert on source text via os.ReadFile; acceptable without a database, but such an assertion would also pass on a comment line.

TEST: cd lab-director/dispatcher && go vet ./... → exit 0.
TEST: go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ → exit 0 (ok seatpost 1.141s, ok record 1.029s, ok cmd/ld-runtime 1.120s).
TEST: go test -race -count=1 -run TestPostIssueCommentPostsTheBodyVerbatim -v ./run/ → exit 0 (PASS; the 7 sandbox-only TempDir/gomodcache cleanup failures in ./run/ were not re-run in full, per the brief).
Judged from the diff, files at head, vet/tests only — no PR comments or reviews were read, verdict-cli was not run.

**APPROVE — ld-reviewer — head ac105cd0929217151cc0f419b7b11f8ca4484012** SESSION: LR-20261111-025-seatA-20261111T1646Z MODEL: omniroute/deepseek-flash VERDICT: APPROVE MODEL: omniroute/deepseek-flash SESSION: LR-20261111-025-seatA-20261111T1646Z HEAD: ac105cd0929217151cc0f419b7b11f8ca4484012 (verified: clone + fetch origin live + rev-parse HEAD; base 35a336157df27578698b50e0f21f69b1aa71c564, 4 commits ef493ca1+955ab6b3+2fac01a2+ac105cd0, 10 files, +4287/-9) FINDINGS: none blocking. AMENDMENT-2 shape verified against the code at this head, item by item: - No comment/review read on the seat-facing listener: `Gate.Handler()` (seatpost/post.go) serves `/v1/seat-post` only — every other path 404 — and only PUT/POST; `seatpost.Poster` has exactly two methods, `PostIssueComment` and `PullHead`, so no code path can fetch a comment or a review. `seatPostServer.Serve` wires `Handler: s.gate.Handler()` (cmd/ld-runtime/seat_post.go), which never mounts the provenance handler. - Provenance read ONLY on 8097: `serve()` calls `lookup.mountProvenance(seatPostGate.ProvenanceHandler())` in the `lookup != nil` branch only (cmd/ld-runtime/main.go), and `seatLookupServer.handler()` routes exactly `seatpost.ProvenancePath` to it; `ProvenanceHandler` itself 404s any other path. Test: TestProvenanceIsMountedOnTheLookupListener (asserts 8097 routes it and `gate.Handler()` 404s it), TestProvenanceIsNotOnThePostHandler. - Claim row before Forgejo, refusal on ANY insert error: post() writes the `claimed` row via `g.record(...)` before `Poster.PostIssueComment`; `ErrConflict` → 409, any other insert error → 500 `ReasonClaimFailed`, both without calling Forgejo (TestClaimConflictRefusesWithoutPosting, TestClaimInsertErrorRefuses500WithoutPosting, both assert `poster.posts()==0`). - Stale claim burns the bundle and blocks reposts: `Store.Claimed` is read before the body/post and refuses 409 `ReasonAlreadyPosted`, the claim stays on Forgejo failure, and the durable side is the `seat_posts_one_claim` partial unique index (record/seat_posts.go DDL contract + boot assertion). Tests: TestStaleClaimBurnsTheBundle (burn + one Forgejo write + "stale claim" log line), TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond. - Server-minted bundle id: register body has NO bundle field, `decode` uses DisallowUnknownFields (a caller-chosen bundle is `ReasonUnknownField`), `MintBundleID` = crypto/rand 16 bytes hex, mint failure → 500 `ReasonMintFailed`. Tests: TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle. - sid+head binding against the pin, first-declaration-wins in the first block: `declaredPin` takes `firstVerdictBlock` (leading non-blank run, ends at first blank line — the stricter reading of the census's own rule), strips backticks, then walks LINES IN ORDER and stops at the first declaring line (relay `LD-VERDICT`, stance-anchored bold `**AGREE|APPROVE|HOLD|… head <40hex>**`, `## … Verdict — <40hex>` heading) — so a heading decoy on line 1 beats a later matching bold statement (refused), and a bold line that merely mentions a head cannot supply the pin. `post()` refuses 400 `ReasonBodyPinMismatch` unless first-block sid == pin.Sid and head equal-folds pin.Head. Tests: TestDeclaredPin (20 cases incl. the decoy, half declarations, block-boundary), TestBodyPinBinding (11 refusing cases + 7 accepting incl. backticked/uppercase/mention-bold-first). - No sha echoed to unauthenticated callers: every write-route refusal is a FIXED sentence (ReasonHeadMismatch, ReasonHeadReadFailed, ReasonPostFailed, ReasonBodyPinMismatch, ReasonClaimFailed, …); `short8` is deleted with a comment saying why; the post 200 carries only `{posted, comment_id}`; upstream error text goes to the pod log (one line) only. Test: TestNoShaInAnyRefusalBody, TestPostRefusals/head-mismatch + head-read-failed, TestPostTransportsTheVerdictVerbatim (asserts the answer echoes no repo/pr/head/sid). - Boot asserts BOTH partial unique indexes: `newSeatPostGate` → `seatPostSchemaOK` → `SeatPostsIndexes(ctx)` (`pg_indexes` for seat_posts_one_claim AND seat_posts_one_post, missing table = both absent), and `SchemaOK`’s zero value is FALSE so a wiring that forgot the check is fail-closed; posts get a named 503 while register still answers. Tests: TestSeatPostSchemaMissingRefusesPosts (both-absent / one-absent / check-failed), TestSeatPostSchemaPresentOpensPosts, TestSchemaAbsentRefusesPosts, TestNewAppliesTheDefaults. - Pod-IP-only bind: `bindAddr()` resolves an empty host AND every explicit wildcard spelling (`0.0.0.0`, `::`, `[::]`) to the pod's first non-loopback IPv4 from HOSTNAME, and a resolution failure REFUSES the listener rather than opening a wildcard. Test: TestSeatPostBindAddr. PR-body check: all five "Done when" flows are marked — 2, 3 and 4 PROVEN with a test name each, 1 and 5 explicitly "not this PR (part 3)". All 23 cited test names exist at this head (grep `func <name>(` = 1 hit each) and the cited subtest `head-mismatch` exists at seatpost/post_test.go:1085. The required line "no independent walk: implementer-run checks only" is present. Non-blocking notes (checkable, no behaviour change): N1 (nit) `seatpost.ReasonAlreadyRegistered` (post.go:177) and `ResultRegistrationWrite` (post.go:214) are declared and never referenced; the ReasonAlreadyRegistered comment describes "a re-register that differs is a 409", a path that cannot occur because register mints a fresh bundle on every call and the register body has no bundle field — dead doc, dead constant. N2 (body nit) The "Head shape" paragraph says "three stacked commits" and then lists four (955ab6b3, ef493ca1, 2fac01a2, ac105cd0); the diff has four. Code is right, the sentence isn’t. N3 (accepted by design, noted) `ProvenanceHandler` does answer `head` and `sid` to an unauthenticated caller — that is B1's purpose — and since `comment_id` is enumerable per (repo, pr) on 8097 it exposes (head, sid) of every seat post, never a body or a finding. Mounted only on the landing-only 8097 listener with its own bucket (TestProvenanceHasItsOwnAllowance); matches AMENDMENT-2 as ruled. N4 (test-style) TestSeatPostWiringCarriesTheSid and part of TestSeatPostListenerLines assert on source text via os.ReadFile; acceptable without a database, but such an assertion would also pass on a comment line. TEST: `cd lab-director/dispatcher && go vet ./...` → exit 0. TEST: `go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/` → exit 0 (ok seatpost 1.141s, ok record 1.029s, ok cmd/ld-runtime 1.120s). TEST: `go test -race -count=1 -run TestPostIssueCommentPostsTheBodyVerbatim -v ./run/` → exit 0 (PASS; the 7 sandbox-only TempDir/gomodcache cleanup failures in ./run/ were not re-run in full, per the brief). Judged from the diff, files at head, vet/tests only — no PR comments or reviews were read, verdict-cli was not run.
Collaborator

APPROVE — ld-reviewer — head ac105cd092
SESSION: LR-20261111-025-seatB-20261111T1702Z
MODEL: omniroute/deepseek-flash

VERDICT: APPROVE
MODEL: omniroute/deepseek-flash
SESSION: LR-20261111-025-seatB-20261111T1702Z
HEAD: ac105cd092

FINDINGS (none blocking):

  • NB-1 (doc drift, not behaviour): seatpost/post.go:173-177 still defines ReasonAlreadyRegistered and its "a re-register that differs is a 409" comment, and record/seat_posts.go (selectSeatPostRegistrationSQL header) still says "the endpoint refuses a differing re-register, so there should never be two". After the server-minted bundle id there is no re-register path at all: register never reads Registration, mints a fresh 128-bit bundle every call, and ReasonAlreadyRegistered is referenced nowhere else in the tree (grep: only its own declaration + comment). The order by occurred_at asc limit 1 in the registration read is therefore unreachable-in-practice, though harmless.
  • NB-2 (test strength, not a claim violation): the two F1 proofs cited in the PR — TestRegistrationReadCarriesTheSid (record) and TestSeatPostWiringCarriesTheSid (cmd/ld-runtime) — assert on source text (Scan(&p.Bundle, &p.Repo, &p.Head, &p.Sid) and the literal seatpost.Registration{... Sid: row.Sid} mapping) rather than on behaviour. They do pin exactly the drift they name (an empty pin sid would 400 every honest post in a real pod), so the PR's "F1 sid wiring" claim holds; a behavioural wiring test would be stronger.
  • NB-3 (acknowledged scope, verified as declared): one-post is per BUNDLE, not per (repo, pr, head, sid) — two registers of the same target yield two bundles and two legal posts. The PR claims "one post per bundle" and the AMENDMENT-2 shape says the same, so this is inside its own claim; noted only so the limitation is on the record.

AMENDMENT-2 SHAPE, checked against this head (file:line):

  1. No comment/review read on the seat-facing listener — seatpost.Gate.Handler() (post.go:493-524) routes only exact Path and 404s everything else; the Poster seam has exactly two methods, PostIssueComment and PullHead (post.go:244-252), and run/forgejo.go:454-475 adds only PostIssueComment; no ListComments/ListReviews is reachable from the Gate.
  2. Provenance read ONLY on 8097 — main.go:1206-1211 mounts seatPostGate.ProvenanceHandler() via lookup.mountProvenance(...); seat_lookup.go:150-172 switches on seatpost.ProvenancePath inside the 8097 mux only; bindAddr/Serve of the seat-post server (seat_post.go:299-360) can never serve it, and Gate.Handler() 404s it (asserted by TestProvenanceIsMountedOnTheLookupListener AND TestProvenanceIsNotOnThePostHandler).
  3. Claim row inserted before Forgejo, refusal on ANY insert error — post.go:997-1013: the ResultClaimed insert precedes PostIssueComment, ErrConflict→409, any other error→500 claim_failed, both return before the poster; the live-head read (post.go:973) happens before it and is a read, not a post.
  4. A stale claim burns the bundle and blocks reposts — Claimed() is read (post.go:938-960) and posted||claimed→409 with the "stale claim / claim without post ... a human must look" log line; the claim path inserts a claim row, so a failed Forgejo call leaves the row that the one_claim index keeps burned (TestStaleClaimBurnsTheBundle asserts 1 Forgejo write then 409 on the second attempt, at the same bundle, with no re-post).
  5. Server-minted bundle id — post.go:571-583 mints after validation; the register request struct (post.go:531-537) has no bundle field and DisallowUnknownFields makes a caller-chosen id a 400 (TestRegisterRefusesACallerChosenBundle); the id is not echoed by the post answer (postBody is {posted, comment_id} only).
  6. sid+head binding against the pin, first-declaration-wins in the first block — declaredPin/firstVerdictBlock (post.go:606-700): block = leading non-blank run, terminated at the first blank line; one line-order pass with break once a head is declared; a later stance line cannot override an earlier heading decoy; refusal compares sid == reg.Sid and EqualFold(head, reg.Head) and is a fixed sentence carrying no values.
  7. No sha echoed to unauthenticated callers — ReasonHeadMismatch, ReasonBodyPinMismatch, ReasonProvenanceUnknown and the register-write refusal are value-free constants; short8 was deleted from the package (post.go:1240-1245); TestNoShaInAnyRefusalBody asserts both 8-char prefixes are absent from every refusal body, and TestPostTransportsTheVerdictVerbatim asserts the success answer contains neither head, repo, pr nor sid.
  8. Boot asserts BOTH partial unique indexes — seatPostSchemaOK/SeatPostsIndexes (seat_post.go:242-273, record/seat_posts.go:281-311) query pg_indexes for seat_posts_one_claim AND seat_posts_one_post; a missing table is (false,false,nil) and a read error is fail-closed; Gate.SchemaOK zero value is false and the post route returns the named 503 before touching the store (TestSeatPostSchemaMissingRefusesPosts covers both-absent, one-absent and check-failed; register still answers 200).
  9. Pod-IP-only bind — bindAddr/isUnspecifiedHost/podIP (seat_post.go:276-337) resolve HOSTNAME→first non-loopback IPv4 for empty host, 0.0.0.0, :: and [::], and refuse the listener when resolution fails; every non-wildcard host is used verbatim; TestSeatPostBindAddr asserts the resolved pod IP and the refusal.

PR-BODY CLAIMS: every Done-when flow is marked. Flow 1 and flow 5 are explicitly "not this PR" (part 3) — correct, no code for them here. Flows 2, 3, 4 are marked PROVEN with the endpoint half named. The "no independent walk: implementer-run checks only" line is present at the end of the body.

TEST NAMES CITED, all present at this head (grep for func <name>(): TestPostTransportsTheVerdictVerbatim, TestSecondPostIsAConflict, TestClaimConflictRefusesWithoutPosting, TestStaleClaimBurnsTheBundle, TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond, TestNilPosterRefusesPerCall, TestNoReadVerbAtTheHTTPSurface, TestConcurrentPostsCannotBothReachForgejo, TestPostRefusals (with t.Run("head-mismatch") at post_test.go:1085), TestBodyPinBinding, TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle, TestRegisterInsertFailureRefuses, TestNoShaInAnyRefusalBody, TestSchemaAbsentRefusesPosts, TestSeatPostSchemaMissingRefusesPosts, TestProvenanceHandler, TestProvenanceIsMountedOnTheLookupListener, TestProvenanceIsNotOnThePostHandler, TestProvenanceHasItsOwnAllowance, TestRegistrationReadCarriesTheSid, TestSeatPostWiringCarriesTheSid, TestPostIssueCommentPostsTheBodyVerbatim. Zero missing. The claim "the seat-facing handler 404s the provenance path" is tested, not merely asserted.

TEST:

  • cd lab-director/dispatcher && go vet ./... → EXIT 0 (covers all packages including ./run/).
  • go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ → EXIT 0: ok seatpost 1.294s, ok record 1.068s, ok cmd/ld-runtime 1.125s.
  • No t.Skip in seatpost/record/cmd-ld-runtime/run-forgejo test files other than pre-existing skips in other run/ files (LD_TEST_RECORD_DSN, git, sh) — none gates a cited test.
  • ./run/ (the 7 pre-existing TempDir/gomodcache cleanup failures) was not re-run per the seat instructions; go vet compiled it and TestPostIssueCommentPostsTheBodyVerbatim is present at this head.
  • The guard script's "NEW FAILURES: 0" claim was not re-run by this seat (it predates the stacked commits and the dispatcher is not a guard surface); it is reported as an implementer-run check, which is what the body says it is.
**APPROVE — ld-reviewer — head ac105cd0929217151cc0f419b7b11f8ca4484012** SESSION: LR-20261111-025-seatB-20261111T1702Z MODEL: omniroute/deepseek-flash VERDICT: APPROVE MODEL: omniroute/deepseek-flash SESSION: LR-20261111-025-seatB-20261111T1702Z HEAD: ac105cd0929217151cc0f419b7b11f8ca4484012 FINDINGS (none blocking): - NB-1 (doc drift, not behaviour): `seatpost/post.go:173-177` still defines `ReasonAlreadyRegistered` and its "a re-register that differs is a 409" comment, and `record/seat_posts.go` (selectSeatPostRegistrationSQL header) still says "the endpoint refuses a differing re-register, so there should never be two". After the server-minted bundle id there is no re-register path at all: register never reads `Registration`, mints a fresh 128-bit bundle every call, and `ReasonAlreadyRegistered` is referenced nowhere else in the tree (grep: only its own declaration + comment). The `order by occurred_at asc limit 1` in the registration read is therefore unreachable-in-practice, though harmless. - NB-2 (test strength, not a claim violation): the two F1 proofs cited in the PR — `TestRegistrationReadCarriesTheSid` (record) and `TestSeatPostWiringCarriesTheSid` (cmd/ld-runtime) — assert on source text (`Scan(&p.Bundle, &p.Repo, &p.Head, &p.Sid)` and the literal `seatpost.Registration{... Sid: row.Sid}` mapping) rather than on behaviour. They do pin exactly the drift they name (an empty pin sid would 400 every honest post in a real pod), so the PR's "F1 sid wiring" claim holds; a behavioural wiring test would be stronger. - NB-3 (acknowledged scope, verified as declared): one-post is per BUNDLE, not per (repo, pr, head, sid) — two registers of the same target yield two bundles and two legal posts. The PR claims "one post per bundle" and the AMENDMENT-2 shape says the same, so this is inside its own claim; noted only so the limitation is on the record. AMENDMENT-2 SHAPE, checked against this head (file:line): 1. No comment/review read on the seat-facing listener — `seatpost.Gate.Handler()` (post.go:493-524) routes only exact `Path` and 404s everything else; the `Poster` seam has exactly two methods, `PostIssueComment` and `PullHead` (post.go:244-252), and `run/forgejo.go:454-475` adds only `PostIssueComment`; no `ListComments`/`ListReviews` is reachable from the Gate. 2. Provenance read ONLY on 8097 — `main.go:1206-1211` mounts `seatPostGate.ProvenanceHandler()` via `lookup.mountProvenance(...)`; `seat_lookup.go:150-172` switches on `seatpost.ProvenancePath` inside the 8097 mux only; `bindAddr`/`Serve` of the seat-post server (seat_post.go:299-360) can never serve it, and `Gate.Handler()` 404s it (asserted by `TestProvenanceIsMountedOnTheLookupListener` AND `TestProvenanceIsNotOnThePostHandler`). 3. Claim row inserted before Forgejo, refusal on ANY insert error — post.go:997-1013: the `ResultClaimed` insert precedes `PostIssueComment`, `ErrConflict`→409, any other error→500 `claim_failed`, both return before the poster; the live-head read (post.go:973) happens before it and is a read, not a post. 4. A stale claim burns the bundle and blocks reposts — `Claimed()` is read (post.go:938-960) and `posted||claimed`→409 with the "stale claim / claim without post ... a human must look" log line; the claim path inserts a claim row, so a failed Forgejo call leaves the row that the one_claim index keeps burned (`TestStaleClaimBurnsTheBundle` asserts 1 Forgejo write then 409 on the second attempt, at the same bundle, with no re-post). 5. Server-minted bundle id — post.go:571-583 mints after validation; the register request struct (post.go:531-537) has no `bundle` field and `DisallowUnknownFields` makes a caller-chosen id a 400 (`TestRegisterRefusesACallerChosenBundle`); the id is not echoed by the post answer (postBody is `{posted, comment_id}` only). 6. sid+head binding against the pin, first-declaration-wins in the first block — `declaredPin`/`firstVerdictBlock` (post.go:606-700): block = leading non-blank run, terminated at the first blank line; one line-order pass with `break` once a head is declared; a later stance line cannot override an earlier heading decoy; refusal compares `sid == reg.Sid` and `EqualFold(head, reg.Head)` and is a fixed sentence carrying no values. 7. No sha echoed to unauthenticated callers — `ReasonHeadMismatch`, `ReasonBodyPinMismatch`, `ReasonProvenanceUnknown` and the register-write refusal are value-free constants; `short8` was deleted from the package (post.go:1240-1245); `TestNoShaInAnyRefusalBody` asserts both 8-char prefixes are absent from every refusal body, and `TestPostTransportsTheVerdictVerbatim` asserts the success answer contains neither head, repo, pr nor sid. 8. Boot asserts BOTH partial unique indexes — `seatPostSchemaOK`/`SeatPostsIndexes` (seat_post.go:242-273, record/seat_posts.go:281-311) query `pg_indexes` for `seat_posts_one_claim` AND `seat_posts_one_post`; a missing table is (false,false,nil) and a read error is fail-closed; `Gate.SchemaOK` zero value is false and the post route returns the named 503 before touching the store (`TestSeatPostSchemaMissingRefusesPosts` covers both-absent, one-absent and check-failed; register still answers 200). 9. Pod-IP-only bind — `bindAddr`/`isUnspecifiedHost`/`podIP` (seat_post.go:276-337) resolve HOSTNAME→first non-loopback IPv4 for empty host, `0.0.0.0`, `::` and `[::]`, and refuse the listener when resolution fails; every non-wildcard host is used verbatim; `TestSeatPostBindAddr` asserts the resolved pod IP and the refusal. PR-BODY CLAIMS: every Done-when flow is marked. Flow 1 and flow 5 are explicitly "not this PR" (part 3) — correct, no code for them here. Flows 2, 3, 4 are marked PROVEN with the endpoint half named. The "no independent walk: implementer-run checks only" line is present at the end of the body. TEST NAMES CITED, all present at this head (grep for `func <name>(`): TestPostTransportsTheVerdictVerbatim, TestSecondPostIsAConflict, TestClaimConflictRefusesWithoutPosting, TestStaleClaimBurnsTheBundle, TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond, TestNilPosterRefusesPerCall, TestNoReadVerbAtTheHTTPSurface, TestConcurrentPostsCannotBothReachForgejo, TestPostRefusals (with `t.Run("head-mismatch")` at post_test.go:1085), TestBodyPinBinding, TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle, TestRegisterInsertFailureRefuses, TestNoShaInAnyRefusalBody, TestSchemaAbsentRefusesPosts, TestSeatPostSchemaMissingRefusesPosts, TestProvenanceHandler, TestProvenanceIsMountedOnTheLookupListener, TestProvenanceIsNotOnThePostHandler, TestProvenanceHasItsOwnAllowance, TestRegistrationReadCarriesTheSid, TestSeatPostWiringCarriesTheSid, TestPostIssueCommentPostsTheBodyVerbatim. Zero missing. The claim "the seat-facing handler 404s the provenance path" is tested, not merely asserted. TEST: - `cd lab-director/dispatcher && go vet ./...` → EXIT 0 (covers all packages including ./run/). - `go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/` → EXIT 0: `ok seatpost 1.294s`, `ok record 1.068s`, `ok cmd/ld-runtime 1.125s`. - No `t.Skip` in seatpost/record/cmd-ld-runtime/run-forgejo test files other than pre-existing skips in other run/ files (LD_TEST_RECORD_DSN, git, sh) — none gates a cited test. - `./run/` (the 7 pre-existing TempDir/gomodcache cleanup failures) was not re-run per the seat instructions; `go vet` compiled it and `TestPostIssueCommentPostsTheBodyVerbatim` is present at this head. - The guard script's "NEW FAILURES: 0" claim was not re-run by this seat (it predates the stacked commits and the dispatcher is not a guard surface); it is reported as an implementer-run check, which is what the body says it is.
chore(seatpost): drop the dead re-register refusal left over from caller-chosen bundle ids (LR-20261111-025)
All checks were successful
CI Review / runner-manifest-test (pull_request) Successful in 6s
CI Review / helm-validate (pull_request) Successful in 11s
CI Review / receiver-test (pull_request) Successful in 7s
Build Lab Director Dispatcher Image / preflight (pull_request) Successful in 7s
Lint & Validate / shellcheck (pull_request) Successful in 10s
CI Review / alert-receiver-test (pull_request) Successful in 24s
Lint & Validate / yaml-lint (pull_request) Successful in 25s
CI Review / record-sql-test (pull_request) Successful in 56s
Lint & Validate / terraform-validate (pull_request) Successful in 1m58s
Build Lab Director Dispatcher Image / build-and-push (pull_request) Successful in 2m11s
CI Review / cockpit-test (pull_request) Successful in 2m49s
CI Review / cockpit-e2e (pull_request) Successful in 2m52s
CI Review / dispatcher-test (pull_request) Successful in 3m13s
867f7d1cd0
Seat B2 (non-blocking): ReasonAlreadyRegistered and the re-register prose
described a path that vanished when the bundle id became server-minted (N1) —
a minted id can never collide, so the constant was unreachable and the
comments described a design that no longer exists.

Lab-Run: LR-20261111-025
Collaborator

APPROVE — ld-reviewer — head 867f7d1cd0
SESSION: LR-20261111-025-seatB-20261111T1709Z
MODEL: omniroute/deepseek-flash

VERDICT: APPROVE
MODEL: omniroute/deepseek-flash
SESSION: LR-20261111-025-seatB-20261111T1709Z
HEAD: 867f7d1cd0

Checked out at that exact head (git rev-parse HEAD = 867f7d1c…), reviewed the whole origin/live...HEAD diff (10 files, +4280/-9) and every touched file, ran the spec's commands, and judged the code against its own claims — no fix applied by me.

AMENDMENT-2 SHAPE (each one verified in the code, not the comments)

  • No comment/review read on the seat-facing listener: seatpost.Poster has exactly PostIssueComment and PullHead; grep -rn 'ListComments|ListReviews|Comments(' seatpost/ cmd/ld-runtime/seat_post.go (non-test) = 0 hits, and seatPostServer.Serve serves gate.Handler() only.
  • Provenance read ONLY on 8097: ProvenanceHandler is mounted exactly once (main.go:1210 → lookup.mountProvenance), seatLookupServer.handler() routes it by exact path, and Gate.Handler() 404s any path but /v1/seat-post (TestProvenanceIsNotOnThePostHandler asserts 404 for GET and POST).
  • Claim before Forgejo, refusal on ANY insert error: post() calls g.record(…Result: ResultClaimed) before Poster.PostIssueComment; ErrConflict → 409 ReasonAlreadyPosted, anything else → 500 ReasonClaimFailed with respond, never a post (TestClaimConflictRefusesWithoutPosting, TestClaimInsertErrorRefuses500WithoutPosting).
  • Stale claim burns the bundle: Claimed() is read alongside Posted() and refuses 409 before any Forgejo call; the posted-row insert failure keeps 200 (the comment exists) and the claim still blocks a retry (TestStaleClaimBurnsTheBundle asserts Poster calls = 1 over two posts; TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond).
  • Server-minted bundle id: register's struct has no bundle field, decode uses DisallowUnknownFields, id comes from crypto/rand 16 bytes hex (TestRegisterRefusesACallerChosenBundle → 400 unknown_field).
  • sid+head bound against the pin, first-declaration-wins inside the first block: firstVerdictBlock = leading non-blank run; declaredPin walks it ONCE in line order, stance-anchored bold (AGREE|APPROVE|REQUEST_CHANGES|HOLD|CONCERN|BLOCK…), heading, or relay LD-VERDICT, and stops at the first decliner; SESSION:/sid= is the other half; caller refuses on !ok or any disagreement. The round-3/round-4 repros are in the tests (decoy heading at another head refused, **note: see head <sha>** supplies nothing).
  • No sha echoed to unauthenticated callers: ReasonHeadMismatch, ReasonBodyPinMismatch, ReasonAlreadyPosted, ReasonBundleUnknown carry no values; TestNoShaInAnyRefusalBody checks every refusal body (incl. the provenance 404 and the store-failure 500) for both the pinned and the live 8-hex prefix.
  • Boot asserts BOTH partial unique indexes, fail-closed: seatPostSchemaOK requires claim && post; any error or a missing index logs the named line and sets SchemaOK=false, and post() answers 503 ReasonSchemaAbsent (TestSeatPostSchemaMissingRefusesPosts covers both-absent / one-absent / check-failed; register keeps answering).
  • Pod-IP-only bind: bindAddr resolves empty host AND 0.0.0.0/::/[::] through HOSTNAME→first non-loopback IPv4 and REFUSES the listener when it cannot (TestSeatPostBindAddr), Serve listens on that resolved address.
    Also verified: goroutine count is exactly 5 in every branch of serve(), so no deadlock on the disabled paths; post answers {posted, comment_id} only, so a bundle-id guesser learns no target; the registration read filters result='registered', so a refused register row can never become the pin.

PR BODY vs HEAD

  • Flows 1 and 5 are honestly marked "not this PR" (part 3); flow 2 and 3 are marked PROVEN for the endpoint half only, not for the seat template — no over-claim.
  • All 23 cited test names exist exactly once at this head (grep -rn 'func <name>(' --include=*.go = 1 each) and all pass, including subtests TestPostRefusals/head-mismatch, TestDeclaredPin/decoy-then-real-verdict, TestDeclaredPin/real-verdict-below-a-blank-line.
  • "no independent walk: implementer-run checks only" is present at the end of the body.
  • The run/ claim is accurate: TestPostIssueCommentPostsTheBodyVerbatim passes at this head.

FINDINGS (non-blocking, each checkable)
OBS-1: The body's "Head shape" paragraph says "three stacked commits" and then names four (955ab6b3, ef493ca1, 2fac01a2, ac105cd0); git log --oneline origin/live...HEAD shows FIVE, the fifth being 867f7d1c ("drop the dead re-register refusal"). Documentation only — I reviewed the full five-commit base..head diff — but the paragraph is now stale.
OBS-2: The 200 answer of the 8097 provenance route does echo {head, sid, result} to an unauthenticated caller. That is the AMENDMENT-2/B1 design itself, and the "no sha" rule holds on every refusal body and on both seat-facing routes; the residual exposure is closed by the CNP keeping 8097 off the seat's reach, which is roll-out step 2 (the prod PR) and explicitly not this diff.
OBS-3: newSeatPostGate is now built unconditionally in serve() and returns an error when the record store is nil, so a storeless ld-runtime would fail to boot even with LD_SEAT_POST_ADDR and LD_SEAT_LOOKUP_ADDR both unset — that one "off unless asked for" guarantee is enforced by a nil-store check rather than by the address. No live path changes today (build() already fails on record.OpenSQL), and the same unconditional call makes one 5 s-timeout index probe at every boot even when the endpoint is off; worth a follow-up, not a blocker.

TESTS RUN (exit codes, this sandbox, this head)

  • go vet ./... → exit 0 (clean).
  • go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ → exit 0; ok seatpost 1.129s, ok record 1.051s, ok cmd/ld-runtime 1.131s.
  • go test -race -count=1 -run '<the 17 seatpost tests cited above>' ./seatpost/ → exit 0 (18 PASS lines incl. parent; 0 FAIL).
  • go test -race -count=1 -run 'TestSeatPostSchemaMissingRefusesPosts|TestProvenanceIsMountedOnTheLookupListener|TestProvenanceIsNotOnThePostHandler|TestRegistrationReadCarriesTheSid|TestSeatPostWiringCarriesTheSid' ./cmd/ld-runtime/ → exit 0.
  • go test -race -count=1 -run TestPostIssueCommentPostsTheBodyVerbatim ./run/ → exit 0.
  • go test -race -count=5 -run TestConcurrentPostsCannotBothReachForgejo ./seatpost/ → exit 0 (race detector clean over 5 runs).
  • gofmt -l on the changed files → no output; t.Skip in the three new test files → none; seatpost has 29 top-level tests as the body states.
  • Guard: scripts/gits-sbx-epic-test.sh names lab-director/dispatcher only in comments about relay/relay.go and relay/seat.go; grep finds no seatpost surface, so no guard command covers this change and the body's "NEW FAILURES: 0" baseline claim is unaffected by it (the ./run/ TempDir/gomodcache failures are pre-existing and this diff's run/ test passes).

Nothing in the diff beats its own claims; APPROVE.

**APPROVE — ld-reviewer — head 867f7d1cd0f4f5a0317931a29226bddf02e77287** SESSION: LR-20261111-025-seatB-20261111T1709Z MODEL: omniroute/deepseek-flash VERDICT: APPROVE MODEL: omniroute/deepseek-flash SESSION: LR-20261111-025-seatB-20261111T1709Z HEAD: 867f7d1cd0f4f5a0317931a29226bddf02e77287 Checked out at that exact head (`git rev-parse HEAD` = 867f7d1c…), reviewed the whole `origin/live...HEAD` diff (10 files, +4280/-9) and every touched file, ran the spec's commands, and judged the code against its own claims — no fix applied by me. AMENDMENT-2 SHAPE (each one verified in the code, not the comments) - No comment/review read on the seat-facing listener: `seatpost.Poster` has exactly `PostIssueComment` and `PullHead`; `grep -rn 'ListComments|ListReviews|Comments(' seatpost/ cmd/ld-runtime/seat_post.go` (non-test) = 0 hits, and `seatPostServer.Serve` serves `gate.Handler()` only. - Provenance read ONLY on 8097: `ProvenanceHandler` is mounted exactly once (main.go:1210 → `lookup.mountProvenance`), `seatLookupServer.handler()` routes it by exact path, and `Gate.Handler()` 404s any path but `/v1/seat-post` (TestProvenanceIsNotOnThePostHandler asserts 404 for GET *and* POST). - Claim before Forgejo, refusal on ANY insert error: post() calls `g.record(…Result: ResultClaimed)` before `Poster.PostIssueComment`; `ErrConflict` → 409 `ReasonAlreadyPosted`, anything else → 500 `ReasonClaimFailed` with `respond`, never a post (TestClaimConflictRefusesWithoutPosting, TestClaimInsertErrorRefuses500WithoutPosting). - Stale claim burns the bundle: `Claimed()` is read alongside `Posted()` and refuses 409 before any Forgejo call; the posted-row insert failure keeps 200 (the comment exists) and the claim still blocks a retry (TestStaleClaimBurnsTheBundle asserts Poster calls = 1 over two posts; TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond). - Server-minted bundle id: register's struct has no `bundle` field, `decode` uses DisallowUnknownFields, id comes from `crypto/rand` 16 bytes hex (TestRegisterRefusesACallerChosenBundle → 400 unknown_field). - sid+head bound against the pin, first-declaration-wins inside the first block: `firstVerdictBlock` = leading non-blank run; `declaredPin` walks it ONCE in line order, stance-anchored bold (`AGREE|APPROVE|REQUEST_CHANGES|HOLD|CONCERN|BLOCK…`), heading, or relay `LD-VERDICT`, and stops at the first decliner; `SESSION:`/`sid=` is the other half; caller refuses on `!ok` or any disagreement. The round-3/round-4 repros are in the tests (decoy heading at another head refused, `**note: see head <sha>**` supplies nothing). - No sha echoed to unauthenticated callers: `ReasonHeadMismatch`, `ReasonBodyPinMismatch`, `ReasonAlreadyPosted`, `ReasonBundleUnknown` carry no values; TestNoShaInAnyRefusalBody checks every refusal body (incl. the provenance 404 and the store-failure 500) for both the pinned and the live 8-hex prefix. - Boot asserts BOTH partial unique indexes, fail-closed: `seatPostSchemaOK` requires `claim && post`; any error or a missing index logs the named line and sets `SchemaOK=false`, and post() answers 503 `ReasonSchemaAbsent` (TestSeatPostSchemaMissingRefusesPosts covers both-absent / one-absent / check-failed; register keeps answering). - Pod-IP-only bind: `bindAddr` resolves empty host AND `0.0.0.0`/`::`/`[::]` through HOSTNAME→first non-loopback IPv4 and REFUSES the listener when it cannot (TestSeatPostBindAddr), `Serve` listens on that resolved address. Also verified: goroutine count is exactly 5 in every branch of serve(), so no deadlock on the disabled paths; post answers `{posted, comment_id}` only, so a bundle-id guesser learns no target; the registration read filters `result='registered'`, so a refused register row can never become the pin. PR BODY vs HEAD - Flows 1 and 5 are honestly marked "not this PR" (part 3); flow 2 and 3 are marked PROVEN for the endpoint half only, not for the seat template — no over-claim. - All 23 cited test names exist exactly once at this head (`grep -rn 'func <name>(' --include=*.go` = 1 each) and all pass, including subtests `TestPostRefusals/head-mismatch`, `TestDeclaredPin/decoy-then-real-verdict`, `TestDeclaredPin/real-verdict-below-a-blank-line`. - "no independent walk: implementer-run checks only" is present at the end of the body. - The run/ claim is accurate: `TestPostIssueCommentPostsTheBodyVerbatim` passes at this head. FINDINGS (non-blocking, each checkable) OBS-1: The body's "Head shape" paragraph says "three stacked commits" and then names four (955ab6b3, ef493ca1, 2fac01a2, ac105cd0); `git log --oneline origin/live...HEAD` shows FIVE, the fifth being 867f7d1c ("drop the dead re-register refusal"). Documentation only — I reviewed the full five-commit base..head diff — but the paragraph is now stale. OBS-2: The 200 answer of the 8097 provenance route does echo `{head, sid, result}` to an unauthenticated caller. That is the AMENDMENT-2/B1 design itself, and the "no sha" rule holds on every refusal body and on both seat-facing routes; the residual exposure is closed by the CNP keeping 8097 off the seat's reach, which is roll-out step 2 (the prod PR) and explicitly not this diff. OBS-3: `newSeatPostGate` is now built unconditionally in serve() and returns an error when the record store is nil, so a storeless ld-runtime would fail to boot even with LD_SEAT_POST_ADDR and LD_SEAT_LOOKUP_ADDR both unset — that one "off unless asked for" guarantee is enforced by a nil-store check rather than by the address. No live path changes today (`build()` already fails on `record.OpenSQL`), and the same unconditional call makes one 5 s-timeout index probe at every boot even when the endpoint is off; worth a follow-up, not a blocker. TESTS RUN (exit codes, this sandbox, this head) - `go vet ./...` → exit 0 (clean). - `go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/` → exit 0; `ok seatpost 1.129s`, `ok record 1.051s`, `ok cmd/ld-runtime 1.131s`. - `go test -race -count=1 -run '<the 17 seatpost tests cited above>' ./seatpost/` → exit 0 (18 PASS lines incl. parent; 0 FAIL). - `go test -race -count=1 -run 'TestSeatPostSchemaMissingRefusesPosts|TestProvenanceIsMountedOnTheLookupListener|TestProvenanceIsNotOnThePostHandler|TestRegistrationReadCarriesTheSid|TestSeatPostWiringCarriesTheSid' ./cmd/ld-runtime/` → exit 0. - `go test -race -count=1 -run TestPostIssueCommentPostsTheBodyVerbatim ./run/` → exit 0. - `go test -race -count=5 -run TestConcurrentPostsCannotBothReachForgejo ./seatpost/` → exit 0 (race detector clean over 5 runs). - `gofmt -l` on the changed files → no output; `t.Skip` in the three new test files → none; seatpost has 29 top-level tests as the body states. - Guard: `scripts/gits-sbx-epic-test.sh` names lab-director/dispatcher only in comments about `relay/relay.go` and `relay/seat.go`; grep finds no seatpost surface, so no guard command covers this change and the body's "NEW FAILURES: 0" baseline claim is unaffected by it (the ./run/ TempDir/gomodcache failures are pre-existing and this diff's run/ test passes). Nothing in the diff beats its own claims; APPROVE.
Collaborator

APPROVE — ld-reviewer — head 867f7d1cd0
SESSION: LR-20261111-025-seatA-20261111T1709Z
MODEL: omniroute/deepseek-flash

VERDICT: APPROVE
MODEL: omniroute/deepseek-flash
SESSION: LR-20261111-025-seatA-20261111T1709Z
HEAD: 867f7d1cd0 (verified: git rev-parse HEAD at this clone = the same 40 hex; base origin/live 35a336157d; 5 stacked commits, full three-dot diff read)

FINDINGS (none blocking):

  1. Non-blocking, docs only: record/seat_posts.go line ~165 still says "registration retries are LEGAL rows (an identical retry is an explicit 200 path, and a differing one is refused by the read ... not by an index)" — that path no longer exists at this head: commit 867f7d1c removed the re-register refusal and a server-minted bundle id can never be retried. The conclusion (no unique index on register rows) is still right; the exemplar is stale. Check: grep -n "identical retry" record/seat_posts.go seatpost/post.go.
  2. Non-blocking, docs only: seatpost/post.go line ~591 "registrationBody is the 200 answer to a register (and to an identical retry)" — same stale "identical retry", same commit. Check: same grep.
  3. Non-blocking, disclosure nit: the code comment on firstVerdictBlock is honest (this endpoint stops at the first blank line; the census continues past a blank after a heading/opening statement), but the PR body says "exactly what the census reads" — it is the STRICTER reading, so the failure direction is a refused honest verdict, never a mis-attributed one. No action required.

AMENDMENT-2 SHAPE, each checkable at this head:

  • No comment/review read on the seat-facing listener: Gate.Handler() serves only exact Path and 404s everything else; seatPost.Poster is PostIssueComment + PullHead only; no ListComments/ListReviews call exists in seatpost/ or cmd/ld-runtime/seat_post.go (grep is empty over non-test files). TestNoReadVerbAtTheHTTPSurface PASS.
  • Provenance read ONLY on 8097: lookup.mountProvenance(seatPostGate.ProvenanceHandler()) in cmd/ld-runtime/main.go; the 8098 handler is bare s.gate.Handler(). TestProvenanceIsMountedOnTheLookupListener asserts 8097 routes seatpost.ProvenancePath to the provenance handler AND that the 8098 handler 404s it. PASS.
  • Claim row before Forgejo, refusal on ANY insert error: post() logs a claimed row via g.record(...) before PostIssueComment, and on error answers 409 on ErrConflict / 500 on anything else, returning before the Forgejo call. record/seat_posts.go's DDL contract carries seat_posts_one_claim. TestClaimConflictRefusesWithoutPosting PASS.
  • Stale claim burns the bundle and blocks reposts: posted || claimed → 409 with a named stale-claim log line; the claim is never deleted (no UPDATE/DELETE by grant, one INSERT statement in the file, no ON CONFLICT). TestStaleClaimBurnsTheBundle PASS.
  • Server-minted bundle id: register decodes {sid,repo,pr,head} with DisallowUnknownFields and no bundle field; MintBundleID = crypto/rand 16 bytes hex. TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle PASS.
  • sid+head bound to the pin, first-declaration-wins, first block only: declaredPin reads firstVerdictBlock only, strips backticks, takes the FIRST declaring line (relay / stance-anchored bold / heading) and breaks, then requires a SESSION line; caller refuses unless sid==pin.Sid and head equals reg.Head. 20 subtests incl. decoy-first-block, heading-beats-later-bold, backticked, relay. TestBodyPinBinding PASS.
  • No sha echoed to unauthenticated callers: ReasonHeadMismatch and ReasonBodyPinMismatch carry no values; short8 is gone from the package. TestNoShaInAnyRefusalBody PASS. (The register 200 echoes the head the caller itself supplied; post 200 is {posted, comment_id} only.)
  • Boot asserts BOTH partial unique indexes: newSeatPostGate → seatPostSchemaOK requires claim && post, fail-closed on read error, logged either way; SchemaOK false refuses every post with a named 503 while register keeps answering. TestSeatPostSchemaMissingRefusesPosts / TestSeatPostSchemaPresentOpensPosts PASS.
  • Pod-IP-only bind: bindAddr resolves every spelling of "no interface" (":8098", "0.0.0.0", "::", "[::]", "[0.0.0.0]") via HOSTNAME→first non-loopback IPv4 and REFUSES when it cannot resolve; a named host is used as-is. TestSeatPostBindAddr PASS.

PR BODY vs THIS HEAD:

  • "Done when" flows: 1 and 5 explicitly "not this PR" (part 3); 2, 3 and 4 marked PROVEN with test names. Every cited test name exists at this head (23/23 verified by grep for func <name>(): TestPostTransportsTheVerdictVerbatim, TestSecondPostIsAConflict, TestClaimConflictRefusesWithoutPosting, TestStaleClaimBurnsTheBundle, TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond, TestNilPosterRefusesPerCall, TestNoReadVerbAtTheHTTPSurface, TestConcurrentPostsCannotBothReachForgejo, TestPostRefusals (incl. head-mismatch), TestBodyPinBinding, TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle, TestRegisterInsertFailureRefuses, TestNoShaInAnyRefusalBody, TestSchemaAbsentRefusesPosts, TestSeatPostSchemaMissingRefusesPosts, TestProvenanceHandler, TestProvenanceIsMountedOnTheLookupListener, TestProvenanceIsNotOnThePostHandler, TestProvenanceHasItsOwnAllowance, TestRegistrationReadCarriesTheSid, TestSeatPostWiringCarriesTheSid, TestPostIssueCommentPostsTheBodyVerbatim.
  • "no independent walk: implementer-run checks only" — present, verbatim.

TEST (each exit code):

  • cd lab-director/dispatcher && go vet ./... → exit 0 (clean).
  • go build ./... → exit 0.
  • go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/ → exit 0 (ok seatpost 1.2s, ok record 1.1s, ok cmd/ld-runtime 1.2s).
  • go test -race -count=1 ./run/ → exit 1, 7 failures, and the FAIL list is IDENTICAL to a clean worktree at base 35a336157d (git worktree add /tmp/base025 35a3361), all "TempDir RemoveAll cleanup: ... gomodcache ... permission denied" — zero assertion failures. Reproduced twice more at head: 7 each time. One extra flake (TestCloseScheduleIsJournalled) appeared once under parallel load in my session and did NOT recur in two further -race runs, and passes alone; not attributable to this diff. Targeted run of the touch points (-run 'TestPostIssueComment|TestPullHead|SeatPost|Forgejo' ./run/) → ok, so PostIssueComment/PullHead assertions pass.
  • Guard (scripts/gits-sbx-epic-test.sh, "live 20 / head 20, NEW FAILURES: 0"): script present at this head; not re-run by me — the dispatcher is not a guard surface and the change is dispatcher-only.

Scope notes accepted as disclosed, not defects: N2 (repo allowlist) and N5 (per-caller limiting / expiry) deferred by El Director; the endpoint buys no read path but does not stop a fake verdict posted by the same Unix user (gateway sid check is the defence); the seat_posts migration and the 8098 Service/CNP ride the prod PR, and until then posts fail closed with a named 503.

**APPROVE — ld-reviewer — head 867f7d1cd0f4f5a0317931a29226bddf02e77287** SESSION: LR-20261111-025-seatA-20261111T1709Z MODEL: omniroute/deepseek-flash VERDICT: APPROVE MODEL: omniroute/deepseek-flash SESSION: LR-20261111-025-seatA-20261111T1709Z HEAD: 867f7d1cd0f4f5a0317931a29226bddf02e77287 (verified: `git rev-parse HEAD` at this clone = the same 40 hex; base origin/live 35a336157df27578698b50e0f21f69b1aa71c564; 5 stacked commits, full three-dot diff read) FINDINGS (none blocking): 1. Non-blocking, docs only: `record/seat_posts.go` line ~165 still says "registration retries are LEGAL rows (an identical retry is an explicit 200 path, and a differing one is refused by the read ... not by an index)" — that path no longer exists at this head: commit 867f7d1c removed the re-register refusal and a server-minted bundle id can never be retried. The conclusion (no unique index on register rows) is still right; the exemplar is stale. Check: grep -n "identical retry" record/seat_posts.go seatpost/post.go. 2. Non-blocking, docs only: `seatpost/post.go` line ~591 "registrationBody is the 200 answer to a register (and to an identical retry)" — same stale "identical retry", same commit. Check: same grep. 3. Non-blocking, disclosure nit: the code comment on `firstVerdictBlock` is honest (this endpoint stops at the first blank line; the census continues past a blank after a heading/opening statement), but the PR body says "exactly what the census reads" — it is the STRICTER reading, so the failure direction is a refused honest verdict, never a mis-attributed one. No action required. AMENDMENT-2 SHAPE, each checkable at this head: - No comment/review read on the seat-facing listener: `Gate.Handler()` serves only exact `Path` and 404s everything else; `seatPost.Poster` is `PostIssueComment` + `PullHead` only; no ListComments/ListReviews call exists in seatpost/ or cmd/ld-runtime/seat_post.go (grep is empty over non-test files). TestNoReadVerbAtTheHTTPSurface PASS. - Provenance read ONLY on 8097: `lookup.mountProvenance(seatPostGate.ProvenanceHandler())` in cmd/ld-runtime/main.go; the 8098 handler is bare `s.gate.Handler()`. TestProvenanceIsMountedOnTheLookupListener asserts 8097 routes `seatpost.ProvenancePath` to the provenance handler AND that the 8098 handler 404s it. PASS. - Claim row before Forgejo, refusal on ANY insert error: `post()` logs a `claimed` row via `g.record(...)` before `PostIssueComment`, and on error answers 409 on ErrConflict / 500 on anything else, returning before the Forgejo call. record/seat_posts.go's DDL contract carries `seat_posts_one_claim`. TestClaimConflictRefusesWithoutPosting PASS. - Stale claim burns the bundle and blocks reposts: `posted || claimed` → 409 with a named stale-claim log line; the claim is never deleted (no UPDATE/DELETE by grant, one INSERT statement in the file, no ON CONFLICT). TestStaleClaimBurnsTheBundle PASS. - Server-minted bundle id: register decodes {sid,repo,pr,head} with DisallowUnknownFields and no bundle field; `MintBundleID` = crypto/rand 16 bytes hex. TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle PASS. - sid+head bound to the pin, first-declaration-wins, first block only: `declaredPin` reads `firstVerdictBlock` only, strips backticks, takes the FIRST declaring line (relay / stance-anchored bold / heading) and breaks, then requires a SESSION line; caller refuses unless sid==pin.Sid and head equals reg.Head. 20 subtests incl. decoy-first-block, heading-beats-later-bold, backticked, relay. TestBodyPinBinding PASS. - No sha echoed to unauthenticated callers: ReasonHeadMismatch and ReasonBodyPinMismatch carry no values; `short8` is gone from the package. TestNoShaInAnyRefusalBody PASS. (The register 200 echoes the head the caller itself supplied; post 200 is `{posted, comment_id}` only.) - Boot asserts BOTH partial unique indexes: `newSeatPostGate` → `seatPostSchemaOK` requires claim && post, fail-closed on read error, logged either way; `SchemaOK` false refuses every post with a named 503 while register keeps answering. TestSeatPostSchemaMissingRefusesPosts / TestSeatPostSchemaPresentOpensPosts PASS. - Pod-IP-only bind: `bindAddr` resolves every spelling of "no interface" (":8098", "0.0.0.0", "::", "[::]", "[0.0.0.0]") via HOSTNAME→first non-loopback IPv4 and REFUSES when it cannot resolve; a named host is used as-is. TestSeatPostBindAddr PASS. PR BODY vs THIS HEAD: - "Done when" flows: 1 and 5 explicitly "not this PR" (part 3); 2, 3 and 4 marked PROVEN with test names. Every cited test name exists at this head (23/23 verified by grep for `func <name>(`): TestPostTransportsTheVerdictVerbatim, TestSecondPostIsAConflict, TestClaimConflictRefusesWithoutPosting, TestStaleClaimBurnsTheBundle, TestPostedInsertFailureAfterPostKeeps200AndBlocksASecond, TestNilPosterRefusesPerCall, TestNoReadVerbAtTheHTTPSurface, TestConcurrentPostsCannotBothReachForgejo, TestPostRefusals (incl. head-mismatch), TestBodyPinBinding, TestRegisterMintsTheBundleID, TestRegisterRefusesACallerChosenBundle, TestRegisterInsertFailureRefuses, TestNoShaInAnyRefusalBody, TestSchemaAbsentRefusesPosts, TestSeatPostSchemaMissingRefusesPosts, TestProvenanceHandler, TestProvenanceIsMountedOnTheLookupListener, TestProvenanceIsNotOnThePostHandler, TestProvenanceHasItsOwnAllowance, TestRegistrationReadCarriesTheSid, TestSeatPostWiringCarriesTheSid, TestPostIssueCommentPostsTheBodyVerbatim. - "no independent walk: implementer-run checks only" — present, verbatim. TEST (each exit code): - `cd lab-director/dispatcher && go vet ./...` → exit 0 (clean). - `go build ./...` → exit 0. - `go test -race -count=1 ./seatpost/ ./record/ ./cmd/ld-runtime/` → exit 0 (ok seatpost 1.2s, ok record 1.1s, ok cmd/ld-runtime 1.2s). - `go test -race -count=1 ./run/` → exit 1, 7 failures, and the FAIL list is IDENTICAL to a clean worktree at base 35a336157df27578698b50e0f21f69b1aa71c564 (`git worktree add /tmp/base025 35a3361`), all "TempDir RemoveAll cleanup: ... gomodcache ... permission denied" — zero assertion failures. Reproduced twice more at head: 7 each time. One extra flake (TestCloseScheduleIsJournalled) appeared once under parallel load in my session and did NOT recur in two further -race runs, and passes alone; not attributable to this diff. Targeted run of the touch points (`-run 'TestPostIssueComment|TestPullHead|SeatPost|Forgejo' ./run/`) → ok, so PostIssueComment/PullHead assertions pass. - Guard (`scripts/gits-sbx-epic-test.sh`, "live 20 / head 20, NEW FAILURES: 0"): script present at this head; not re-run by me — the dispatcher is not a guard surface and the change is dispatcher-only. Scope notes accepted as disclosed, not defects: N2 (repo allowlist) and N5 (per-caller limiting / expiry) deferred by El Director; the endpoint buys no read path but does not stop a fake verdict posted by the same Unix user (gateway sid check is the defence); the `seat_posts` migration and the 8098 Service/CNP ride the prod PR, and until then posts fail closed with a named 503.
Sign in to join this conversation.
No reviewers
No labels
operator-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Homelab/infra-core!939
No description provided.