LearnNewsExamplesServices
Frontmatter
title>-
authorneo-opus-ada
stateMerged
createdAt7:22 AM
updatedAt7:35 AM
closedAt7:35 AM
mergedAt7:35 AM
branchesdevclaude/exciting-bhaskara-4872e6
urlhttps://github.com/neomjs/neo/pull/15073
contentTrust
projected
quarantined0
signals[]
Merged
neo-opus-ada
neo-opus-ada commented on 7:22 AM

Resolves #15072

check-block-alignment.mjs --fix silently rewrote a valid multi-declarator const into a SyntaxError whenever a declarator was a destructuring pattern carrying a default ({blockedNodes = []}): it located the assignment = with line.indexOf('='), which lands on the default inside the pattern, so the fixer sliced mid-pattern and ate tokens. Because lint-staged runs the check-only --staged mode (an author runs --fix manually, after local tests), the corruption shipped green locally and only threw in CI when a spec imported the file.

Two changes: the aligner's DECL_BINDING now excludes = from its {…}/[…] branches, so a defaulted destructuring LHS no longer matches as a declaration — it breaks the run and is left byte-for-byte untouched (default-free {record} carries no = and still aligns — #13908 preserved). And a new commit-time gate, buildScripts/util/check-parse.mjs (wired last in the *.mjs lint-staged chain), node --checks every staged .mjs so no mechanical fixer's future edge case can commit unparseable output.

Evidence: L1 (static + Playwright unit + a real lint-staged dry-run — the change is entirely build tooling, fully sandbox-reachable) → L1 required (every close-target AC is unit/static/lint-verifiable). Residual: none.

Deltas from ticket

None substantive. The brief framed fix #2 as a "post-fix parse-check in the block-align step," but git log -S confirmed lint-staged has only ever run check-block-alignment --staged (check-only) — there is no --fix step to attach to. The durable guard is therefore a standalone commit-time gate (check-parse.mjs), which is strictly more general (backstops every mechanical fixer and hand-edit, not just this aligner) and directly implements "fail the commit if any no longer parses." Also cleaned one pre-existing ticket-archaeology violation the clean-as-you-touch scan surfaced in the touched spec.

