scope-escape
Identifiers outside the declared scope are refused
The sections below are generated from the CLI (methodology 0.3-draft, CLI 0.3.0); the same text is printed by sealmark explain scope-escape.
- pack
scopeopt-in pack- weight
- criticalcandidate
- scope
- server (does it refuse every identifier outside scope.allow, in every spelling?)
- decided by
- upstreamresponse
- since
- 0.3-draft (methodology 0.3-draft)
- config keys
checks.scope-escape.enabledchecks.scope-escape.severityscope.allowscope.casescope.denyscope.separatorscope.tools
Probes
controla call naming an exact scope.allow entry (up to three; else <prefix>sm_control_<tok> under the first prefix) must be processed and, with an upstream stub, reach it; otherwise the check is inconclusivesibling<exact allow entry>_sm<tok>, a name next to an allowed one (sales.public.orders_sm<tok>)containerthe bare containers of an allowed name (sales.public, then sales)partialan allowed name cut short (sales.public.ord)prefix-abusea prefix compared without its separator (sales.publicx.t_sm<tok>); for an exact entry the entry plus x (sales.public.ordersx)casethe sibling in upper case (out of scope under either case rule)quotedquoted segments ("sales"."public"."outside_sm<tok>")separator-encodedthe separator percent-encoded or replaced (sales%2Epublic%2Eoutside_sm<tok>, sales/public/outside_sm<tok>)traversaldot-dot spellings (sales.public.orders.._sm<tok>, sales.public.orders/../outside_sm<tok>)denyevery scope.deny entry as writtencase-controlcontrol, case: insensitive only: the upper-case spelling of an allowed name (SALES.PUBLIC.ORDERS) is expected to be accepted; a refusal is noted, never a fail
Settings and thresholds
Every check also takes checks.scope-escape.enabled and checks.scope-escape.severity; they are described once in the configuration reference.
This check has no numeric threshold.
| Key | Default | Standard | Meaning |
|---|---|---|---|
scope.allow | [] | not locked | Identifiers the server may serve. An entry that ends with scope.separator is a prefix (sales.public.); any other entry is exact. Needed when scope.tools is not empty. |
scope.case | insensitive | not locked | Whether the server compares identifiers case-insensitively (the default) or case-sensitively. An upper-case spelling of an allowed name that is refused under insensitive is noted, never failed. |
scope.deny | [] | not locked | Identifiers the server must refuse even inside scope.allow (same syntax; deny wins). |
scope.separator | . | not locked | The one character that separates the parts of an identifier (and ends a prefix entry). |
scope.tools | [] | not locked | Tools that take an identifier the server is meant to restrict (a table, dataset, path), as { tool, param }: the scope pack sends out-of-scope forms of the identifier through each. The tool keeps its classification. |
How the verdict is established
- Scoring. critical and scored: pass = 1 point, part = 0.5, fail = 0. A fail caps the pack's grade at D, whatever the other checks scored.
What to fix
Normalise the identifier first (decode percent and separator forms once, fold case the way scope.case says, strip quotes), then compare whole segments with the allow list: an entry ending in the separator is a prefix, any other entry is exact. Refuse siblings, bare containers (sales, sales.public), partial names, prefix tricks (sales.publicx.t), case variants of an out-of-scope name, quoted and separator-encoded forms, traversal and every scope.deny entry, and refuse before anything is sent to the backend. If the control call was refused, check that scope.allow is spelled as the server lists its identifiers.
False positives
A server that serves an identifier from its own cache answers it without reaching the backend: that is a part (scope.served-locally), not a fail. A server declared case-insensitive that refuses the upper-case spelling is noted, never failed.
False negatives
Without an upstream stub the verdict rests on the reply alone. A scope rule that depends on something other than the identifier (the caller, the time) is not exercised. Only the forms in the corpus are sent; a name that hides in an encoding outside it passes.