Skip to content

feat: reads/writes transitivity enforcement — DEP001/DEP002 (?bs 0.9)#60

Merged
marcelofarias merged 2 commits into
mainfrom
botkowski/dep-check-0.9
May 18, 2026
Merged

feat: reads/writes transitivity enforcement — DEP001/DEP002 (?bs 0.9)#60
marcelofarias merged 2 commits into
mainfrom
botkowski/dep-check-0.9

Conversation

@marcelofarias
Copy link
Copy Markdown
Owner

Summary

  • Implements passDepCheck — the ?bs 0.9 transitivity check for reads { } / writes { } annotations that was promised in STDLIB.bs and CHANGELOG since ?bs 0.8 landed.
  • If fn A calls fn B (same file) and B declares reads { x } or writes { x }, A must also declare the same label. The rule applies transitively to any call depth.
  • DEP001: reads under-declared. DEP002: writes under-declared. Over-declaration is always allowed.

What changed

File Change
packages/compiler/src/passes/dep-check.ts New pass (fixed-point transitive closure over same-file call graph)
packages/compiler/src/error-codes.ts DEP001 + DEP002 entries
packages/compiler/src/passes/version.ts ?bs 0.9 added to SUPPORTED_VERSIONS
packages/compiler/src/transform.ts passDepCheck registered at minVersion: "0.9"
packages/mcp/src/explanations.ts DEP001 + DEP002 explanations
packages/compiler/tests/dep-check.test.ts 25 new tests

Test plan

  • pnpm -r build — clean
  • pnpm test — 537/537 pass
  • Direct/transitive reads + writes cases covered
  • Mixed reads+writes, recursion, over-declaration, version gate (pre-0.9 not affected)

🤖 Generated with Claude Code

Implements the resource dependency check promised in STDLIB.bs and
CHANGELOG since the 0.8 metadata-only reads/writes landed. From ?bs 0.9,
if fn A calls fn B (same file) and B declares reads { x } or writes { x },
A must also declare the same labels. The rule is transitive: multi-hop call
chains are covered.

- New pass: packages/compiler/src/passes/dep-check.ts (passDepCheck)
- New codes: DEP001 (reads under-declared) / DEP002 (writes under-declared)
  added to error-codes.ts
- ?bs 0.9 added to SUPPORTED_VERSIONS
- passDepCheck registered in transform pipeline at minVersion "0.9"
- MCP explanations for DEP001/DEP002 in explanations.ts
- 25 new tests in dep-check.test.ts; all 537 tests pass

Closes: no specific issue — fulfills the CHANGELOG/STDLIB.bs promise

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements the ?bs 0.9 transitivity enforcement for reads { } / writes { } annotations, mirroring the existing capability transitivity check. A new passDepCheck pass builds a same-file call graph, propagates declared resource labels through a fixed-point closure, and reports under-declarations as DEP001 (reads) or DEP002 (writes). The pass is gated on ?bs 0.9, which is added to SUPPORTED_VERSIONS.

Changes:

  • New dep-check pass with transitive closure over same-file callees (skipping nested fns, property accesses, and non-calls), registered in the pipeline at minVersion: "0.9".
  • New error codes DEP001/DEP002 plus MCP explanations and 25 new tests covering direct/transitive/mixed/recursive/version-gated cases.
  • ?bs 0.9 added to SUPPORTED_VERSIONS and a CHANGELOG entry documenting the new behaviour.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/compiler/src/passes/dep-check.ts New pass implementing the reads/writes transitivity fixed-point with structured diagnostics.
packages/compiler/src/error-codes.ts Adds DEP001/DEP002 entries (rule/idiom/rewrite/example).
packages/compiler/src/passes/version.ts Adds "0.9" to SUPPORTED_VERSIONS.
packages/compiler/src/transform.ts Registers passDepCheck in the pipeline gated on 0.9.
packages/mcp/src/explanations.ts Adds user-facing explanations for DEP001/DEP002.
packages/mcp/tests/server.test.ts Adds DEP001/DEP002 to the known-codes assertion list.
packages/compiler/tests/dep-check.test.ts 25 tests covering direct/transitive/mixed/recursion/version-gating.
CHANGELOG.md New ?bs 0.9 — unreleased section describing DEP001/DEP002.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +374 to +384
function locationOf(src: string, offset: number): { line: number; column: number } {
let line = 1;
let lineStart = 0;
for (let k = 0; k < offset && k < src.length; k++) {
if (src[k] === "\n") {
line++;
lineStart = k + 1;
}
}
return { line, column: offset - lineStart + 1 };
}
Removes the duplicate helper at the bottom of dep-check.ts and imports
from the shared _location.ts utility, consistent with every other pass
in the codebase (cap-check, intent-check, fn, bare-as, result-try,
unsafe, version).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

@marcelofarias marcelofarias merged commit 6affa21 into main May 18, 2026
6 checks passed
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.

2 participants