On this page
The built-in `effects-bypass` check: a compiler-API scanner failing on direct process, filesystem or network calls reachable from a handler.
#typescript/src/checks/effects_bypass
#typescript/src/checks/effects_bypass
The built-in effects-bypass check provider.
It statically analyses the consumer's own sources and fails on any direct process, filesystem-mutation or network call REACHABLE FROM A REGISTERED COMMAND HANDLER (§11).
Additionally -- and this part is TypeScript-specific -- it flags the two accepted Proxy ceilings: a bare truthiness test and an identity comparison against a value the analyser can trace to an effects-handle return. Those two are the only things the runtime seal cannot catch, so lint is the sole line of defence and the check names them explicitly.
ANALYSER: the TypeScript compiler API, a REGULAR dependency -- typescript sits in dependencies, not devDependencies, and there is no optional import and no soft degradation. Concretely it is the compiler's own scanner (createScanner from typescript/unstable/ast). The compiler package at version 7 is the native port: it ships the scanner, the SyntaxKind enum and the AST node predicates, but NO in-process parser -- building a syntax tree there means spawning the native language server against a resolved tsconfig, which a check declared fast and pure must not do.
WHAT THE SCANNER DELIVERS, and what it cannot. Brace depth gives real containment, and token adjacency gives a serviceable function table (function f(...) {}, const f = (...) => {}) plus handler roots (the handler: property of a factory options object, inline or naming a declared function). On top of those the check builds an intra-FILE call graph and follows it transitively from every root, which is what closes the two shapes that escape the narrower "a block that mentions .effects" reading: a handler that never mentions the handle, and a bypass one helper-call away.
The residual gap is recorded as an accepted ceiling in §17 rather than papered over: without a parser there is no import resolution (a helper in ANOTHER FILE is not followed), no scope or shadowing resolution (a name is matched as a name), no method-call resolution (this.helper() and obj.helper() are not followed), and handler roots are recognized only through the literal handler: spelling or an .effects mention. Python and Go, which have real in-process parsers, deliver intra-module reachability; TypeScript delivers intra-file.
#BypassFinding
export interface BypassFindingOne reported bypass.
#scanTokens
export function scanTokens(Scans one tokenized file. A call is a finding when it sits in a scope reachable from a registered command handler (or from an .effects mention).
#scanEffectsBypasses
export function scanEffectsBypasses(root: string): BypassFinding[]Finds direct effect calls and untrappable carrier uses in sources under root. Returns findings in file-then-line order.
#observeAllowlistBreadthWarning
export function observeAllowlistBreadthWarning(binary: string): stringThe observe-allowlist-breadth warning (contract §6.2).
A one-token prefix is a near-blanket exemption for that binary: EVERY invocation of it becomes an observe, which means it really executes under --dry-run, is never written to the would-do log, and is legal inside a read_only command. That may be exactly what the app wants -- the allowlist is a declared, source-visible choice and it authorizes real execution in dry mode -- so this is a warning, not an error.
#consequentialGrantWarning
export function consequentialGrantWarning(The consequential-grant-agreement warning (contract §8.1, §11).
A grant exists so a reviewer reading a preview sees WHY a dangerous step is there (§6.1) -- the same judgement consequential makes. When the grant's kind is one that leaves this process (proc_mutate runs another program, net_mutate changes remote state), the two declarations should almost always agree. They can legitimately disagree, so this is a warning: making it an error would push consumers to declare consequential reflexively to clear a gate, which is exactly the reflex the declaration exists to end.
#effectsBypassProvider
export function effectsBypassProvider(_app: AppImpl): () => CheckSpec[]The built-in provider. Registered whenever the check system turns on, so a consumer that adopts checks at all gets all three lints without a TOML declaration: effects-bypass (error), observe-allowlist-breadth (warn) and consequential-grant-agreement (warn).