fix(db): close round-8 review evasions in writer-coverage assertion
ci/woodpecker/pr/ci Pipeline was successful

- Dressed quoted computed keys (as/satisfies/!) fail closed anywhere: the
  static key survives the dressing but breaks every ['name'] matcher, and
  matcher tolerance cannot span types containing ']' (as Foo['x']), so the
  shape itself is the trigger (with an !(?!=) guard for ordinary
  comparisons).
- Escape-built quoted keys (\u/\x/octal) fail closed: statically
  resolvable, so outside the non-literal computed-member residual.
- Reflect verb indirection fails closed: any Reflect.* call naming a
  write/exec verb in its argument text (Reflect.apply(db.insert, ...),
  Reflect.get(db, 'insert')).
- CODE_SHAPE_REGISTER: enumerated disposition path for the fail-closed
  code-shape rules (template key, dressed/escaped key, apply/call/bind,
  Reflect) — a reviewed legitimate hit is registered, never resolved by
  weakening the shape. Empty today; eval/new Function stays unconditional.
- KNOWN RESIDUALS: test-file/out-of-src modules named as import-graph
  conduit blind spots; TYPE_ANN/DECL_LIST single-line limit documented.
- Controls E93-E102 (dressed/escaped keys at write target, conduit export,
  default export, single-file factory extraction; Reflect.apply/get) plus a
  clean control pinning the !== guard.
