Skip to content

feat(ci): enforce coding standards and architecture boundaries - #59

Merged
yohnark merged 5 commits into
mainfrom
feat/25-coding-standards
Aug 7, 2026
Merged

yohnark merged 5 commits into
mainfrom
feat/25-coding-standards

Conversation

@yohnark

@yohnark yohnark commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Introduce repository-wide coding standards and automated architecture-boundary checks for TypeScript source, local MCP tools, process-facing code, and workflow workers.

Linked issue

Closes #25

Scope

Establish deterministic formatting, linting, and architecture validation in local development and CI without changing runtime request behavior.

Included

  • Pin Prettier 3.6.2, ESLint 9.29.0, and typescript-eslint 8.35.0.
  • Add shared Prettier and ESLint configuration plus package scripts.
  • Add an AST-based architecture checker covering import resolution, layer direction, runtime cycles, stdout, import-time execution, process boundaries, TypeScript escape hatches, and local-tool contracts.
  • Treat the existing task-start worker and workflow bootstrap environment as explicit, tested boundaries.
  • Add focused architecture-check fixtures and tests.
  • Add compression transformation and preservation coverage required for the touched compression module.
  • Add a dedicated standards job to CI.
  • Document the coding standards, architecture rules, exceptions, and validation commands.

Excluded

  • No broad mechanical reformat of the existing source tree; format checking is scoped to the new standards tooling and package metadata.
  • No runtime feature or behavior refactor.

Implementation

The checker uses the TypeScript compiler API with NodeNext resolution and reports deterministic rule IDs, file paths, line numbers, detected constructs, and fixes. Existing intentional boundaries are represented by explicit, reasoned suppression markers or narrowly scoped allowlists. The task worker remains a process entry point because it must consume argv and emit one JSON result on stdout for the concurrency test.

Behavioral changes

CI now rejects formatting drift, lint violations, invalid architecture imports, unsafe process/output boundaries, and malformed local-tool definitions. Runtime request routing and upstream behavior remain unchanged.

Validation

  • Typecheck (pnpm run typecheck)
  • Tests (pnpm test: 651/651; pnpm run architecture:test: 8/8)
  • Build (pnpm run build)
  • Package check (npm pack --dry-run)
  • Standards (pnpm run verify:standards)
  • Governance (pnpm run governance:test: 18/18)
  • Diff check (git diff --check)
  • Compression transformation and preservation cases covered by src/compress/code.test.ts.

Risks

  • Formatting enforcement intentionally excludes the legacy source tree to avoid a large mechanical diff; future changes outside the scoped files remain subject to the checker as the scope expands.
  • Architecture exceptions are explicit and reviewed through marker text or allowlists; adding an exception can weaken enforcement if its reason is not justified.

Breaking changes

No. Runtime API and request behavior remain unchanged.

Review focus

  • AST import/runtime graph and layer-direction rules.
  • Workflow worker, process, stdout, environment, and signal boundary detection.
  • Local-tool schema, output-envelope, and annotation checks.
  • Compression transformation/preservation test scope.
  • CI job scope and the documented exception policy.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b2ad0650-ce73-49bf-b98d-4b51d6cb7ba4

📥 Commits

Reviewing files that changed from the base of the PR and between 96e6a16 and 1ad1c8b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • AGENTS.md
  • docs/coding-standards.md
  • package.json
  • scripts/architecture-check.mjs
  • scripts/architecture-check.test.mjs
  • scripts/fixtures/architecture/accepted-double-assertion.ts
  • scripts/fixtures/architecture/accepted-local-tool.ts
  • scripts/fixtures/architecture/rejected-local-tool-inline-schema.ts
  • src/adaptive/trace.ts
  • src/compress/code.ts
🚧 Files skipped from review as they are similar to previous changes (9)
  • package.json
  • src/compress/code.ts
  • scripts/architecture-check.test.mjs
  • docs/coding-standards.md
  • scripts/fixtures/architecture/accepted-local-tool.ts
  • scripts/architecture-check.mjs
  • scripts/fixtures/architecture/accepted-double-assertion.ts
  • AGENTS.md
  • src/adaptive/trace.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added automated formatting, linting, architecture, and standards validation in continuous integration.
    • Added consistent formatting and linting configurations.
    • Added architecture checks for dependency boundaries, runtime behavior, and project conventions.
  • Documentation

    • Added project-wide coding standards and contribution guidance.
    • Clarified required verification steps and which standards are automatically enforced.
  • Tests

    • Expanded architecture validation coverage.
    • Added coverage confirming unsupported code fences remain unchanged.

