feat(compiler): SYN015 — warn on localStorage/sessionStorage access that bypasses the storage capability model (?bs 0.7+)#178
Conversation
…hat bypasses the storage capability model (?bs 0.7+)
localStorage.* and sessionStorage.* accesses are synchronous same-origin
Web Storage operations invisible to botscript's capability model: reads {}
and writes {} labels cover declared resource identifiers, not the Web
Storage API globals. A fn that accesses either store has undeclared
persistent (localStorage) or session-scoped (sessionStorage) state
dependencies that callers cannot observe or audit from the fn header.
Detection: localStorage or sessionStorage ident not preceded by ./?.
(member-of-another-object guard), followed by . or ?. (confirming global
access, not a bare reference). fn/function/function* declarations named
localStorage/sessionStorage are excluded. unsafe {} blocks and unsafe fn
bodies are suppressed.
Wired through: error-codes, MCP explain + server test, AGENTS.md diagnostic
table, README.md explain row, and 21 tests covering both globals, optional
chains, unsafe suppression, version guard, and negative cases.
This closes the gap that multiple previous PRs (SYN016, SYN024) referenced
as (SYN015) without the code existing in the registry.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
✅ Ready to approve
The new diagnostic is implemented consistently with existing SYN checks and is fully wired through registry, MCP explainability, tests, and docs.
Note: this review does not count toward required approvals for merging.
Pull request overview
Adds missing diagnostic SYN015 to the compiler’s structural warning pass so botscript warns (at ?bs 0.7+) when a function body accesses localStorage.* / sessionStorage.*, which bypasses the reads {} / writes {} storage model, and wires the new code through registry/tests/MCP/docs.
Changes:
- Implemented SYN015 detection in
syn-check(with unsafe suppression + exclusions matching the SYN-series patterns). - Registered SYN015 in the compiler error-code registry and MCP “explain” content + known-codes assertions.
- Added a dedicated SYN015 test suite and updated public docs to list the new code.
File summaries
| File | Description |
|---|---|
packages/compiler/src/passes/syn-check.ts |
Adds SYN015 detection for localStorage.* / sessionStorage.* accesses within fn bodies at ?bs 0.7+. |
packages/compiler/src/error-codes.ts |
Registers SYN015 with rule/idiom/rewrite/example text for explain and diagnostics metadata. |
packages/compiler/tests/syn015-check.test.ts |
New tests covering positive/negative cases, optional chaining, unsafe suppression, and version gating. |
packages/compiler/tests/error-codes.test.ts |
Adds SYN015 to the exhaustive allowlist for emitted diagnostics. |
packages/mcp/src/explanations.ts |
Adds long-form SYN015 explanation + example fails/passes pair. |
packages/mcp/tests/server.test.ts |
Adds SYN015 to the MCP server’s KNOWN_CODES assertion list. |
AGENTS.md |
Documents SYN015 in the diagnostic-codes table alongside related SYN checks. |
README.md |
Updates MCP explain tool documentation to include SYN015 in the supported-code list. |
Copilot's findings
- Files reviewed: 8/8 changed files
- Comments generated: 0
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
SYN015to the compiler's syn-check pass: fires whenlocalStorage.*orsessionStorage.*is accessed inside a?bs 0.7+fn bodyreads {}/writes {}labels cover declared resource identifiers, not the Web Storage API.getItem,.setItem,.removeItem,.clear,.length, etc.) on both globals, including optional-chain formslocalStorage?.getItem(); excludesobj.localStorage.*(member on a local), bare references, fn/function/function* declarations namedlocalStorage/sessionStorage, andunsafe {}/unsafe fnbodiesCloses the (SYN015) reference gap
Multiple previous PRs (#162 SYN016, #177 SYN024) referenced
(SYN015)in diagnostic text and AGENTS.md without the code existing. This PR creates the code those references pointed at.Completes the Web Storage trilogy
localStorage/sessionStorage(synchronous, persistent/session-scoped)indexedDB(asynchronous, same-origin database)document.cookie(+ implicit network-side effect)Test plan
localStorage.getItem(),.setItem(),.removeItem(),.clear(),.lengthsessionStorage.getItem(),.setItem()localStorage?.getItem()/sessionStorage?.setItem()obj.localStorage.*, barelocalStorage,fn localStorage()declaration,function localStorage(),function* localStorage()unsafe {}blocks andunsafe fnbodies?bs 0.7🤖 Generated with Claude Code