diff --git a/.github/workflows/demo-rule.yml b/.github/workflows/reference-corpus.yml similarity index 93% rename from .github/workflows/demo-rule.yml rename to .github/workflows/reference-corpus.yml index 6bd76977..4f5cd059 100644 --- a/.github/workflows/demo-rule.yml +++ b/.github/workflows/reference-corpus.yml @@ -1,4 +1,4 @@ -# Runs every shipped demonstration rule's own fixtures. +# Runs every conformance corpus rule's own fixtures, as a smoke test. # # ## Why this is its own workflow # @@ -18,10 +18,10 @@ # conformance corpus published as `@taskless/cli/reference.json`, and # `test/reference.test.ts` only proves that payload matches the asset trees. # This job proves the trees themselves hold: it copies the manifest's own -# written-path list, read straight off `assets/demo-*/`, into one bare project +# written-path list, read straight off `assets/reference-*/`, into one bare project # and runs the engines over it. A corpus rule that fails its own cases would # hand another team a broken oracle. -name: Demo rules +name: Reference corpus on: push: @@ -43,8 +43,8 @@ env: TASKLESS_TELEMETRY_DISABLED: "1" jobs: - demo-rules: - name: Demo rules + reference-corpus: + name: Reference corpus runs-on: ubuntu-latest steps: @@ -81,7 +81,7 @@ jobs: # The script writes the file itself. Redirecting its stdout here # captured pnpm's platform warnings alongside the manifest, and the # loop below then tried to stage a rule named "WARN". - pnpm --filter @taskless/cli demo:manifests /tmp/manifests.txt + pnpm --filter @taskless/cli corpus:manifests /tmp/manifests.txt cat /tmp/manifests.txt # The trailing field is the manifest's own written-path list, so this # stages exactly the rule and its cases. A `cp -R` of the asset @@ -119,5 +119,5 @@ jobs: if (rule.ran !== true) throw new Error(id + " fixtures did not run: " + JSON.stringify(rule)); if (rule.ok !== true) throw new Error(id + " fixtures failed: " + JSON.stringify(rule.errors)); } - console.log("all " + expected.length + " demo rules ran and passed"); + console.log("all " + expected.length + " reference rules ran and passed"); ' diff --git a/eslint.config.js b/eslint.config.js index a5c03a39..5dc2b503 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -16,12 +16,12 @@ export default tseslint.config( "plugins/", "openspec/", "**/test/fixtures/", - // The demonstration rule ships as DATA, not as source. Its `check.ts` + // The runtime reference rule ships as DATA, not as source. Its `check.ts` // is a rule in the published conformance corpus, run under `tsx` // against a structural contract and importing nothing from this // repository — so it is deliberately outside every tsconfig, and // type-aware linting has no project to resolve it against. - "packages/cli/assets/demo-runtime/", + "packages/cli/assets/reference-runtime/", "tmp/", // Worktrees are full checkouts nested inside the repo. Without this, a // root `eslint .` lints every worktree's copy of the tree — slow, and it diff --git a/packages/cli/assets/demo-runtime/.tests/fail/undeclared/.env b/packages/cli/assets/reference-runtime/.tests/fail/undeclared/.env similarity index 100% rename from packages/cli/assets/demo-runtime/.tests/fail/undeclared/.env rename to packages/cli/assets/reference-runtime/.tests/fail/undeclared/.env diff --git a/packages/cli/assets/demo-runtime/.tests/fail/undeclared/src/config.ts b/packages/cli/assets/reference-runtime/.tests/fail/undeclared/src/config.ts similarity index 100% rename from packages/cli/assets/demo-runtime/.tests/fail/undeclared/src/config.ts rename to packages/cli/assets/reference-runtime/.tests/fail/undeclared/src/config.ts diff --git a/packages/cli/assets/demo-runtime/.tests/pass/declared/.env b/packages/cli/assets/reference-runtime/.tests/pass/declared/.env similarity index 100% rename from packages/cli/assets/demo-runtime/.tests/pass/declared/.env rename to packages/cli/assets/reference-runtime/.tests/pass/declared/.env diff --git a/packages/cli/assets/demo-runtime/.tests/pass/declared/src/config.ts b/packages/cli/assets/reference-runtime/.tests/pass/declared/src/config.ts similarity index 100% rename from packages/cli/assets/demo-runtime/.tests/pass/declared/src/config.ts rename to packages/cli/assets/reference-runtime/.tests/pass/declared/src/config.ts diff --git a/packages/cli/assets/demo-runtime/captures/env-read.yml b/packages/cli/assets/reference-runtime/captures/env-read.yml similarity index 100% rename from packages/cli/assets/demo-runtime/captures/env-read.yml rename to packages/cli/assets/reference-runtime/captures/env-read.yml diff --git a/packages/cli/assets/demo-runtime/check.ts b/packages/cli/assets/reference-runtime/check.ts similarity index 100% rename from packages/cli/assets/demo-runtime/check.ts rename to packages/cli/assets/reference-runtime/check.ts diff --git a/packages/cli/assets/demo-runtime/prompt.md b/packages/cli/assets/reference-runtime/prompt.md similarity index 100% rename from packages/cli/assets/demo-runtime/prompt.md rename to packages/cli/assets/reference-runtime/prompt.md diff --git a/packages/cli/assets/demo-sg/.tests/no-eval-call-test.yml b/packages/cli/assets/reference-sg/.tests/no-eval-call-test.yml similarity index 100% rename from packages/cli/assets/demo-sg/.tests/no-eval-call-test.yml rename to packages/cli/assets/reference-sg/.tests/no-eval-call-test.yml diff --git a/packages/cli/assets/demo-sg/no-eval-call.yml b/packages/cli/assets/reference-sg/no-eval-call.yml similarity index 100% rename from packages/cli/assets/demo-sg/no-eval-call.yml rename to packages/cli/assets/reference-sg/no-eval-call.yml diff --git a/packages/cli/assets/demo-sg/prompt.md b/packages/cli/assets/reference-sg/prompt.md similarity index 100% rename from packages/cli/assets/demo-sg/prompt.md rename to packages/cli/assets/reference-sg/prompt.md diff --git a/packages/cli/assets/demo-vale/.tests/fail/README.md b/packages/cli/assets/reference-vale/.tests/fail/README.md similarity index 100% rename from packages/cli/assets/demo-vale/.tests/fail/README.md rename to packages/cli/assets/reference-vale/.tests/fail/README.md diff --git a/packages/cli/assets/demo-vale/.tests/pass/README.md b/packages/cli/assets/reference-vale/.tests/pass/README.md similarity index 100% rename from packages/cli/assets/demo-vale/.tests/pass/README.md rename to packages/cli/assets/reference-vale/.tests/pass/README.md diff --git a/packages/cli/assets/demo-vale/.vale.ini b/packages/cli/assets/reference-vale/.vale.ini similarity index 100% rename from packages/cli/assets/demo-vale/.vale.ini rename to packages/cli/assets/reference-vale/.vale.ini diff --git a/packages/cli/assets/demo-vale/prefer-use-over-utilize.yml b/packages/cli/assets/reference-vale/prefer-use-over-utilize.yml similarity index 100% rename from packages/cli/assets/demo-vale/prefer-use-over-utilize.yml rename to packages/cli/assets/reference-vale/prefer-use-over-utilize.yml diff --git a/packages/cli/assets/demo-vale/prompt.md b/packages/cli/assets/reference-vale/prompt.md similarity index 100% rename from packages/cli/assets/demo-vale/prompt.md rename to packages/cli/assets/reference-vale/prompt.md diff --git a/packages/cli/package.json b/packages/cli/package.json index 8b0a27c6..8ee19e5c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -11,7 +11,7 @@ "build": "vite build && tsc -p tsconfig.public.json", "build:nightly": "TASKLESS_BUILD_TARGET=nightly vite build && tsc -p tsconfig.public.json", "build:self": "TASKLESS_BUILD_TARGET=self vite build", - "demo:manifests": "tsx scripts/print-demo-manifests.ts", + "corpus:manifests": "tsx scripts/print-corpus-manifests.ts", "generate:api": "pnpm generate:api:schema && pnpm generate:api:types", "generate:api:schema": "tsx scripts/fetch-api-schema.ts", "generate:api:types": "openapi-typescript src/generated/api-v2.schema.json -o src/generated/api-v2.d.ts", diff --git a/packages/cli/scripts/print-demo-manifests.ts b/packages/cli/scripts/print-corpus-manifests.ts similarity index 82% rename from packages/cli/scripts/print-demo-manifests.ts rename to packages/cli/scripts/print-corpus-manifests.ts index f42b5ed2..b1c1ad46 100644 --- a/packages/cli/scripts/print-demo-manifests.ts +++ b/packages/cli/scripts/print-corpus-manifests.ts @@ -1,5 +1,5 @@ /** - * Write each shipped demo rule as + * Write each conformance corpus rule as * ` ...`. * * Exists so CI can stage every sample without restating the list in YAML, @@ -17,19 +17,19 @@ * reading it then tried to stage a rule called `WARN`. A file the script writes * itself cannot pick up a caller's noise. * - * Run: pnpm --filter @taskless/cli demo:manifests + * Run: pnpm --filter @taskless/cli corpus:manifests */ import { writeFile } from "node:fs/promises"; -import { DEMO_MANIFESTS, writtenPaths } from "../src/rules/demo/manifest"; +import { CORPUS_MANIFESTS, writtenPaths } from "../src/rules/corpus/manifest"; const target = process.argv[2]; if (target === undefined) { - throw new Error("usage: print-demo-manifests "); + throw new Error("usage: print-corpus-manifests "); } -const lines = DEMO_MANIFESTS.map( +const lines = CORPUS_MANIFESTS.map( (manifest) => `${manifest.engine} ${manifest.ruleId} ${manifest.assetDirectory} ${writtenPaths(manifest).join(" ")}` ); diff --git a/packages/cli/scripts/write-reference.ts b/packages/cli/scripts/write-reference.ts index 06243da2..8658a9ef 100644 --- a/packages/cli/scripts/write-reference.ts +++ b/packages/cli/scripts/write-reference.ts @@ -1,7 +1,7 @@ /** * Regenerate `assets/reference.json` from the shipped rules. * - * The corpus is every demonstration rule with the prompt it answers, the rule + * The corpus is every reference rule with the prompt it answers, the rule * itself, and the held-out cases — separately, so another team can run their * rule against our cases and ours against theirs. * @@ -15,7 +15,7 @@ import { writeFile } from "node:fs/promises"; import { join } from "node:path"; import { buildReference } from "../src/rules/reference"; -import { readReferenceInputs } from "../src/rules/demo/manifest"; +import { readReferenceInputs } from "../src/rules/corpus/manifest"; const assetsRoot = join(import.meta.dirname, "..", "assets"); diff --git a/packages/cli/src/rules/demo/manifest.ts b/packages/cli/src/rules/corpus/manifest.ts similarity index 91% rename from packages/cli/src/rules/demo/manifest.ts rename to packages/cli/src/rules/corpus/manifest.ts index 7366eab8..9076d51f 100644 --- a/packages/cli/src/rules/demo/manifest.ts +++ b/packages/cli/src/rules/corpus/manifest.ts @@ -1,5 +1,5 @@ /** - * The demonstration rules behind the conformance corpus: their identities, + * The rules behind the conformance corpus: their identities, * their file lists, and the one reader that loads them off disk. * * Nothing in the bundle imports this. The rules used to be written into a @@ -25,8 +25,8 @@ import { join } from "node:path"; import type { EngineName } from "../layout"; import type { ReferenceInput } from "../reference"; -/** One shipped demonstration rule. */ -export interface DemoManifest { +/** One rule in the conformance corpus. */ +export interface CorpusManifest { engine: EngineName; /** * The rule's directory name, and the id `check` and `verify` address it by. @@ -72,11 +72,11 @@ export interface DemoManifest { assetDirectory: string; } -export const DEMO_MANIFESTS: readonly DemoManifest[] = [ +export const CORPUS_MANIFESTS: readonly CorpusManifest[] = [ { engine: "sg", ruleId: "no-eval-call", - assetDirectory: "demo-sg", + assetDirectory: "reference-sg", promptPath: "prompt.md", rulePaths: ["no-eval-call.yml"], testPaths: [".tests/no-eval-call-test.yml"], @@ -84,7 +84,7 @@ export const DEMO_MANIFESTS: readonly DemoManifest[] = [ { engine: "vale", ruleId: "prefer-use-over-utilize", - assetDirectory: "demo-vale", + assetDirectory: "reference-vale", promptPath: "prompt.md", // `.vale.ini` is the rule's own engine config, so it is part of what a // generator must produce rather than part of the oracle. @@ -94,7 +94,7 @@ export const DEMO_MANIFESTS: readonly DemoManifest[] = [ { engine: "runtime", ruleId: "env-keys-declared", - assetDirectory: "demo-runtime", + assetDirectory: "reference-runtime", promptPath: "prompt.md", rulePaths: ["check.ts", "captures/env-read.yml"], testPaths: [ @@ -107,7 +107,7 @@ export const DEMO_MANIFESTS: readonly DemoManifest[] = [ ]; /** Every file of the staged rule tree: the rule and its cases, never the prompt. */ -export function writtenPaths(manifest: DemoManifest): readonly string[] { +export function writtenPaths(manifest: CorpusManifest): readonly string[] { return [...manifest.rulePaths, ...manifest.testPaths]; } @@ -126,7 +126,7 @@ export async function readReferenceInputs( ); return Promise.all( - DEMO_MANIFESTS.map(async (manifest) => ({ + CORPUS_MANIFESTS.map(async (manifest) => ({ engine: manifest.engine, ruleId: manifest.ruleId, prompt: await read(manifest.assetDirectory, manifest.promptPath), diff --git a/packages/cli/test/reference.test.ts b/packages/cli/test/reference.test.ts index 82df8137..157fd32e 100644 --- a/packages/cli/test/reference.test.ts +++ b/packages/cli/test/reference.test.ts @@ -11,10 +11,10 @@ import { } from "../src/rules/reference"; import { RULE_CONSTRAINTS } from "../src/rules/constraints"; import { - DEMO_MANIFESTS, + CORPUS_MANIFESTS, readReferenceInputs, writtenPaths, -} from "../src/rules/demo/manifest"; +} from "../src/rules/corpus/manifest"; import { ENGINE_LAYOUTS, ENGINES, type EngineName } from "../src/rules/layout"; import { ruleDirectory } from "../src/rules/engines"; @@ -93,7 +93,7 @@ function shapePaths(value: unknown): string[] { return [...paths].toSorted(); } -describe("the demo reference payload", () => { +describe("the reference corpus payload", () => { it("is current — regenerate with `pnpm --filter @taskless/cli reference`", async () => { expect(await readReference()).toEqual( buildReference(await readReferenceInputs(assetsRoot)) @@ -117,10 +117,10 @@ describe("the demo reference payload", () => { // the point: whoever adds it states which of its files are dot-paths, // rather than inheriting a guard that silently covers nothing. expect( - DEMO_MANIFESTS.map((manifest) => manifest.engine).toSorted() + CORPUS_MANIFESTS.map((manifest) => manifest.engine).toSorted() ).toEqual(Object.keys(required).toSorted()); - for (const manifest of DEMO_MANIFESTS) { + for (const manifest of CORPUS_MANIFESTS) { const written = writtenPaths(manifest); for (const path of required[manifest.engine] ?? []) { expect(written, `${manifest.engine} no longer lists ${path}`).toContain( @@ -414,7 +414,7 @@ describe("the reference payload is reachable by another team", () => { /** * One rule's worth of input, with only the fixture paths varying. * - * Hand-built rather than mutated out of `DEMO_MANIFESTS`, so a test that + * Hand-built rather than mutated out of `CORPUS_MANIFESTS`, so a test that * asserts a refusal cannot also alter what the real corpus publishes. */ function refusalInput(engine: EngineName, testPaths: string[]): ReferenceInput {