From dea286851f43324f406ead0d30f6cc55e9684582 Mon Sep 17 00:00:00 2001 From: Jakob Heuser Date: Tue, 1 Sep 2026 18:43:21 -0700 Subject: [PATCH] test(runtime): pin that an unknown metadata.taskless key is tolerated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The generator asked whether a capture survives discovery with an unrecognised key under `metadata.taskless`, before depending on it. The answer is yes, and the honest form of that answer is that it works by ACCIDENT: `assessCaptureRule` checks the fields it needs and never rejects the ones it does not know, and ast-grep treats `metadata` as opaque. Neither is a decision anyone wrote down, so neither was a promise. Verified end to end before claiming it — a capture carrying `metadata.taskless.note` passes `verify` AND still fires under `check`, which is the assertion that matters. A dropped capture verifies clean and finds nothing, and finding nothing is what a passing run looks like. This test holds the tolerance in place. The generator writes a demonstration disclaimer into the rule rather than only into the HTTP response, because a note in an envelope is gone the moment the rule reaches disk — which is exactly when a reader with no memory of asking for a demo needs to know what it is. Confirmed it bites by making the assessor reject unknown keys, the way a schema-based rewrite plausibly would: it fails, and passes again when restored. --- packages/cli/test/runtime-harness.test.ts | 68 +++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/packages/cli/test/runtime-harness.test.ts b/packages/cli/test/runtime-harness.test.ts index 0d98006b..6512afd7 100644 --- a/packages/cli/test/runtime-harness.test.ts +++ b/packages/cli/test/runtime-harness.test.ts @@ -59,6 +59,74 @@ const ECHO_CHECK = `export default async function (root, matches) { } `; +/** + * An unknown key under `metadata.taskless` does not drop the capture. + * + * The generator asked before depending on it, which is the right order, and + * the honest answer was that it works by ACCIDENT rather than by design: + * `assessCaptureRule` checks the fields it needs and never rejects the ones it + * does not know, and ast-grep treats `metadata` as opaque. Neither is a + * decision anybody wrote down, so neither is a promise until something holds + * it. + * + * This holds it. The generator carries a demonstration disclaimer as + * `metadata.taskless.note`, written INTO the rule rather than only into the + * HTTP response, because a note in an envelope is gone the moment the rule + * reaches disk — which is exactly when a reader with no memory of asking for a + * demo needs to know what it is. + * + * The assertion is that the capture still MATCHES, not merely that discovery + * accepted it. A capture that is dropped produces no findings, and no findings + * is what a passing run looks like. + */ +describe("an unknown metadata.taskless key", () => { + let cwd: string; + + beforeEach(async () => { + cwd = await mkdtemp(join(tmpdir(), "tskl-unknown-meta-")); + }); + + afterEach(async () => { + await rm(cwd, { recursive: true, force: true }); + }); + + const withNote = [ + "id: env-read-abc12345", + "language: typescript", + "rule:", + " pattern: process.env.$NAME", + "metadata:", + " taskless:", + " version: 1", + " kind: runtime", + " name: env-read", + " check: check.ts", + " match: anchor", + ' note: "Example rule. May not apply to this repository."', + "", + ].join("\n"); + + it("is discovered, and its capture still matches", async () => { + await writeRuntimeRule( + cwd, + "env-read", + { "env.yml": withNote }, + ECHO_CHECK + ); + await writeFile( + join(cwd, "src.ts"), + "const home = process.env.HOME;\n", + "utf8" + ); + + const rules = await discoverRuntimeRules(cwd); + expect(rules).toHaveLength(1); + + const findings = await executeRuntimeRule(cwd, rules[0]!); + expect(findings.length).toBeGreaterThan(0); + }); +}); + describe("runtime harness", () => { let root: string;