Live latest-open sweep: checked the latest 20 open issues at 2026-09-03T13:59:34Z; no equivalent found. A2A claim sweep over the last 30 messages (all read-states) at 13:45Z, plus my own [lane-claim] on this exact row at 13:48Z: no competing claim. Memory Core rationale sweep on the problem's nouns (deleted release-note orphan guard, broad-staging witness) returned no prior decision on this row beyond #17922's own ruling. Own-assignment sweep: 13 open tickets assigned to me, none covering the release path's coverage.
Context
c623b2f63c (#17791 via #17806) deleted 804 unit spec files on the test/playwright/unit/ai/** path prefix. #17922 censused the 30 under ai/buildScripts/ and found 27 whose subject never left this repository. 21 recovered verbatim in #17924 / PR #17925; DataSyncPipeline came back via #17920 / #17927; WorkflowScopeClassifier via #18052 / #18053; check-theme-surfaces via #18162 / #18163.
Re-measured at dev@f6c7a0c360, #17922's owed set is 3, not the 4 its body still states — the check-theme-surfaces row reads as "in flight — PR #18163, awaiting review" and that PR merged at 09:29Z today. This ticket takes one of the three: release/PublishReleaseNoteOrphan.spec.mjs, 171 lines, 6 arms.
The Problem
The subject is buildScripts/release/publish.mjs — 281 lines at HEAD, the operator-invoked release entrypoint, protected by §critical_gates 8. It never left. Four of its six deleted arms guard properties that are live today with no witness at all:
unguarded property
consequence if it silently breaks
the staging note is removed only AFTER gh release create reads it
the release is cut from a file the script already deleted, or the staging copy lingers
no top-level release-notes/v*.md survives beside its chunk-N mirror
the version double-lists in the release index and the sitemap
the orphan predicate distinguishes a pre-publish staging note from a post-publish duplicate
either the designed staging state reads as a defect, or the defect reads as staging
each release leaf appears once in apps/portal/resources/data/releases.json
the reader sees the duplicate the orphan class produces
Two more arms asserted through ai/scripts/lifecycle/postReleaseSync.mjs, which correctly departed. #17922's disposition ruling (2026-09-02) decided both per arm rather than per file: the handoff arm re-aims onto the ordering invariant that survives, and the broad-stage arm keeps its Engine half, with its Brain half named as a custody transfer owed to neomjs/neo-agent-brain rather than dropped.
The broad-stage half is the sharpest of the four live properties. publish.mjs:155 stages with git add . and :154 is assertNoArchiveLogicalIdentityCollisions(...). Every commit on the release path runs --no-verify by design, so husky and the lint-staged copy of that guard are structurally blind to it, and proving the ordering behaviourally would require cutting a release. A source-ordering assertion is the only available instrument, and there is none.
The Architectural Reality
Placement is the surviving sibling tree test/playwright/unit/buildScripts/** (17 specs at HEAD), not the deleted unit/ai/buildScripts/** path. The ai/ prefix is what classified the file as extracted substrate and would re-arm the same deletion at the next boundary change. This contradicts .agents/skills/unit-test/references/unit-test.md §7, which still routes buildScripts specs to unit/ai/buildScripts/; that is stale substrate and is out of scope here.
The arms read sources rather than importing them: publish.mjs is a top-level release script whose module scope runs main(), so a source-text assertion is the honest instrument, matching the restored WorkflowScopeClassifier.spec.mjs precedent.
The release-index arm's subject is generated: buildScripts/docs/index/release.mjs writes releases.json, and its line 138 deliberately omits isLeaf on release nodes.
The Fix
Restore the spec to test/playwright/unit/buildScripts/release/.
Re-aim the handoff arm: drop the ai:post-release-sync script resolution (that script is absent from package.json), keep the ordering half, and assert the print names the Brain-side checkout — a beat that does not say where the next step runs is not a handoff.
Reduce the broad-stage arm to its Engine half, keeping the per-file pinning (never a total) so a second unguarded broad stage cannot arrive and still pass, and name the Brain-side custody transfer in the file.
Repair the release-index arm, which cannot fail as written. It filters node.isLeaf; the generator omits that field on release leaves, so the filter matches 0 of 174 nodes — and 0 at c623b2f63c~1 as well, so this is not split drift: the arm was already vacuous when it was deleted. Select a leaf by the property that distinguishes one, assert the population is non-empty so it cannot silently re-vacuate, and check path alongside id.
6 arms over publish.mjs, the release-notes corpus and releases.json
none — a release path with no witness is the defect
spec header
each arm red against a seeded mutation of its own subject
the release-index leaf predicate
buildScripts/docs/index/release.mjs:131,138
a leaf is a node pointing at a release-note file; the population is asserted non-empty
n/a
spec JSDoc
red when the index is stripped of leaves, which the pre-repair arm could not see
Decision Record impact
none — restoring Engine-owned coverage to the Engine is what ADR 0040 §2.3 already prescribes (the ADR lives in neo-agent-brain, not here; its absence from learn/agentos/decisions/ is not evidence).
Acceptance Criteria
PublishReleaseNoteOrphan.spec.mjs exists under test/playwright/unit/buildScripts/release/ and passes against its HEAD subjects.
Every arm is shown red against a seeded mutation of its own subject, and each mutation reddens only its own arm — a restored spec that cannot fail is not restored coverage. Mutations must cover, at minimum: the staging-note removal moved before the release, a lingering post-publish duplicate, a neutered orphan predicate, a twice-listed release leaf, an index with no leaves at all, a deleted handoff print, a handoff that names no destination, and a broad stage moved before its guard.
The file names both re-aimed arms and the reason, so the difference from the deleted original is auditable rather than invisible.
The release-index arm's vacuity is stated with the measurement from both trees, so it cannot read as split drift.
The Brain-side broad-stage half is named in the spec as a custody transfer, not silently absent.
The unit project's collected spec-file count rises by exactly 1, measured by count and not by a green run.
#17922's body is corrected so its check-theme-surfaces row no longer reads as in flight.
Out of Scope
The other two owed rows — RebuildContentIndexesAndSeo and WorkflowConcurrency stay with #17922, unclaimed. WorkflowConcurrency is the sharpest of them: its subject runs on every PR.
Filing the Brain-side witness. The ordering invariant in ai/scripts/lifecycle/postReleaseSync.mjs has no spec in the repository that owns it. That is a neomjs/neo-agent-brain filing with its own sweep, and #17922's ruling deliberately declined to file it from inside this arc.
Changing what publish.mjs does. Restoration is not the moment to fix the subject; both call sites are correctly ordered at HEAD and this ticket reports no live defect in them.
unit-test.md §7's stale placement rule. Real friction, wrong repository — the skill corpus is neomjs/neo-agent-skills substrate.
Related
#17922 — the parent census; this is one of its owed residual rows
#17924 / PR #17925 — the 21-spec verbatim restoration
#18052 / PR #18053 — the sibling residual, same shape (restore + re-aim + name the drops)
#17920 / PR #17927 — the DataSyncPipeline residual
Sub of #17922 · sibling of #17924, #17964, #18052 · the third of #17922's owed residual rows
Live latest-open sweep: checked the latest 20 open issues at 2026-09-03T13:59:34Z; no equivalent found. A2A claim sweep over the last 30 messages (all read-states) at 13:45Z, plus my own
[lane-claim]on this exact row at 13:48Z: no competing claim. Memory Core rationale sweep on the problem's nouns (deleted release-note orphan guard, broad-staging witness) returned no prior decision on this row beyond #17922's own ruling. Own-assignment sweep: 13 open tickets assigned to me, none covering the release path's coverage.Context
c623b2f63c(#17791 via #17806) deleted 804 unit spec files on thetest/playwright/unit/ai/**path prefix. #17922 censused the 30 underai/buildScripts/and found 27 whose subject never left this repository. 21 recovered verbatim in #17924 / PR #17925;DataSyncPipelinecame back via #17920 / #17927;WorkflowScopeClassifiervia #18052 / #18053;check-theme-surfacesvia #18162 / #18163.Re-measured at
dev@f6c7a0c360, #17922's owed set is 3, not the 4 its body still states — thecheck-theme-surfacesrow reads as "in flight — PR #18163, awaiting review" and that PR merged at 09:29Z today. This ticket takes one of the three:release/PublishReleaseNoteOrphan.spec.mjs, 171 lines, 6 arms.The Problem
The subject is
buildScripts/release/publish.mjs— 281 lines at HEAD, the operator-invoked release entrypoint, protected by §critical_gates 8. It never left. Four of its six deleted arms guard properties that are live today with no witness at all:gh release createreads itrelease-notes/v*.mdsurvives beside itschunk-Nmirrorapps/portal/resources/data/releases.jsonTwo more arms asserted through
ai/scripts/lifecycle/postReleaseSync.mjs, which correctly departed. #17922's disposition ruling (2026-09-02) decided both per arm rather than per file: the handoff arm re-aims onto the ordering invariant that survives, and the broad-stage arm keeps its Engine half, with its Brain half named as a custody transfer owed toneomjs/neo-agent-brainrather than dropped.The broad-stage half is the sharpest of the four live properties.
publish.mjs:155stages withgit add .and:154isassertNoArchiveLogicalIdentityCollisions(...). Every commit on the release path runs--no-verifyby design, so husky and thelint-stagedcopy of that guard are structurally blind to it, and proving the ordering behaviourally would require cutting a release. A source-ordering assertion is the only available instrument, and there is none.The Architectural Reality
test/playwright/unit/buildScripts/**(17 specs at HEAD), not the deletedunit/ai/buildScripts/**path. Theai/prefix is what classified the file as extracted substrate and would re-arm the same deletion at the next boundary change. This contradicts.agents/skills/unit-test/references/unit-test.md§7, which still routesbuildScriptsspecs tounit/ai/buildScripts/; that is stale substrate and is out of scope here.publish.mjsis a top-level release script whose module scope runsmain(), so a source-text assertion is the honest instrument, matching the restoredWorkflowScopeClassifier.spec.mjsprecedent.buildScripts/docs/index/release.mjswritesreleases.json, and its line 138 deliberately omitsisLeafon release nodes.The Fix
test/playwright/unit/buildScripts/release/.ai:post-release-syncscript resolution (that script is absent frompackage.json), keep the ordering half, and assert the print names the Brain-side checkout — a beat that does not say where the next step runs is not a handoff.node.isLeaf; the generator omits that field on release leaves, so the filter matches 0 of 174 nodes — and 0 atc623b2f63c~1as well, so this is not split drift: the arm was already vacuous when it was deleted. Select a leaf by the property that distinguishes one, assert the population is non-empty so it cannot silently re-vacuate, and checkpathalongsideid.Contract Ledger Matrix
test/playwright/unit/buildScripts/release/PublishReleaseNoteOrphan.spec.mjstest/playwright/unit/buildScripts/util/WorkflowScopeClassifier.spec.mjspublish.mjs, the release-notes corpus andreleases.jsonbuildScripts/docs/index/release.mjs:131,138Decision Record impact
none— restoring Engine-owned coverage to the Engine is what ADR 0040 §2.3 already prescribes (the ADR lives inneo-agent-brain, not here; its absence fromlearn/agentos/decisions/is not evidence).Acceptance Criteria
PublishReleaseNoteOrphan.spec.mjsexists undertest/playwright/unit/buildScripts/release/and passes against its HEAD subjects.unitproject's collected spec-file count rises by exactly 1, measured by count and not by a green run.check-theme-surfacesrow no longer reads as in flight.Out of Scope
RebuildContentIndexesAndSeoandWorkflowConcurrencystay with #17922, unclaimed.WorkflowConcurrencyis the sharpest of them: its subject runs on every PR.ai/scripts/lifecycle/postReleaseSync.mjshas no spec in the repository that owns it. That is aneomjs/neo-agent-brainfiling with its own sweep, and #17922's ruling deliberately declined to file it from inside this arc.publish.mjsdoes. Restoration is not the moment to fix the subject; both call sites are correctly ordered at HEAD and this ticket reports no live defect in them.unit-test.md§7's stale placement rule. Real friction, wrong repository — the skill corpus isneomjs/neo-agent-skillssubstrate.Related
DataSyncPipelineresidualefba884dcb— the spec-retirement account guard whose contract #17922 narrowedHandoff Retrieval Hints
Retrieval Hint: "the release path's broad git add . stage has no ordering witness since c623b2f63c"Retrieval Hint: releases.json carries no isLeaf:true node, so a node.isLeaf filter is vacuous in both trees