CORRECTED 2026-08-31, ~20 minutes after filing, by me. The first version named the twelve failures as the #17214 group. That was wrong. I had listed the file's test names with a tail, and reported the tail as the population — the #17214 tests sit at the end of the file, call PullRequestService.managePrReview, and pass; they are Brain-owned service coverage and correctly stay there. The twelve that actually fail are the workflow-lint tests of #13910 (4), #15257 (6) and #16148 (2), which call runAgentPrReviewBodyLintWorkflow. The measurement, the premise and the prescription are unchanged — only the attribution was wrong, and the extraction is harder than the first Fix section implied. Both corrected below.
Context
.github/workflows/agent-pr-review-body-lint.yml is 33,399 bytes of PR-blocking review-body policy — prior-demand sequences, RA-N prose refusal, post-budget disposition families, follow-up-owner lookups. This repository tests none of it.
Twelve specs covering exactly that contract exist, and they live in neomjs/neo-agent-brain, where they have been red since the repository split because the file they exercise is here.
Measured at Engine dev / Brain dev on 2026-08-31:
|
result |
grep -rln "agent-pr-review-body-lint" test/ buildScripts/ in this repo |
no match |
PullRequestService.spec.mjs in the Brain, as-is |
12 failed / 180 passed |
| the same file, with this workflow copied into the Brain |
192 passed, 0 failed |
That second pair is the whole ticket. The specs are live, correct coverage of the current workflow — not stale leftovers. They fail for one reason: the artifact they exercise is in a different repository.
Live latest-open sweep: checked the latest 20 open issues at 2026-08-31T06:09:20Z; no equivalent found. Nearest neighbour #17783 read in full and is distinct — it owns guards that have no caller (R2 authorship, R3 hook↔CI parity), not a workflow whose only test is in the other repo. A2A in-flight claim sweep over the last 30 messages: no [lane-claim] on this scope.
The Problem
The specs do not merely reference the workflow — they execute it. getAgentPrReviewBodyLintScript() loads the YAML, finds the Validate PR Review Body step, and pulls out step.with.script; runAgentPrReviewBodyLintWorkflow() then runs that source against stubbed GitHub Actions services and captures the comments, failures and logs it produces.
So the coverage is behavioural, against the real shipped script, not a reimplementation of its rules. That is the expensive kind to write and the easy kind to lose.
The spec knows which repository it is testing — its stub context is hardcoded {repo: {owner: 'neomjs', repo: 'neo'}}. The tests were authored for #13910 / #15257 / #16148 and were correct where they were written. The split moved the workflow and left the tests behind, and nothing failed loudly enough to notice: the Brain's unit CI check runs four named smoke specs (brain-unit.yml), so these twelve have been red locally and invisible in CI for the whole interval.
Why this is worth porting rather than deleting. Deleting removes the only executable check on a 33 KB PR-blocking policy. The rules it covers are exactly the ones that fail silently when wrong — a review-budget accounting error admits a demand it should refuse, and nobody notices until a reviewer is blocked or, worse, isn't.
The Architectural Reality
- Producer:
.github/workflows/agent-pr-review-body-lint.yml, job lint-pr-review-body, step Validate PR Review Body, whose with.script is the unit under test.
- Current consumer of that surface:
neomjs/neo-agent-brain:test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs — two module-scope helpers plus twelve tests, in a 5,427-line file whose remaining coverage is Brain-owned.
- The twelve, precisely — all callers of
runAgentPrReviewBodyLintWorkflow: #13910 ×4 (Micro-Delta bodies: accepts documented, rejects incomplete before canonical fallback, rejects semantic-blocker shortcuts, requires Premise Coherence), #15257 ×6 (activation cutover, zero merged dev closers, fail-closed on malformed activation relations, bypass/COMMENTED never weakening Drop+Supersede, one-sided Drop+Supersede contradiction, override-only provenance after cutover), #16148 ×2 (origin sessions accepted / rejected across every documented review format).
- The extraction is NOT contiguous, and that is the real cost of this ticket. The twelve are interleaved inside the
managePrReview (#11273) describe, which opens at line 1834 and closes at 5427. At least two neighbours in the same run — #13910: rejects Micro-Delta review with a semantic blocker class and #14263: accepts a Micro-Review — do not call the workflow helper and must stay behind. So this is a selective lift of twelve named tests plus two helpers out of a block that keeps running, not a block move.
- Dependency check:
js-yaml already resolves in this repository, so the port introduces no new dependency.
- Placement precedent: this repo currently has no spec that loads a
.github/workflows/*.yml, so the destination directory is a novel choice rather than a sibling match. test/playwright/unit/workflows/ mirroring the source tree is the shape I would expect, but §2 Stage 3 applies — the implementer runs structural-pre-flight and records the outcome rather than inheriting this line as settled.
- The split's shape is the cause, not a defect in either file. The workflow is correctly Engine-owned (it gates this repo's PRs); the
PullRequestService service is correctly Brain-owned. Only the twelve specs are on the wrong side.
The Fix
Port the review-body-lint block into this repository as its own spec:
- Port
getAgentPrReviewBodyLintScript() and runAgentPrReviewBodyLintWorkflow() — the YAML load, the step lookup and the stubbed-Actions harness — into an Engine spec that resolves the workflow from this repo root, so the read that is currently cross-repository becomes local.
- Port the twelve named tests above. Selectively: they are interleaved with neighbours that stay, so this is twelve named lifts, not a range copy. The
#17214 group and the rest of managePrReview are untouched.
- Verify by the same instrument that found this: with the port landed, those twelve run green here, against the real workflow file, with no path leaving the repository.
Sequencing is deliberate — this lands first and the Brain-side removal follows, so the coverage never ceases to exist in both repositories at once.
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
agent-pr-review-body-lint.yml → job lint-pr-review-body → step Validate PR Review Body → with.script |
This repository (the workflow gates its own PRs) |
Its inline script is executed by an Engine spec against stubbed Actions services; the twelve workflow-lint behaviours are asserted here |
None — the alternative is the current state, zero executable coverage of a PR-blocking policy |
spec header naming the workflow path and why the test lives beside it |
12 failed → 192 passed when the workflow is present, measured 2026-08-31; after the port, the same twelve green in this repo with no cross-repo read |
Row anchors verified before assertion: the workflow file, its job name, its step name and with.script were read at Engine dev; the helper names and test count were read at Brain dev.
Decision Record impact
none — this relocates test coverage to the repository that owns the artifact under test. It does not alter the split's dependency direction, which ADR 0040 governs, and takes nothing from the Brain that the Brain owns.
Acceptance Criteria
Out of Scope
- Removing the block from the Brain. That is a separate repository and a separate PR; it should follow this one, so coverage never ceases to exist in both places at once.
neomjs/neo-agent-brain#201 holds the measurement identifying these twelve as part of its cross-repository class.
- Changing any rule the workflow enforces. This ticket relocates coverage; it does not renegotiate policy.
- The other fourteen cross-repository read failures in the Brain's unit suite. Same family, different files, and each needs its own disposition — several may be deletions rather than ports.
- Broadening what the Brain's
unit CI check executes — neomjs/neo-agent-brain#201 owns that.
Avoided Traps
- Deleting the specs as "Brain cruft." The obvious reading of a red cross-repo test is that it is stale. Measured otherwise: supplied with the workflow, all twelve pass against the current file. Deleting would have removed live coverage and left a 33 KB PR-blocking policy with none.
- Making the Brain resolve the Engine's workflow. A path or package hop would turn the tests green without moving the coverage to the repository that owns the artifact, and would make a Brain spec fail whenever an Engine workflow changed — the dependency direction the split exists to prevent.
- Asserting the file exists. A presence check passes against a workflow whose rules have silently inverted. The AC above requires a mutation that reds a named test.
Related
Related: #13910, #15257, #16148 (the tickets these twelve specs were written for), #17214 (closed — a NEIGHBOURING group in the same file that stays in the Brain), #17783 (sibling post-split residual: guards with no caller), neomjs/neo-agent-brain#201 (the Brain-side measurement and cross-repository class), neomjs/neo-agent-brain#191 (domain-slice disposition for legacy Brain surfaces).
Retrieval Hint: query_raw_memories for "agent-pr-review-body-lint coverage stranded post-split" · the 12→192 measurement and the cross-repo classification are recorded on neomjs/neo-agent-brain#201.
Origin Session ID: 56bc214a-5b55-41a2-848a-cdfa372abbcd
Context
.github/workflows/agent-pr-review-body-lint.ymlis 33,399 bytes of PR-blocking review-body policy — prior-demand sequences, RA-N prose refusal, post-budget disposition families, follow-up-owner lookups. This repository tests none of it.Twelve specs covering exactly that contract exist, and they live in
neomjs/neo-agent-brain, where they have been red since the repository split because the file they exercise is here.Measured at Engine
dev/ Braindevon 2026-08-31:grep -rln "agent-pr-review-body-lint" test/ buildScripts/in this repoPullRequestService.spec.mjsin the Brain, as-isThat second pair is the whole ticket. The specs are live, correct coverage of the current workflow — not stale leftovers. They fail for one reason: the artifact they exercise is in a different repository.
Live latest-open sweep: checked the latest 20 open issues at 2026-08-31T06:09:20Z; no equivalent found. Nearest neighbour #17783 read in full and is distinct — it owns guards that have no caller (R2 authorship, R3 hook↔CI parity), not a workflow whose only test is in the other repo. A2A in-flight claim sweep over the last 30 messages: no
[lane-claim]on this scope.The Problem
The specs do not merely reference the workflow — they execute it.
getAgentPrReviewBodyLintScript()loads the YAML, finds theValidate PR Review Bodystep, and pulls outstep.with.script;runAgentPrReviewBodyLintWorkflow()then runs that source against stubbed GitHub Actions services and captures the comments, failures and logs it produces.So the coverage is behavioural, against the real shipped script, not a reimplementation of its rules. That is the expensive kind to write and the easy kind to lose.
The spec knows which repository it is testing — its stub context is hardcoded
{repo: {owner: 'neomjs', repo: 'neo'}}. The tests were authored for #13910 / #15257 / #16148 and were correct where they were written. The split moved the workflow and left the tests behind, and nothing failed loudly enough to notice: the Brain'sunitCI check runs four named smoke specs (brain-unit.yml), so these twelve have been red locally and invisible in CI for the whole interval.Why this is worth porting rather than deleting. Deleting removes the only executable check on a 33 KB PR-blocking policy. The rules it covers are exactly the ones that fail silently when wrong — a review-budget accounting error admits a demand it should refuse, and nobody notices until a reviewer is blocked or, worse, isn't.
The Architectural Reality
.github/workflows/agent-pr-review-body-lint.yml, joblint-pr-review-body, stepValidate PR Review Body, whosewith.scriptis the unit under test.neomjs/neo-agent-brain:test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs— two module-scope helpers plus twelve tests, in a 5,427-line file whose remaining coverage is Brain-owned.runAgentPrReviewBodyLintWorkflow:#13910×4 (Micro-Delta bodies: accepts documented, rejects incomplete before canonical fallback, rejects semantic-blocker shortcuts, requires Premise Coherence),#15257×6 (activation cutover, zero merged dev closers, fail-closed on malformed activation relations, bypass/COMMENTED never weakening Drop+Supersede, one-sided Drop+Supersede contradiction, override-only provenance after cutover),#16148×2 (origin sessions accepted / rejected across every documented review format).managePrReview (#11273)describe, which opens at line 1834 and closes at 5427. At least two neighbours in the same run —#13910: rejects Micro-Delta review with a semantic blocker classand#14263: accepts a Micro-Review— do not call the workflow helper and must stay behind. So this is a selective lift of twelve named tests plus two helpers out of a block that keeps running, not a block move.js-yamlalready resolves in this repository, so the port introduces no new dependency..github/workflows/*.yml, so the destination directory is a novel choice rather than a sibling match.test/playwright/unit/workflows/mirroring the source tree is the shape I would expect, but §2 Stage 3 applies — the implementer runsstructural-pre-flightand records the outcome rather than inheriting this line as settled.PullRequestServiceservice is correctly Brain-owned. Only the twelve specs are on the wrong side.The Fix
Port the review-body-lint block into this repository as its own spec:
getAgentPrReviewBodyLintScript()andrunAgentPrReviewBodyLintWorkflow()— the YAML load, the step lookup and the stubbed-Actions harness — into an Engine spec that resolves the workflow from this repo root, so the read that is currently cross-repository becomes local.#17214group and the rest ofmanagePrRevieware untouched.Sequencing is deliberate — this lands first and the Brain-side removal follows, so the coverage never ceases to exist in both repositories at once.
Contract Ledger
agent-pr-review-body-lint.yml→ joblint-pr-review-body→ stepValidate PR Review Body→with.script12 failed → 192 passedwhen the workflow is present, measured 2026-08-31; after the port, the same twelve green in this repo with no cross-repo readRow anchors verified before assertion: the workflow file, its job name, its step name and
with.scriptwere read at Enginedev; the helper names and test count were read at Braindev.Decision Record impact
none— this relocates test coverage to the repository that owns the artifact under test. It does not alter the split's dependency direction, which ADR 0040 governs, and takes nothing from the Brain that the Brain owns.Acceptance Criteria
.github/workflows/agent-pr-review-body-lint.yml, extracts theValidate PR Review Bodystep'swith.script, and executes it against stubbed Actions services.structural-pre-flight, and the rationale is recorded in the spec header rather than only in this ticket.Out of Scope
neomjs/neo-agent-brain#201holds the measurement identifying these twelve as part of its cross-repository class.unitCI check executes —neomjs/neo-agent-brain#201owns that.Avoided Traps
Related
Related: #13910, #15257, #16148 (the tickets these twelve specs were written for), #17214 (closed — a NEIGHBOURING group in the same file that stays in the Brain), #17783 (sibling post-split residual: guards with no caller),
neomjs/neo-agent-brain#201(the Brain-side measurement and cross-repository class),neomjs/neo-agent-brain#191(domain-slice disposition for legacy Brain surfaces).Retrieval Hint:
query_raw_memoriesfor "agent-pr-review-body-lint coverage stranded post-split" · the 12→192 measurement and the cross-repo classification are recorded onneomjs/neo-agent-brain#201.Origin Session ID: 56bc214a-5b55-41a2-848a-cdfa372abbcd