import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import test from "node:test"; import { extractScriptDocuments, verifyEntries } from "./verify-workspace-descriptor-files.mjs"; const repositoryRoot = fileURLToPath(new URL("../..", import.meta.url)); const canonicalDescriptor = await readFile(join(repositoryRoot, "deploy/workspaces/example.yaml"), "utf8"); async function fixture(t) { const root = await mkdtemp(join(tmpdir(), "thoth-workspace-yaml-verifier-")); t.after(() => rm(root, { recursive: true, force: true })); return root; } async function put(root, path, content) { await mkdir(dirname(join(root, path)), { recursive: true }); await writeFile(join(root, path), content); } function entry(kind, path) { return { kind, path }; } function bashN(root, path) { execFileSync("/bin/bash", ["-n", join(root, path)], { stdio: "pipe" }); } function replaceWorkspaceKeys(source, workspaceKey, schemaLine) { return source .replace(/^workspace:$/m, workspaceKey) .replace(/^ schema_version: 3$/m, schemaLine); } test("production parser accepts semantic v3 with quoted Unicode/tagged keys and spacing", async (t) => { const root = await fixture(t); const unicode = replaceWorkspaceKeys( canonicalDescriptor, '"\\u0077orkspace" :', ' "\\u0073chema_version" : 3', ); const tagged = replaceWorkspaceKeys( canonicalDescriptor, "!!str workspace :", " !!str schema_version : 3", ); await put(root, "deploy/workspaces/unicode.yaml", unicode); await put(root, "deploy/workspaces/tagged.yaml", tagged); await verifyEntries({ root, entries: [ entry("workspace_descriptor", "deploy/workspaces/unicode.yaml"), entry("workspace_descriptor", "deploy/workspaces/tagged.yaml"), ], }); }); test("production parser rejects fancy keys with every non-v3 or ambiguous value", async (t) => { const invalid = [ ["unicode-v2", '"\\u0077orkspace" :', ' "\\u0073chema_version" : 2'], ["tagged-leading-zero", "!!str workspace :", " !!str schema_version : 02"], ["hexadecimal", "workspace :", " schema_version : 0x2"], ["multiline", "workspace :", " schema_version : >\n 3"], ["duplicate", "workspace :", " schema_version : 3\n schema_version: 3"], ["inline", "workspace: { schema_version: 3 }", " schema_version: 3"], ]; for (const [name, workspaceKey, schemaLine] of invalid) { await t.test(name, async () => { const root = await mkdtemp(join(tmpdir(), `thoth-workspace-yaml-${name}-`)); try { const source = replaceWorkspaceKeys(canonicalDescriptor, workspaceKey, schemaLine); const path = `deploy/workspaces/${name}.yaml`; await put(root, path, source); await assert.rejects( verifyEntries({ root, entries: [entry("workspace_descriptor", path)] }), /workspace descriptor/i, ); } finally { await rm(root, { recursive: true, force: true }); } }); } }); test("Bash embedded workspace mappings are rejected while tracked-fixture-only bundles pass", async (t) => { const root = await fixture(t); const validScript = [ "#!/usr/bin/env bash", "cat <<'WORKSPACE_YAML'", canonicalDescriptor.trimEnd(), "WORKSPACE_YAML", "cat <<'BUNDLE_YAML'", "bundle:", " name: deploy", "schema_version: 1", "job:", " state: operational", "BUNDLE_YAML", "", ].join("\n"); await put(root, "scripts/operator-smoke.sh", validScript); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", "scripts/operator-smoke.sh")] }), /embedded workspace descriptor/i, ); const bundleScript = validScript.replace(canonicalDescriptor.trimEnd(), "job:\n name: deploy"); await put(root, "scripts/operator-smoke.sh", bundleScript); await verifyEntries({ root, entries: [entry("deployment_script", "scripts/operator-smoke.sh")], }); }); test("PowerShell embedded workspace mappings are rejected while bundle-only strings pass", async (t) => { const root = await fixture(t); const source = [ "$workspace = @'", canonicalDescriptor.replace(" schema_version: 3", " schema_version: 0x2").trimEnd(), "'@", '$bundle = @"', "bundle:", " schema_version: 1", '"@', "", ].join("\n"); await put(root, "scripts/operator.ps1", source); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", "scripts/operator.ps1")] }), /workspace descriptor/i, ); }); test("workspace descriptor family entries require a top-level workspace", async (t) => { const root = await fixture(t); await put(root, "scripts/fixtures/workspace-registry-future.yaml", "bundle:\n schema_version: 3\n"); await assert.rejects( verifyEntries({ root, entries: [entry("workspace_descriptor", "scripts/fixtures/workspace-registry-future.yaml")], }), /top-level workspace/i, ); }); test("script scalar workspace remains a bundle even with descriptor-like siblings", async (t) => { const root = await fixture(t); const path = "scripts/job-smoke.sh"; const job = [ "#!/usr/bin/env bash", "cat <<'JOB-YAML'", "job: refresh", "workspace: analytics", "schema_version: 2", "state: operational", "JOB-YAML", "", ].join("\n"); await put(root, path, job); bashN(root, path); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); const bundles = [ job.replace("job: refresh", "dwh:\n engine: postgres"), job.replace("job: refresh", "evidence:\n source: bundle"), ]; for (const bundle of bundles) { await put(root, path, bundle); bashN(root, path); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); } }); test("standalone descriptor files require workspace to be a mapping", async (t) => { const root = await fixture(t); const path = "scripts/fixtures/workspace-registry-scalar.yaml"; await put(root, path, "workspace: analytics\nschema_version: 3\n"); await assert.rejects( verifyEntries({ root, entries: [entry("workspace_descriptor", path)] }), /workspace.*mapping/i, ); }); test("Bash extractor supports hyphen, digit, escaped delimiters, and tab stripping", async (t) => { const root = await fixture(t); const cases = [ { name: "hyphen-v2", opener: "cat <<'WORKSPACE-YAML'", delimiter: "WORKSPACE-YAML", descriptor: canonicalDescriptor.replace(" schema_version: 3", " schema_version: 2"), rejected: true, }, { name: "digit-v3", opener: "cat <<2YAML", delimiter: "2YAML", descriptor: canonicalDescriptor, rejected: true, }, { name: "escaped-v2", opener: "cat < `\t${line}`).join("\n"), rejected: true, }, ]; for (const item of cases) { await t.test(item.name, async () => { const path = `scripts/${item.name}-smoke.sh`; const source = ["#!/usr/bin/env bash", item.opener, item.descriptor.trimEnd(), item.delimiter, ""].join("\n"); await put(root, path, source); bashN(root, path); const verification = verifyEntries({ root, entries: [entry("deployment_script", path)] }); if (item.rejected) await assert.rejects(verification, /workspace descriptor/i); else await verification; }); } }); test("unsupported Bash heredoc opener fails closed while a bundle heredoc stays allowed", async (t) => { const root = await fixture(t); const unsupportedPath = "scripts/unsupported-smoke.sh"; const unsupported = [ "#!/usr/bin/env bash", "cat <<$DELIMITER", canonicalDescriptor.trimEnd(), "$DELIMITER", "", ].join("\n"); await put(root, unsupportedPath, unsupported); bashN(root, unsupportedPath); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", unsupportedPath)] }), /unsupported Bash heredoc opener/i, ); const bundlePath = "scripts/bundle-smoke.sh"; const bundle = [ "#!/usr/bin/env bash", "cat <<'BUNDLE-YAML'", "job: refresh", "workspace: analytics", "schema_version: 1", "state: operational", "BUNDLE-YAML", "", ].join("\n"); await put(root, bundlePath, bundle); bashN(root, bundlePath); await verifyEntries({ root, entries: [entry("deployment_script", bundlePath)] }); }); test("non-stripping heredoc close requires an exact physical delimiter line", async (t) => { const root = await fixture(t); const path = "scripts/trailing-close-smoke.sh"; const source = [ "#!/usr/bin/env bash", "cat <<'---'", "--- ", canonicalDescriptor.replace(" schema_version: 3", " schema_version: 2").trimEnd(), "---", "", ].join("\n"); await put(root, path, source); bashN(root, path); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /workspace descriptor/i, ); }); test("delimiter-like body lines remain content until a real exact close", async (t) => { const root = await fixture(t); const path = "scripts/delimiter-content-smoke.sh"; const source = [ "#!/usr/bin/env bash", "cat <<'END'", "END ", " END", "job: refresh", "workspace: analytics", "schema_version: 1", "END", "", ].join("\n"); await put(root, path, source); bashN(root, path); const [candidate] = extractScriptDocuments(source, path); assert.match(candidate.source, /^END \n END\n/u); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("double-quoted non-special backslash is preserved in the delimiter", async (t) => { const root = await fixture(t); const path = "scripts/double-quoted-nonspecial-smoke.sh"; const source = [ "#!/usr/bin/env bash", 'cat <<"\\---"', "---", canonicalDescriptor.replace(" schema_version: 3", " schema_version: 2").trimEnd(), "\\---", "", ].join("\n"); await put(root, path, source); bashN(root, path); assert.match(execFileSync("/bin/bash", [join(root, path)], { encoding: "utf8" }), /schema_version: 2/u); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /workspace descriptor/i, ); }); test("double-quoted delimiter quote removal matches Bash special escapes", async (t) => { const root = await fixture(t); const cases = [ ["dollar", 'cat <<"DOL\\$LAR"', "DOL$LAR"], ["backtick", 'cat <<"TIC\\`K"', "TIC`K"], ["quote", 'cat <<"QUO\\\"TE"', 'QUO"TE'], ["backslash", 'cat <<"SLA\\\\SH"', "SLA\\SH"], ["newline", 'cat <<"LINE\\\nBREAK"', "LINEBREAK"], ["nonspecial", 'cat <<"NON\\-SPECIAL"', "NON\\-SPECIAL"], ]; for (const [name, opener, close] of cases) { const path = `scripts/double-quoted-${name}-smoke.sh`; const source = ["#!/usr/bin/env bash", opener, "job: refresh", close, ""].join("\n"); await put(root, path, source); bashN(root, path); assert.equal(execFileSync("/bin/bash", [join(root, path)], { encoding: "utf8" }), "job: refresh\n"); assert.equal(extractScriptDocuments(source, path)[0].source, "job: refresh\n"); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); } }); test("split heredoc operator continuation cannot bypass v2 validation", async (t) => { const root = await fixture(t); const path = "scripts/split-operator-smoke.sh"; const source = [ "#!/usr/bin/env bash", "cat <\\", "<'YAML'", canonicalDescriptor.replace(" schema_version: 3", " schema_version: 2").trimEnd(), "YAML", "", ].join("\n"); await put(root, path, source); bashN(root, path); assert.match(execFileSync("/bin/bash", [join(root, path)], { encoding: "utf8" }), /schema_version: 2/u); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /workspace descriptor/i, ); }); test("multiple opener continuations are joined before heredoc discovery", async (t) => { const root = await fixture(t); const path = "scripts/multiple-continuation-smoke.sh"; const source = [ "#!/usr/bin/env bash", "cat \\", "<\\", "<'YAML'", "job: refresh", "workspace: analytics", "YAML", "", ].join("\n"); await put(root, path, source); bashN(root, path); assert.equal( execFileSync("/bin/bash", [join(root, path)], { encoding: "utf8" }), "job: refresh\nworkspace: analytics\n", ); const [candidate] = extractScriptDocuments(source, path); assert.equal(candidate.label, `${path}:5 Bash heredoc`); assert.equal(candidate.source, "job: refresh\nworkspace: analytics\n"); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("backslash-newline inside single quotes is not removed", async (t) => { const root = await fixture(t); const path = "scripts/single-quoted-noncontinuation-smoke.sh"; const source = [ "#!/usr/bin/env bash", "printf '%s' 'literal\\", "continued'", "cat <<'YAML'", "job: refresh", "workspace: analytics", "YAML", "", ].join("\n"); await put(root, path, source); bashN(root, path); assert.equal( execFileSync("/bin/bash", [join(root, path)], { encoding: "utf8" }), "literal\\\ncontinuedjob: refresh\nworkspace: analytics\n", ); const [candidate] = extractScriptDocuments(source, path); assert.equal(candidate.label, `${path}:5 Bash heredoc`); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("PowerShell comment backslash cannot hide a following v2 here-string", async (t) => { const root = await fixture(t); const path = "scripts/powershell-comment-smoke.ps1"; const source = [ "# harmless PowerShell comment \\", "$workspace = @'", canonicalDescriptor.replace(" schema_version: 3", " schema_version: 2").trimEnd(), "'@", "", ].join("\n"); await put(root, path, source); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /workspace descriptor/i, ); }); test("PowerShell dialect accepts normal v3 and non-workspace bundle here-strings", async (t) => { const root = await fixture(t); const path = "scripts/powershell-valid-smoke.ps1"; const source = [ "$workspace = @'", canonicalDescriptor.trimEnd(), "'@", "$bundle = @'", "evidence:", " source: bundle", "schema_version: 2", "'@", "", ].join("\n"); await put(root, path, source); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /embedded workspace descriptor/i, ); const bundleOnly = [ "$bundle = @'", "evidence:", " source: bundle", "schema_version: 2", "'@", "", ].join("\n"); await put(root, path, bundleOnly); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("unknown deployment script dialect fails closed", async (t) => { const root = await fixture(t); const path = "scripts/operator-smoke.cmd"; await put(root, path, "echo harmless\n"); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /unknown deployment script dialect/i, ); }); test("PowerShell cast and concatenation openers cannot hide embedded descriptors", async (t) => { const root = await fixture(t); for (const [name, opener] of [["cast", "[string]@'"], ["concat", "+@'"]]) { const path = `scripts/powershell-${name}-smoke.ps1`; const source = [opener, canonicalDescriptor.trimEnd(), "'@", ""].join("\n"); await put(root, path, source); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /embedded workspace descriptor/i, ); } }); test("expandable YAML interpolation that can hide a workspace descriptor fails closed", async (t) => { const root = await fixture(t); const cases = [ ["braced-key", "${key}:\n schema_version: 3"], ["plain-key", "$key:\n schema_version: 3"], ["quoted-key", '"$key" :\n schema_version: 3'], ["subexpression-key", "$($key):\n schema_version: 3"], ["version", "workspace:\n schema_version: $version"], ]; for (const [name, body] of cases) { const path = `scripts/powershell-interpolation-${name}.ps1`; await put(root, path, [`$yaml = @\"`, body, `\"@`, ""].join("\n")); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /interpolation|embedded workspace descriptor/i, ); } }); test("Bash heredoc discovery ignores quoted, comment, here-string, and arithmetic tokens", async (t) => { const root = await fixture(t); const path = "scripts/bash-lexer-smoke.sh"; const source = [ "#!/usr/bin/env bash", `printf '%s\\n' \"cat <<'QUOTED'\"`, `printf '%s\\n' 'cat <<\"SINGLE\"'`, "# cat <<'COMMENT'", "value=$((1 << 2))", `cat <<< \"not a heredoc\"`, "cat <<'YAML'", "job: refresh", "YAML", "", ].join("\n"); await put(root, path, source); bashN(root, path); const extracted = extractScriptDocuments(source, path); assert.equal(extracted.length, 1); assert.equal(extracted[0].source, "job: refresh\n"); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("UTF-8 decoding is fatal but literal replacement characters are valid text", async (t) => { const root = await fixture(t); const validPath = "deploy/workspaces/replacement.yaml"; await put(root, validPath, `${canonicalDescriptor}# literal replacement: �\n`); await verifyEntries({ root, entries: [entry("workspace_descriptor", validPath)] }); const invalidPath = "deploy/workspaces/malformed.yaml"; await mkdir(dirname(join(root, invalidPath)), { recursive: true }); await writeFile(join(root, invalidPath), Buffer.concat([Buffer.from(canonicalDescriptor), Buffer.from([0xff])])); await assert.rejects( verifyEntries({ root, entries: [entry("workspace_descriptor", invalidPath)] }), /valid UTF-8/i, ); }); test("unmarked expandable Bash YAML cannot generate descriptor keys or values at runtime", async (t) => { const root = await fixture(t); const cases = [ ["quoted", '"$key" :'], ["command", "$(printf workspace):"], ["braced", "${key}:"], ["plain", "$key:"], ]; for (const [name, generatedKey] of cases) { const path = `scripts/bash-dynamic-${name}.sh`; const source = [ "#!/usr/bin/env bash", "key=workspace", "cat < { const root = await fixture(t); for (const [path, source] of [ ["scripts/fake-marker.sh", [ "#!/usr/bin/env bash", "# schema-v3-only: expandable-nonworkspace", "cat < { const reviewedPaths = [ "scripts/preprocess-smoke.sh", "scripts/test-server-pi-state-topology.sh", "scripts/test-vector-backup-restore-safety.sh", "scripts/test-windows-clone-contract.ps1", "scripts/unified-deployment-smoke.sh", "scripts/vector-backup.sh", "scripts/vector-restore.sh", ]; await verifyEntries({ root: repositoryRoot, entries: reviewedPaths.map((path) => entry("deployment_script", path)), }); const root = await fixture(t); const original = await readFile(join(repositoryRoot, "scripts/preprocess-smoke.sh"), "utf8"); await put(root, "scripts/copied-preprocess.sh", original); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", "scripts/copied-preprocess.sh")] }), /exact-content reviewed allowlist/, ); await put(root, "scripts/preprocess-smoke.sh", original.replace('$tmp/smoke.yaml', '$tmp/other.yaml')); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", "scripts/preprocess-smoke.sh")] }), /exact-content reviewed allowlist/, ); }); test("PowerShell tokenizer ignores opener text in comments and ordinary strings", async (t) => { const root = await fixture(t); const path = "scripts/powershell-lexical-context.ps1"; const source = [ "# example @'", '\"example @\'\"', "'example @\"'", "<# block @'", "still @\" #>", "$cast = [string]@'", "job: cast", "'@", "$concat = $cast +@'", "job: concat", "'@", "", ].join("\n"); await put(root, path, source); const extracted = extractScriptDocuments(source, path); assert.equal(extracted.length, 2); assert.deepEqual(extracted.map((item) => item.source), ["job: cast\n", "job: concat\n"]); await verifyEntries({ root, entries: [entry("deployment_script", path)] }); }); test("policy text rejects NUL and prescribed symbol substrings but permits lower-camel legacy identifiers", async (t) => { const root = await fixture(t); await put(root, "backend/src/nul.ts", Buffer.from("safe\0WorkspaceV2")); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", "backend/src/nul.ts")] }), /NUL byte/); for (const [name, text] of [ ["compat", "type X = WorkspaceV2Compat;"], ["mixed-prescribed", "type X = wOrKsPaCeV2;"], ["lower-deprecated", "type X = deprecatedV2Descriptor;"], ["upper-function", "WRITEMIGRATEDWORKSPACE(value);"], ["adapter", "type X = LegacyWorkspaceAdapter;"], ["lower", "type X = legacyworkspace;"], ["mixed", "type X = LeGaCyWoRkSpAcE;"], ]) { const path = `backend/src/${name}.ts`; await put(root, path, text); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /forbidden/); } await put(root, "backend/src/allowed.ts", "const legacyWorkspacePath = value;"); await verifyEntries({ root, entries: [entry("policy_text", "backend/src/allowed.ts")] }); }); test("revision-state structural scan permits only the exact historical decoder occurrence", async (t) => { const root = await fixture(t); const registry = "backend/src/workspaces/registry.ts"; await put(root, registry, 'if (revision.state !== "operational") return;\n'); await verifyEntries({ root, entries: [entry("policy_text", registry)] }); const variants = [ 'if (revision.state !== "operational") return;\nif (revision["state"] === value) return;\n', 'if (workspaceRevision\n .state === value) return;\n', "if (selectedWorkspace [ 'state' ] === value) return;\n", ]; for (let index = 0; index < variants.length; index += 1) { const path = index === 0 ? registry : `frontend/src/revision-${index}.ts`; await put(root, path, variants[index]); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/); } }); test("complete descriptors supplied only through Bash or PowerShell variables require exact review", async (t) => { const root = await fixture(t); const cases = [ ["scripts/variable-descriptor.sh", ["#!/usr/bin/env bash", "cat < { const root = await fixture(t); const cases = [ ["scripts/positional.sh", "cat < { const root = await fixture(t); for (const [name, prefix] of [ ["escaped-hash", "Write-Output `# harmless"], ["escaped-quote", 'Write-Output `" harmless'], ]) { const path = `scripts/${name}.ps1`; const source = [prefix, "$yaml = @'", "workspace:", " schema_version: 2", "'@", ""].join("\n"); await put(root, path, source); assert.equal(extractScriptDocuments(source, path).length, 1); await assert.rejects( verifyEntries({ root, entries: [entry("deployment_script", path)] }), /embedded workspace descriptor/, ); } }); test("TypeScript AST rejects comment-separated and destructured revision state", async (t) => { const root = await fixture(t); for (const [index, source] of [ "const value = revision /*legacy*/ . state;", "const { state } = revision;", "const { state: oldState } = selectedWorkspace;", ].entries()) { const path = `frontend/src/ast-revision-${index}.ts`; await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/); } const registry = "backend/src/workspaces/registry.ts"; await put(root, registry, 'if (revision.state !== "operational") return;\nconst { state } = revision;\n'); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", registry)] }), /revision-state/); await put(root, "backend/src/unrelated.ts", "const { state } = lease; const jobState = job.state;"); await verifyEntries({ root, entries: [entry("policy_text", "backend/src/unrelated.ts")] }); }); test("AST recognizes semantic state keys in every revision destructuring form", async (t) => { const root = await fixture(t); const cases = [ ["backend/src/computed.mts", 'const { ["state"]: oldState } = revision;'], ["frontend/src/renamed.cts", 'const { "state": oldState = fallback } = workspaceRevision;'], ["backend/scripts/template.TS", 'const { [`state`]: oldState } = selectedWorkspace;'], ["scripts/parameter.txt", 'function read({ state: oldState = fallback } = revision) {}'], ["scripts/assignment.sh", '({ state } = workspaceRevision);'], ["scripts/computed-assignment.data", '({ ["state"]: oldState = fallback } = selectedWorkspace);'], ]; for (const [path, source] of cases) { await put(root, path, source); await assert.rejects( verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path, ); } const registry = "backend/src/workspaces/registry.ts"; await put(root, registry, [ 'if (revision.state !== "operational") return;', 'function read({ ["state"]: oldState } = revision) {}', "", ].join("\n")); await assert.rejects( verifyEntries({ root, entries: [entry("policy_text", registry)] }), /revision-state/, ); }); test("tolerant all-suffix AST scan ignores strings/comments and unrelated state", async (t) => { const root = await fixture(t); const path = "scripts/arbitrary.weird"; await put(root, path, [ '// const { state } = revision;', '"revision.state";', "'({ [\\\"state\\\"]: oldState } = selectedWorkspace)';", "const { state } = lease;", "const jobState = job.state;", "record.state = 'ready';", "", ].join("\n")); await verifyEntries({ root, entries: [entry("policy_text", path)] }); }); test("computed revision destructuring keys fold parentheses assertions templates and string concatenation", async (t) => { const root = await fixture(t); const cases = [ ["backend/src/paren.ts", 'const { [("state")]: oldState } = revision;'], ["backend/src/concat.ts", 'const { ["st" + "ate"]: oldState } = workspaceRevision;'], ["frontend/src/template.ts", 'const { [`st${"ate"}`]: oldState } = selectedWorkspace;'], ["scripts/assertion.data", 'const { [("st" as string) + (`ate` satisfies string)]: oldState } = revision;'], ["scripts/assignment.txt", '({ ["st" + "ate"]: oldState } = selectedWorkspace);'], ]; for (const [path, source] of cases) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path); } const registry = "backend/src/workspaces/registry.ts"; for (const injected of [ 'const { [("state")]: oldState } = revision;', '({ ["st" + "ate"]: oldState } = revision);', ]) { await put(root, registry, `if (revision.state !== "operational") return;\n${injected}\n`); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", registry)] }), /revision-state/); } }); test("polyglot masking and JSX syntax prevent comment and string false positives", async (t) => { const root = await fixture(t); const passing = [ ["backend/scripts/comment.py", '# revision.state\nvalue = "revision.state"\ntext = """selectedWorkspace.state"""\n'], ["scripts/comment.ps1", '# revision.state\n<# workspaceRevision.state #>\n$value = "revision.state"\n'], ["scripts/comment.sh", '# revision.state\nprintf \'%s\\n\' "selectedWorkspace.state"\n'], ["frontend/src/content.tsx", 'export const view =
revision.state
;'], ["frontend/src/attribute.tsx", 'export const view =
;'], ["frontend/src/expression.tsx", 'export const view =
{"revision.state"}
;'], ["scripts/arbitrary.data", 'title: "revision.state"\n# const { state } = revision\nlease:\n state: ready\n'], ]; for (const [path, source] of passing) { await put(root, path, source); await verifyEntries({ root, entries: [entry("policy_text", path)] }); } for (const [path, source] of [ ["scripts/code.txt", "const { state } = revision;"], ["scripts/code.data", '({ ["st" + "ate"]: oldState } = workspaceRevision);'], ]) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/); } }); test("rest bindings and dynamic computed keys are not semantic state-property access", async (t) => { const root = await fixture(t); const cases = [ ["backend/src/rest.ts", "const { ...state } = revision;"], ["frontend/src/renamed.ts", "const { other: state } = workspaceRevision;"], ["scripts/dynamic.txt", "const { [state]: value } = selectedWorkspace;"], ["scripts/dynamic-assignment.data", "({ [state]: value } = revision);"], ["scripts/spread-assignment.data", "({ ...state } = workspaceRevision);"], ]; for (const [path, source] of cases) { await put(root, path, source); await verifyEntries({ root, entries: [entry("policy_text", path)] }); } }); test("polyglot code remains structural across shell Python PowerShell YAML TSX and JSX", async (t) => { const root = await fixture(t); const failing = [ ["scripts/code.sh", "value=revision.state\n"], ["scripts/code.ps1", "$value = workspaceRevision.state\n"], ["backend/scripts/code.py", "value = selectedWorkspace.state\n"], ["scripts/code.yaml", "value: revision.state\n"], ["frontend/src/code.tsx", "export const view =
{revision.state}
;"], ["frontend/src/code.jsx", "export const view =
{workspaceRevision.state}
;"], ]; for (const [path, source] of failing) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path); } }); test("PowerShell executable subexpressions expose dollar-prefixed revision access", async (t) => { const root = await fixture(t); const failing = [ ["scripts/ps-property.ps1", 'Write-Output "revision: $($revision.state)"\n'], ["scripts/ps-element.ps1", 'Write-Output "$($workspaceRevision[\'state\'])"\n'], ["scripts/ps-workspace.ps1", '$value = $workspaceRevision.state\n'], ["scripts/ps-nested.ps1", 'Write-Output "$($($revision.state))"\n'], ]; for (const [path, source] of failing) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path); } const passing = [ '# $revision.state\nWrite-Output "revision.state"\n', "Write-Output '$selectedWorkspace[\"state\"]'\n", ]; for (let index = 0; index < passing.length; index += 1) { const path = `scripts/ps-literal-${index}.ps1`; await put(root, path, passing[index]); await verifyEntries({ root, entries: [entry("policy_text", path)] }); } }); test("Python f-string fields expose revision access while literal text remains masked", async (t) => { const root = await fixture(t); const failing = [ ["backend/scripts/f-property.py", 'value = f"{revision.state}"\n'], ["backend/scripts/fr-element.py", 'value = fr"{workspaceRevision[\'state\']}"\n'], ["backend/scripts/rf-element.py", 'value = rf"prefix {selectedWorkspace[\"state\"]}"\n'], ]; for (const [path, source] of failing) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path); } const passing = [ 'value = f"revision.state"\n', 'value = f"{{revision.state}}"\n', 'value = "revision.state"\n', 'value = r"workspaceRevision.state"\n', 'value = """selectedWorkspace.state"""\n', 'value = r"""revision.state"""\n', ]; for (let index = 0; index < passing.length; index += 1) { const path = `backend/scripts/python-literal-${index}.py`; await put(root, path, passing[index]); await verifyEntries({ root, entries: [entry("policy_text", path)] }); } }); test("Bash masking preserves parameter trimming and executable command consumers", async (t) => { const root = await fixture(t); const failing = [ ["scripts/trim.sh", "trimmed=${value#prefix}; old=revision.state\n"], ["scripts/base.sh", "base=${path##*/}; old=workspaceRevision.state\n"], ["scripts/backtick.sh", "old=`echo revision.state`\n"], ["scripts/quoted-backtick.sh", 'echo "old: `echo revision.state`"\n'], ["scripts/jq.sh", "jq '.revision.state' snapshot.json\n"], ["scripts/substitution.sh", 'echo "$(echo revision.state)"\n'], ]; for (const [path, source] of failing) { await put(root, path, source); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/, path); } await put(root, "scripts/echo.sh", 'echo "revision.state"\n# workspaceRevision.state\n'); await verifyEntries({ root, entries: [entry("policy_text", "scripts/echo.sh")] }); await put(root, "scripts/literal.yaml", '# revision.state\nvalue: "selectedWorkspace.state"\n'); await verifyEntries({ root, entries: [entry("policy_text", "scripts/literal.yaml")] }); }); test("YAML keeps URL slashes as data rather than a false line comment", async (t) => { const root = await fixture(t); const path = "scripts/url.yaml"; await put(root, path, "url: https://host/x; old: selectedWorkspace.state\n"); await assert.rejects(verifyEntries({ root, entries: [entry("policy_text", path)] }), /revision-state/); });