Walkthrough

The PR adds Prettier and ESLint configuration, package verification scripts, a custom architecture validator, rule fixtures and tests, a Node 22 CI standards job, coding-standard documentation, and scoped annotations for existing exceptions.

Changes

Standards validation

Layer / File(s) Summary
Formatting, lint, and verification tooling
prettier.config.mjs, eslint.config.mjs, package.json, docs/coding-standards.md, CONTRIBUTING.md, AGENTS.md
Adds executable formatting, lint, architecture, and standards checks with documented automated and human-only rules.
Architecture validator implementation
scripts/architecture-check.mjs
Adds source parsing, boundary checks, type-safety checks, local-tool validation, import-graph validation, diagnostics, and a CLI runner.
Architecture rule tests and fixtures
scripts/architecture-check.test.mjs, scripts/fixtures/architecture/*
Adds accepted and rejected fixtures and tests for boundaries, exceptions, dependency direction, import-time execution, process access, and tool contracts.
CI wiring and source compliance
.github/workflows/ci.yml, src/adaptive/trace.ts, src/compress/code.ts, src/compress/code.test.ts
Runs standards checks in CI, annotates existing allowed exceptions, and adds unsupported-language compression coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions
  participant Scripts as package.json scripts
  participant Validator as architecture-check.mjs
  participant Tests as architecture-check.test.mjs
  CI->>Scripts: run standards verification
  Scripts->>Validator: execute architecture check
  Scripts->>Tests: execute architecture tests
  Validator-->>CI: return diagnostics and exit status
  Tests-->>CI: return test status
Loading

Possibly related issues

Possibly related PRs

  • yohn-jp/mottainai#1 — Adds foundation code that this PR validates with architecture checks.
  • yohn-jp/mottainai#5 — Shares the CI, contributor-guidance, and package-configuration areas extended by this PR.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The changes address the issue requirements, but pinned dependency resolution cannot be verified because pnpm-lock.yaml was excluded. Review pnpm-lock.yaml to confirm the pinned tools resolve under the supported pnpm and Node 22/24 environments.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: CI enforcement of coding standards and architecture boundaries.
Description check ✅ Passed The description directly explains the standards, architecture checks, CI changes, documentation, tests, scope, and validation.
Out of Scope Changes check ✅ Passed The changes remain within the linked issue scope and support standards enforcement, architecture validation, documentation, fixtures, tests, and CI.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/25-coding-standards

Comment @coderabbitai help to get the list of available commands.

@yohnark
yohnark force-pushed the feat/25-coding-standards branch from 3d8cb0b to 4d519a3 Compare August 7, 2026 13:15
@yohnark

yohnark commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

yohnark added a commit that referenced this pull request Aug 7, 2026
startTask now rejects task starts where the local base branch trails
origin/<branch> when policy.worktree.staleBaseBranch=enforce, preventing
CI from seeing files the local branch point never saw (root cause behind
PR #59's post-merge boundary gaps).

Also adds governance:pr:local, a CLI wrapper around the existing
validatePullRequest that lets PR title/body/files be checked locally
before gh pr create, instead of only after CI runs validate-pr.mjs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (6)
scripts/architecture-check.mjs (4)

279-289: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

processAccess misses indirect process access.

The function only matches a direct process.<name> access. const { env } = process, const p = process; p.env, and globalThis.process.env bypass the boundary rules. The rule is still useful, but the gap should be documented or covered, because the boundary allowlist is presented as executable enforcement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/architecture-check.mjs` around lines 279 - 289, Update processAccess
to recognize indirect process references such as destructuring, aliases, and
globalThis.process accesses, or explicitly document and test these as
unsupported cases. Ensure the boundary allowlist’s executable enforcement
behavior matches the supported access patterns.

723-742: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Tool detection depends on hardcoded declaration names.

checkLocalToolDefinitions only inspects localTools, worktreeNewTool, and issueViewTool. A new tool constant with a different name passes the check silently, so the OUTPUT_SCHEMA and annotation contract is not enforced for it. Detect tool objects structurally instead, for example by the presence of name plus inputSchema, or by a Tool type annotation.

Run the following script to see how many tool definitions the current list misses:

#!/bin/bash
# List top-level const declarations in src/local-tools.ts and their type annotations.
fd -t f 'local-tools.ts' src | while IFS= read -r file; do
  rg -n -C 2 '^(export )?const \w+' "$file"
done
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/architecture-check.mjs` around lines 723 - 742, Update
checkLocalToolDefinitions to identify tool declarations structurally rather than
by the hardcoded localTools, worktreeNewTool, and issueViewTool names. Inspect
top-level object declarations that expose the tool shape, such as name plus
inputSchema, or use a Tool type annotation, and pass each matching object to
checkToolObject while preserving the existing source-file restriction.

122-137: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Start the file walk at src/.

collectFiles walks the whole repository and then drops every path that does not start with src/. Passing path.join(root, "src") as the initial current keeps the same result and avoids scanning unrelated directories.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/architecture-check.mjs` around lines 122 - 137, Update collectFiles
so its initial traversal starts at path.join(root, "src") instead of the
repository root, while preserving the existing recursive collection and
filtering behavior.

835-835: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the dead continue statement.

Line 835 is the last statement of the loop body, so the continue has no effect. The special-edge case is already handled by isDependencyAllowed on line 824.

♻️ Proposed change
-    if (allowedSpecialEdges.has(special)) continue;

Then remove the now-unused special binding on line 823.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/architecture-check.mjs` at line 835, Remove the dead continue
statement guarded by allowedSpecialEdges.has(special) in the loop, then remove
the now-unused special binding from the surrounding dependency-check logic.
Leave isDependencyAllowed and the remaining edge-handling behavior unchanged.
package.json (2)

27-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use double quotes for glob arguments in scripts.

Single quotes are not removed by cmd.exe. On Windows, eslint 'src/**/*.ts' receives the quotes as part of the pattern and matches nothing. The prettier entries pass literal file paths, so they only need quoting removed or converted. Use double quotes for the glob patterns to keep the scripts portable.

