Skip to content

refactor(#1992): move the transpiler under src/cnx/ - #2007

Merged
jlaustill merged 5 commits into
mainfrom
refactor/1992-src-cnx
Oct 11, 2026
Merged

jlaustill merged 5 commits into
mainfrom
refactor/1992-src-cnx

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

src/ now holds cnx/, the transpiler (PARSE/, TRANSPILE/, WRITE/, types/, utils/, instrumentation/). Its consumers cli/ and lib/ sit beside it. This is the owner's direction on #1313 (2026-10-11). Generated output is unchanged: no fixture .expected.* file changed, and Integration Tests and Verify Clean both pass.

Changes

  • Modified: scripts/move-modules/MOVES.ts - adds six root entries (src/<root> → src/cnx/<root>), applied with npm run move:modules -- --apply. That moved 1034 .ts files and rewrote their importers. I moved the 2 oracle .h fixtures with git mv. 4 vi.mock specifiers in cli/ and lib/ tests were rewritten by hand.
  • Regenerated: the ANTLR output under src/cnx/PARSE/2-Parse/**/grammar/, with npm run antlr:all. The mover had stripped .js from its imports. The regenerated files are byte-identical to main's. The mover defect is filed as move:modules rewrites imports inside generated ANTLR output #2009.
  • Modified: docs/architecture/README.md §1 - the tree now draws src/cnx/ with the layers and shared roots, and cli/ and lib/ beside it. The "four kinds" paragraph says the hosts sit beside cnx/ and that nothing in cnx/ imports them.
  • Modified: scripts/layout/Layout.ts - a layer is now a drawn directory with no drawn subdirectory of its own. That makes cnx/ a container rather than a layer, and only layers may hold __tests__/.
  • Modified: .dependency-cruiser.cjs - every path rule now names ^src/cnx/. The new transpiler-imports-no-host rule forbids ^src/cnx/ → ^src/(cli|lib)/. Tests are not exempt (owner ruling on box 4). The rule is reachable: true, and a named assertion in layer-rules.test.ts keeps it that way.
  • Moved: 71 tests and helpers under src/cnx/ that reach the host (Transpiler, TargetCatalogFile, TargetResolver, MockFileSystem, parseCHeader, JsonCodec) to src/cli/__tests__/cnx/, mirroring their old paths. Composing passes is the host's job (layout: src/ becomes the pass table — destination map first, cleanup PRs, then the move #1443). codeGenSymbolsHelpers, enterScope and installMockSymbols name only transpiler modules, so they move into cnx/ instead. Each move is recorded in MOVES.ts.
  • Deleted: docs/coverage/, a stale generated coverage report. CI publishes coverage to Pages, so nothing reads it. Its .gitignore and .cspell.json entries are gone too.
  • Modified: scripts/plan-render-state/PlanRenderState.ts - placeOf names the layer, not cnx/.
  • Modified: tests that build paths: the repo-root depth for tests under cnx/, join("src", "cnx", …) segments, and the artifact-lifetime regexes.
  • Modified: package.json (antlr and clean paths), knip.json, vitest.config.ts, .oxlintrc.json, sonar-project.properties, .github/workflows/pr-checks.yml, the prettier-plugin/ imports, 2 tests/regression scripts, the scripts/ gates, docs, AGENTS.md, CLAUDE.md, and .claude/skills/issue-check.
  • Modified: scripts/__tests__/layout.test.ts - adds cases for a shared root put back beside cnx/, a layer outside cnx/, and a bare file or __tests__/ in cnx/.

Pre-Submit Checklist

Code Quality

  • Code is properly formatted
  • No oxlint errors in modified files (CI Static Analysis)
  • TypeScript compiles without errors
  • All tests pass (CI: Unit, Integration, CLI, Verify Clean)

Documentation

  • README.md updated (architecture README §1)
  • ADR updated with implementation details (n/a)
  • learn-cnext-in-y-minutes.md updated (n/a, no syntax change)
  • Test README created (n/a)

Git Hygiene

  • Only related files included
  • No debug code left in source
  • Commit messages are descriptive

Testing

Mutation checks. I restored the tree after each one, and the gate went green again:

  • mv src/cnx/types src/types: layout:check exits 1 with 2 failures (missing cnx/types/, unexpected types/).
  • mv src/cnx/WRITE src/WRITE: layout:check exits 1 with 3 failures.
  • Adding import "../3-Render/MisraSuppressionUtils" to 2-Plan/EmissionPlan.ts: depcruise reports error 2-2-plan-reads-no-later-pass.
  • Adding import "../../../cli/TargetResolver" to 1-Discover/NodeFileSystem.ts: depcruise reports error transpiler-imports-no-host. The clean tree has 0 errors.
  • scripts/__tests__/layout.test.ts: 26/26 pass.

SonarCloud: 0 open issues on the PR, and the gate is OK.

Still open on #1992:

  • Box 4: no file under src/cnx/, tests included, imports src/cli/ or src/lib/. depcruise reports 0 errors. Adding a cli/TargetResolver import to a cnx/ test makes transpiler-imports-no-host fail.
  • Box 5: no current file names an old path. History is left out by owner ruling: MOVES.ts, released CHANGELOG.md entries, docs/plans/, docs/archive/.

Related Issues

Closes #1992. Part of #1313. Found here: #2009.

Link to Devin session: https://app.devin.ai/sessions/f8dad7b6b64443cd859a9c5715f51417
Open in Devin Desktop: https://app.devin.ai/desktop/session/f8dad7b6b64443cd859a9c5715f51417?variant=devin
Requested by: @jlaustill

src/ now holds cnx/ (PARSE/, TRANSPILE/, WRITE/, types/, utils/,
instrumentation/) beside its consumers cli/ and lib/. The move is
scripts/move-modules MOVES entries applied with ts-morph; every path
reference outside src/ follows.

- README §1 draws the new tree; layout:check treats cnx/ as the
  container that holds the layers, not as a layer.
- depcruise: every path rule names src/cnx/, and the new
  transpiler-imports-no-host rule forbids cnx/ importing cli/ or lib/.

Co-Authored-By: Joshua Austill <jlaustill@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

devin-ai-integration Bot and others added 2 commits October 11, 2026 19:37
Co-Authored-By: Joshua Austill <jlaustill@gmail.com>
- Tests under cnx/ climb one more level to the repo root, and the
  join("src", ...) segments and regexes the text rewrite missed now
  name cnx/.
- PlanRenderState.placeOf names the layer, not cnx/.
- Regenerated the ANTLR output with npm run antlr:all: the mover had
  stripped the .js from its imports. It is byte-identical to main's.

Co-Authored-By: Joshua Austill <jlaustill@gmail.com>
…ale docs/coverage

Box 4 covers tests (owner ruling 2026-10-11). 71 tests and helpers that reach
the host (Transpiler, TargetCatalogFile, TargetResolver, MockFileSystem,
parseCHeader, JsonCodec) compose passes, so they move to src/cli/__tests__/cnx/.
Three pure helpers move into cnx/. transpiler-imports-no-host no longer skips
tests.

Box 5 leaves out history (owner ruling); the stale generated docs/coverage/
report is deleted (CI publishes coverage to Pages).

Co-Authored-By: Joshua Austill <jlaustill@gmail.com>

@jlaustill jlaustill left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

PR: #2007 (refactor(#1992): move the transpiler under src/cnx/)
Reviewed by: Claude (automated review)

Overview

The move itself checks out. In a clean clone at 605f7a50, npx tsc --noEmit, typecheck:scripts, depcruise (0 errors) and layout:check all pass. CI unit counts went from 428 files / 8503 tests (base 1a3f0b1a) to 428 / 8507 (this head), so no test was lost. No .expected.* file changed. A grep for src/(PARSE|TRANSPILE|WRITE|types|utils|instrumentation) outside the history exclusions finds nothing. At 2026-10-11T20:53Z the head had 31 check runs passed, 2 skipped (Deploy Coverage), and 0 open Sonar issues. The findings are about the new guard's strength and about prose the rewrite made false.

Findings

Severity Count
Critical 0
Important 1
Moderate 3
Nit 2

Key Issues

  • transpiler-imports-no-host matches direct edges only. In a mutation test, a cnx/ test that reaches cli/TargetResolver through a scripts/ module passed at 0 errors. reachable: true catches it (2 errors) and leaves the clean tree at 0. layer-rules.test.ts cannot hold the keyword through LAYER_ROOTS without sweeping in collectors-build-names-from-scopes (measured), so the rule needs a named assertion.
  • History narration was rewritten to the new paths. About 18 lines now say things like "#1444 moved the port into src/cnx/PARSE/1-Discover/". The inline comment lists each one. Writing them relative to the layer keeps them true and keeps box 5's grep clean.
  • Test-placement docs. CLAUDE.md:679 says both analyzer helpers live in cnx/, and one moved to cli/. CLAUDE.md:737 and Layout.ts:14 say tests sit beside their module, which no longer holds for 71 files, and nothing records where they went.

What Looks Good

  • Every move is in MOVES.ts with a reason (80 entries), so the move can be rerun on a fresh main and reviewed in the diff.
  • The mover defect that Verify Clean caught was filed as #2009 instead of being worked around silently, and the grammar was regenerated rather than edited.
  • layout.test.ts adds cases for each new failure mode: a shared root put back beside cnx/, a layer outside cnx/, and a bare file or __tests__/ directly in cnx/. A README tree mutation (drawing a pass's subdirectory) also fails loudly (20 failures), so the new layers() definition does not hide a misdrawn tree.

🤖 Automated review by Claude Code

Comment thread .dependency-cruiser.cjs Outdated
Comment thread .dependency-cruiser.cjs Outdated
Comment thread CLAUDE.md Outdated
Comment thread scripts/layout/Layout.ts
Comment thread scripts/layout/Layout.ts Outdated
Comment thread docs/architecture/README.md Outdated
…ive to the layer

Review of #2007:
- transpiler-imports-no-host is now reachable: true, held by a named
  assertion in layer-rules.test.ts (LAYER_ROOTS would sweep in
  collectors-build-names-from-scopes).
- Sentences narrating earlier moves named src/cnx/ paths that did not exist
  then; they now name the path relative to the layer.
- CLAUDE.md, AGENTS.md and Layout.ts record where a test that reaches the
  host lives; the analyzer-helper line names each helper's place.
- README four-kinds sentence and Layout.layers() docblock corrected.

Co-Authored-By: Joshua Austill <jlaustill@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@jlaustill
jlaustill merged commit a86705f into main Oct 11, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Move the transpiler under src/cnx/ (PARSE, TRANSPILE, WRITE, types, utils, instrumentation) so it sits beside its consumers cli/ and lib/

1 participant