This commit is contained in:
fred
2026-08-27 19:02:44 -05:00
parent f9a05bba92
commit f3250e32d7
+180 -46
View File
@@ -82,15 +82,20 @@
* residual is accepted and reviews of DI provider modules carry it.
* - Computed member access with a NON-literal name (obj[verb]()) is not
* statically resolvable; literal computed access (obj['insert']()) is
* flagged, and a computed member — access or call, in any position —
* whose key is a text-only template literal (obj[`insert`](),
* ns[`companies`]) fails closed anywhere — template text never reaches
* the lexer's code output, so such a member is indistinguishable from a
* runtime-constructed one (a template key WITH interpolation is a
* non-literal computed member, above). Invoking a write/exec verb via
* `.apply`/`.call`/`.bind` likewise fails closed anywhere. Constructing
* the member at runtime is adjacent to eval and is expected to be caught
* in review.
* flagged, and the statically-resolvable DISGUISES of a literal key fail
* closed — access or call, in any position: a text-only template-literal
* key (obj[`insert`](), ns[`companies`] — template text never reaches
* the lexer's code output), a quoted key carrying expression dressing
* (`ns['companies' as const]`, `ns['companies'!]`), and a quoted key
* built from string escapes (`\u`/`\x`/octal). (A template key WITH
* interpolation is a non-literal computed member, above.) Invoking a
* write/exec verb via `.apply`/`.call`/`.bind`, or through any
* `Reflect.*` call naming a verb, fails closed the same way. These
* code-shape rules match ordinary syntax over ordinary method names, so
* they carry their own enumerated disposition (CODE_SHAPE_REGISTER,
* empty today): a reviewed legitimate hit is registered, never resolved
* by weakening the shape. Constructing the member at runtime is adjacent
* to eval and is expected to be caught in review.
* - The DB_FACTORY_IMPORTERS enumeration counts the import edges
* hasSymbolImportEdge can see (named import, literal dynamic package
* import with symbol use, namespace member use). Destructuring a factory
@@ -115,6 +120,12 @@
* - The scan perimeter is <root>/<pkg>/src for the three roots; production
* TS outside a src/ directory (e.g. packages/mosaic/framework/**) is not
* scanned (verified free of db/driver/execute references at review time).
* Files excluded from the scan — test files and out-of-src modules — are
* also invisible as import-graph CONDUITS: test files are emitted to
* dist, so a production module could launder a symbol or capability
* through a re-export in one. Importing a test module from production
* code is anomalous and review-visible; the blind spot is accepted as a
* residual, not closed.
*
* The writer allowlist names hierarchy command/repository modules ONLY. It is
* empty today: the hierarchy command family (M4-1b) has not landed, so no
@@ -247,6 +258,20 @@ const DB_FACTORY_IMPORTERS: string[] = [
'packages/storage/src/cli.ts',
'packages/storage/src/migrate-tier.ts',
];
/**
* Enumerated disposition for the fail-closed CODE-SHAPE rules (text-only
* template keys, dressed/escape-built quoted keys, verb
* `.apply`/`.call`/`.bind`, `Reflect.*` verb indirection). Those shapes use
* ordinary syntax over ordinary method names (`query`, `delete`), so a
* legitimate hit is possible — e.g. a non-SQL `.query.bind(this)` on a
* log-shaped service. Such a hit is registered here with a justification,
* reviewed under §5.1, and is never resolved by weakening the shape. Empty
* today: the production tree has zero occurrences of any of these shapes
* (calibrated by the full-tree test). Exemption covers the shape rules ONLY —
* every prong still applies in full. eval/new Function stays unconditional:
* constructed code has no disposition path.
*/
const CODE_SHAPE_REGISTER: string[] = [];
const SCAN_ROOTS = ['apps', 'packages', 'plugins'];
const EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);
@@ -506,7 +531,9 @@ const CALL_OPEN = `\\s*(?:\\?\\.)?\\s*\\(`;
* initializer); DECL_LIST skips prior declarators whose initializers are
* comma-free. Both are approximations of the declarator grammar — exotic
* prior initializers (an array or call containing a comma) fall to the
* value-flow residual.
* value-flow residual. Both are also SINGLE-LINE shapes: a multiline type
* annotation (prettier keeps one only past the print width) falls to the
* value-flow residual too.
*/
const TYPE_ANN = `(?:\\s*:\\s*(?:[^=;\\n]|=>)*?)?`;
const DECL_LIST = `(?:[\\w$]+${TYPE_ANN}\\s*=\\s*[^,;\\n]*,\\s*)*`;
@@ -987,42 +1014,93 @@ function analyzeFile(f: FileFacts, ctx: AnalysisCtx): Violation[] {
) {
violations.push({ file: rel, prong: 'code-construction', detail: 'eval/new Function' });
}
// A computed member — access or call — whose key is a text-only template
// literal is invisible to every member and verb matcher (the lexer routes
// template text to spans, so the key survives in code as two ADJACENT
// backticks — the discriminator against backticks inside quoted-string
// prose, whose text stays in code, and against interpolated keys, whose
// `${…}` expression stays in code between the backticks). Runtime code
// construction's sibling: fail-closed anywhere, in any position (write
// target, export expression, receiver, call). A template key WITH
// interpolation is a non-literal computed member (documented residual
// above).
if (new RegExp(`\\[\\s*\`\`\\s*\\]`).test(code)) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'template-literal computed member',
});
}
// Invoking a write/exec verb through Function.prototype indirection
// (`db.insert.apply(db, [companies])`, `d.execute.call(d, s)`,
// `db.insert.bind(db)`) hides the argument shape from every verb matcher
// while both member names stay statically visible — unlike the
// method-EXTRACTION residual, where the verb never appears as a member.
// Fail-closed anywhere: no legitimate site invokes a builder verb this way
// (calibrated clean over the production tree).
if (
new RegExp(
`(?:${DOT}(?:insert|update|delete|execute|query|unsafe|raw)\\b|` +
`\\[\\s*['"](?:insert|update|delete|execute|query|unsafe|raw)['"]\\s*\\])` +
`${DOT}(?:apply|call|bind)${CALL_OPEN}`,
).test(code)
) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'verb apply/call/bind indirection',
});
// Fail-closed CODE-SHAPE rules: statically-resolvable disguises of a
// literal member key or verb invocation. They match ordinary syntax, so a
// reviewed legitimate hit is dispositioned through CODE_SHAPE_REGISTER —
// the shapes themselves are never weakened.
if (!CODE_SHAPE_REGISTER.includes(rel)) {
// A computed member — access or call — whose key is a text-only template
// literal is invisible to every member and verb matcher (the lexer routes
// template text to spans, so the key survives in code as two ADJACENT
// backticks — the discriminator against backticks inside quoted-string
// prose, whose text stays in code, and against interpolated keys, whose
// `${…}` expression stays in code between the backticks). Runtime code
// construction's sibling: fail-closed in any position (write target,
// export expression, receiver, call). A template key WITH interpolation
// is a non-literal computed member (documented residual above).
if (new RegExp(`\\[\\s*\`\`\\s*\\]`).test(code)) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'template-literal computed member',
});
}
// A quoted computed key carrying expression dressing
// (`ns['companies' as const]`, `ns['companies' satisfies 'companies']`,
// `ns['companies'!]`) keeps its static value while breaking every
// `['name']` matcher — the bracket alternatives require the closing
// quote to touch the `]`. Tolerance inside the matchers cannot span the
// class (the dressing's type text may itself contain a `]`, e.g.
// `as Foo['x']`), so the SHAPE fails closed: a quote-close followed by
// `!`/`as`/`satisfies` inside a bracket. The `!(?!=)` guard keeps
// ordinary comparisons (`o['k'] !== x` — dressing AFTER the bracket)
// clean.
if (
new RegExp(`\\[\\s*(['"])(?:(?!\\1)[^\\n])*\\1\\s*(?:!(?!=)|as\\s|satisfies\\s)`).test(code)
) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'dressed computed-member key',
});
}
// A quoted key built from string escapes (a `\` + `u`/`x`/octal-digit
// sequence whose decoded text is a plain identifier, e.g. a key spelling
// `companies` with its first letter unicode-escaped) stays invisible to
// every `\w+`-keyed matcher. The key IS statically
// resolvable, so it is not under the non-literal residual: any bracketed
// quoted key containing an identifier-capable escape fails closed.
if (new RegExp(`\\[\\s*(['"])[^'"\\n]*\\\\[ux0-7][^'"\\n]*\\1\\s*\\]`).test(code)) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'escape-built computed-member key',
});
}
// Invoking a write/exec verb through Function.prototype indirection
// (`db.insert.apply(db, [companies])`, `d.execute.call(d, s)`,
// `db.insert.bind(db)`) hides the argument shape from every verb matcher
// while both member names stay statically visible — unlike the
// method-EXTRACTION residual, where the verb never appears as a member.
if (
new RegExp(
`(?:${DOT}(?:insert|update|delete|execute|query|unsafe|raw)\\b|` +
`\\[\\s*['"](?:insert|update|delete|execute|query|unsafe|raw)['"]\\s*\\])` +
`${DOT}(?:apply|call|bind)${CALL_OPEN}`,
).test(code)
) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'verb apply/call/bind indirection',
});
}
// `Reflect` reaches the same members without member syntax:
// `Reflect.apply(db.insert, db, [companies])`, `Reflect.get(db,
// 'insert')`, `Reflect.getOwnPropertyDescriptor(db, 'execute')`. Any
// Reflect call whose argument text (up to the first `)`) names a verb
// fails closed — the tree has zero Reflect call sites (measured).
if (
new RegExp(
`\\bReflect${DOT}[\\w$]+${CALL_OPEN}[^)\\n]*\\b(?:insert|update|delete|execute|query|unsafe|raw)\\b`,
).test(code)
) {
violations.push({
file: rel,
prong: 'code-construction',
detail: 'Reflect verb indirection',
});
}
}
// Dynamic import whose specifier is not a single string literal: the
// import graph becomes unanalyzable. Checked per call site, so a literal
@@ -2032,6 +2110,58 @@ describe('hierarchy writer coverage (contract 1 §6.3b)', () => {
name: 'E92 template-keyed receiver verb in capability-free file',
src: `export class R { constructor(private pool: { execute(s: string): Promise<unknown> }) {}\n async f(t: string) { await this.pool[\`execute\`].apply(this.pool, ['TRUNCATE ' + t]); } }`,
},
{
name: 'E93 as-dressed computed key as write target',
src: `import * as ns from '@mosaicstack/db';\nimport { db } from './x.js';\nexport async function f() { await db.insert(ns['companies' as const]).values({}); }`,
},
{
name: 'E94 satisfies-dressed computed key as write target',
src: `import * as ns from '@mosaicstack/db';\nimport { db } from './x.js';\nexport async function f() { await db.insert(ns['companies' satisfies 'companies']).values({}); }`,
},
{
name: 'E95 non-null-dressed computed key as write target',
src: `import * as ns from '@mosaicstack/db';\nimport { db } from './x.js';\nexport async function f() { await db.insert(ns['companies'!]).values({}); }`,
},
{
name: 'E96 escape-built computed key as write target',
src: `import * as ns from '@mosaicstack/db';\nimport { db } from './x.js';\nexport async function f() { await db.insert(ns['\\u0063ompanies']).values({}); }`,
},
{
name: 'E97 dressed computed key in schema conduit export',
src: `import { co } from './evasion-mid41.js';\nimport { db } from './x.js';\nexport async function f() { await db.insert(co).values({}); }`,
extras: [
{
rel: 'packages/db/src/evasion-mid41.ts',
src: `import * as ns from '@mosaicstack/db';\nexport const co = ns['companies' as const];`,
},
],
},
{
name: 'E98 dressed computed key in schema default export',
src: `import c from './evasion-mid42.js';\nimport { db } from './x.js';\nexport async function f() { await db.insert(c).values({}); }`,
extras: [
{
rel: 'packages/db/src/evasion-mid42.ts',
src: `import * as ns from '@mosaicstack/db';\nexport default ns['companies' as const];`,
},
],
},
{
name: 'E99 dressed computed key in single-file factory extraction',
src: `import * as ns from '@mosaicstack/db';\nexport async function f(t: string) { const mk = ns['createDb' as const]; const d = mk('u'); await d.execute('DELETE FROM ' + t); }`,
},
{
name: 'E100 Reflect.apply of a write verb',
src: `import { companies } from '@mosaicstack/db';\nimport { db } from './x.js';\nexport async function f() { await Reflect.apply(db.insert, db, [companies]); }`,
},
{
name: 'E101 Reflect.apply of an execution verb in capability-free file',
src: `export class R { constructor(private pool: { execute(s: string): Promise<unknown> }) {}\n async f(t: string) { await Reflect.apply(this.pool.execute, this.pool, ['TRUNCATE ' + t]); } }`,
},
{
name: 'E102 Reflect.get extraction of an execution verb',
src: `import { db } from './x.js';\nexport async function f(t: string) { const fn = Reflect.get(db, 'execute') as (s: string) => Promise<unknown>; await fn.call(db, 'DELETE FROM ' + t); }`,
},
];
const CLEAN_CONTROLS: Array<{ name: string; src: string }> = [
{
@@ -2046,6 +2176,10 @@ describe('hierarchy writer coverage (contract 1 §6.3b)', () => {
name: 'clean: interpolated template key is a non-literal computed member, not a text-only key',
src: `export function g(o: Record<string, () => void>, k: string) { o[\`\${k}\`](); }`,
},
{
name: 'clean: strict-inequality after a bracket member is not key dressing',
src: `export function h(o: Record<string, string>) { return o['kind'] !== 'x'; }`,
},
];
it('analyzer flags every known evasion form', () => {