♻️ Proposed change
-    "format": "prettier --write 'scripts/architecture-check.mjs' 'scripts/architecture-check.test.mjs' 'eslint.config.mjs' 'prettier.config.mjs' 'package.json'",
-    "format:check": "prettier --check 'scripts/architecture-check.mjs' 'scripts/architecture-check.test.mjs' 'eslint.config.mjs' 'prettier.config.mjs' 'package.json'",
-    "lint": "eslint 'src/**/*.ts' 'src/**/*.mjs' 'scripts/**/*.mjs' 'eslint.config.mjs'",
+    "format": "prettier --write scripts/architecture-check.mjs scripts/architecture-check.test.mjs eslint.config.mjs prettier.config.mjs package.json",
+    "format:check": "prettier --check scripts/architecture-check.mjs scripts/architecture-check.test.mjs eslint.config.mjs prettier.config.mjs package.json",
+    "lint": "eslint \"src/**/*.ts\" \"src/**/*.mjs\" \"scripts/**/*.mjs\" eslint.config.mjs",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 27 - 32, Update the package scripts’ glob
arguments in format:check and lint to use double quotes instead of single quotes
so Windows cmd.exe passes valid patterns; remove or convert quoting for the
literal Prettier file paths in format and format:check as appropriate.

47-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin typescript-eslint to 8.66.0 and update the documented version.

