HOMELAB-2682: fix(forgejo): documentation never supplies a verdict, stance or pin, and a section severity word never decides a finding #111
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "plane/HOMELAB-2682-verdict-arm-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
The verdict arm and the finding arm of the landing lock, after the round-4 blind seat's measured defects on the merged
a570a5df(PR #108) and homelab-88's orch15 repro (working-files/infra-stability/orch15/lock-parser-repro.md).Branch
plane/HOMELAB-2682-verdict-arm-fixoffmainata570a5df. Nothing placed anywhere: the merged parser atmainis under HOLD and this PR is a branch and a PR, nothing else.Defects fixed
BLK-1 — prose acquired a stance and shadowed a real hold (fail-open, merged). A first line whose subject merely mentions review/verdict/approval (
Review notes on 4f2a1bc) opened a verdict statement, the paragraph under it was attached, its incidental "approved in principle" became the comment's stance, and that stance shadowed the whole-body hold-first read — so a realREQUEST_CHANGES at <head>later in the SAME comment was discarded and the lock permitted. The seat measured: base refused,a570a5dfpermitted.Now: a statement's block supplies a stance only when the opener NAMES a verdict (
**Verdict summary**,verdict: request_changes,**Verdict of record — <reviewer>**) — the round-3 shapes. A prose opener's stance is (1) its own line, else (2) a hold read anywhere in the body (fail-closed), else (3) a line that states a stance about a head it also names IN THAT LINE (the shape a reviewer's answer takes when it points at its own verdict:Comment 16035 is an approval of <sha>— the real corpus comment that pinned this). Prose no longer manufactures an APPROVE either: "approved in principle" with a sha above it is discussion, not a verdict.BLK-2 / RISK-2 — fenced and blockquoted text was read as the verdict block. The findings arm has treated fences and blockquotes as documentation since round 3 (
documentationLines); the verdict arm never did, so the same text was documentation when it would raise a finding and evidence when it would permit a merge:verdict: pass+head: <sha>template (the blank-skip walked INTO the fence) — exact-head APPROVE ata570a5df, refusal at base;> verdict: pass/> head: <sha>— same flip;> ## Verdict — APPROVE at <head>(> ##is not/^#{1,6}\s/, so the quoted line was an "opener" and the quote supplied both polarity and pin).verdictStatementLinesis now documentation-aware: leading documentation is SKIPPED (so a quoted attribution line above a real verdict does not swallow it — homelab-88's shape, which reported "None carries a verdict statement in the recognised forms" for a comment that plainly carried one) and the statement block STOPS at the first documentation line rather than consuming it. A comment that is only a quote therefore has no statement at all: it is not a verdict, supplies no stance and no pin. The body fallback reads approve/concern from non-documentation lines only, with a raw-body hold still winning.RISK-3 — a section's severity word decided whether its line was a finding. Under
## Blockers,- B1: blocker — …yielded ZERO findings while- B1: high — …andBLOCKER B1: …both counted: the severity WORD matched the token path, where every pattern wants the token at the line HEAD, and the token path never fell through to the section arm. A token standing in the label's own severity SLOT (<lead gap><id label><separator>blocker) is now read by the section's content rules, whose own guards (negation, zero-claims, resolution notes, documentation, non-blocker labels) still decide what the line is.Deliberately NOT widened: a token MID-SENTENCE still does not count (
- I checked whether the (blocker) tag applies …,- no new blockers were introduced at this head). Round 2's rule — a parenthetical token is a LABEL, never prose — is unchanged; the r2/B1 tests that pin it stay green, and the partial state of this branch (a blanket fall-through) broke them.CONCERN-2 — docs.
docs/forgejo.mdclaimed "Fenced and BLOCKQUOTED text is documentation in both arms". That sentence is now true, and it says what the verdict arm does with a quote: no stance, no head pin, and a comment that is only a quote is not a verdict.Unchanged, recorded and accepted
### Findingsno longer supplies severity. Unchanged.isVerdictShapedis narrower thanisReviewVerdict. Unchanged.Tests
forgejo/tests/landing-verdict-arm-2682.test.ts, written first, 30 cases: BLK-1 (including theAPPROVE with concernscontrol and the round-3 machine-form controls), BLK-2a/2b, RISK-2, RISK-3 (every severity word, the zero-claims, the negations, the documented template, prose-outside-forms), homelab-88's orch15 regressions (## No blockers.over 15 evidence lines, the no-#body,Blockers: none., the attribution line above a verdict), and both directions of the finding rule (the three forms still count; only the forms).Measured BOTH ways, not asserted:
a570a5df(stashed tree)tsc --noEmitcleanThe three homelab-88 cases that are green at
a570a5dfas well are #108's own fixes, kept as guard rails against this change reopening them.Files changed:
forgejo/landing.ts,forgejo/tests/landing-verdict-arm-2682.test.ts(new),docs/forgejo.md(the one false sentence). Nothing wider.Reviewer limitation (the fleet's own rule): a reviewer may read, comment and approve or request changes — never edit, commit or push, and nobody posts a verdict in a reviewer's place.
PR-description addendum — the accepted cost, recorded plainly (not a verdict; documentation for the seats)
The fix worker could not edit the description (no tool exists for it in this session), so ruling item 2 of
working-files/ldv0/tooling10-ruling-1555.mdis recorded here, in the form it should be pasted into the description, and indocs/forgejo.md. This comment is not verdict-shaped and carries no stance in either direction — checked against the deployed lock at34fdf7f5and against this head before posting.Accepted cost:
Three things follow, and the first is the cost:
## Blockers. The exit for a reviewer whose objection was written as a quote is a rewrite, not a re-tone: post it as a verdict block (**Verdict of record — <reviewer> — head <sha>: REQUEST_CHANGES**, orverdict: request_changesplushead:), or list it under## Blockers.no-verdict-block, which is what it always was.Round 6's documented-hold leg is removed, not extended:
requestChangesPinsIn's documented-text half, the stance-state documented-hold branch, andextractVerdict's "a documented hold takes its own pins" are all gone. The resolution carve-out now reads non-documentation lines only, so a quote cannot re-arm a resolution either.Differs from the deployed lock at
34fdf7f5in exactly the ruled direction: of a 109-shape corpus, 10 rows move refuses → permits, and every one is a hold that existed only as a quoted or fenced line (no unquoted hold, no fail-closed shape, no corpus verdict).New head:
6f18ab9cbc7b85aa192679a3e091da525ee37b8e. Package suite 1022/1022 green, deployed-shape suite 1022/1022,tsc --noEmitclean. Nothing merged, nothing placed.Loosening vs the deployed lock (recorded as a loosening)
478 rows (N4: 260, N5: 106, N6: 112): a mid-sentence severity marker in prose with no ## Blockers section no longer raises a finding. Reason: with no ## Blockers section these lines are prose, and the rule is that everything else never parses; failing them closed would re-create a false refusal (the #108 seat-1 B1 class). This loosens the lock against what is deployed at
34fdf7f5.Refuses→permits additions, recorded before merge
Loosening, in addition to the 478 N4–N6 rows above:
(a)
## No blockers.over a defect line — 6 rows measured; the heading is not the exact## Blockers, so the section rule does not apply; includes- B1: highand- RISK-2:forms.(b) Malformed or glued markers with NO section —
(blocker],(blocker ],[blocker),[ blockers ),- B1: ... (blocker],BLOCKER<B1>:— not fully counted.(c) A verdict block plus prose about a REQUEST_CHANGES on an older head — 1 row measured.
Not a loosening (list only):
- None.,- **None.**,none,none!,blockers resolved, and lines after a nested heading or---under## Blockersraise no finding at this head — the structural rule names only exactlyNone.as the exception, so this is wider than the rule's letter; no refuse→permit move is involved.verdict: pass
head:
48509e5994model: omniroute/deepseek-flash
session: 01a1b13e-8972-700b-89cf-897d0d24ca0c
Concerns
approve(d) with concerns. It restores symmetry with shapes base already permitted (a bareApproved at <sha>and**APPROVE — head <sha>**both permitted at base), and I measured no new refusal from the fail-closed leg when a clean exact-head approve is present, but it is a behavioural change to a recognizer both arms share that the six criteria do not name.BLIND SEAT 1, closing report.
What I verified myself, from git objects only (
git fetchof the branch and base; the diff,forgejo/landing.ts,forgejo/tests/landing-verdict-arm-2682.test.ts,docs/forgejo.md):a570a5df: 13 failed, 17 passed (30) — exactly the defect cases (prose-stance absorption, fenced machine form, blockquoted machine form, blockquoted heading verdict, quoted attribution,- B1: blocker —under a Blockers section, and the two seat controls that the recognition regex had to be widened for). At48509e5: 30 passed (30). Whole module suite at head: 993 passed (36 files).tsc --noEmit: clean.evaluateLandingLock,extractVerdict,findOpenBlockers,readVerdictStance) rather than through internals: documentation lines are now skipped and the statement block STOPS at the first fenced or quoted line, so a quote can supply neither a stance, a pin, nor a verdict, while a quote above a real verdict no longer swallows it; a line under## Blockersraises whatever its severity word says, and only in the label's severity slot.Blockers: none., an outside-a-section label and a negation-claim section all still raise nothing.Approved at <sha>permitted at base; the same with "with concerns" did not, and now does). I also confirmed the change does not create new bricks: a verdict-shaped comment with no readable block, or one whose stance is readable but whose head is not, still permits beside one clean exact-head approve.statedrule) and the blocker finding-line reader, plus the widened stance-first recognizer in C2. Nothing in the policy, identity, CI, formal-review or ledger legs moved.What I did not see: PR comments or reviews, the landing census, the Plane ticket, anything under working-files/ (including anything about the other seat), and the other seat's verdict. I did not edit, commit, push, merge, or change formal review state.
Scope note for the landing worker: the two concerns are advisory under the pipeline contract; no blocker is open from this seat.
verdict: pass
head:
48509e5994model: omniroute/deepseek-flash
session: 01a1b13e-899e-700b-89cf-897ef7ac1da4
Concerns
approve/approved, thenwith concerns, then its separator) is outside the six items the brief names, and it does change behaviour in both directions: three shapes base refused now permit, and an unpinnedAPPROVE with concernsnow classifies as verdict-shaped and refuses. The new test labels that case CONTROL although it FAILS at base, and neither docs/forgejo.md nor the token's own comment mentions the extension. Relabel it as a fix, add the one-line doc/comment, and record it in the changed-behaviour inventory.Verification (plain prose, not findings)
I reviewed git objects only: the branch and base were fetched from the Forgejo remote and read in scratch worktrees.
Red at base
a570a5df, green at head48509e5. The new test file at base is 13 failed / 17 passed, with the other 980 tests in the package passing there; at head that file is 30/30 and the package is 993/993, andtsc --noEmitis clean. Of those 13, twelve are the cases the brief requires to be red (the two prose-opener cases plus the "no hold" direction, the fenced template, the fence-cannot-supply-the-pin case, the quoted machine form, the quoted bold variant, the quoted heading verdict, the two homelab-88 attribution cases, and the section severity-word cases); the thirteenth is the CONTROL that C1 is about, which is red at base because base read that shape as no verdict at all.A differential run of the same 82 real comment bodies from the repo fixtures through extractVerdict, isReviewVerdict, isVerdictShaped and findOpenBlockers gives identical results at both revisions, and 34 finding-arm line variants are identical too, so the change is confined to the shapes it names apart from C1. Each of the measured defects now refuses where base permitted: the prose first line no longer takes a stance from the paragraph beneath it, so a real REQUEST_CHANGES under it still holds; a fence or blockquote supplies neither stance nor pin, so a quoted template or quoted heading is no verdict; a quoted attribution line above a real verdict no longer swallows it; and a line under the section heading raises whatever its severity word says, while zero-claims, negations and quoted templates still raise nothing. The pinned corpus shapes still permit.
I did not see the other seat's verdict, the PR discussion, the census, the ticket, or anything under the working files, and I make no claim about the two risk items the brief leaves out of scope beyond this: no code path or test of theirs was touched, and the whole-suite pass plus the differential above shows no other behavioural delta I could find.
verdict: request changes
head:
0d8add5ecamodel: omniroute/deepseek-flash
session: 01a1b15d-f58d-700b-89cf-898d93e173d1
Blockers
docs/forgejo.md:501(and:618) now say "Documentation never supplies a verdict — but a quoted or fenced HOLD still supplies a hold for a comment that is already verdict-shaped", and step 3 repeats "the whole-body leg still lets a quoted hold refuse a comment that is already verdict-shaped". Measured through the public API at this head: a verdict-shaped comment whose statement block resolves a stance, followed by a quoted or fenced hold at the same head —**Verdict of record — \ld-reviewer` — head : APPROVE**+model:+session:then> REQUEST_CHANGES at(and the fenced equivalent) — givesreadVerdictStance = "approve"andevaluateLandingLock = PERMIT; the same body withverdict: pass+head:instead of the bold opener permits too. The quoted hold only refuses where the statement leaves the stance UNRESOLVED (a## Verdictheading + quoted hold: stancehold), becauseif (stated) return statedreturns before the whole-bodypolarityOf(item.body)leg ever runs. The PR's own test contradicts the doc sentence:tests/landing-hold-under-approve-2682.test.ts:332` ("a documented (quoted or fenced) hold is NOT this comment's hold") ASSERTS the permit for exactly that shape. So the criterion "docs true on both legs — a quoted/fenced hold still holds for a verdict-shaped comment" is unmet: either the docs must be qualified to the unresolved-stance case, or the approve-stance short-circuit must consult the documented hold. This is not a base→head permission difference (a570a5dfpermits the same shape), but the sentence is new in this PR and states a safety property the code does not have, in the one direction a reviewer relies on ("quoting my objection cannot dodge it").Concerns
**Verdict summary**\nverdict: pass\nhead: <sha>\nmodel: …\nsession: …is a real exact-head APPROVE ata570a5df—readVerdictStance = approve,extractVerdict = approve/exactHead true, lock PERMIT — and decides nothing at this head (stance = null,verdict = none, REFUSE). That is a documented round-3 approve shape going invisible; the table row records it asalone: "unrecognised"with a comment that base read the block, so the change is honest about it, but the behaviour difference is real and is in neither of the two directions the ruling names.tests/landing-hold-under-approve-2682.test.ts:257"(an approve form ALONE still approves (the table's control column))" is one of the 18 that fail ata570a5df, and it fails for exactly C1: the**Verdict summary**row'salonevalue is head's answer, not base's, so the "control column" is not a control. The four tests explicitly labelledCONTROL:(verdict-arm 141, 156, 250, 256) do pass at base — I checked the base failure list line by line — so the letter of the criterion is met for those four, but the lower-case control column is mislabelled.polarityPinningHeadaccepts any single unquoted line that both pins a head and carries a stance, so prose like anapproval of <sha> was earlierreference can read as an approval of this head. I looked for a case where that permits something base refused and found none — 85 real corpus comment bodies fromtests/fixtures/give byte-identical stance and polarity at both revisions, and 40 synthetic shapes are identical or tighter. Recording it as the one place I would watch, not as a finding.Evidence and tallies. Test-first, run by me in scratch checkouts at
/tmp(symlinkednode_modules, worktrees of this branch's git objects; the two new test files were copied into the base tree sincea570a5dfdoes not contain them). Basea570a5df, the two new files: 18 failed | 24 passed (42) across 2 failed files. Head0d8add5e, the same two files: 42 passed (42) across 2 passed files. Full suite: base 18 failed | 987 passed (1005, 2 files failed); head 1005 passed (1005, 37 files passed) — so nothing in the pre-existing 35 files regresses. Approve-form coverage is real: I drove 15 approve/stance bodies (machineverdict: pass, machineverdict: approved,**Verdict summary**,**APPROVE — head <sha>**,**APPROVE — reviewer — head <sha>.**,**APPROVE at <sha>**,Approved at <sha>,**APPROVE**+head:label,LGTM at <sha>,**APPROVAL OF RECORD …**,**APPROVAL OF RECORD …: APPROVE with concerns, no blocker.**,**Verdict of record …: APPROVE**, legacy## Verdict — head <sha>+verdict: approved,## Approval pinned to exact head <sha>,Approved with concerns, <sha>) against 6 hold spellings (plain line, bold,Requesting changes,Changes requested, first person, machineverdict: request_changes+head:) throughevaluateLandingLock/extractVerdict: every combination PERMITS at base and REFUSES at head withstance = hold,verdict = hold/exactHead true. The no-widening leg holds:STANCE_FIRST_TOKEN_REis byte-identical to base's pattern (only rewrapped), andApproved with concerns,<sha>,**APPROVE with concerns — head <sha>**and**APPROVAL OF RECORD …: APPROVE with concerns, no blocker.**parse identically at both revisions. The findings arm only tightens: under## Blockers,- B1: blocker — …,- B2: blocker: …,- B1: blocker (…)and- B4: blockernow raise (base raised nothing,- B1: high — …raised at both), whileNone.,- no new blockers were introduced at this head,- B1: nit — …,- B1: non-blocking — …,- B1: blocker resolved in this commit, the placeholder template and a quoted template still raise nothing — so no base-refuses/head-permits difference in either arm was measured. Exposure: I have seen earlier review findings through this review brief and the PR's test file names, and I reviewed git objects only (diff,landing.ts, both new test files,docs/forgejo.md, fixtures); I have not seen the PR discussion, the census, the ticket, or the other seat's verdict.Posted by blind review seat 1. Read-only throughout: nothing edited, committed, pushed or merged.
verdict: request changes
head:
0d8add5ecamodel: omniroute/deepseek-flash
session: 01a1b15d-f5c8-700b-89cf-898f801107d6
Blockers
B1: blocker — a QUOTED or FENCED hold no longer holds when the comment is verdict-shaped but has no stance of its own (a prose opener that mentions review/verdict/approval). Base refused, head PERMITS. This is the fail-closed leg the change's own docs and code comments promise, bypassed by one early return.
Measured through the public API (
evaluateLandingLock, one clean independent exact-head approval plus the comment, head4f2a1bc9d1e2f…, authorld-reviewer) at basea570a5dfand at this head:## Review notes+ blank +> REQUEST_CHANGES at <head>Review of the retry path+ blank +> REQUEST_CHANGES at <head>Review of the retry path+head: <head>+ blank +> REQUEST_CHANGES at <head>Review notes on the diff+ blank +> **REQUEST_CHANGES at <head>**Approval notes for the delta+ blank +> REQUEST_CHANGES at <head>Review notes on 4f2a1bc+ blank +> REQUEST_CHANGES at <head>Review of the retry path+ blank + fencedREQUEST_CHANGES at <head>Cause: in
readVerdictStance, when the comment is not a heading and its opener is not a verdict NAME, the lineif (!isHeading && !namesVerdict) return polarityPinningHead(item.body);returns before both theoutside === "hold"fail-closed check and the finalpolarityOf(item.body) === "hold"leg — the leg the diff's own comment calls "a hold stated anywhere still refuses" and docs/forgejo.md:501 states as "a quoted or fenced HOLD still supplies a hold for a comment that is already verdict-shaped". In the heading variant (## Review notes+ quoted hold) the stance IS read as a hold, butverdictStatementLinesnow stops at the documentation line, so the statement carries no pin andextractVerdictreturns null — the same permit by a second route.Real-world harm: a reviewer answers a colleague's objection by quoting it (
> REQUEST_CHANGES at <sha>) under a "Review notes …" opener, an independent clean approval is on the head, and the lock merges. Base refused all seven shapes. Under the ruling this is a base-refuses→head-permits difference and it is not one of the six named items — the named item is that documentation supplies no verdict/stance/pin for the APPROVE direction; the criteria require the quoted/fenced hold to keep holding for a verdict-shaped comment.Suggested direction (not prescriptive): keep the BLK-2 rule that documentation supplies no approve and no pin, and make the hold leg fail closed over the whole body — read the hold on the document-free lines first, and when no stance at all was found, fall back to the whole body's polarity before returning null.
Concerns
**Verdict summary**opener + machine block (**Verdict summary**/verdict: pass/head: <head>) lost as an approval: base reads it as an exact-head APPROVE and permits; head returns no verdict and refuses (with a clean approval present it still permits, but a single-verdict stream now refuses). Direction is safe, but docs/forgejo.md:482-483 still presents**Verdict summary**as one of "the fleet's bold titles" whose block "the block with them exactly as a## Verdictheading does", and the test file records the loss only as a table comment. Either the doc sentence and the reader should be reconciled, or the opener should be added to the verdict-NAME vocabulary.a documented (quoted or fenced) hold is NOT this comment's hold(landing-hold-under-approve-2682.test.ts:332) passes at base and at head, so the suite is green on exactly the class B1 measures. The test is written against a comment that already STATES an explicit APPROVE in its own block; the un-owned (prose-opener) shapes where base refused are not covered, which is why B1 shipped behind a green suite.Verified working (this seat's own measurements)
- B1: blocker — …under## Blockersraises (base did not) while- B1: high — …,- B1: medium/critical/majorand the token forms are unchanged; BLK-2 —> verdict: pass+> head:, fencedverdict: pass, and> ## Verdict — APPROVE at <head>supply no stance and no pin at head (base approved them AND permitted a stream containing only the quote); orch15/homelab-88 cases pass.verdict: pass+head:,**APPROVE — head <head>**,Approved at <head>,LGTM at <head>,**Verdict of record — … — head <head>: APPROVE**,## Approval pinned to exact head <head>. Alone each reads as before at both revisions; each with a later unquotedREQUEST_CHANGES at <head>appended permits at base and refuses at head.STANCE_FIRST_TOKEN_REis character-for-character base's pattern (theapprove[d]?(?:\s+with\s+concerns)?widening in intermediate48509e5is reverted by0d8add5);**APPROVE with concerns — head <head>**andApproved with concerns, <head>are unrecognised at base and at head;**APPROVAL OF RECORD … : APPROVE with concerns, no blocker.**is an APPROVE at both.it("CONTROL…")tests pass at base, so no CONTROL test proves its claim by failing.forgejo/suite: basea570a5df604 passed / 0 failed; head0d8add5646 passed / 0 failed (+42, the new files). 14 files fail to import at BOTH revisions withCannot find package 'typebox'fromforgejo/index.ts— a local dependency gap in my scratch checkouts, identical on both sides, not attributable to this change.forgejo/landing.ts, the two new test files anddocs/forgejo.mdchange; no other code path touched, no new dependency, no write path altered.Exposure: I reviewed from git objects only (branch and base fetched read-only, three scratch checkouts under /tmp, pruned). I HAVE seen earlier review findings through this brief and the PR's test-file names — expected for reviewing a fix. I have NOT seen the other seat's verdict, the PR discussion/comments, the landing census, the Plane ticket, or anything under working-files/.
verdict: request changes
head:
e63c05609cmodel: omniroute/deepseek-flash
session: 01a1b182-4d1b-700b-89cf-8994d37c92c8
Blockers
D1: high — an attribution-prefixed quoted or fenced hold at the exact head is dropped, and the lock PERMITS where base
a570a5dfand the deployed lock at34fdf7f5both REFUSE (e.g.> Reviewer: REQUEST_CHANGES at <head>under## Verdict — APPROVE at <head>now reads as an exact-head APPROVE; under## Approval notesit reads as a hold with no pin).The gated set, each measured at all three revisions (
34fdf7f5= hold at this head, refuse;a570a5df= refuse;e63c0560= permit):·
## Approval notesor## Final approval checklist(verdict-shaped, no stance) +> Reviewer: REQUEST_CHANGES at <head>— head reads stanceholdbutextractVerdict= null (no pin), so the objection is demoted to unpinned evidence and decides nothing; the lock permits. Same for> ld-reviewer: REQUEST_CHANGES at <head>,> ld-reviewer wrote: REQUEST_CHANGES at <head>,> **ld-reviewer**: REQUEST_CHANGES at <head>,> ld-reviewer — REQUEST_CHANGES at <head>,> Quote from ld-reviewer: …, and> Reviewer: Requesting changes at <head>.·
## Verdict — APPROVE at <head>or## Approval pinned to exact head <head>+ any blockquoted line above, plus the fencedReviewer: REQUEST_CHANGES at <head>— head reads an EXACT-HEAD APPROVE (polarity=approve, exactHead=true) and permits: a merge authorised by a comment that contains the reviewer's hold at that very head.· The same words UNQUOTED still refuse at this head (
stance=hold, verdict=hold/exactHead), so this is the first revision whose answer depends on whether the hold was blockquoted. Cause:documentedRequestChangesPinsrequiresisHoldStatementon the de-quoted text, so theName:attribution defeats the line-initial / first-person bar, while the unquoted leg reaches the same head through the looserstatementPins(statement), which still sees the unquoted line inside the statement block.docs/forgejo.mdpromises the opposite twice — quoted and fenced holds are read "exactly as on every other" leg, and "a reviewer who objects must never be skipped over the way they formatted the objection" — so the docs are also false on the quoted-hold leg for this spelling. It is in none of the ruling's exceptions: the quoted-hold leg exists to make quoted holds REFUSE, never to release one, and no test in the three new files covers an attributed quote (all of them use the bare> REQUEST_CHANGES at <sha>spelling).Concerns
a570a5dfand34fdf7f5refused (measured:**Verdict of record — … head <head>: APPROVE**+> REQUEST_CHANGES at <old head>, and the fenced form). This is the sanctioned supersession bound, so I record it rather than block on it — but it is a real widening against both prior revisions and belongs in the landing announcement.**Verdict summary**+ machine block) is declared out of scope intests/landing-hold-under-approve-2682.test.ts. Direction-safe (an approval lost, never a hold dropped) and noted only so a census reader is not surprised.Evidence
34fdf7f5reconstructed from git objects in api-extensionsclone (git cat-file -t,git show):forgejo/landing.tsblob =564594a4f3b482ca55f3abde232347ac3d1fda26, sha25658a081275575740c7ccb9f280cc24854430e98a4268c6c8a29145b6299548731(matches the expected58a08127prefix). No drop fallback used.34fdf7f5is an ancestor of the PR basea570a5df; the four commits between them are the prior finding-rule merge, so no exemption accounts for D1./tmpwithnode_modulessymlinked: basea570a5df963 passed / 35 files (all green); heade63c05601018 passed / 38 files (all green); the three PR test files copied onto base: 22 failed / 33 passed of 55; the four tests labelled CONTROL inlanding-verdict-arm-2682.test.ts: 4 passed, 0 failed at base.tsc --noEmitclean at head.## Blockers(- B1: blocker — …is now a finding, identical to any other severity word), the prose-opener shadowing fix, documentation supplying no verdict/stance/pin, the quoted attribution line above a real verdict (homelab-88 / orch15), and the four homelab-88 cases.hold(base: 78 failed;34fdf7f5: 78 failed). A hold on an OLDER head still does not flip an approval.> REQUEST_CHANGES at <head>(or the fenced form) refuses at head AND at base; a resolved-restatement comment plus a quoted hold at the same head refuses as a supersession at all three revisions. Both pass — D1 is the attributed spelling only.STANCE_FIRST_TOKEN_REis byte-identical to base (only re-wrapped across lines). Whole diff reviewed:forgejo/landing.ts, the three test files,docs/forgejo.md; no other file touched, and the finding-arm change is monotone (it can only add findings, never remove one).34fdf7f5check: 2,316 generated comment shapes (prose/heading/machine/bold openers × hold-in-prose / unquoted hold / quoted hold / fenced hold / quoted templates / attributions / old-head pins, plus standalone forms), each run throughreadVerdictStance,extractVerdictandevaluateLandingLockat34fdf7f5,a570a5dfande63c0560. Every case where34fdf7f5refuses and this head permits is D1 or the C1 bound — nothing else in that direction was found.working-files/, or the other seat's verdict.verdict: request changes
head:
e63c05609cmodel: omniroute/deepseek-flash
session: 01a1b182-4cf3-700b-89cf-8993a8f8e485
Blockers
a570a5dfand the deployed lock at34fdf7f5both REFUSED these shapes and this head PERMITS them, so the quoted-hold leg fails open in a stance state the change does not cover, and docs/forgejo.md's claim that documentation may only ever make a verdict harder to get is false for it. Minimal repro, measured through evaluateLandingLock with a clean exact-head approval paired so that a refusal could only mean the hold was read: a## Review notes on <older sha>heading, an optional blank line, then a quoted> REQUEST_CHANGES at <current head sha>, thenmodel:/session:labels. Every revision reads the stance as hold; the difference is the PIN. The statement block pins only the older sha,documentedRequestChangesPinsis consulted only underif (!pins.length && stance === "hold"), so the hold's own head is discarded, the verdict is not exact-head, and the lock permits. Same outcome for the fenced spelling, for the fenced machine form (verdict: request_changesplushead:inside a fence), and for a## Verdict — APPROVE at <older sha>heading followed by a quoted hold at the current head — where the stance is even read as approve and the objection is lost twice over. The docs' bound is not a licence for this: "a hold the reviewer quotes on an OLDER head is that hold's supersession" covers the opposite direction, and here the hold names the CURRENT head, which is exactly the case the leg exists to refuse. Fix direction: let a documented hold supply its head whenever the statement's pins do not name the head being judged (or refuse when the statement pins another head and a documented hold names the current one), and add these four shapes to landing-quoted-hold-2682.test.ts with theira570a5dfand34fdf7f5columns recorded as measured.Concerns
**Verdict summary**plus a machine block is disclosed in the PR as "approves nothing", safe direction, out of scope. At this head it also trips the finding rule's fail-closed leg, so one such comment refuses the whole PR with "1 piece(s) of PR text cannot be read in the finding rule" where basea570a5dfpermitted it. The legal exit exists (a later exact-head verdict from the same key supersedes it), but that is not what the disclosure says happens, and the disclosure is the only place a reader would learn it.Measurement record. Test files at head: 38 files, 1018 tests, all pass. The three head test files dropped into a frozen
a570a5dfcheckout: 3 files failed, 22 tests failed, 996 passed of 1018, and no test labelled CONTROL fails at base (4 CONTROL tests in landing-verdict-arm-2682.test.ts, all green at base). STANCE_FIRST_TOKEN_RE is byte-identical toa570a5df— wrapped across two lines, same regex source. The34fdf7f5parser was reconstructed from git objects (git cat-file -t 34fdf7f5...answers commit in a pi-extensions clone, forgejo/landing.ts at that commit hashes to 58a08127..., matching the verified blob), so no mgmt-drop fallback was needed. The refuses-and-then-permits sweep covered the whole 34fdf7f5..head diff, not only this PR's delta: about 1200 hand-built and harvested shapes (comment and review kinds), the five real Forgejo bodies in verdict-shaped-controls.json, the 13 prose-attack lines, and 300 random recombination bodies. Three families came back in that direction. (i) Quoted## Blockerstext no longer refusing — the affected rows already permit ata570a5df, so that is the ruled documentation fix merged between34fdf7f5and this PR's base, an allowed prior-ruling change. (ii) The supersession case: a quoted hold on an OLDER head beneath an approve heading — states, and documented, in docs/forgejo.md. (iii) B1 above, which is new to this PR and fails open. Nothing else moved from refuses to permits.Exposure: I have seen earlier review findings only through my brief and the PR's test-file names, which is the expected basis for reviewing a fix. I have not seen the other seat's verdict, the PR discussion, the census, or the ticket.
PR-description addendum — the accepted cost, recorded plainly (not a verdict; documentation for the seats)
The fix worker could not edit the description (no tool exists for it in this session), so ruling item 2 of
working-files/ldv0/tooling10-ruling-1555.mdis recorded here, in the form it should be pasted into the description, and indocs/forgejo.md. This comment is not verdict-shaped and carries no stance in either direction — checked against the deployed lock at34fdf7f5and against this head before posting.Accepted cost:
Three things follow, and the first is the cost:
## Blockers. The exit for a reviewer whose objection was written as a quote is a rewrite, not a re-tone: post it as a verdict block (**Verdict of record — <reviewer> — head <sha>: REQUEST_CHANGES**, orverdict: request_changesplushead:), or list it under## Blockers.no-verdict-block, which is what it always was.Round 6's documented-hold leg is removed, not extended:
requestChangesPinsIn's documented-text half, the stance-state documented-hold branch, andextractVerdict's "a documented hold takes its own pins" are all gone. The resolution carve-out now reads non-documentation lines only, so a quote cannot re-arm a resolution either.Differs from the deployed lock at
34fdf7f5in exactly the ruled direction: of a 109-shape corpus, 10 rows move refuses → permits, and every one is a hold that existed only as a quoted or fenced line (no unquoted hold, no fail-closed shape, no corpus verdict).New head:
6f18ab9cbc7b85aa192679a3e091da525ee37b8e. Package suite 1022/1022 green, deployed-shape suite 1022/1022,tsc --noEmitclean. Nothing merged, nothing placed.verdict: pass
head:
6f18ab9cbcmodel: omniroute/deepseek-flash
session: 01a1b1a2-4d18-700b-89cf-899a6f34cb8a
Blockers
None.
List
The rule's legs, as I applied them: quoted and fenced text counts for nothing in either direction — it supplies no verdict, no stance, no hold and no pin, cannot rescue anything and cannot block anything; a hold must be a verdict or a line under
## Blockers; approvals cannot be quoted into existence. Ruled, not a finding.Verification I ran myself, both revisions:
/tmpwithnode_modulessymlinked: basea570a5df— 35 files / 963 tests pass; head6f18ab9c— 38 files / 1022 tests pass.tsc --noEmitat head: no errors.a570a5df, as does the pre-existing CONTROL case in the finding-rule suite.git show 34fdf7f5:forgejo/landing.ts, sha25658a08127…, matching the deployed fingerprint; base0a4b36ca…, head7aca64e9…), and the identical synthetic comment stream was driven throughevaluateLandingLock/extractVerdict/readVerdictStanceat each revision undernode --experimental-strip-types. No network, no PR reads, no census, no ticket.Refuses → permits: every row I measured in that direction
In the ruled class — the hold exists only as a quoted or fenced line. In these rows a clean exact-head approval from a second reviewer key carries the merge; the solo variants of the same bodies still refuse at head, because nothing approves them:
Review notes on <head>, and its bold,## heading,**Review round 2 — <head>**and**Approval notes on <head>**spellings, each followed by a quoted hold.**Review — head <head>**+ a fenced hold.## Review notes+ a quoted hold (the comment pins no head of its own).Review notes on <short sha>+ a quoted hold.## Verdict — APPROVE at <head>+ a quoted hold beneath, the same + a fenced hold beneath, and the same with model/session labels under it — the statement block used to consume the quote, so a real heading approval was lost.Inside the rule's leg but not "hold only as a quote" — a quote may not BLOCK, so a real verdict beneath a quotation is read again. These are the ordered homelab-88 / orch15 cases; each refused at the deployed lock and at the base as well:
> **ld-reviewer** wrote:above## Verdict — head <sha>withverdict: approvedlabels.> Originally posted by another reviewer:above a verdict-of-record APPROVE block.Pre-existing at base, not introduced by this head (the documentation / finding-rule work merged between
34fdf7f5anda570a5df), recorded so the census does not read them as new:verdict: pass/verdict: approvewithhead:beneath) is a verdict of record — the deployed lock refused it outright.## Blockerssection no longer raises a finding (the findings arm's half of the documentation rule).Permit → refuse (safe direction), all measured at both revisions
Review notes on <sha>plus an incidental "approved", andReview notes on <head>plus "I approve this diff" with no sha on that line, now decide nothing.## Blockersnow decides nothing:- B1: blocker — …raises a finding at head (none at base), every other severity word reads the same, mid-sentence prose and "no new blockers were introduced" still raise nothing, and no line that raised at base stops raising.Other observations, no direction change
**Verdict summary**with a quoted hold refuses at head (fail-closed: verdict-shaped, no readable block) — it refused at base too.unquotedRequestChangesPins, a pure helper); no IO, no network, no state; the stance token regex is byte-identical to base;docs/forgejo.mdstates the rule and the accepted cost as measured here.verdict: pass
head:
6f18ab9cbcmodel: omniroute/deepseek-flash
session: 01a1b1a2-4ce6-700b-89cf-8998558ac349
Blockers
None.
List
The
**Verdict summary**title now fails closed instead of deciding nothing. The body**Verdict summary**+verdict: approve+head: <sha>+ model + session permitted at the deployed lock and at base; at this head the comment is verdict-shaped with no readable block, so the finding-rule arm refuses the whole merge (no-verdict-block). It refuses, so nothing is permitted that the deployed lock refused, but a reviewer using that common bold title now blocks the lock until they re-post in a named form. One docs line, or adding the phrase to the closed verdict-name vocabulary, closes it.A hold that names an OLDER head flips 3 of the 14 approve forms I probed, which contradicts the sentence in
docs/forgejo.md§3. With the verdict-of-record and machine openers the older-head hold is correctly read as supersession (permit). With a prose opener (Approved with concerns, <sha>,Approved in principle on <sha>.) the statement block's blank-line skip pulls the following paragraph into the block, so the older sha lands injudgingand the same-head test matches. Safe direction (over-refusal), so it blocks nothing; either the sentence or the block termination wants a follow-up.A pin supplied only inside a fence stops counting.
**Verdict of record — <reviewer>: APPROVE**followed by a fencedhead:line permitted at base and refuses here. That is the rule applied consistently; recorded so the narrowing is not later read as a regression.Two rows of the table below were already permitted at BASE, i.e. they are PR #108's change and not this diff: the quoted
## Blockerssection, and the mid-sentence(blocker)line under## Blockers. The second is a FINDING that #108's defect-language filter drops rather than documentation text, so I name it explicitly for the rule owner even though base and this head agree.Accepted cost, declared by the change itself. A hold that exists only as a quote, in a comment that does not otherwise read as verdict-shaped, is ignored when others have approved. The docs state it, and the suite pins it as an accepted-cost test rather than hiding it.
The rule's legs, as I applied them
## Blockers.Exposure and measurement
Exposure line: the deployed parser was reconstructed from git objects only —
git show 34fdf7f5:forgejo/landing.ts | sha256sumin a scratch clone of Homelab/pi-extensions gives58a081275575740c…, the stated 58a08127 prefix. The three revisions then ran beside each other (deployed34fdf7f5at /tmp/ldv0-deployed, basea570a5dfat /tmp/ldv0-base, head6f18ab9cat /tmp/ldv0-head), the identical input stream throughevaluateLandingLock, withreadVerdictStance,extractVerdictandfindOpenBlockerscompared comment by comment.Tallies and checks:
a570a5df: 35 test files / 963 tests, all pass.6f18ab9c: 38 test files / 1022 tests, all pass.CONTROL-labelled tests pass at base — the fixes are what fail there, not the controls.npx tsc --noEmitclean at head.STANCE_FIRST_TOKEN_RE: identical regex literal at base and head (only the source line is wrapped); the pattern source was compared at all three revisions. No stance widening.Rows where the deployed lock refuses and this head permits
Class 1 — the hold exists only as a quoted or fenced line (the ruled class). Base also refused, so this diff is the change:
## Review notes, beside a clean approvalReview notes on <sha>opener, beside a clean approvalApproved, no blockers at <sha>.), alone and beside a clean approvalClass 2 — a quote was BLOCKING a real, unquoted verdict beneath it (documentation cannot block). Base also refused, so this diff is the change:
**APPROVE at <sha>**, two quoted lines, and an attribution above a resolution. The homelab-88/orch15 case 4 is one of thesehead: <older sha>, then a real verdict, alone**APPROVE at <sha>**with no labels, aloneClass 3 — inherited from PR #108: base already permitted these, so this diff changes nothing.
## Blockerssection, alone and beside a clean approval(blocker)line under## Blockers, alone and beside a clean approvalNo other row in that direction exists in the roughly 230 shapes I pushed through all three revisions (108 generative rows plus 32 documentation-in-pin-position rows plus the 59 new tests replayed item for item). Every remaining difference runs the other way, permits to refuses, which is the direction that can only refuse more.
What I verified positively
Review notes on <sha>with an incidental "approved" no longer approves, and a real unquoted hold below such a prose line still holds.## Blockersno longer decides:- B1: blocker — …raises one finding at this head (base raised none),- B1: high — …reads the same, and a zero-claim under that heading still raises nothing.## No blockers.over fifteen evidence lines raises zero findings, the no-#variant is clean, all fourBlockers: none.claim forms are clean, and the attribution line above a verdict no longer swallows the verdict.no-verdict-block(a quoted hold does not rescue it), a placeholder## Blockerssection refuses asmalformed-blockers, and a later exact-head verdict from the same key lifts either.## Approval notes,## Final approval checklistwith a disclaimer,## Verdict grammar, a fix-worker note, a post-merge record and a## Review round 1 — pinned to head …comment all permit beside a clean approval.docs/forgejo.mdstates the rule as ruled, including the fail-closed paragraph, the accepted cost and the rewrite exit.Verdict of record — ld-reviewer — head
df0ab62d8a: REQUEST_CHANGESmodel: omniroute/deepseek-flash
session: 01a1b1c3-dab4-700b-89cf-89af9a03003d
Blockers
## Blockersa line whose severity WORD is present in a MALFORMED marker still raises no finding: the mismatched bracket pair ((blocker],(blocker ],[blocker),[ blockers ), and the id-labelled form- B1: … (blocker] …) and the glued labelBLOCKER<B1>: …were all REFUSED by the deployed lock34fdf7f5and all PERMIT at this head, while the identical line WITHOUT the severity word is a finding (the section's content rules count it); the marker reader requires a matching bracket pair, so the token's mere presence still diverts the line away from the section arm — the exact asymmetry the round-4 severity-slot fix and ruling 2a set out to end, and the doc sentence this head writes ("a severity marker ANYWHERE on the line is a finding … in any spelling") promises it is ended.Concerns
df0ab62are right about every spelling they ENUMERATE and wrong about the word "any": the reader honours matched bracket pairs only. Fix the reader (when no token pattern matched, let a token-bearing line under a defect section fall through to the section's own content rules, which already exclude negations, zero-claims, documentation placeholders and non-blocker labels) and the sentence becomes true without a doc change.List
git show 34fdf7f5:forgejo/landing.ts | sha256sumin the clone gives 58a081275575740c7ccb9f280cc24854430e98a4268c6c8a29145b6299548731, matching the brief. That file,a570a5df(sha256 0a4b36ca…30a4a4) and this head (dd344479…771c1) were extracted side by side and imported under node --experimental-strip-types; every row below was driven through evaluateLandingLock / findOpenBlockers / extractVerdict as a synthetic stream, the same input to all three revisions.a570a5df150 pass / 59 fail; deployed34fdf7f5112 pass / 97 fail. Per file (failures at deployed / base / head): finding-rule-2682 49/1/0 of 68; hold-under-approve-2682 7/6/0 of 13; quoted-hold-2682 13/11/0 of 16; verdict-arm-2682 13/12/0 of 30; lock-midsentence-severity-2682 12/29/0 of 44; lock-defects-2682 0/0/0 of 18; lock-negation-heading-2682 3/0/0 of 20.a570a5df(29 failures in that file) and pass at this head; 18 of the 24 already pass at deployed (the plain parenthetical and severity-label spellings the deployed reader matched anywhere), while a6 and a7 (emphasis made transparent) are new refusals the deployed reader never saw, exactly as the code comment states. I also drove the marker spellings through the three modules directly: every one of the 18 generated marker shapes that the head now counts moved permit→refuse relative to base, so the fix itself introduces ZERO refuses→permits rows; the only base→head permit rows in my whole corpus are the two round-7 quoted-hold rows the ruling names.(**blocker**),severity: **blocker**,severity = **blocker**,(***blocker***); the label-slot token- B1: blocker — …; the documentation placeholder line; an unquoted hold after an approve opener; a 4-space-indented hold; a code-span hold.34fdf7f5(the real unquoted section still refuses; the round-3 machine form holds when the block carries the stance; the same machine form unquoted is an approval of record) — recorded so the deployed column is not read as a base; they are base's controls.BLOCKER<B1>:row in the table is inherited from base (it arrived witha570a5dfand is documented there as "not the exact form"), not introduced by this diff; I name it inside B1's class because it is the same defect shape (a token-bearing line under a section escaping the section's content rules), not as a separate regression.## Blockersare now findings, and the prose-beside-a-verdict case moved under a neutral heading so it still raises nothing). I found no deleted assertion that weakens an existing guarantee and no change to the approval, dangerous-class, session, model or resolution arms.Refuses at
34fdf7f5-> permits at this head, every row:## Blockerstemplate, quoted hold beside an APPROVE, quotedBLOCKER <id>:line, quoted marker line, headless quoted hold, headless fenced hold, quoted section heading with unquoted content, fenced section heading with unquoted content### Findingsor## Concernsdefect line carrying a marker, outside## Blockers### Findings, 26 under## Concerns)verdict: pass## Blockerssection## Blockerswhose severity word sits in a malformed marker: mismatched bracket pair(blocker],(blocker ],[blocker),[ blockers )including the id-labelled form, and the gluedBLOCKER<B1>:labelCorpus behind the counts: 55 marker-shaped lines crossed with 4 contexts (under
## Blockers, no section,### Findings,## Concerns) = 220 streams, plus 12 hand-written verdict-and-hold streams, plus 512 verdict-block shapes (16 openers by 8 stance spellings by 4 pin forms). Under## Blockersthe only refuses->permits rows in that corpus are the five in the last table row; outside a blockers section every marker row is a ruled class-2 or class-5 row, and the verdict-block arm produced no refuses->permits row at all.Verdict of record — ld-reviewer — head
df0ab62d8a: APPROVEmodel: omniroute/deepseek-flash
session: 01a1b1c3-dae7-700b-89cf-89b078d09e20
Blockers
None.
Concerns
**Verdict summary**+verdict: pass+head:is an exact-head APPROVE ata570a5dfand decides nothing here (measured, both line orders). It is disclosed and pinned in tests/landing-hold-under-approve-2682.test.ts as out of scope, in the safe direction, "a separate ticket". I agree it is not this branch's to fix — but it is a shape the fleet has posted, so it should have a ticket rather than only a test comment.a570a5df); this branch's own widening is exactly the 6 ordered documentation rows. Recorded so the census is not read as this branch's regression.List
34fdf7f5is a commit in the clone andgit show 34fdf7f5:forgejo/landing.ts | sha256sum= 58a081275575740c7ccb9f280cc24854430e98a4268c6c8a29145b6299548731, matching the brief's 58a08127 prefix. I archived four trees withgit archive(a570a5dfbase,34fdf7f5deployed,6f18ab9for the newest fix alone,df0ab62dhead) and ran the same harness files unchanged against each, calling evaluateLandingLock, extractVerdict and findOpenBlockers on synthetic streams only — no PR, no network, no edits.- <id>: blocker — …under a section is a finding again, restored rather than removed. CONCERN-2 and the homelab-88/orch15 documentation cases: a quote or fence ABOVE a real verdict is skipped so the verdict under it is still the statement (6 shapes), while a quoted hold alone still holds nothing.6f18ab9→ head), measured directly, not from the tests: 60 permits→refuses rows and 0 refuses→permits rows. Under a real ## Blockers section every spelling raises a finding —(blocker),[blocker],severity: blocker,severity:blocker,severity = blocker,(**Blocker**),severity = **blocker**,severity: [blockers], a bare parenthetical, an id label whose severity word is emphasised, and the same shapes on a 2-space and on a 4-space indented sub-bullet. Still inert: a real quote, a real tilde or backtick fence, and every no-section marker line, which stays prose in all 7 spellings. A 4-space indented line that carries the marker DOES raise a finding when it sits under the section, and a 4-space line that is not a real quote is never documentation — both are the ruled leg, not an exception. Lines about the word rather than marked by it (- no new blockers were introduced at this head,This is the same class of blocker I raised on issue 207) stay prose in both directions, exactly as at the deployed lock./^(?:approve[d]?|lgtm|request(?:ed|ing)?[ _-]?changes|changes?[ _-]requested)\b/i); only prettier re-wrapped the declaration onto two lines. The revert of the stance-token widening is intact.a570a5df(2/5 at the deployed revision, 5/5 at head). The controls that pin behaviour introduced by the earlier finding-rule merge correctly fail at the older deployed revision, which is not a base failure.a570a5df59 failed / 132 passed of 191; deployed34fdf7f597 failed / 94 passed; headdf0ab62d191 passed / 0 failed. Per file at head (all pass): finding-rule 68, hold-under-approve 13, quoted-hold 16, verdict-arm 30, mid-sentence-severity 44, negation-heading 20. Full forgejo suite at head: 39 files, 1066 tests, all pass.I checked whether the (blocker) tag appliessentence still reports nothing. That is the measured behaviour in both directions. The quoted-and-fenced paragraph and the new approve-form table row (a real unquoted hold below an approve opener) also match what I measured on all 8 approve forms.Refuses→permits census,
34fdf7f5→ headdf0ab62dEvery row below was refused by the deployed reader and permits at this head. 401 cells at each of the three revisions (8 approve forms × 45 streams = 360, plus 26 approve-form and documentation cases, plus 15 section-content shapes), plus 12 marker spellings measured at this head. Rows outside these ruled classes: 0.
> ## Blockerssection, and a quoted marker line under a real sectiona570a5df), not this branch### Findingsdefect line outside## Blockersa570a5df)verdict: pass/verdict: approved+head:, and bold name + head + machine linea570a5df)a570a5df)## Blockerssection: parenthetical, bracketed,severity:/severity =,severity: [blockers], bullet-repro, tag prose, plus a 4-space indented marker with no sectiona570a5df)df0ab62d)Total 92 rows, 86 inherited from the merged finding rule and 6 from this branch. The newest fix contributes none:
6f18ab9→ head is 60 permits→refuses and 0 refuses→permits.a570a5dfand at this head. At34fdf7f5the same body also approves, but the deployed reader raises two findings inside it — one on the row-5 table line, whose marker spellings have no section, and one on a prose line it reads as a marker — which is the ruled loosening in row 5 read from the other side, and one more reason the deployed reader is the one being replaced.Verdict of record — ld-reviewer — head
ce0e7394f4: APPROVEmodel: omniroute/deepseek-flash
session: 01a1b1d8-c5ad-700b-89cf-89b69855b797
Blockers
None.
Concerns
a570a5df, at34fdf7f5or at head, so nothing moved here, and docs/forgejo.md does describe the carve-out in its resolutions section. Two right paragraphs read jointly as an exception to an absolute sentence; wording follow-up, not a landing blocker.34fdf7f5and at head: all three drop the later line, so the structural rule neither introduced nor widened it. A reviewer who separates two blockers with a horizontal rule or a sub-heading loses the second silently.List
34fdf7f5reconstructed from git, method stated: git show 34fdf7f5:forgejo/landing.ts piped to sha256sum yields 58a08127 5575740c7ccb9f280cc24854430e98a4268c6c8a29145b6299548731 — the prefix the brief names — so the deployed baseline I measured is the commit object itself, not a copy or a re-implementation.34fdf7f5is an ancestor of the head.a570a5df0a4b36ca, deployed34fdf7f558a08127, headce0e7394fc0d317d), plus a recording wrapper that logs every evaluateLandingLock and findOpenBlockers call. Flips are computed on a full-input fingerprint (comment bodies + CI state + changed files + required contexts + head), never on bodies alone, because two tests sharing a body collided into false flips in my first pass. A directed 48-shape matrix over the ruled classes was then run at all three revisions, independent of the suite.a570a5dfrunning its own suite: 35 files, 963 tests, all green. Base reader against the HEAD suite: 90 failures across 11 files (section-structural 18, severity-word arm 31, verdict arm 15, quoted-hold arm 11, hold-under-approve 6, heading-context 3, finding-rule 2, and 1 each in tightenings, severity-none, defects, negation-heading). Deployed reader34fdf7f5against the HEAD suite: 115 failures across 11 files. Head: 40 files, 1105 tests, 0 failures; tsc --noEmit clean. Every one of the six ordered fixes therefore has assertions that fail at both earlier revisions and pass at the head, and 0 CONTROL-labelled tests fail at base (the head suite carries 29 control tests, none failing).34fdf7f5/ head. Malformed markers under a real section — (blocker], (blocker ], [blocker), [ blockers ), the id-labelled "- B1: … (blocker]", the glued BLOCKER:, an indented sub-bullet — permit / refuse / refuse, and at head each raises the finding it names (an id where the line carries one, an id-less finding otherwise). A bare sentence with no marker under the section is a finding at all three. Negation vocabulary under the section ("None found.", "Nothing outstanding.", "0 remaining.", "No blocking findings.", "Resolved B1: …", a "nit:" label, a resolution note) permits / permits / refuses — the new findings. The bare None., - None., - None. and "none" stay zero at all three, and a determiner with content after it ("None found. F1 …", "None. The guard still prints …") stays a finding at all three. A real quote, a real fence and a grammar citation under the section raise no finding at head (the section then reads as empty, and the existing malformed-blockers refusal still refuses — the refuse direction). No-section prose with a mid-sentence severity word raises nothing at head. The structural check is the first statement of isBlockerFindingLine and its caller only skips documentation lines, so no spelling veto upstream of it can silence a section line.34fdf7f5raised a finding and the head raises none; I replayed all 26 as standalone comments at base,34fdf7f5and head, and head is byte-identical to base on 26 of 26 while34fdf7f5raised a finding on all 26. Of those 26, three sit under a real ## Blockers section and all three are quoted lines; 22 have no ## Blockers section at all (Findings headings, zero-claim headings such as "## No blockers.", mid-sentence prose, a bare parenthetical label, the glued form); one has a section holding None. with the dropped line in a later non-blockers heading. No finding was lost from a real, unquoted, unfenced line under a real ## Blockers section.34fdf7f5and at head (only its line wrapping changed), checked on the extracted regex text rather than the formatting. The three new refusal paths added to the stance reader (a real unquoted hold anywhere, a hold naming the same head, a stance pinned by its own line) all move in the refuse direction: measured, a real REQUEST_CHANGES below an approve opener and a real hold alone both permit at base and at34fdf7f5and refuse at head.Refuses at
34fdf7f5→ permits at headRows are shape, named class, count. Measured on 423 distinct full-input fingerprints shared by both revisions (397 identical outcomes, 0 permits→refuses at lock level), and on the directed matrix.
No row outside the ruled classes. The findings arm contributes no refuses→permits row of its own: the 26 findings-arm drops are all base-identical, and none of them is a real section line.
Permits at
34fdf7f5→ refuses at head (tightenings, listed for completeness)Verdict of record — ld-reviewer — head
ce0e7394f4: APPROVEmodel: omniroute/deepseek-flash
session: 01a1b1d8-c580-700b-89cf-89b428f560bf
Blockers
None.
Concerns
docs/forgejo.md understates the zero determination. The new paragraph says the section's one exception is "the bare
None."; the reader also zeroes- **None.**,noneandnone!(that exact set is listed in the function's own comment and is whatisBareEmptyStatementTextaccepts). Measured at head: those three raise nothing whileNone found.raises one id-less finding. The reader side is right and is unchanged from basea570a5df; the incomplete half is the doc sentence — one clause, a follow-up, not a blocker."Documentation counts nothing" is true of the findings arm, and only of it. A
## Blockerssection whose only content is a real quote or a real fence produces zero findings, but the LOCK still refuses that comment through themalformed-blockersfail-closed arm (measured: a fenced defect line, a tilde-fenced defect line and a quoted grammar template under## Blockersall give findings[]and lock false, where the deployed reader permitted the merge). This is byte-for-byte the basea570a5dfbehaviour, so nothing is smuggled, but a reviewer who quotes the template under their own## Blockersheading is refused rather than ignored, and the doc reads as "inert". Naming it so it is not discovered as a surprise.The ruled resolution-note cost is real, and it cannot be closed in place.
resolved B1 — filter addedunder## Blockerscloses B1 and at the same time raises its own id-less finding; that finding is only closed by a later comment carrying the canonical resolution sentence. It is pinned by the changed assertion in the blocker-heading-context suite and stated as a known consequence of the structural rule — recorded here, not blocked.List
>quote and a real backtick or tilde fence count nothing in either direction, an INDENTED line is a finding, a hold must be a verdict or a line under## Blockers, and everything else never parses.a570a5df/ deployed34fdf7f5/ headce0e739stays): (1) prose opener + incidental approve + a real hold at the head => exact-head hold, refused; (2) fenced, blockquoted and blockquoted-heading verdict templates supply no stance and no pin => "no exact-head verdict", refused (all three permitted at base); (3) the severity WORD in the label's slot now raises B1 where base and deployed raised nothing; (4) the documented-hold removal consequence (Concern 3); (5) the four homelab-88/orch15 cases hold:## No blockers.over 15 evidence lines => zero findings and permits, the same body with no#and a trailing "No blockers." sentence => zero,Blockers: none.outside a section => zero, and a quoted attribution line above a heading verdict => verdict of record read, permits (that last one was refused at base and at deployed).(blocker],(blocker ],[blocker),[ blockers ), the id-labelled malformed marker and the glued angle label each raise a finding; negation vocabulary under a section raises;None found.raises; bareNone.,- **None.**andnone!stay zero; a real quote and both fence spellings stay inert; no-section prose stays nothing. The section check is the FIRST statement ofisBlockerFindingLine, before every spelling veto, and it only ever ADDS: across 630## Blockersrows (five heading spellings) it tightened 162 and loosened ZERO.STANCE_FIRST_TOKEN_REis byte-identical to basea570a5df(the diff only re-wraps the same literal onto two lines); the only two regex literals new to the tree are the severity-MARKER matcher (findings arm, tightening) and the machine request-changes matcher (hold recognition, narrowing).unquotedRequestChangesPins(internal use only, no external caller), the second parameter ofisSectionDefectLineis now unused, and two symbols went dead with the rewrite —SECTION_RESOLUTION_LEAD_REandisNonBlockerLabelLineare defined and never referenced.npx tsc --noEmitis clean, so this is the flagged cleanup, not a break.a570a5df— 239 passed, 90 failed of 329; deployed34fdf7f5— 195 passed, 66 failed of 261 collected, with one suite failing to IMPORT (68 tests never load there, which is itself a finding about the older tree, not this one). CONTROL-labelled failures at base: ZERO of the five CONTROL assertions — which is what a control must be.Exposure
Reconstructed from git objects only. The deployed revision was not named by memory but by digest:
git show 34fdf7f5:forgejo/landing.ts | sha256sum= 58a08127…, matching the named prefix; the same digest method gives basea570a5df= 0a4b36ca… and this head = fc0d317d…. Differentials were produced by three detached worktrees (one per revision) driving 1,997 identical probes — synthetic grids over the verdict arm, the findings arm and the section grid, plus every comment in the four fixture corpora — throughevaluateLandingLockandfindOpenBlockers. Seen before writing: this brief, and the PR's test-file names (expected for a fix review), plus earlier rounds' findings only as the brief restates them. Not seen: the other seat's verdict, any PR discussion or review comment, the census, the ticket, and anything under working-files/. Read-only on the PR object throughout: no edit, no commit, no push, and no formal review state.Refusals -> permits, deployed
34fdf7f5-> headce0e739(every row, by shape and class)### Findings, under## Concerns, under## No blockers.## Blockerssection: no section 32,### Findings32,## Concerns32,## No blockers.32### Findings: plain, flush-left, id-labelled, adjective severity, indented,class:label, evidence line, "must be fixed" prose## No blockers.: id-labelled, adjective severity, id-style label (counted under class 2 because the homelab-88/orch15 negation-heading ruling — fix 5, above — requires that heading to supply nothing; if class 2 is read as### Findingsonly, these 6 rows are the gap and are still ruled by fix 5)Zero rows are unclassified, and zero rows sit under any
## Blockersheading: 630 section rows measured, 162 tightened, 0 loosened. Of the 192, 166 also permitted at basea570a5df(they restore it); the 26 that did not are the accepted cost listed in## List.The blocker raised in review 22832 is resolved on head
ce0e7394f4.The blocker raised in review 22834 is resolved on head
ce0e7394f4.The blocker raised in review 22839 is resolved on head
ce0e7394f4.The blocker raised in review 22846 is resolved on head
ce0e7394f4.The blocker raised in review 22847 is resolved on head
ce0e7394f4.The blocker raised in review 22850 is resolved on head
ce0e7394f4.