LearnNewsExamplesServices
Frontmatter
id13563
titleBlock-alignment lint v1b: object colons + `=` declaration blocks
stateClosed
labels
enhancementaibuild
assigneesneo-opus-vega
createdAtJun 19, 2026, 6:42 PM
updatedAtJun 20, 2026, 1:42 AM
githubUrlhttps://github.com/neomjs/neo/issues/13563
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 20, 2026, 1:42 AM

Block-alignment lint v1b: object colons + = declaration blocks

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaibuild
neo-opus-vega
neo-opus-vega commented on Jun 19, 2026, 6:42 PM

Context

Follow-up to #13556 / #13558 (the block-alignment lint v1 — import-from alignment, merged 2026-06-19). v1 explicitly documented object-literal colon + =-declaration-block alignment as fast-follows. Triggered now by an operator decision (@tobiu, 2026-06-19): build v1b so #13553 (embed-drain watchdog) can be fully mechanically reformatted — its intervals / hooks / enables object blocks have colon drift v1 cannot fix — closing the hand-formatting friction→gold completely (mechanize ALL the block-formatting basics, not just imports).

The Problem

v1 (buildScripts/util/check-block-alignment.mjs) aligns only import-from columns. Two house-style block patterns remain hand-done — exactly the mis-count-prone task v1 set out to kill:

  1. Object-literal colons: within a run of key: value properties at one nesting level, the : aligns to a shared column (.github/CODING_GUIDELINES.md rule 2). A newly-added longer key silently breaks the block (e.g. #13553's embedDrainLivenessWatchdogCheck: in the intervals block; graphLogCompactionGetDueTask: in hooks).
  2. = comma-blocks: within a single-keyword comma-block (a lone const/let/var line + its indented name = value continuations), the = aligns to a shared column (rule 35).

The Architectural Reality

  • Extend the existing buildScripts/util/check-block-alignment.mjs (v1) — same check + --fix shape, same conservative group-detection (a run of ≥ 2 consecutive alignable lines at the same indent; any non-conforming line breaks the run → no false positives), same pure/injectable column math (mirror evaluateImportAlignment).
  • House-style SoT = .github/CODING_GUIDELINES.md (rule 2 colon-align; rule 35 =-align). The = aligner scopes ONLY to the single-keyword comma-block (rule 35's unit) — see the Scope Refinement note below for why separate consecutive declarations are NOT grouped.

The Fix

Add to check-block-alignment.mjs:

  • Object-colon alignment: detect runs of <indent>key: value lines sharing an indent within an object literal; align : to max(indent + keyLength). Group breaks on a non-key: line, a blank line, or an indent change. Only the property-key colon participates (ignore colons inside the value / strings). One nesting level at a time (nested objects re-group at their own indent). Computed [bracket] keys participate (the [isDescriptor] descriptor pattern).
  • = comma-block alignment: detect a lone const/let/var keyword line + its indented name = value continuations (the rule-35 comma-block); align their = to a shared column. Separate consecutive declarations and bare assignments are NOT grouped; a block-opening value ({/(/[) is excluded.
  • --fix rewrites both; check reports file:line + expected column. Idempotent.

Scope Refinement (post-validation, 2026-06-19)

Real-file validation (running check-mode across src/core/Base.mjs, src/Neo.mjs, ai/config.template.mjs, Orchestrator.spec.mjs) corrected the original = scope. The first draft proposed aligning = across adjacent same-indent declarations agnostic to comma-vs-repeat-keyword. Validation showed that over-groups unrelated statements (e.g. let a = …; const b = …; are distinct statements, not a rule-35 block). Resolution: the = aligner is scoped ONLY to the single-keyword comma-block. Two further false-positive classes were found + fixed the same way: a block-opening = value (cloneMap = {) is excluded; computed [isDescriptor] colon keys participate. The ACs below reflect the corrected (delivered) scope.

Acceptance Criteria

  • check flags + --fix aligns object-literal colon blocks (≥ 2 same-indent key: lines, incl. computed [bracket] keys) to one column; lone/broken runs untouched.
  • check flags + --fix aligns the = of a single-keyword comma-block (a lone keyword line + ≥ 2 indented name = value continuations) to one column. Separate consecutive declarations and bare assignments are NOT grouped; a block-opening ({/(/[) value is excluded.
  • No false positives: nested objects re-group per indent; non-conforming/blank lines break the run; colons/= inside string or value content are ignored.
  • --fix is idempotent (a second run changes nothing).
  • Unit specs per pattern (misaligned → flagged; --fix → aligned + idempotent; lone / nested / broken → skipped; separate-declarations-NOT-grouped; computed-key / block-opening regression guards), constructed WITHOUT hand-aligned fixtures (derive the aligned form via --fix, mirroring v1's spec discipline).
  • Running --fix on #13553's changed files yields a fully-aligned result (imports via v1, objects/= via v1b).

Out of Scope

  • A whole-codebase re-alignment sweep (the lint runs on changed files; a one-time sweep is separate/optional — note: validation found widespread pre-existing over-padding, so a sweep is a likely follow-up).
  • Internal alignment of multi-line property values (only the top-level key-colon / declaration-= column).
  • Aligning = across separate consecutive declarations or bare assignments (only the single-keyword comma-block is the alignment unit — see Scope Refinement).

Avoided Traps

  • Prettier / ESLint — Prettier STRIPS alignment by design (would obliterate the house style); ESLint key-spacing{align} covers object-colons but not the =-block / import patterns and isn't wired. The Neo-native check is deliberate (per #13556).
  • Aligning across blank lines / indent changes — would merge unrelated blocks; group strictly by contiguous same-indent runs.
  • Force-grouping separate declarations — over-aligns unrelated statements (caught in validation); scope = to the comma-block only.

Related

  • Parent concept: #13556 (v1 lint, closed by #13558). v1: #13558 (merged). Consumer / reformat target: #13553 (embed-drain watchdog — operator-directed full reformat).
  • House-style SoT: .github/CODING_GUIDELINES.md (rules 2, 35).

Release classification

post-release (dev-experience / Agent-OS formatting hardening). Boardless.

Origin Session ID

64ee317e-53b6-4f76-8241-f4eade1c084d

Handoff Retrieval Hints

  • query_raw_memories: "block-alignment lint v1b object colon = declaration alignment"
  • Builds on buildScripts/util/check-block-alignment.mjs (v1, #13558).