typescript-eslint@8.66.0 supports the project’s TypeScript range. Replace ^8.66.0 with 8.66.0, and change docs/coding-standards.md from 8.35.0 to 8.66.0.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` around lines 47 - 51, Pin the typescript-eslint dependency in
package.json by changing its version from ^8.66.0 to 8.66.0, and update the
documented typescript-eslint version in docs/coding-standards.md from 8.35.0 to
8.66.0.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Around line 220-227: Use one normative documentation source for executable
standards: update AGENTS.md lines 220-227 to either retain the command-and-rule
list as the canonical documentation or replace it with a concise pointer to the
canonical configuration/source; update CONTRIBUTING.md lines 78-80 to preserve
the no-duplication rule and link to that same source. Ensure both documents are
consistent and do not maintain duplicate normative lists.

In `@package.json`:
- Around line 47-51: Pin the typescript-eslint dependency consistently: in
package.json lines 47-51, change the caret range to exact version 8.66.0; in
docs/coding-standards.md lines 23-30, replace the documented 8.35.0 with 8.66.0.

In `@scripts/architecture-check.mjs`:
- Around line 219-258: Update layerForFile in scripts/architecture-check.mjs so
the listed server-related files return the documented server layer instead of
upstream, and update docs/coding-standards.md lines 38-54 to describe the
dependency chain produced by the corrected layer assignments. Keep layerRules
and the documented architecture consistent across both sites.
- Around line 263-277: Update hasRuleMarker to clamp the computed searchToLine
so it never falls below searchFromLine before calling
getPositionOfLineAndCharacter. Preserve the existing boundaryLine and
trailing-line limits while ensuring same-line top-level statements, including
line 1, produce a valid search range instead of throwing.
- Around line 929-931: Update the entry-point check around runArchitectureCheck
to import and use node:url’s fileURLToPath(import.meta.url) instead of new
URL(import.meta.url).pathname, while preserving the existing path.resolve
comparison and process arguments.

In `@scripts/fixtures/architecture/accepted-double-assertion.ts`:
- Around line 1-2: Update the marker comment above value to keep the
“architecture-check allow: double-assertion --” prefix unchanged while
translating only the existing reason into Japanese. Preserve the explanation
that this fixture models a validated native interop boundary, and do not modify
the assertion.

In `@scripts/fixtures/architecture/accepted-local-tool.ts`:
- Around line 1-14: Update scripts/fixtures/architecture/accepted-local-tool.ts,
specifically OUTPUT_SCHEMA, to declare all required named fields from the shared
output envelope in src/envelope.ts. Update scripts/architecture-check.test.mjs
at lines 17-20 to add a local-tool fixture or case using outputSchema: {} and
assert RULE_IDS.localToolSchema is reported.

In `@src/adaptive/trace.ts`:
- Around line 258-263: Translate only the rationale after the machine-readable
“architecture-check allow” marker into Japanese why-comments, without changing
the markers or adding what-comments. Update src/adaptive/trace.ts lines 258-263
for request records, 276-283 for execution records, and 292-312 for review and
dispatch normalization; update src/compress/code.ts lines 31-41 for parser and
native-handle exceptions. Ensure each rationale explains only why the TypeScript
architecture exception is permitted.

---

Nitpick comments:
In `@package.json`:
- Around line 27-32: Update the package scripts’ glob arguments in format:check
and lint to use double quotes instead of single quotes so Windows cmd.exe passes
valid patterns; remove or convert quoting for the literal Prettier file paths in
format and format:check as appropriate.
- Around line 47-51: Pin the typescript-eslint dependency in package.json by
changing its version from ^8.66.0 to 8.66.0, and update the documented
typescript-eslint version in docs/coding-standards.md from 8.35.0 to 8.66.0.

In `@scripts/architecture-check.mjs`:
- Around line 279-289: Update processAccess to recognize indirect process
references such as destructuring, aliases, and globalThis.process accesses, or
explicitly document and test these as unsupported cases. Ensure the boundary
allowlist’s executable enforcement behavior matches the supported access
patterns.
- Around line 723-742: Update checkLocalToolDefinitions to identify tool
declarations structurally rather than by the hardcoded localTools,
worktreeNewTool, and issueViewTool names. Inspect top-level object declarations
that expose the tool shape, such as name plus inputSchema, or use a Tool type
annotation, and pass each matching object to checkToolObject while preserving
the existing source-file restriction.
- Around line 122-137: Update collectFiles so its initial traversal starts at
path.join(root, "src") instead of the repository root, while preserving the
existing recursive collection and filtering behavior.
- Line 835: Remove the dead continue statement guarded by
allowedSpecialEdges.has(special) in the loop, then remove the now-unused special
binding from the surrounding dependency-check logic. Leave isDependencyAllowed
and the remaining edge-handling behavior unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dc175781-e865-42d8-b26c-077070399af6

📥 Commits

Reviewing files that changed from the base of the PR and between a064439 and 96e6a16.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • .github/workflows/ci.yml
  • AGENTS.md
  • CONTRIBUTING.md
  • docs/coding-standards.md
  • eslint.config.mjs
  • package.json
  • prettier.config.mjs
  • scripts/architecture-check.mjs
  • scripts/architecture-check.test.mjs
  • scripts/fixtures/architecture/accepted-boundary.ts
  • scripts/fixtures/architecture/accepted-double-assertion.ts
  • scripts/fixtures/architecture/accepted-local-tool.ts
  • scripts/fixtures/architecture/rejected-boundary.ts
  • scripts/fixtures/architecture/rejected-double-assertion.ts
  • scripts/fixtures/architecture/rejected-local-tool.ts
  • src/adaptive/trace.ts
  • src/compress/code.test.ts
  • src/compress/code.ts

Comment thread AGENTS.md Outdated
Comment on lines +220 to +227
### 実行可能規則(Issue #25)

- `pnpm run format:check` は新規standard tooling(`scripts/architecture-check*`、ESLint/Prettier設定、`package.json`)をPrettier検証。既存production codeの一括整形は別変更。
- `pnpm run lint` はESLintでproduction/test TypeScript、`.mjs`、standard configを検証。broad `any` と理由なしTypeScript suppressionを拒否。
- `pnpm run architecture:test` はvalidatorのaccepted/rejected fixtureを実行。
- `pnpm run architecture:check` はTypeScript ASTとNodeNext module resolutionで、相対runtime import拡張子、未解決import、runtime dependency direction、import-time execution、MCP stdout、process/global boundary、unsafe type escape、local-tool `OUTPUT_SCHEMA`/annotationsを検証。
- `pnpm run verify:standards` は上記4コマンドのcombined check。CIは原因を分離したstepで実行。
- architecture layer map、boundary allowlist、suppression markerの正本は `scripts/architecture-check.mjs`。allow markerには局所理由必須。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use one normative source for executable standards.

AGENTS.md lists executable rules normatively, while CONTRIBUTING.md forbids a second normative list. Keep the configuration files as the implementation source and make the documentation a single consistent pointer.

  • AGENTS.md#L220-L227: Replace the normative command-and-rule list with a concise pointer, or define it as the canonical documentation.
  • CONTRIBUTING.md#L78-L80: Keep the no-duplication rule and link to the selected canonical source.
📍 Affects 2 files
  • AGENTS.md#L220-L227 (this comment)
  • CONTRIBUTING.md#L78-L80
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AGENTS.md` around lines 220 - 227, Use one normative documentation source for
executable standards: update AGENTS.md lines 220-227 to either retain the
command-and-rule list as the canonical documentation or replace it with a
concise pointer to the canonical configuration/source; update CONTRIBUTING.md
lines 78-80 to preserve the no-duplication rule and link to that same source.
Ensure both documents are consistent and do not maintain duplicate normative
lists.