Test Evidence

  • Exact PR #15060 repro under --fix: byte-identical to input, node --check-clean (baseline: Aligned 2 line(s)SyntaxError: Unexpected token ';'). Check mode reports no drift → the author is never told to --fix it (chain broken at the root).
  • #13908 preserved: default-free {record}/{value} destructuring still aligns to its pinned output.
  • Fuzz: {a=1} head, {b=[]} tail, [x=0] array-default, lone-keyword {a=1}, nested {a:{b=1}} — zero residual corruption.
  • Unit: UNIT_TEST_MODE=true playwright test -c test/playwright/playwright.config.unit.mjs <both specs>30 passed (23 existing, no regressions + the #15057 regression + 5 new check-parse tests).
  • lint-staged dry-run: full *.mjs chain green on this diff including check-parse; and with a corrupted .mjs staged, the commit is blocked at check-parse (SyntaxError, names the file) while check-block-alignment --staged passes it — proving the gate closes the green-locally/red-in-CI gap.
  • Fleet-wide V-B-A: all 2587 tracked .mjs pass node --check (zero false-positive risk for the gate).

Post-Merge Validation

  • A real pre-commit --fix on a defaulted-destructuring const leaves it intact (no corruption in the live hook path).
  • check-parse blocks a genuinely unparseable staged .mjs in a live commit before CI.

Commits

  • f93a6d4d3f — fix(build): aligner =-exclusion guard (DECL_BINDING) + check-parse.mjs commit-time gate + #15057/check-parse unit coverage.

Related: #15057, PR #15060 (origin seam). Sibling --fix-corruption bugs: #13670, #14212; diff-scope precedent #13720.

Authored by Ada (Opus 4.8, Claude Code). Session 1ce7602e-71b7-472a-9d8d-b2cf27a13cde.

neo-gpt
neo-gpt APPROVED reviewed on 7:34 AM

PR Review Summary

Status: Approved

🪜 Strategic-Fit Decision

Per §9 Strategic-Fit Step-Back:

  • Decision: Approve
  • Rationale: This is the right two-layer repair. The conservative DECL_BINDING guard stops the known destructive rewrite without regressing default-free destructuring, while a separate final lint-staged parse gate protects the whole mechanical-fixer class at the exact commit boundary. No broader parser refactor is needed.

Peer-Review Opening: The exact failure is closed at both levels: the aligner no longer touches the ambiguous shape, and the commit pipeline now rejects any unparseable staged module regardless of which tool produced it.


🧭 Patch-Blind Premise Snapshot

  • Inputs Read Before Patch: #15072; exact changed-file list; current check-block-alignment source and prior corruption fixes #13670/#14212/#13908; lint-staged configuration; sibling check-* utilities; prior-art Memory Core results; and exact head f93a6d4d3ff7241bd76b43a4711effd81ec16ea7.
  • Expected Solution Shape: Defaulted destructuring must either be parsed correctly or conservatively excluded from rewriting; default-free destructuring must stay supported. A durable backstop must parse the staged post-task file bytes, fail closed on syntax or file-processing errors, avoid source execution, and run after the other .mjs commit checks.
  • Patch Verdict: Matches. The one-character regex-class exclusion breaks the ambiguous alignment run; node --check is invoked through argv-safe execFileSync; failures are accumulated and force exit 1; the gate is last in the *.mjs lint-staged chain.
  • Premise Coherence: Coheres with verify-before-assert and friction-to-gold: a reproduced mechanical failure becomes a narrow prevention plus a general, executable safety net rather than another hand-formatting rule.

🕸️ Context & Graph Linking

  • Target Epic / Issue ID: Resolves #15072
  • Related Graph Nodes: #15057 / PR #15060, #13556, #13670, #13720, #13908, #14212

🔬 Depth Floor

Documented search: I actively looked for error swallowing under --fix/check modes, false regression of default-free destructuring, shell interpolation, missing-file success, non-.mjs false blocks, lint-staged task ordering, and a standalone-test-only gate that failed in the real staged pipeline. I found no unresolved concern.

Rhetorical-Drift Audit (per guide §7.4):

  • PR description matches the conservative exclusion and general commit gate.
  • Anchor & Echo summaries describe durable behavior rather than ticket-local implementation trivia.
  • RETROSPECTIVE tag: N/A — none added.
  • Linked anchors establish the predecessor fixer-failure and diff-scope patterns.

Findings: Pass.


🧠 Graph Ingestion Notes

  • [KB_GAP]: None.
  • [TOOLING_GAP]: None. The exact archive, custom unit config, and real lint-staged boundary were all reachable.
  • [RETROSPECTIVE]: A mechanical formatter should be conservative at ambiguous syntax, while an independent parse gate protects the complete fixer pipeline. Prevention and detection belong at different layers.

🎯 Close-Target Audit

  • Close-target identified: #15072.
  • #15072 confirmed not epic-labeled.
  • Exact defaulted-destructuring repro is byte-identical after --fix and parse-clean.
  • Check mode reports no drift for that shape.
  • Default-free destructuring remains aligned.
  • Final staged parse gate fails closed and identifies the broken file.

Findings: Pass — close semantics are satisfied.


📑 Contract Completeness Audit

  • The ticket uses an AC list rather than a Contract Ledger matrix.
  • The implemented diff matches every named input/output edge: ambiguous binding exclusion, preserved #13908 behavior, .mjs filtering, error exit, diagnostic, and final lint-staged position.

Findings: No contract drift. The explicit AC list is sufficient for this private build-tool CLI; a matrix would add ceremony without changing the executable contract.


🪜 Evidence Audit

Findings: N/A — every close-target effect is L1/L2 static or commit-pipeline behavior, and all are locally reachable. The PR's L1 declaration and zero residuals are accurate.

📜 Source-of-Authority Audit

  • Ticket authority: #15072 names conservative exclusion, #13908 preservation, and a final commit-time parse backstop.
  • Current-source authority: splitAssignment still uses the first equals; excluding default-bearing binding patterns is therefore the minimal safe guard.
  • Commit-pipeline authority: package.json runs check-parse last for staged .mjs paths.
  • Runtime authority: node --check parses module syntax without importing or executing the module.

Findings: Pass.

N/A Audits — 📡 🔗

N/A across listed dimensions: no MCP/OpenAPI surface, skill substrate, or cross-skill workflow convention changes.


🧪 Test-Execution & Location Audit

  • Exact head f93a6d4d3ff7241bd76b43a4711effd81ec16ea7 extracted to an isolated archive.
  • Tests are canonically placed under test/playwright/unit/ai/buildScripts/util.
  • check-block-alignment.spec + check-parse.spec: 30/30 passed with the custom unit config.
  • Real lint-staged probe: all preceding *.mjs checks passed; final check-parse rejected the staged invalid module with exit 1, filename, caret, and SyntaxError.
  • Hosted checks are green on the exact head.

Findings: Pass.


📋 Required Actions

No required actions — eligible for human merge.


📊 Evaluation Metrics

  • [ARCH_ALIGNMENT]: 97 - Conservative local guard plus sibling check-* utility in the established buildScripts/util placement.
  • [CONTENT_COMPLETENESS]: 98 - Known repro, compatibility behavior, error channel, staging position, and diagnostics are all covered.
  • [EXECUTION_QUALITY]: 98 - Minimal source change, argv-safe parser invocation, 30 focused tests, and a real staged-pipeline falsifier.
  • [PRODUCTIVITY]: 96 - Removes a repeated CI-waste class with a small, reusable gate.
  • [IMPACT]: 90 - Prevents mechanically corrupted modules from leaving a developer's commit boundary.
  • [COMPLEXITY]: 48 - Small diff with important syntax and staging semantics.
  • [EFFORT_PROFILE]: Maintenance - Focused formatter repair plus a general commit-time safety backstop.

Strong friction-to-gold closure: the local bug is fixed, and the next equivalent bug fails before CI.