Context
While implementing #15153 / PR #15698, the default agent-preflight repair pass exposed a new corruption edge in check-block-alignment.mjs --fix. A valid multiline callback inside a comma-style declaration block was rewritten from observation => … to observation = > …; the later parse gate caught the resulting SyntaxError.
This is the same high-level failure class as #15072, but a distinct parser edge. The earlier fix excludes defaulted destructuring bindings; it does not distinguish a callback arrow from a bare declaration assignment.
The Problem
The current declaration collector accepts a bare continuation through:
DECL_BINDING + `\\s*=\\s*.+`
When a multiline callback has the same indentation as the comma-block's declarators, observation => observation.keep matches that grammar as if it were observation = (> observation.keep). splitAssignment() then splits at the arrow's = and the fixer re-emits it with assignment spacing:
function selectObservations(observations) {
const
selected = observations.filter(
observation => observation.keep
),
count = selected.length;
return {selected, count}
}
observation = > observation.keepFresh reproduction on 2026-07-22:
node --check passes before the fixer.
node buildScripts/util/check-block-alignment.mjs --fix <repro> reports two aligned lines.
node --check then fails at observation = > observation.keep with SyntaxError: Unexpected token '>'.
The production witness was the opened filter in test/playwright/unit/ai/services/github-workflow/PullRequestReconciliationService.spec.mjs; #15153 avoided the corruption by separating that multiline expression from the surrounding comma block.
Memory Core prior art: session 090a68e6-1a28-4b20-a5fd-842ebac3e729 mapped the earlier template-mask corruption family. Knowledge Base and live tracker searches found #13670, #14212, and #15072, but no callback-arrow owner.
The Architectural Reality
buildScripts/util/check-block-alignment.mjs:210-241 owns DECL_BINDING, BARE_DECL, and splitAssignment().
buildScripts/util/check-block-alignment.mjs:289-362 collects comma-style declaration runs by regex and indentation.
buildScripts/util/check-block-alignment.mjs:372-401 reconstructs every accepted entry as left = value, so a false-positive match necessarily mutates =>.
test/playwright/unit/ai/buildScripts/util/check-block-alignment.spec.mjs is the established regression-test owner.
buildScripts/util/check-parse.mjs is a commit-time backstop, not permission for --fix to corrupt source.
- Agent OS structure-map gate run on 2026-07-22: N/A for placement; the affected runtime is in the established
buildScripts/util/check-*.mjs sibling family outside the map's ai/ ownership tree.
The Fix
Make the declaration parser distinguish an assignment operator from an arrow token before admitting or reconstructing a bare continuation. Prefer conservative non-mutation: if the line cannot be proven to be a declaration binding plus assignment, break the run and leave it byte-identical.
Add the exact same-indent multiline-callback reproducer and idempotency/parse assertions to the existing block-alignment spec. Preserve legitimate bare declarators and the default-free destructuring behavior already covered there.
Also repair the stale descriptive #15057 pointers in the existing regression test and parse-gate diagnostic: the fixer-corruption ticket is #15072; #15057 is the unrelated route-attribution seam on which that earlier bug happened to surface.
Contract Ledger
| Target surface |
Source of authority |
Proposed behavior |
Fallback |
Docs |
Evidence |
check-block-alignment --fix declaration parsing |
buildScripts/util/check-block-alignment.mjs |
Never classify => as a declaration assignment |
Leave an ambiguous line byte-identical and break the run |
Existing module/function JSDoc |
Exact callback-arrow regression plus node --check |
agent-preflight repair pass |
buildScripts/util/agent-preflight.mjs |
Repair alignment without invalidating source |
Existing parse gate fails closed if another edge escapes |
Existing CLI help/JSDoc |
Focused preflight test and idempotent second run |
Decision Record impact
none — bounded build-tool parser correction; no ADR contract changes.
Acceptance Criteria
Out of Scope
- Replacing the regex-based formatter with a full JavaScript parser.
- Changing Neo's comma-block alignment convention.
- Removing the commit-time parse gate.
- Refactoring unrelated alignment rules.
Avoided Traps
- Relying only on
check-parse: that prevents a bad commit but leaves the advertised repair command destructive.
- Blanket-skipping multiline declarations: that would regress supported block-opening values and legitimate bare declarators.
- Whitespace-only patching of the witness: splitting the production declaration avoids one instance but leaves the fixer unsafe for the next caller.
Related
Handoff Retrieval Hints
query_raw_memories: "block alignment fixer corrupts callback arrow"
- Exact source anchor:
DECL_BINDING / BARE_DECL / splitAssignment in buildScripts/util/check-block-alignment.mjs
- Exact witness anchor:
PullRequestReconciliationService.spec.mjs callback filtering pull_request.opened
Live latest-open sweep: checked latest 20 open issues immediately before creation on 2026-07-22; no equivalent found.
A2A in-flight claim sweep: checked the latest 30 all-status messages within the 60-minute herd window immediately before creation; no overlapping claim found.
Context
While implementing #15153 / PR #15698, the default
agent-preflightrepair pass exposed a new corruption edge incheck-block-alignment.mjs --fix. A valid multiline callback inside a comma-style declaration block was rewritten fromobservation => …toobservation = > …; the later parse gate caught the resultingSyntaxError.This is the same high-level failure class as #15072, but a distinct parser edge. The earlier fix excludes defaulted destructuring bindings; it does not distinguish a callback arrow from a bare declaration assignment.
The Problem
The current declaration collector accepts a bare continuation through:
DECL_BINDING + `\\s*=\\s*.+`When a multiline callback has the same indentation as the comma-block's declarators,
observation => observation.keepmatches that grammar as if it wereobservation = (> observation.keep).splitAssignment()then splits at the arrow's=and the fixer re-emits it with assignment spacing:// INPUT: valid JavaScript function selectObservations(observations) { const selected = observations.filter( observation => observation.keep ), count = selected.length; return {selected, count} } // CURRENT --fix OUTPUT: invalid JavaScript observation = > observation.keepFresh reproduction on 2026-07-22:
node --checkpasses before the fixer.node buildScripts/util/check-block-alignment.mjs --fix <repro>reports two aligned lines.node --checkthen fails atobservation = > observation.keepwithSyntaxError: Unexpected token '>'.The production witness was the
openedfilter intest/playwright/unit/ai/services/github-workflow/PullRequestReconciliationService.spec.mjs; #15153 avoided the corruption by separating that multiline expression from the surrounding comma block.Memory Core prior art: session
090a68e6-1a28-4b20-a5fd-842ebac3e729mapped the earlier template-mask corruption family. Knowledge Base and live tracker searches found #13670, #14212, and #15072, but no callback-arrow owner.The Architectural Reality
buildScripts/util/check-block-alignment.mjs:210-241ownsDECL_BINDING,BARE_DECL, andsplitAssignment().buildScripts/util/check-block-alignment.mjs:289-362collects comma-style declaration runs by regex and indentation.buildScripts/util/check-block-alignment.mjs:372-401reconstructs every accepted entry asleft = value, so a false-positive match necessarily mutates=>.test/playwright/unit/ai/buildScripts/util/check-block-alignment.spec.mjsis the established regression-test owner.buildScripts/util/check-parse.mjsis a commit-time backstop, not permission for--fixto corrupt source.buildScripts/util/check-*.mjssibling family outside the map'sai/ownership tree.The Fix
Make the declaration parser distinguish an assignment operator from an arrow token before admitting or reconstructing a bare continuation. Prefer conservative non-mutation: if the line cannot be proven to be a declaration binding plus assignment, break the run and leave it byte-identical.
Add the exact same-indent multiline-callback reproducer and idempotency/parse assertions to the existing block-alignment spec. Preserve legitimate bare declarators and the default-free destructuring behavior already covered there.
Also repair the stale descriptive
#15057pointers in the existing regression test and parse-gate diagnostic: the fixer-corruption ticket is#15072;#15057is the unrelated route-attribution seam on which that earlier bug happened to surface.Contract Ledger
check-block-alignment --fixdeclaration parsingbuildScripts/util/check-block-alignment.mjs=>as a declaration assignmentnode --checkagent-preflightrepair passbuildScripts/util/agent-preflight.mjsDecision Record impact
none— bounded build-tool parser correction; no ADR contract changes.Acceptance Criteria
=>aftercheck-block-alignment --fix.node --check.--fixrun is idempotent.#15057pointers in the fixer regression test and parse diagnostic are corrected to#15072.Out of Scope
Avoided Traps
check-parse: that prevents a bad commit but leaves the advertised repair command destructive.Related
Handoff Retrieval Hints
query_raw_memories: "block alignment fixer corrupts callback arrow"DECL_BINDING/BARE_DECL/splitAssignmentinbuildScripts/util/check-block-alignment.mjsPullRequestReconciliationService.spec.mjscallback filteringpull_request.openedLive latest-open sweep: checked latest 20 open issues immediately before creation on 2026-07-22; no equivalent found. A2A in-flight claim sweep: checked the latest 30 all-status messages within the 60-minute herd window immediately before creation; no overlapping claim found.