Comment thread package.json Outdated
Comment on lines +219 to +258
function layerForFile(relative) {
if (
relative === "src/index.ts" ||
relative === "src/cli.ts" ||
relative === "src/init.ts" ||
relative.startsWith("src/commands/")
)
return "entry";
if (
relative === "src/server.ts" ||
relative === "src/proxy.ts" ||
relative === "src/local-tools.ts" ||
relative === "src/broker.ts" ||
relative === "src/catalog.ts" ||
relative === "src/code-search.ts" ||
relative === "src/execution.ts"
)
return "upstream";
if (relative === "src/upstream.ts" || relative === "src/upstream-call.ts" || relative === "src/auth.ts")
return "upstream";
if (relative.startsWith("src/adaptive/") || relative.startsWith("src/read-governor/")) return "adaptive";
if (relative.startsWith("src/compress/")) return "compression";
if (relative.startsWith("src/state/") || relative.startsWith("src/workflow/") || relative === "src/retrieve.ts")
return "persistence";
if (
relative === "src/config.ts" ||
relative === "src/envelope.ts" ||
relative === "src/logging.ts" ||
relative === "src/telemetry.ts"
)
return "shared";
if (relative === "src/subprocess.ts") return "utility";
return "shared";
}

export function isDependencyAllowed(sourceLayer, targetLayer, targetPath = "") {
if (sourceLayer === targetLayer) return true;
if (allowedSpecialEdges.has(`${sourceLayer}->${targetLayer}:${targetPath}`)) return true;
return layerRules[sourceLayer]?.has(targetLayer) ?? true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

The documented server layer is unreachable. layerForFile never returns server, so layerRules.server is dead and the documented dependency chain does not describe the enforced behavior.

  • scripts/architecture-check.mjs#L219-L258: return server for src/server.ts, src/proxy.ts, src/local-tools.ts, src/broker.ts, src/catalog.ts, src/code-search.ts, and src/execution.ts, or delete the server entry from layerRules.
  • docs/coding-standards.md#L38-L54: update the chain on line 41 to match the layers that layerForFile actually assigns.
📍 Affects 2 files
  • scripts/architecture-check.mjs#L219-L258 (this comment)
  • docs/coding-standards.md#L38-L54
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/architecture-check.mjs` around lines 219 - 258, Update layerForFile
in scripts/architecture-check.mjs so the listed server-related files return the
documented server layer instead of upstream, and update docs/coding-standards.md
lines 38-54 to describe the dependency chain produced by the corrected layer
assignments. Keep layerRules and the documented architecture consistent across
both sites.

Comment thread scripts/architecture-check.mjs
Comment thread scripts/architecture-check.mjs Outdated
Comment thread scripts/fixtures/architecture/accepted-double-assertion.ts Outdated
Comment thread scripts/fixtures/architecture/accepted-local-tool.ts Outdated
Comment thread src/adaptive/trace.ts Outdated
yohnark added 5 commits August 7, 2026 23:04
typescript-eslint@8.35.0 declares a peer range of typescript <5.9.0,
but the lockfile resolves typescript to 5.9.3 — the lint stack was
running outside its declared support range. 8.66.0 raises the peer
ceiling to <6.1.0.
hasRuleMarker() matched an allow-marker against the whole file's text,
so a single marker for double-assertion or import-time-side-effect
silently suppressed the rule for every other violation anywhere else
in that file — not just the annotated line, contrary to the "local
marker" documentation.

hasRuleMarker() now searches a narrow window around the flagged node
(one leading line, one trailing line bounded by the next sibling
statement) instead of the full source text. This surfaced 9
previously-hidden double-assertion violations in src/adaptive/trace.ts
that were masked by one marker on an unrelated function; each now
carries its own local marker. src/compress/code.ts markers were moved
next to the statements they actually cover.

Added regression tests proving a marker no longer suppresses unrelated
violations elsewhere in the same file.
CI failed because the branch predated main's Repository Semantic IR
addition (PR #58); the new architecture checker flagged its top-level
snapshot()/create*Id() helper calls and TextEncoder as import-time
side effects. Rebased onto main and extended the pure-call/constructor
allowlists to cover these declarative factory patterns.

Also addresses CodeRabbit findings:
- hasRuleMarker no longer throws when two top-level statements share
  one line (clamp searchToLine to searchFromLine)
- entry-point check uses fileURLToPath instead of URL().pathname
- removed the unreachable "server" layer; upstream-facing files keep
  the "upstream" layer that matches their actual dependency direction
- pinned typescript-eslint to an exact version, matching eslint/prettier
- AGENTS.md points to docs/coding-standards.md instead of duplicating
  the executable-rules list (per CONTRIBUTING.md's no-duplication rule)
- translated remaining English marker/rationale comments to Japanese
- strengthened the accepted-local-tool fixture's OUTPUT_SCHEMA to the
  real shared envelope shape and added a rejected-fixture regression
  test for inline (non-shared) output schemas
@yohnark
yohnark force-pushed the feat/25-coding-standards branch from 96e6a16 to 1ad1c8b Compare August 7, 2026 14:13
@yohnark
yohnark merged commit ee59bd1 into main Aug 7, 2026
11 checks passed
@yohnark
yohnark deleted the feat/25-coding-standards branch August 7, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce coding standards and architecture boundaries in CI

1 participant