@catspec/core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/diagnostics.ts","../src/config.ts","../src/schema-issues.ts","../src/util.ts","../src/workflow/schema.ts","../src/spec-schema.ts","../src/facts.ts","../src/match.ts","../src/codebase.ts","../src/spec.ts","../src/frontmatter.ts","../src/spec-body.ts","../src/resolve.ts","../src/contracts.ts","../src/rules.ts","../src/check.ts","../src/lock.ts","../src/git/git.ts","../src/git/providers.ts","../src/staged.ts","../src/coverage.ts","../src/graph.ts","../src/load.ts","../src/spec-editor.ts","../src/rename.ts","../src/sync.ts","../src/workflow/engine.ts","../src/workflow/doctor.ts","../src/workflow/format.ts","../src/index.ts"],"sourcesContent":["/**\n * Diagnostics (plan §D12, ADR-011): every problem CatSpec reports has a stable `CSxxxx` code, a\n * severity, a location and a message. The registry below is the single source of the codes: a\n * code that isn't registered can't be emitted, and the docs are generated from it.\n */\n\nexport type Severity = \"error\" | \"warning\" | \"info\";\n\nexport interface CodeInfo {\n /** Default severity; a check may lower or raise it (config, spec status, plan §D8). */\n severity: Severity;\n title: string;\n /** Reference text for the diagnostics docs: what the code means and how to fix it. */\n docs: string;\n}\n\n/** The code registry. Codes are never reused and their meaning never changes (ADR-011). */\nexport const CODES = {\n CS0101: {\n severity: \"error\",\n title: \"invalid spec\",\n docs:\n \"The spec can't be read as a valid spec: the file has no `---` frontmatter or it isn't \" +\n \"closed, the YAML is invalid, a required field is missing, or a value has the wrong type or \" +\n \"isn't one of the allowed values. The message names the field and the allowed values. Fix \" +\n \"the frontmatter at the reported line.\",\n },\n CS0102: {\n severity: \"warning\",\n title: \"unknown key\",\n docs:\n \"A top-level frontmatter key that CatSpec doesn't know. It is ignored, so teams can keep \" +\n \"their own metadata in the spec. Check the spelling if it was meant to be a CatSpec key.\",\n },\n CS0103: {\n severity: \"error\",\n title: \"duplicate id\",\n docs:\n \"Spec ids must be unique across the repository, and binding and rule ids unique within \" +\n \"their spec. Rename one of them; the message names every place that uses the id.\",\n },\n CS0104: {\n severity: \"error\",\n title: \"unknown dependency\",\n docs:\n \"`depends_on` names a spec id that doesn't exist. Fix the id (the message suggests close \" +\n \"matches) or add the missing spec.\",\n },\n CS0105: {\n severity: \"error\",\n title: \"dependency cycle\",\n docs:\n \"The `depends_on` relations form a cycle, so no spec in it can ever be started. The message \" +\n \"shows the full cycle (`a → b → c → a`); remove one of its dependencies.\",\n },\n CS0106: {\n severity: \"warning\",\n title: \"spec outside a feature folder\",\n docs:\n \"With `layout: feature-folders`, every `*.spec.md` lives directly in `docs/spec/<feature>/`, \" +\n \"and the architecture spec at the path in `specs.architecture`. Move the file as suggested, \" +\n \"or set `layout: free` in `catspec.yaml` if the repository uses another layout.\",\n },\n CS0107: {\n severity: \"error\",\n title: \"architecture spec missing or ambiguous\",\n docs:\n \"Exactly one file must match `specs.architecture` (default \" +\n \"`docs/architecture/adr/*-adr.md`). Create it with `catspec init`, remove the extra \" +\n \"matches, or change `specs.architecture` in `catspec.yaml`. In `check --staged`, an ADR \" +\n \"log that exists on disk but isn't staged yet is a warning that names the file to stage, \" +\n \"so the first commit after `catspec init` isn't blocked.\",\n },\n CS0108: {\n severity: \"warning\",\n title: \"lock file without spec\",\n docs:\n \"A generated `<spec-id>.lock.json` has no spec with that id in its folder, usually because \" +\n \"the spec was deleted, renamed or moved without its lock file. Delete the lock file, or \" +\n \"move it next to its spec (a spec's lock file is named after its id).\",\n },\n CS0110: {\n severity: \"error\",\n title: \"unknown reference\",\n docs:\n \"The spec body references `[rule:<id>]` or `[binding:<id>]`, but the frontmatter has no \" +\n \"rule or binding with that id. Fix the reference or add the rule or binding.\",\n },\n CS0111: {\n severity: \"warning\",\n title: \"unenforced prose invariant\",\n docs:\n \"A bullet under a `Contracts` or `Invariants` heading has no `[rule:<id>]` or \" +\n \"`[binding:<id>]` reference, so nothing checks it. Add a rule (a `manual` rule if it can't \" +\n \"be checked from code) and reference it. Controlled by `enforcement.unenforced_prose`.\",\n },\n CS0112: {\n severity: \"error\",\n title: \"unknown ADR id\",\n docs:\n \"A rule's `adr` field names a decision that isn't in the architecture spec's ADR log \" +\n \"(a `## ADR-NNN: <title>` heading). Fix the id or add the decision to the log.\",\n },\n CS0130: {\n severity: \"error\",\n title: \"invalid query\",\n docs:\n \"A `query` rule's Tree-sitter query doesn't compile for its language (for example unbalanced \" +\n \"parentheses or an unknown node type), or no language adapter is installed for its `lang`. \" +\n \"Queries are compiled when the specs load, before any code is read. Fix the query at the \" +\n \"reported line.\",\n },\n CS0201: {\n severity: \"error\",\n title: \"binding not found\",\n docs:\n \"No declaration in the code matches the binding's `symbol` (and `kind`). CatSpec looks in \" +\n \"the files of the `file` hint first, then in every source file, so a moved file is still \" +\n \"found. The message suggests close names of the same kind, in the hinted files first. Fix \" +\n \"the symbol, restore the code, or run `catspec sync` after a rename.\",\n },\n CS0202: {\n severity: \"error\",\n title: \"binding ambiguous\",\n docs:\n \"More than one declaration matches the binding's `symbol` and they aren't C# `partial` \" +\n \"parts of one type. The message lists every location. Qualify the symbol \" +\n \"(`Namespace.Type` or `path/to/module#Name`) or add a `file` hint.\",\n },\n CS0203: {\n severity: \"error\",\n title: \"member missing\",\n docs:\n \"The bound declaration has no member with the name a `members` entry requires. The message \" +\n \"suggests the closest existing members with their location. Add the member, rename it back, \" +\n \"mark the entry `optional: true`, or update the spec.\",\n },\n CS0204: {\n severity: \"error\",\n title: \"base type missing\",\n docs:\n \"The bound declaration doesn't directly extend or implement a type listed in `implements` \" +\n \"or `extends`. Types match by qualified-name suffix and generic arguments. Add the base \" +\n \"type or update the spec.\",\n },\n CS0205: {\n severity: \"error\",\n title: \"signature mismatch\",\n docs:\n \"A member exists but its kind, parameter types, return type or modifiers differ from the \" +\n \"spec. The message shows the expected and the found signature. `*` in `params` matches any \" +\n \"type.\",\n },\n CS0206: {\n severity: \"error\",\n title: \"attribute missing\",\n docs:\n \"The declaration or member lacks a C# attribute or TypeScript decorator that the spec \" +\n \"requires in `attributes`. Names match without a trailing `Attribute`; arguments are \" +\n \"compared only when the spec gives them.\",\n },\n CS0207: {\n severity: \"error\",\n title: \"constructor dependency missing\",\n docs:\n \"No constructor of the bound class takes every type in `constructor.requires` (dependency \" +\n \"injection). The message names the missing types for the closest constructor.\",\n },\n CS0208: {\n severity: \"error\",\n title: \"visibility or export mismatch\",\n docs:\n \"`exported` requires the declaration to be exported (TypeScript) or `public` (C#), or not, \" +\n \"or a member lacks a required visibility modifier (`public`, `private`, `protected`, \" +\n \"`internal`).\",\n },\n CS0210: {\n severity: \"error\",\n title: \"renamed\",\n docs:\n \"A declaration a binding pointed to was renamed or moved, and CatSpec found where it went \" +\n \"(a rename map, the same name in another file, a namespace or path prefix change, a git \" +\n \"file rename, the same shape, or a similarity score at or above `heal.threshold`). The \" +\n \"diagnostic carries the location-only patch (`symbol` and `file` only, never the \" +\n \"contract). Run `catspec sync --apply`; with `heal.mode: auto` the pre-commit hook applies \" +\n \"it and stages the spec. As info, it also reports backticked mentions of the old name in \" +\n \"the spec body, rewritten only with `catspec sync --apply --update-mentions`.\",\n },\n CS0215: {\n severity: \"error\",\n title: \"large refactor\",\n docs:\n \"Many bindings broke at once: more than `refactor.detect_threshold` in one commit, or any \" +\n \"while a refactor (`catspec refactor`) is in progress. The hook reports this one summary \" +\n \"instead of a binding, drift or ratchet error per binding. Run `catspec sync` to see the \" +\n \"mapping and `catspec sync --apply` to update every spec in one batch. During a refactor \" +\n \"started with `--allow-wip` it is a warning on the refactor's branch, so intermediate \" +\n \"commits go through.\",\n },\n CS0216: {\n severity: \"error\",\n title: \"ambiguous rename\",\n docs:\n \"`catspec sync` can't tell which declaration a binding's old declaration became: several \" +\n \"candidates are equally close, or a closer match took the only one. CatSpec never guesses: \" +\n \"no spec is changed. The message lists the candidates. Name the rename in a rename map \" +\n '(`{ \"symbols\": { \"Old.Name\": \"New.Name\" } }`) and run `catspec sync --apply --map ' +\n \"<file>`, or fix the binding by hand.\",\n },\n CS0217: {\n severity: \"error\",\n title: \"binding lost in refactor\",\n docs:\n \"A binding's declaration is gone and no candidate replaces it (the closest candidate, if \" +\n \"any, scores below `heal.threshold`). During a refactor this keeps the refactor open. \" +\n \"Restore the code, add the rename to a rename map (`--map`), or change the spec; \" +\n \"`catspec sync --apply --partial` applies the rest meanwhile.\",\n },\n CS0220: {\n severity: \"warning\",\n title: \"unresolvable\",\n docs:\n \"CatSpec can't decide the check from syntax alone, for example a base type that is a type \" +\n \"alias, a parameter without a type annotation, or a class without its own constructor that \" +\n \"inherits one. It is never reported as a failure of the contract; its severity is \" +\n \"`enforcement.unresolvable` (`warn` or `error`). Write the type explicitly to make it \" +\n \"checkable.\",\n },\n CS0300: {\n severity: \"warning\",\n title: \"drift\",\n docs:\n \"The shape of a bound declaration (kind, name, bases, attributes, modifiers and member \" +\n \"signatures; bodies excluded) changed since it was recorded in the spec's lock file, and the \" +\n \"spec's binding didn't change with it. Implemented specs report it with the severity of \" +\n \"`enforcement.drift` (`off`, `warn`, `strict`), in-progress specs as info. Run \" +\n \"`catspec accept <spec-id>` to record an intended change, update the spec, or change the \" +\n \"code back.\",\n },\n CS0301: {\n severity: \"error\",\n title: \"regression of a satisfied item\",\n docs:\n \"A contract item that passed before (recorded in `satisfied` of the spec's lock file) fails \" +\n \"now. This is an error even while the spec is in progress (the ratchet, ADR-006): work in \" +\n \"progress may be incomplete, but what already worked must not break. The message keeps the \" +\n \"original code and text. Fix the code, or change the spec item (a changed item leaves \" +\n \"`satisfied` until it passes again).\",\n },\n CS0400: {\n severity: \"info\",\n title: \"waived\",\n docs:\n \"A rule violation covered by a waiver (`waivers` in the spec, with a reason and an \" +\n \"optional `until` date). It doesn't fail the check. The message keeps the original code \" +\n \"and text.\",\n },\n CS0401: {\n severity: \"error\",\n title: \"waiver expired\",\n docs:\n \"A waiver's `until` date has passed. The violations it covered are reported again. Fix \" +\n \"them and remove the waiver, or extend `until` with a reason.\",\n },\n CS0502: {\n severity: \"error\",\n title: \"dependencies not satisfied\",\n docs:\n \"`catspec status` refuses the transition: `ready` needs every `depends_on` spec to exist, \" +\n \"`in-progress` and `implemented` need them `implemented` with passing contracts. The \" +\n \"message names each dependency and why. `--force` skips this gate.\",\n },\n CS0601: {\n severity: \"error\",\n title: \"forbidden call\",\n docs:\n \"A `forbid_call` rule matched a call in its scope (`within` a binding or member, the \" +\n \"spec's files, or `paths`). `*` in the pattern matches any text. Remove the call or add a \" +\n \"waiver with a reason.\",\n },\n CS0602: {\n severity: \"error\",\n title: \"required call missing\",\n docs: \"A `require_call` rule found no matching call in its scope. Add the call.\",\n },\n CS0603: {\n severity: \"error\",\n title: \"forbidden import\",\n docs:\n \"A file matching the rule's `from` imports a module that `forbid_import` forbids, or that \" +\n \"`allow_import_only` doesn't allow. Relative imports are resolved to repository paths \" +\n \"before they are matched. Remove the import or move the code.\",\n },\n CS0604: {\n severity: \"error\",\n title: \"naming rule violated\",\n docs:\n \"A declaration whose kind and name match a `naming` rule doesn't satisfy its \" +\n \"`implements`, `extends`, `attributes` or `in_path` requirement.\",\n },\n CS0605: {\n severity: \"error\",\n title: \"symbol must not exist\",\n docs:\n \"A `must_not_exist` rule found a declaration it forbids (usually a deprecated API). Remove \" +\n \"it or rename it.\",\n },\n CS0610: {\n severity: \"error\",\n title: \"query match\",\n docs:\n \"A `query` rule with `expect: absent` matched, or one with `expect: present` found \" +\n \"nothing, in its scope.\",\n },\n CS0620: {\n severity: \"error\",\n title: \"test missing\",\n docs:\n \"A `test` rule names a test symbol that doesn't exist in the code. Write the test or fix \" +\n \"the symbol.\",\n },\n CS0621: {\n severity: \"error\",\n title: \"test failed\",\n docs:\n \"With `--run-tests`, the `tests.command` of `catspec.yaml` failed for a `test` rule. The \" +\n \"command runs without a shell; `{test}` in it is replaced with the test symbol.\",\n },\n CS0700: {\n severity: \"error\",\n title: \"invalid workflow config\",\n docs:\n \"The `workflow:` section of `catspec.yaml` is invalid: an unknown preset, stage key, gate, \" +\n \"status or placeholder (valid placeholders: `{feature}`, `{feature_dir}`, `{spec}`). The \" +\n \"message names the value and suggests close matches. `catspec workflow doctor` also reports \" +\n \"it as a warning when the preset doesn't match the repository (no `openspec/` folder for \" +\n \"`openspec`, no `.specify/` for `spec-kit`).\",\n },\n CS0701: {\n severity: \"error\",\n title: \"start gate failed\",\n docs:\n \"`catspec stage start` (or MCP `start_stage`) refused the stage: one of its start gates \" +\n \"failed. The message names the gate and why, followed by the diagnostics of the underlying \" +\n \"check. Fix them and start the stage again; `--force` starts it anyway and logs the override.\",\n },\n CS0702: {\n severity: \"error\",\n title: \"finish gate failed\",\n docs:\n \"`catspec stage finish` (or MCP `finish_stage`) refused the stage: one of its finish gates \" +\n \"failed, e.g. `contracts_pass` while a contract fails or `tasks_done` while a task is \" +\n \"unticked. The status isn't changed. Fix what it reports and finish the stage again.\",\n },\n CS0703: {\n severity: \"warning\",\n title: \"implemented spec fails its final gates\",\n docs:\n \"An `implemented` spec in the commit no longer passes the built-in gates of its workflow's \" +\n \"final stage (the one that sets `implemented`), e.g. a task was unticked. Reported by the \" +\n \"pre-commit hook with the severity of `workflow.enforce_in_hook`; `command:` gates never run \" +\n \"in the hook.\",\n },\n CS0704: {\n severity: \"error\",\n title: \"driver not found\",\n docs:\n \"`catspec workflow doctor` couldn't find what a stage needs: a skill's file \" +\n \"(`<skills_dir>/<name>/SKILL.md`) or a command's program on PATH. The message names the \" +\n \"skill or command and the expected path.\",\n },\n CS0705: {\n severity: \"error\",\n title: \"stage out of order\",\n docs:\n \"A stage was started or finished before an earlier stage is done (its finish gates pass and \" +\n \"its status is reached). Run `catspec next <feature>` to see the current stage. `--force` \" +\n \"overrides the order and logs the override.\",\n },\n CS0706: {\n severity: \"warning\",\n title: \"command gate skipped\",\n docs:\n \"A `command:` gate wasn't run because `workflow.allow_commands` is false (the default), so \" +\n \"it doesn't block the stage. Run the command yourself, or set `workflow.allow_commands: \" +\n \"true` to let CatSpec run it (without a shell).\",\n },\n CS0901: {\n severity: \"warning\",\n title: \"parse error in file\",\n docs:\n \"A source file has a syntax error at the reported location. CatSpec still uses the \" +\n \"declarations it could read before and after the error, so results for that file may be \" +\n \"incomplete. Fix the syntax error. A file larger than 1 MiB, or one the language adapter \" +\n \"fails on, isn't parsed at all: it gets one CS0901 at its first line and no facts.\",\n },\n CS0902: {\n severity: \"error\",\n title: \"git unavailable\",\n docs:\n \"The command reads the git index or history (`catspec check --staged`, the pre-commit \" +\n \"hook, `install-hooks`), but git can't be run: it isn't installed or isn't on PATH. Install \" +\n \"git or fix PATH. CatSpec runs git without a shell.\",\n },\n} as const satisfies Record<string, CodeInfo>;\n\nexport type DiagnosticCode = keyof typeof CODES;\n\nexport const isRegisteredCode = (code: string): code is DiagnosticCode =>\n Object.prototype.hasOwnProperty.call(CODES, code);\n\n/** A position in a file. Lines and columns are 1-based; `file` is relative to the repo root. */\nexport interface Location {\n file: string;\n line: number;\n column: number;\n endLine?: number;\n endColumn?: number;\n}\n\n/** A frontmatter edit, see `applyPatch` (spec-editor.ts). */\nexport type PatchPath = (string | number)[];\nexport type PatchOp =\n { op: \"set\"; path: PatchPath; value: unknown } | { op: \"delete\"; path: PatchPath };\n\n/** A proposed edit of one spec file. */\nexport interface SpecPatch {\n file: string;\n ops: PatchOp[];\n}\n\nexport interface Suggestion {\n message: string;\n patch?: SpecPatch;\n}\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n severity: Severity;\n /** Id of the spec the diagnostic is about. */\n spec?: string;\n /** Where in the spec file: the binding, rule or key in the frontmatter, or the body line. */\n specLocation?: Location;\n /** Where in the code. */\n codeLocation?: Location;\n /** A human sentence that includes what was expected and what was found. */\n message: string;\n expected?: unknown;\n actual?: unknown;\n suggestions?: Suggestion[];\n ruleId?: string;\n bindingId?: string;\n /** The contract item checked, e.g. `binding:auth.login` or `rule:no-console` (ratchet, F5). */\n item?: string;\n}\n\nexport type DiagnosticInit = Omit<Diagnostic, \"code\" | \"severity\"> & { severity?: Severity };\n\n/** Creates a diagnostic with the registered default severity unless `severity` is given. */\nexport function createDiagnostic(code: DiagnosticCode, init: DiagnosticInit): Diagnostic {\n if (!isRegisteredCode(code)) {\n throw new Error(`unregistered diagnostic code ${String(code)}; add it to CODES`);\n }\n const { severity, ...rest } = init;\n return { code, severity: severity ?? CODES[code].severity, ...rest };\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = { error: 0, warning: 1, info: 2 };\n\n/** Sorts diagnostics by file, line, column, then code, so output is deterministic. */\nexport function sortDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const key = (d: Diagnostic): Location =>\n d.specLocation ?? d.codeLocation ?? { file: \"\", line: 0, column: 0 };\n return [...diagnostics].sort((a, b) => {\n const la = key(a);\n const lb = key(b);\n return (\n compareStrings(la.file, lb.file) ||\n la.line - lb.line ||\n la.column - lb.column ||\n compareStrings(a.code, b.code) ||\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] ||\n compareStrings(a.message, b.message)\n );\n });\n}\n\nexport interface DiagnosticCounts {\n errors: number;\n warnings: number;\n infos: number;\n}\n\nexport function countDiagnostics(diagnostics: readonly Diagnostic[]): DiagnosticCounts {\n const counts: DiagnosticCounts = { errors: 0, warnings: 0, infos: 0 };\n for (const d of diagnostics) {\n if (d.severity === \"error\") counts.errors++;\n else if (d.severity === \"warning\") counts.warnings++;\n else counts.infos++;\n }\n return counts;\n}\n\n/** Locale-independent string comparison, for deterministic ordering on every platform. */\nexport const compareStrings = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n","/**\n * `catspec.yaml` (plan §D4): schema, defaults and discovery. Every key has a default, so a\n * repository without a config works. The `workflow` section is kept as written and validated by\n * the workflow profiles (plan §D17).\n */\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { LineCounter, parseDocument } from \"yaml\";\nimport * as z from \"zod\";\n\nimport { formatPath, locate, schemaIssues } from \"./schema-issues.js\";\nimport { listOf, relativePosix } from \"./util.js\";\nimport { resolveWorkflow, WorkflowSchema, type WorkflowProfile } from \"./workflow/schema.js\";\n\nexport const CONFIG_FILE = \"catspec.yaml\";\n\nconst globList = z.array(z.string().min(1));\n\nconst language = (include: string[], exclude: string[]) =>\n z\n .strictObject({\n include: globList.default(include).describe(\"Source files of this language (globs).\"),\n exclude: globList.default(exclude).describe(\"Files to leave out (globs).\"),\n })\n .prefault({});\n\nexport const ConfigSchema = z\n .strictObject({\n version: z.literal(1).default(1).describe(\"Config format version.\"),\n layout: z\n .enum([\"feature-folders\", \"free\"])\n .default(\"feature-folders\")\n .describe(\"feature-folders: specs live in docs/spec/<feature>/ (CS0106 otherwise).\"),\n workflow: WorkflowSchema.prefault({}),\n specs: z\n .strictObject({\n include: globList.default([\"docs/spec/*/*.spec.md\"]).describe(\"Machine spec files.\"),\n architecture: z\n .string()\n .min(1)\n .default(\"docs/architecture/adr/*-adr.md\")\n .describe(\"The architecture spec (ADR log); exactly one file must match (CS0107).\"),\n })\n .prefault({}),\n languages: z\n .strictObject({\n typescript: language([\"src/**/*.{ts,tsx}\"], [\"**/*.d.ts\", \"**/node_modules/**\"]),\n csharp: language([\"src/**/*.cs\"], [\"**/obj/**\", \"**/bin/**\", \"**/*.g.cs\"]),\n })\n .prefault({}),\n enforcement: z\n .strictObject({\n drift: z.enum([\"off\", \"warn\", \"strict\"]).default(\"warn\"),\n unresolvable: z.enum([\"warn\", \"error\"]).default(\"warn\"),\n unenforced_prose: z.enum([\"off\", \"warn\"]).default(\"warn\"),\n })\n .prefault({}),\n tests: z\n .strictObject({\n command: z\n .union([z.string().min(1), globList.min(1)])\n .optional()\n .describe(\n \"Test command run by `check --run-tests` for each test rule, without a shell: a \" +\n \"string split at spaces, or a list of arguments. `{test}` is replaced with the \" +\n \"test symbol.\",\n ),\n })\n .prefault({}),\n heal: z\n .strictObject({\n mode: z.enum([\"off\", \"suggest\", \"auto\"]).default(\"suggest\"),\n threshold: z.number().min(0).max(1).default(0.8),\n })\n .prefault({}),\n hook: z\n .strictObject({\n stage_generated: z\n .boolean()\n .default(true)\n .describe(\"Re-stage lock files and auto-healed specs.\"),\n })\n .prefault({}),\n refactor: z\n .strictObject({\n detect_threshold: z\n .number()\n .int()\n .min(1)\n .default(10)\n .describe(\"Broken bindings in one commit that count as a large refactor.\"),\n allow_wip: z.boolean().default(false),\n })\n .prefault({}),\n mcp: z\n .strictObject({\n allow_location_edits: z.boolean().default(true),\n allow_contract_edits: z.boolean().default(false),\n })\n .prefault({}),\n })\n .describe(\"CatSpec configuration (catspec.yaml).\");\n\nexport type CatspecConfig = z.output<typeof ConfigSchema>;\n\n/** The configuration used when the repository has no `catspec.yaml`. */\nexport const defaultConfig = (): CatspecConfig => ConfigSchema.parse({});\n\nexport interface ConfigIssue {\n /** The config file, relative to the repository root. */\n file: string;\n line: number;\n column: number;\n /** Dotted key path, e.g. `heal.mode`. */\n key: string;\n message: string;\n /** Allowed values, when the key has a fixed set. */\n allowed?: string[];\n /** CS0700 for a problem in the `workflow:` section (plan §D17.7). */\n code?: \"CS0700\";\n}\n\n/** An invalid `catspec.yaml`; the CLI reports it as a usage/config error (exit code 2). */\nexport class ConfigError extends Error {\n constructor(readonly issues: ConfigIssue[]) {\n super(\n issues\n .map((i) => `${i.file}:${i.line}:${i.column}: ${i.code ? `${i.code} ` : \"\"}${i.message}`)\n .join(\"\\n\"),\n );\n this.name = \"ConfigError\";\n }\n}\n\n/** Parses and validates the text of a `catspec.yaml`. Throws `ConfigError`. */\nexport function parseConfig(text: string, file = CONFIG_FILE): CatspecConfig {\n const lineCounter = new LineCounter();\n const doc = parseDocument(text, { lineCounter, prettyErrors: false });\n const at = (offset: number): { line: number; column: number } => {\n const { line, col } = lineCounter.linePos(offset);\n return { line, column: col };\n };\n\n if (doc.errors.length > 0) {\n throw new ConfigError(\n doc.errors.map((error) => ({\n file,\n ...at(error.pos[0]),\n key: \"\",\n message: `invalid YAML: ${error.message.split(\"\\n\")[0]!.replace(/ at line \\d+.*$/, \"\")}`,\n })),\n );\n }\n\n let value: unknown;\n try {\n value = (doc.toJS() as unknown) ?? {};\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new ConfigError([\n { file, line: 1, column: 1, key: \"\", message: `the config can't be read: ${reason}` },\n ]);\n }\n const result = ConfigSchema.safeParse(value);\n if (result.success) return withWorkflowDefaults(result.data, value);\n\n throw new ConfigError(\n schemaIssues(result.error.issues, doc, ConfigSchema).map((issue) => {\n const range = locate(doc, issue.path, issue.atKey);\n const allowed =\n Array.isArray(issue.expected) && issue.expected.every((v) => typeof v === \"string\")\n ? issue.expected\n : undefined;\n const hint =\n issue.suggestions.length > 0 ? `; did you mean ${listOf(issue.suggestions)}?` : \"\";\n return {\n file,\n ...(range ? at(range.start) : { line: 1, column: 1 }),\n key: formatPath(issue.path),\n message: issue.message + hint,\n ...(allowed ? { allowed } : {}),\n ...(issue.path[0] === \"workflow\" ? { code: \"CS0700\" as const } : {}),\n };\n }),\n );\n}\n\n/** The workflow profile in effect (plan §D17): the preset with the config's overrides. */\nexport const workflowProfile = (config: CatspecConfig): WorkflowProfile =>\n resolveWorkflow(config.workflow);\n\n/**\n * A preset whose features live outside `docs/spec/` (OpenSpec, Spec Kit, a custom `feature_dir`)\n * changes the defaults of `specs.include` and `layout`; values written in the file win.\n */\nfunction withWorkflowDefaults(config: CatspecConfig, raw: unknown): CatspecConfig {\n const written = (raw ?? {}) as { layout?: unknown; specs?: { include?: unknown } | null };\n const profile = workflowProfile(config);\n return {\n ...config,\n layout: written.layout === undefined ? profile.layout : config.layout,\n specs: {\n ...config.specs,\n include: written.specs?.include === undefined ? profile.specsInclude : config.specs.include,\n },\n };\n}\n\nexport interface LoadedConfig {\n config: CatspecConfig;\n /**\n * Absolute path of the repository root: the folder of the `catspec.yaml` that was found, else\n * (no config, or `--config`) the git root, else `cwd`.\n */\n root: string;\n /** Absolute path of the config file, if one was found. */\n file?: string;\n}\n\n/** The closest folder at or above `dir` that contains `.git`, if any. */\nexport function findGitRoot(dir: string): string | undefined {\n for (let current = resolve(dir); ; current = dirname(current)) {\n if (existsSync(join(current, \".git\"))) return current;\n if (dirname(current) === current) return undefined;\n }\n}\n\n/**\n * The git common directory of the repository at `root` (where `.git` is): `.git` itself, or for a\n * linked worktree the main repository's `.git`, so every worktree shares one cache. Read from\n * the files git writes, without running git. Undefined outside a git repository.\n */\nexport function findGitCommonDir(root: string): string | undefined {\n const dotGit = join(root, \".git\");\n if (!existsSync(dotGit)) return undefined;\n let gitDir = dotGit;\n if (statSync(dotGit).isFile()) {\n const pointer = /^gitdir:\\s*(.+?)\\s*$/m.exec(readFileSync(dotGit, \"utf8\"));\n if (!pointer) return undefined;\n gitDir = resolve(root, pointer[1]!);\n }\n const commonDir = join(gitDir, \"commondir\");\n return existsSync(commonDir) ? resolve(gitDir, readFileSync(commonDir, \"utf8\").trim()) : gitDir;\n}\n\n/**\n * Finds `catspec.yaml` by walking up from `cwd` to the git root (or the file-system root outside\n * a git repository).\n */\nexport function findConfig(cwd: string): string | undefined {\n const stop = findGitRoot(cwd);\n for (let current = resolve(cwd); ; current = dirname(current)) {\n const candidate = join(current, CONFIG_FILE);\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;\n if (current === stop || dirname(current) === current) return undefined;\n }\n}\n\n/**\n * Loads the configuration for a command run in `cwd`. `configPath` (the `--config` flag) skips\n * discovery. Throws `ConfigError` for an invalid file, and when `configPath` doesn't exist.\n */\nexport async function loadConfig(cwd: string, configPath?: string): Promise<LoadedConfig> {\n const file = configPath ? resolve(cwd, configPath) : findConfig(cwd);\n if (!file) {\n return { config: defaultConfig(), root: findGitRoot(cwd) ?? resolve(cwd) };\n }\n const text = await readFile(file, \"utf8\").catch(() => undefined);\n if (text === undefined) {\n throw new ConfigError([\n { file, line: 1, column: 1, key: \"\", message: `config file not found: ${file}` },\n ]);\n }\n // A config given with --config may live anywhere (e.g. ci/catspec.yaml); the specs are still\n // found from the repository root.\n const root = configPath ? (findGitRoot(cwd) ?? resolve(cwd)) : dirname(file);\n return { config: parseConfig(text, relativePosix(root, file)), root, file };\n}\n\n/** JSON Schema of `catspec.yaml`, for editor autocompletion. */\nexport const configJsonSchema = (): Record<string, unknown> =>\n z.toJSONSchema(ConfigSchema, { io: \"input\", target: \"draft-2020-12\" });\n","/**\n * Turns zod validation issues into messages that name the YAML key, the value found and the\n * allowed values, and finds the YAML node each issue is about, so diagnostics point to the exact\n * line (plan §D5, PBIs `config-loader` and `spec-schema`).\n */\nimport { isMap, isScalar, isSeq, type Document, type Node } from \"yaml\";\nimport type * as z from \"zod\";\n\nimport type { PatchPath } from \"./diagnostics.js\";\nimport { didYouMean, listOf } from \"./util.js\";\n\nexport interface SchemaIssue {\n /** Full path of the value (or, with `atKey`, of the key) the issue is about. */\n path: PatchPath;\n /** Point at the key node instead of its value (unknown keys). */\n atKey: boolean;\n message: string;\n expected?: unknown;\n actual?: unknown;\n /** \"Did you mean\" candidates. */\n suggestions: string[];\n}\n\n/** Formats a path as `bindings[0].kind`. */\nexport function formatPath(path: PatchPath): string {\n let out = \"\";\n for (const segment of path) {\n out += typeof segment === \"number\" ? `[${segment}]` : out ? `.${segment}` : segment;\n }\n return out;\n}\n\n/** Describes a YAML value for a message: `\"klass\"`, `12`, `a list`, `a map`, `nothing`. */\nexport function describeValue(value: unknown): string {\n if (value === undefined || value === null) return \"nothing\";\n if (Array.isArray(value)) return \"a list\";\n if (typeof value === \"object\") return \"a map\";\n return JSON.stringify(value);\n}\n\ntype AnySchema = z.core.$ZodType;\n\n/** Unwraps optional / default / pipe wrappers around a schema. */\nfunction unwrap(schema: AnySchema): AnySchema {\n let current = schema;\n for (;;) {\n const def = current._zod.def as { type: string; innerType?: AnySchema; in?: AnySchema };\n if (def.innerType) current = def.innerType;\n else if (def.type === \"pipe\" && def.in) current = def.in;\n else return current;\n }\n}\n\n/** The keys an object schema at `path` accepts (for unions: the keys of every object option). */\nexport function objectKeysAt(schema: AnySchema, path: PatchPath): string[] {\n let candidates: AnySchema[] = [schema];\n for (const segment of path) {\n const next: AnySchema[] = [];\n for (const candidate of candidates.flatMap(expandUnion)) {\n const def = candidate._zod.def as {\n type: string;\n shape?: Record<string, AnySchema>;\n element?: AnySchema;\n catchall?: AnySchema;\n };\n if (def.type === \"object\" && typeof segment === \"string\") {\n const field = def.shape?.[segment] ?? def.catchall;\n if (field) next.push(field);\n } else if (def.type === \"array\" && typeof segment === \"number\" && def.element) {\n next.push(def.element);\n } else if (def.type === \"record\" && typeof segment === \"string\") {\n const value = (def as { valueType?: AnySchema }).valueType;\n if (value) next.push(value);\n }\n }\n candidates = next;\n }\n const keys = candidates\n .flatMap(expandUnion)\n .flatMap((c) => Object.keys((c._zod.def as { shape?: object }).shape ?? {}));\n return [...new Set(keys)];\n}\n\nfunction expandUnion(schema: AnySchema): AnySchema[] {\n const inner = unwrap(schema);\n const def = inner._zod.def as { type: string; options?: AnySchema[] };\n return def.type === \"union\" && def.options ? def.options.flatMap(expandUnion) : [inner];\n}\n\n/** The plain value at `path` in a YAML document, or undefined. */\nexport function valueAt(doc: Document, path: PatchPath): unknown {\n const node = doc.getIn(path, true) as Node | undefined | null;\n if (node === undefined || node === null) return undefined;\n if (isScalar(node)) return node.value;\n try {\n return node.toJSON() as unknown;\n } catch {\n return undefined; // e.g. too many aliases; the caller reports the document itself\n }\n}\n\n/**\n * The source range `[start, end)` of the node at `path` in `doc` (the key node with `atKey`). When\n * the path doesn't exist, the range of its closest existing ancestor; undefined for the root of\n * an empty document.\n */\nexport function locate(\n doc: Document,\n path: PatchPath,\n atKey = false,\n): { start: number; end: number } | undefined {\n let node = doc.contents;\n let found: [number, number, number] | undefined = node?.range ?? undefined;\n for (const [index, segment] of path.entries()) {\n const last = index === path.length - 1;\n if (isMap(node)) {\n const pair = node.items.find(\n (p) => isScalar(p.key) && String(p.key.value) === String(segment),\n );\n if (!pair || !isScalar(pair.key)) break;\n const keyRange = pair.key.range ?? found;\n if ((last && atKey) || pair.value === null || !(pair.value as Node | undefined)?.range) {\n found = keyRange;\n if (last && atKey) break;\n node = null;\n continue;\n }\n node = pair.value as Node;\n found = node.range ?? found;\n } else if (isSeq(node) && typeof segment === \"number\") {\n const item = node.items[segment] as Node | null | undefined;\n if (!item?.range) break;\n node = item;\n found = item.range;\n } else {\n break;\n }\n }\n return found ? { start: found[0], end: found[1] } : undefined;\n}\n\n/**\n * Converts zod issues for the value at `basePath` (validated by `schema`) into messages. `doc`\n * gives the values that were found; `schema` the keys that are allowed. `schemaPath` is the path\n * `schema` validates, when the issues come from a nested schema (a union branch).\n */\nexport function schemaIssues(\n issues: readonly z.core.$ZodIssue[],\n doc: Document,\n schema: AnySchema,\n basePath: PatchPath = [],\n schemaPath: PatchPath = basePath,\n): SchemaIssue[] {\n const out: SchemaIssue[] = [];\n for (const issue of issues) {\n const path = [...basePath, ...(issue.path as PatchPath)];\n const where = formatPath(path);\n const prefix = where ? `${where}: ` : \"\";\n const actual = valueAt(doc, path);\n\n switch (issue.code) {\n case \"invalid_type\": {\n if (actual === undefined && path.length > 0) {\n const parent = path.slice(0, -1);\n const key = String(path[path.length - 1]);\n const owner = formatPath(parent);\n out.push({\n path: parent,\n atKey: false,\n message: `${owner ? `${owner}: ` : \"\"}missing required key \"${key}\"`,\n expected: key,\n suggestions: [],\n });\n } else {\n out.push({\n path,\n atKey: false,\n message: `${prefix}expected ${article(issue.expected)}, found ${describeValue(actual)}`,\n expected: issue.expected,\n actual,\n suggestions: [],\n });\n }\n break;\n }\n case \"invalid_value\": {\n const values = issue.values.map((v) => (typeof v === \"string\" ? v : String(v)));\n out.push({\n path,\n atKey: false,\n message: `${prefix}invalid value ${describeValue(actual)}; allowed: ${listOf(values)}`,\n expected: issue.values,\n actual,\n suggestions: typeof actual === \"string\" ? didYouMean(actual, values) : [],\n });\n break;\n }\n case \"unrecognized_keys\": {\n const allowed = objectKeysAt(schema, path.slice(schemaPath.length)).filter(\n (k) => !issue.keys.includes(k),\n );\n for (const key of issue.keys) {\n out.push({\n path: [...path, key],\n atKey: true,\n message:\n `unknown key \"${key}\"${where ? ` in ${where}` : \"\"}` +\n (allowed.length > 0 ? `; allowed: ${listOf(allowed)}` : \"\"),\n expected: allowed,\n actual: key,\n suggestions: didYouMean(key, allowed),\n });\n }\n break;\n }\n case \"invalid_union\": {\n const discriminator = issue as typeof issue & { note?: string; options?: unknown[] };\n if (discriminator.note === \"No matching discriminator\" && discriminator.options) {\n const values = discriminator.options.map(String);\n out.push({\n path,\n atKey: false,\n message:\n actual === undefined\n ? `${formatPath(path.slice(0, -1))}: missing required key \"${String(path.at(-1))}\"; allowed values: ${listOf(values)}`\n : `${prefix}invalid value ${describeValue(actual)}; allowed: ${listOf(values)}`,\n expected: values,\n actual,\n suggestions: typeof actual === \"string\" ? didYouMean(actual, values) : [],\n });\n break;\n }\n // Report the branch that matched the value's type; if none did, name the accepted types.\n const branch = issue.errors.find(\n (errors) => !errors.some((e) => e.code === \"invalid_type\" && e.path.length === 0),\n );\n if (branch) {\n out.push(...schemaIssues(branch, doc, schema, path, schemaPath));\n } else {\n const types = issue.errors.flatMap((errors) =>\n errors.flatMap((e) => (e.code === \"invalid_type\" ? [article(e.expected)] : [])),\n );\n out.push({\n path,\n atKey: false,\n message: `${prefix}expected ${[...new Set(types)].join(\" or \")}, found ${describeValue(actual)}`,\n expected: types,\n actual,\n suggestions: [],\n });\n }\n break;\n }\n case \"too_small\":\n case \"too_big\": {\n const limit = issue.code === \"too_small\" ? issue.minimum : issue.maximum;\n const word = issue.code === \"too_small\" ? \"at least\" : \"at most\";\n const what =\n issue.origin === \"string\" && issue.code === \"too_small\" && Number(limit) === 1\n ? \"must not be empty\"\n : issue.origin === \"array\"\n ? `must have ${word} ${String(limit)} item(s)`\n : issue.origin === \"string\"\n ? `must have ${word} ${String(limit)} character(s)`\n : `must be ${word} ${String(limit)}`;\n out.push({ path, atKey: false, message: `${prefix}${what}`, actual, suggestions: [] });\n break;\n }\n default: {\n // invalid_format and custom issues carry the schema's own message.\n const message = issue.message.startsWith(\"Invalid\")\n ? `invalid value ${describeValue(actual)}`\n : issue.message;\n out.push({ path, atKey: false, message: `${prefix}${message}`, actual, suggestions: [] });\n }\n }\n }\n return out;\n}\n\nconst article = (type: string): string =>\n type === \"array\"\n ? \"a list\"\n : type === \"object\"\n ? \"a map\"\n : /^[aeiou]/.test(type)\n ? `an ${type}`\n : `a ${type}`;\n","/** Small helpers shared by the spec model: text positions, paths and \"did you mean\". */\nimport { createHash } from \"node:crypto\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\n\nimport picomatch from \"picomatch\";\n\nimport { compareStrings } from \"./diagnostics.js\";\n\n/** Maps string offsets to 1-based line and column numbers. Works for `\\n` and `\\r\\n` text. */\nexport class LineIndex {\n private readonly starts: number[] = [0];\n\n constructor(readonly text: string) {\n for (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n this.starts.push(i + 1);\n }\n }\n\n /** 1-based line and column of `offset` (column counts UTF-16 code units). */\n position(offset: number): { line: number; column: number } {\n const clamped = Math.max(0, Math.min(offset, this.text.length));\n let low = 0;\n let high = this.starts.length - 1;\n while (low < high) {\n const mid = (low + high + 1) >> 1;\n if (this.starts[mid]! <= clamped) low = mid;\n else high = mid - 1;\n }\n return { line: low + 1, column: clamped - this.starts[low]! + 1 };\n }\n\n /** Offset of the start of a 1-based line. */\n lineStart(line: number): number {\n return this.starts[Math.max(0, Math.min(line - 1, this.starts.length - 1))]!;\n }\n}\n\n/** Converts a path to forward slashes, for output that is the same on every platform. */\nexport const toPosix = (path: string): string => (sep === \"\\\\\" ? path.replace(/\\\\/g, \"/\") : path);\n\n/** `path` relative to `root`, with forward slashes. */\nexport const relativePosix = (root: string, path: string): string => toPosix(relative(root, path));\n\n/** Joins a list as \"a, b, c\". */\n/** `text` with every regular-expression metacharacter escaped. */\nexport const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nexport const listOf = (items: readonly unknown[]): string => items.map(String).join(\", \");\n\n/** Optimal string alignment (Damerau-Levenshtein) distance between two strings. */\nexport function editDistance(a: string, b: string): number {\n const rows = a.length + 1;\n const cols = b.length + 1;\n const d: number[][] = Array.from({ length: rows }, (_, i) =>\n Array.from({ length: cols }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n );\n for (let i = 1; i < rows; i++) {\n for (let j = 1; j < cols; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n let best = Math.min(d[i - 1]![j]! + 1, d[i]![j - 1]! + 1, d[i - 1]![j - 1]! + cost);\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n best = Math.min(best, d[i - 2]![j - 2]! + 1);\n }\n d[i]![j] = best;\n }\n }\n return d[a.length]![b.length]!;\n}\n\n/**\n * Up to `max` candidates close to `input` (case-insensitive edit distance at most a third of the\n * input's length, minimum 1), closest first.\n */\nexport function didYouMean(input: string, candidates: Iterable<string>, max = 3): string[] {\n const needle = input.toLowerCase();\n const limit = Math.max(1, Math.floor(needle.length / 3));\n const scored: { candidate: string; distance: number }[] = [];\n for (const candidate of new Set(candidates)) {\n if (candidate === input) continue;\n const distance = editDistance(needle, candidate.toLowerCase());\n if (distance <= limit) scored.push({ candidate, distance });\n }\n return scored\n .sort((x, y) => x.distance - y.distance || compareStrings(x.candidate, y.candidate))\n .slice(0, max)\n .map((s) => s.candidate);\n}\n\n/** Converts a name to kebab-case: \"My Repo_2\" → \"my-repo-2\". */\nexport const kebabCase = (name: string): string =>\n name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n\n/**\n * Lists every file under `root` as a sorted, root-relative POSIX path. Skips `node_modules`,\n * dot-folders (`.git`, `.github`, …), symbolic links and nested projects (`withoutNestedProjects`).\n */\nexport async function listFiles(root: string): Promise<string[]> {\n const files: string[] = [];\n const walk = async (dir: string): Promise<void> => {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n await Promise.all(\n entries.map(async (entry) => {\n if (entry.isSymbolicLink()) return;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name.startsWith(\".\")) return;\n await walk(path);\n } else if (entry.isFile()) {\n files.push(relativePosix(root, path));\n }\n }),\n );\n };\n await walk(root);\n return withoutNestedProjects(files.sort(compareStrings));\n}\n\n/**\n * Leaves out the files of nested projects: a folder below the root with its own `catspec.yaml`\n * (an example repository, a vendored project) is checked on its own, not as part of the root.\n */\nexport const withoutNestedProjects = (paths: readonly string[]): string[] => {\n const nested = paths\n .filter((path) => path.endsWith(\"/catspec.yaml\"))\n .map((path) => path.slice(0, -\"catspec.yaml\".length));\n return nested.length === 0\n ? [...paths]\n : paths.filter((path) => !nested.some((folder) => path.startsWith(folder)));\n};\n\n/**\n * True for a root-relative POSIX path that `listFiles` would list: no `node_modules` and no\n * dot-folder (`.git`, `.github`, …) on the way. For listings that don't come from disk (the git\n * index), so every source sees the same files.\n */\nexport const isListedPath = (path: string): boolean =>\n path\n .split(\"/\")\n .slice(0, -1)\n .every((segment) => segment !== \"node_modules\" && !segment.startsWith(\".\"));\n\n/** A matcher for root-relative POSIX paths against globs (dot-files excluded). */\nexport const globMatcher = (patterns: string | readonly string[]): ((path: string) => boolean) =>\n picomatch(typeof patterns === \"string\" ? patterns : [...patterns], { dot: false });\n\n/** The git blob SHA-1 of a file's content: the same id `git hash-object` prints. */\nexport const gitBlobSha = (content: string | Uint8Array): string => {\n const bytes = typeof content === \"string\" ? Buffer.from(content, \"utf8\") : content;\n return createHash(\"sha1\").update(`blob ${bytes.length}\\0`).update(bytes).digest(\"hex\");\n};\n","/**\n * The `workflow:` section of `catspec.yaml` (plan §D17.1–§D17.3), PBIs `workflow-config` and\n * `workflow-presets`: stages, who drives them, what they produce, and the gates and status\n * transitions that apply when a stage starts and finishes. A preset fills in every key; the\n * config can still override any of them (`stages` replaces the preset's list as a whole).\n *\n * The section is validated with the rest of the config; its problems are config errors with the\n * code CS0700.\n */\nimport * as z from \"zod\";\n\nimport { SPEC_STATUSES, type SpecStatus } from \"../spec-schema.js\";\nimport { escapeRegExp } from \"../util.js\";\n\nexport const PRESETS = [\"catspec\", \"openspec\", \"spec-kit\", \"custom\"] as const;\nexport type PresetName = (typeof PRESETS)[number];\n\n/** The built-in gates (plan §D17.4). */\nexport const GATES = [\n \"specs_valid\",\n \"artifacts\",\n \"contracts_declared\",\n \"deps_known\",\n \"deps_ready\",\n \"contracts_pass\",\n \"tasks_done\",\n \"no_drift\",\n \"adr_valid\",\n] as const;\nexport type BuiltinGate = (typeof GATES)[number];\n\n/** Placeholders of path templates and `command:` gates. */\nexport const PLACEHOLDERS = [\"{feature}\", \"{feature_dir}\", \"{spec}\"] as const;\n\nconst PLACEHOLDER = /\\{[^{}]*\\}/g;\n\n/** The placeholders in `text` that aren't valid. */\nexport const unknownPlaceholders = (text: string): string[] =>\n [...text.matchAll(PLACEHOLDER)]\n .map((m) => m[0])\n .filter((p) => !(PLACEHOLDERS as readonly string[]).includes(p));\n\nconst template = z\n .string()\n .min(1)\n .superRefine((value, ctx) => {\n for (const placeholder of unknownPlaceholders(value)) {\n ctx.addIssue({\n code: \"custom\",\n message: `unknown placeholder \"${placeholder}\"; valid: ${PLACEHOLDERS.join(\", \")}`,\n });\n }\n });\n\nconst GateSchema = z.union([\n z.enum(GATES),\n z.strictObject({\n command: template.describe(\n \"A command that must exit with 0, run without a shell; only with workflow.allow_commands.\",\n ),\n }),\n]);\n\nconst TransitionSchema = z\n .strictObject({\n gates: z.array(GateSchema).default([]).describe(\"Gates that must pass.\"),\n status: z\n .enum(SPEC_STATUSES)\n .optional()\n .describe(\"The status the stage's specs get when the gates pass.\"),\n })\n .prefault({});\n\nconst DriverSchema = z\n .union([\n z.literal(\"manual\"),\n z.strictObject({ skill: z.string().min(1).describe(\"An agent skill, in skills_dir.\") }),\n z.strictObject({ slash: z.string().min(1).describe(\"An agent slash command.\") }),\n z.strictObject({ command: template.describe(\"A command the person or agent runs.\") }),\n z.strictObject({ manual: z.string().min(1).describe(\"What the person does.\") }),\n ])\n .describe(\"Who performs the stage.\");\n\nconst StageSchema = z.strictObject({\n id: z.string().regex(/^[a-z][a-z0-9-]*$/, { error: \"must be lowercase letters, digits and '-'\" }),\n per: z\n .enum([\"feature\", \"spec\"])\n .default(\"feature\")\n .describe(\"feature: once for the feature folder; spec: once per work item (spec).\"),\n driver: DriverSchema.default(\"manual\"),\n produces: z.array(template).default([]).describe(\"Path templates of the stage's artifacts.\"),\n start: TransitionSchema,\n finish: TransitionSchema,\n});\n\nexport const WorkflowSchema = z\n .strictObject({\n preset: z.enum(PRESETS).default(\"catspec\").describe(\"A ready-made profile, or custom.\"),\n allow_commands: z\n .boolean()\n .default(false)\n .describe(\"Let `command:` gates run commands (without a shell).\"),\n enforce_in_hook: z\n .enum([\"off\", \"warn\", \"error\"])\n .default(\"warn\")\n .describe(\"Re-check implemented specs' final gates in the pre-commit hook (CS0703).\"),\n feature_dir: z\n .union([template, z.array(template).min(1)])\n .optional()\n .describe(\n 'Where features live, e.g. \"docs/spec/{feature}\", or a list for features at several depths ' +\n '(domain folders): [\"docs/spec/billing/{feature}\", \"docs/spec/{feature}\"].',\n ),\n skills_dir: z.string().min(1).optional().describe(\"Where `skill:` drivers are found.\"),\n stages: z\n .array(StageSchema)\n .min(1)\n .optional()\n .describe(\"The stages, in order; replaces the preset's stages.\"),\n })\n .superRefine((value, ctx) => {\n const dirs = value.feature_dir;\n for (const [index, dir] of (typeof dirs === \"string\" ? [dirs] : (dirs ?? [])).entries()) {\n if (dir.split(\"{feature}\").length !== 2 || dir.includes(\"{spec}\")) {\n ctx.addIssue({\n code: \"custom\",\n path: typeof dirs === \"string\" ? [\"feature_dir\"] : [\"feature_dir\", index],\n message:\n 'feature_dir must contain \"{feature}\" exactly once and no \"{spec}\", e.g. \"docs/spec/{feature}\"',\n });\n }\n }\n const seen = new Set<string>();\n for (const [index, stage] of (value.stages ?? []).entries()) {\n if (seen.has(stage.id)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"stages\", index, \"id\"],\n message: `duplicate stage id \"${stage.id}\"`,\n });\n }\n seen.add(stage.id);\n }\n })\n .describe(\"Workflow profile (plan §D17).\");\n\nexport type WorkflowInput = z.output<typeof WorkflowSchema>;\n\nexport type Gate = BuiltinGate | { command: string };\n\nexport type Driver =\n | { kind: \"skill\"; name: string }\n | { kind: \"slash\"; name: string }\n | { kind: \"command\"; command: string }\n | { kind: \"manual\"; text?: string };\n\nexport interface Transition {\n gates: Gate[];\n status?: SpecStatus;\n}\n\nexport interface Stage {\n id: string;\n per: \"feature\" | \"spec\";\n driver: Driver;\n produces: string[];\n start: Transition;\n finish: Transition;\n}\n\n/** The workflow in effect: the preset with the config's overrides. */\nexport interface WorkflowProfile {\n preset: PresetName;\n /** The version of the third-party tool layout the preset follows. */\n presetVersion?: string;\n allowCommands: boolean;\n enforceInHook: \"off\" | \"warn\" | \"error\";\n /** The first feature folder pattern, for messages and templates. */\n featureDir: string;\n /** Every feature folder pattern, most specific first (see `featureFolderOf`). */\n featureDirs: string[];\n skillsDir: string;\n stages: Stage[];\n /** Folder names under the feature folder's parent that aren't features (OpenSpec's archive). */\n notFeatures: string[];\n /** Files every stage passes to agents as extra context (Spec Kit's constitution). */\n context: string[];\n /** The `specs.include` default that matches this workflow's feature folders. */\n specsInclude: string[];\n /** The `layout` default: `free` when specs move out of their feature folder (OpenSpec). */\n layout: \"feature-folders\" | \"free\";\n}\n\nexport const gateName = (gate: Gate): string =>\n typeof gate === \"string\" ? gate : `command: ${gate.command}`;\n\nexport const driverText = (driver: Driver): string => {\n switch (driver.kind) {\n case \"skill\":\n return `skill ${driver.name}`;\n case \"slash\":\n return `slash command ${driver.name}`;\n case \"command\":\n return `command \\`${driver.command}\\``;\n case \"manual\":\n return driver.text ? `manual: ${driver.text}` : \"manual\";\n }\n};\n\nconst driverOf = (input: z.output<typeof DriverSchema>): Driver => {\n if (input === \"manual\") return { kind: \"manual\" };\n if (\"skill\" in input) return { kind: \"skill\", name: input.skill };\n if (\"slash\" in input) return { kind: \"slash\", name: input.slash };\n if (\"command\" in input) return { kind: \"command\", command: input.command };\n return { kind: \"manual\", text: input.manual };\n};\n\nconst transition = (gates: Gate[], status?: SpecStatus): Transition =>\n status === undefined ? { gates } : { gates, status };\n\nconst stage = (\n id: string,\n per: Stage[\"per\"],\n driver: Driver,\n produces: string[],\n start: Transition,\n finish: Transition,\n): Stage => ({ id, per, driver, produces, start, finish });\n\n/** The stages of CatSpec's own flow (plan §D17.2) with the given drivers. */\nconst catspecStages = (drivers: Record<\"spec\" | \"plan\" | \"task\" | \"close\", Driver>): Stage[] => [\n stage(\n \"spec\",\n \"feature\",\n drivers.spec,\n [\"{feature_dir}/spec.md\", \"{feature_dir}/*.spec.md\"],\n transition([]),\n transition([\"specs_valid\", \"artifacts\", \"contracts_declared\"]),\n ),\n stage(\n \"plan\",\n \"feature\",\n drivers.plan,\n [\"{feature_dir}/plan.md\"],\n transition([]),\n transition([\"artifacts\", \"deps_known\"], \"ready\"),\n ),\n stage(\n \"task\",\n \"spec\",\n drivers.task,\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([\"contracts_pass\"]),\n ),\n stage(\n \"close\",\n \"spec\",\n drivers.close,\n [],\n transition([]),\n transition([\"contracts_pass\", \"tasks_done\", \"no_drift\"], \"implemented\"),\n ),\n];\n\ntype Preset = Omit<WorkflowProfile, \"allowCommands\" | \"enforceInHook\" | \"preset\" | \"featureDirs\">;\n\n/**\n * The presets (plan §D17.3). Third-party layouts and command names were checked on 2026-10-22:\n * OpenSpec 1.x (`/opsx:*` slash commands, `openspec validate`, changes archived to\n * `openspec/changes/archive/<date>-<name>/`) and Spec Kit (`/speckit.*` commands, feature folders\n * `specs/<NNN-name>/`, constitution in `.specify/memory/constitution.md`).\n */\nexport const PRESET_PROFILES: Record<Exclude<PresetName, \"custom\">, Preset> = {\n catspec: {\n featureDir: \"docs/spec/{feature}\",\n skillsDir: \".claude/skills\",\n stages: catspecStages({\n spec: {\n kind: \"manual\",\n text: \"write spec.md and the *.spec.md work items (MCP prompt stage-spec)\",\n },\n plan: {\n kind: \"manual\",\n text: \"order the work items and write plan.md (MCP prompt stage-plan)\",\n },\n task: { kind: \"manual\", text: \"implement the work item (MCP prompt stage-task)\" },\n close: {\n kind: \"manual\",\n text: \"tick the tasks and close the work item (MCP prompt stage-close)\",\n },\n }),\n notFeatures: [],\n context: [],\n specsInclude: [\"docs/spec/*/*.spec.md\"],\n layout: \"feature-folders\",\n },\n openspec: {\n presetVersion: \"openspec-1\",\n featureDir: \"openspec/changes/{feature}\",\n skillsDir: \".claude/skills\",\n stages: [\n stage(\n \"proposal\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:propose\" },\n [\"{feature_dir}/proposal.md\", \"{feature_dir}/tasks.md\"],\n transition([]),\n transition([\"artifacts\", { command: \"openspec validate {feature}\" }, \"specs_valid\"]),\n ),\n stage(\n \"apply\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:apply\" },\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([]),\n ),\n stage(\n \"archive\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:archive\" },\n [],\n transition([\"contracts_pass\", \"tasks_done\"], \"implemented\"),\n transition([]),\n ),\n ],\n notFeatures: [\"archive\"],\n context: [],\n specsInclude: [\"openspec/changes/**/*.spec.md\"],\n layout: \"free\",\n },\n \"spec-kit\": {\n presetVersion: \"spec-kit-1\",\n featureDir: \"specs/{feature}\",\n skillsDir: \".claude/skills\",\n stages: [\n stage(\n \"specify\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.specify\" },\n [\"{feature_dir}/spec.md\"],\n transition([]),\n transition([\"artifacts\", \"specs_valid\"]),\n ),\n stage(\n \"plan\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.plan\" },\n [\"{feature_dir}/plan.md\"],\n transition([]),\n transition([\"artifacts\", \"deps_known\"], \"ready\"),\n ),\n stage(\n \"tasks\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.tasks\" },\n [\"{feature_dir}/tasks.md\"],\n transition([]),\n transition([\"artifacts\"]),\n ),\n stage(\n \"implement\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.implement\" },\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([\"contracts_pass\", \"tasks_done\"], \"implemented\"),\n ),\n ],\n notFeatures: [],\n context: [\".specify/memory/constitution.md\"],\n specsInclude: [\"specs/*/*.spec.md\"],\n layout: \"feature-folders\",\n },\n};\n\n/** The `sdd-*` skills of the custom preset's example (plan §D17.2). */\nexport const SDD_SKILLS = [\"sdd-spec\", \"sdd-plan\", \"sdd-task\", \"sdd-close\"] as const;\n\n/** `specs.include` for machine specs directly in each feature folder. */\nconst includeFor = (featureDirs: readonly string[]): string[] =>\n featureDirs.map((dir) => `${dir.replaceAll(\"{feature}\", \"*\").replace(/\\/+$/, \"\")}/*.spec.md`);\n\n/** Feature folder patterns, most specific first: more folders, then longer. */\nconst bySpecificity = (dirs: readonly string[]): string[] =>\n [...new Set(dirs)].sort(\n (a, b) => b.split(\"/\").length - a.split(\"/\").length || b.length - a.length,\n );\n\n/** A feature folder: its name (`{feature}`) and its path. */\nexport interface FeatureFolder {\n name: string;\n dir: string;\n}\n\n/**\n * The feature folder a root-relative path is in, by the most specific matching pattern of\n * `featureDirs`. The folders that hold another pattern's features (`docs/spec/billing` for\n * `docs/spec/billing/{feature}`) are never features themselves.\n */\nexport function featureFolderOf(\n featureDirs: readonly string[],\n path: string,\n): FeatureFolder | undefined {\n const parents = new Set(\n featureDirs.map((dir) => dir.slice(0, dir.indexOf(\"{feature}\")).replace(/\\/+$/, \"\")),\n );\n for (const dir of featureDirs) {\n const [before, after] = dir.split(\"{feature}\").map(escapeRegExp);\n const match = new RegExp(`^(${before}([^/]+)${after})/`).exec(path);\n if (match && !parents.has(match[1]!)) return { name: match[2]!, dir: match[1]! };\n }\n return undefined;\n}\n\n/** The feature folder patterns in words, for messages: \"docs/spec/{feature}\". */\nexport const featureDirsText = (profile: WorkflowProfile): string => profile.featureDirs.join(\", \");\n\n/** The profile in effect for a validated `workflow:` section. */\nexport function resolveWorkflow(input: WorkflowInput): WorkflowProfile {\n const base: Preset =\n input.preset === \"custom\"\n ? {\n featureDir: \"docs/spec/{feature}\",\n skillsDir: \".claude/skills\",\n stages: catspecStages({\n spec: { kind: \"skill\", name: \"sdd-spec\" },\n plan: { kind: \"skill\", name: \"sdd-plan\" },\n task: { kind: \"skill\", name: \"sdd-task\" },\n close: { kind: \"skill\", name: \"sdd-close\" },\n }),\n notFeatures: [],\n context: [],\n specsInclude: [\"docs/spec/*/*.spec.md\"],\n layout: \"feature-folders\",\n }\n : PRESET_PROFILES[input.preset];\n const configured = input.feature_dir ?? base.featureDir;\n const dirs = (typeof configured === \"string\" ? [configured] : configured).map((d) =>\n d.replace(/\\/+$/, \"\"),\n );\n const featureDir = dirs[0]!;\n const featureDirs = bySpecificity(dirs);\n const stages =\n input.stages?.map((s) =>\n stage(\n s.id,\n s.per,\n driverOf(s.driver),\n s.produces,\n transition(s.start.gates, s.start.status),\n transition(s.finish.gates, s.finish.status),\n ),\n ) ?? base.stages;\n return {\n preset: input.preset,\n ...(base.presetVersion ? { presetVersion: base.presetVersion } : {}),\n allowCommands: input.allow_commands,\n enforceInHook: input.enforce_in_hook,\n featureDir,\n featureDirs,\n skillsDir: (input.skills_dir ?? base.skillsDir).replace(/\\/+$/, \"\"),\n stages,\n notFeatures: base.notFeatures,\n context: base.context,\n specsInclude:\n dirs.length === 1 && featureDir === base.featureDir\n ? base.specsInclude\n : includeFor(featureDirs),\n layout: base.layout,\n };\n}\n","/**\n * Schema of the spec frontmatter (plan §D5.2, §D5.3, §D6.1–6.3, §D6.5), PBI `spec-schema`.\n * The zod schemas validate; the JSON Schema exported from them documents the format.\n */\nimport * as z from \"zod\";\n\nexport const SPEC_TYPES = [\"feature\", \"component\", \"contract\", \"architecture\", \"adr\"] as const;\nexport const SPEC_STATUSES = [\n \"draft\",\n \"ready\",\n \"in-progress\",\n \"implemented\",\n \"deprecated\",\n] as const;\nexport const BINDING_KINDS = [\n \"class\",\n \"interface\",\n \"struct\",\n \"enum\",\n \"record\",\n \"function\",\n \"method\",\n \"type\",\n \"module\",\n] as const;\nexport const MEMBER_KINDS = [\"method\", \"property\", \"field\", \"event\", \"constructor\"] as const;\nexport const MODIFIERS = [\n \"public\",\n \"private\",\n \"protected\",\n \"internal\",\n \"static\",\n \"async\",\n \"abstract\",\n \"override\",\n \"readonly\",\n] as const;\nexport const RULE_CLASSES = [\"structural\", \"query\", \"test\", \"manual\"] as const;\n/** The structural rule catalogue (plan §D6.2): a structural rule uses exactly one of these keys. */\nexport const STRUCTURAL_KINDS = [\n \"forbid_call\",\n \"require_call\",\n \"forbid_import\",\n \"allow_import_only\",\n \"naming\",\n \"must_not_exist\",\n] as const;\n\nexport type SpecType = (typeof SPEC_TYPES)[number];\nexport type SpecStatus = (typeof SPEC_STATUSES)[number];\nexport type BindingKind = (typeof BINDING_KINDS)[number];\nexport type MemberKind = (typeof MEMBER_KINDS)[number];\nexport type Modifier = (typeof MODIFIERS)[number];\nexport type RuleClass = (typeof RULE_CLASSES)[number];\n\nexport const SPEC_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;\n\nconst specId = z.string().regex(SPEC_ID_PATTERN, {\n error:\n \"must be 2–64 characters of lowercase letters, digits and '-', starting with a letter or digit\",\n});\nconst text = z.string().min(1);\nconst textList = z.array(text);\n/** A string or a list of strings; always a list in the model. */\nconst oneOrMany = z\n .union([text, textList])\n .transform((value): string[] => (typeof value === \"string\" ? [value] : value));\n\nexport const MemberSchema = z.strictObject({\n name: text,\n kind: z.enum(MEMBER_KINDS).optional(),\n params: textList.optional().describe('Parameter types, positional; \"*\" matches any type.'),\n returns: text.optional(),\n modifiers: z.array(z.enum(MODIFIERS)).optional(),\n attributes: textList.optional(),\n optional: z.boolean().default(false),\n});\n\n/** A member, or its name as shorthand for a name-only member of any kind. */\nexport const MemberEntrySchema = z.union([text, MemberSchema]);\n\nconst ConstructorSchema = z.strictObject({ requires: textList });\n/**\n * `constructor` is also the name of a property every JavaScript object inherits, which zod reads\n * when the key is missing; that inherited function means \"not set\".\n */\nconst constructorField = z.preprocess(\n (value) => (typeof value === \"function\" ? undefined : value),\n ConstructorSchema.optional(),\n);\n\nexport const BindingSchema = z.strictObject({\n id: text.optional().describe(\"Local id; defaults to the last segment of `symbol`.\"),\n symbol: text.describe(\"Qualified name, matched by suffix: Namespace.Type or path#Name.\"),\n kind: z.enum(BINDING_KINDS).optional(),\n lang: text.optional(),\n file: oneOrMany.optional().describe(\"Hint: a path, a glob, or a list of them.\"),\n implements: textList.optional(),\n extends: text.optional(),\n attributes: textList.optional(),\n constructor: constructorField,\n members: z.array(MemberEntrySchema).optional(),\n exported: z.boolean().optional(),\n});\n\nconst ruleCommon = {\n id: text,\n message: text.optional(),\n adr: z\n .string()\n .regex(/^ADR-\\d+$/, { error: \"must be an ADR id such as ADR-001\" })\n .optional(),\n paths: textList.optional(),\n};\n\nconst importRule = z.strictObject({ from: oneOrMany, to: oneOrMany });\n\nexport const StructuralRuleSchema = z\n .strictObject({\n ...ruleCommon,\n class: z.literal(\"structural\"),\n within: text.optional().describe(\"A binding id, or binding.member.\"),\n forbid_call: text.optional(),\n require_call: text.optional(),\n forbid_import: importRule.optional(),\n allow_import_only: importRule.optional(),\n naming: z\n .strictObject({\n kind: z.enum(BINDING_KINDS).optional(),\n name: text,\n implements: textList.optional(),\n extends: text.optional(),\n attributes: textList.optional(),\n in_path: oneOrMany.optional(),\n })\n .optional(),\n must_not_exist: z\n .strictObject({ symbol: text, kind: z.enum(BINDING_KINDS).optional() })\n .optional(),\n })\n .superRefine((rule, ctx) => {\n const used = STRUCTURAL_KINDS.filter((key) => rule[key] !== undefined);\n if (used.length !== 1) {\n ctx.addIssue({\n code: \"custom\",\n message:\n used.length === 0\n ? `a structural rule needs one of ${STRUCTURAL_KINDS.join(\", \")}`\n : `a structural rule uses exactly one of ${STRUCTURAL_KINDS.join(\", \")}; found ${used.join(\", \")}`,\n });\n }\n });\n\nexport const QueryRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"query\"),\n lang: text,\n query: text.describe(\"A Tree-sitter query.\"),\n expect: z.enum([\"absent\", \"present\"]).default(\"absent\"),\n within: text.optional(),\n});\n\nexport const TestRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"test\"),\n test: z.strictObject({ symbol: text, lang: text.optional() }),\n});\n\nexport const ManualRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"manual\"),\n text,\n});\n\n/** Rule schemas by class; `class` selects the schema. */\nexport const RULE_SCHEMAS = {\n structural: StructuralRuleSchema,\n query: QueryRuleSchema,\n test: TestRuleSchema,\n manual: ManualRuleSchema,\n} as const;\n\nexport const RuleSchema = z.discriminatedUnion(\"class\", [\n StructuralRuleSchema,\n QueryRuleSchema,\n TestRuleSchema,\n ManualRuleSchema,\n]);\n\nconst isoDate = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, { error: \"must be a date: YYYY-MM-DD\" })\n .refine(\n (value) => {\n const [year, month, day] = value.split(\"-\").map(Number) as [number, number, number];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n },\n { error: \"must be a date that exists\" },\n );\n\nexport const WaiverSchema = z.strictObject({\n rule: text,\n reason: text,\n until: isoDate.optional(),\n paths: textList.optional(),\n});\n\nconst reference = z.union([text, z.number()]);\n\n/** The frontmatter. Unknown top-level keys are allowed (warning CS0102). */\nexport const SpecFrontmatterSchema = z\n .looseObject({\n catspec: z.literal(1).describe(\"Spec format version.\"),\n id: specId.describe(\"Unique across the repository.\"),\n title: text.optional().describe(\"Defaults to the first # heading.\"),\n type: z.enum(SPEC_TYPES).describe(\"architecture makes the rules global.\"),\n status: z.enum(SPEC_STATUSES),\n depends_on: z.array(text).optional().describe(\"Ids of the specs this one depends on.\"),\n owners: textList.optional(),\n scope: textList.optional().describe(\"Extra paths (globs) that belong to this spec.\"),\n bindings: z.array(BindingSchema).optional(),\n rules: z.array(RuleSchema).optional(),\n infrastructure: z.array(z.record(z.string(), z.unknown())).optional(),\n waivers: z.array(WaiverSchema).optional(),\n links: z\n .strictObject({\n pr: reference.optional(),\n issue: reference.optional(),\n commit: text.optional(),\n })\n .optional(),\n })\n .describe(\"Frontmatter of a CatSpec spec file (*.spec.md).\");\n\nexport const FRONTMATTER_KEYS = Object.keys(SpecFrontmatterSchema.shape);\n\nexport type RuleInput = z.output<typeof RuleSchema>;\nexport type Rule = RuleInput & {\n /** Position in the `rules` list. */\n index: number;\n};\nexport type StructuralRule = z.output<typeof StructuralRuleSchema> & { index: number };\nexport type Waiver = z.output<typeof WaiverSchema> & { index: number };\nexport type Links = NonNullable<z.output<typeof SpecFrontmatterSchema>[\"links\"]>;\n\nexport interface Member {\n name: string;\n /** Undefined means any kind. */\n kind?: MemberKind;\n params?: string[];\n returns?: string;\n modifiers?: Modifier[];\n attributes?: string[];\n optional: boolean;\n}\n\nexport interface Binding {\n /** Local id; the last segment of `symbol` unless set. */\n id: string;\n symbol: string;\n kind?: BindingKind;\n lang?: string;\n /** Location hints (paths or globs). */\n file?: string[];\n implements?: string[];\n extends?: string;\n attributes?: string[];\n /** `constructor.requires`: types a constructor must take. */\n constructorRequires?: string[];\n members: Member[];\n exported?: boolean;\n /** Position in the `bindings` list. */\n index: number;\n}\n\n/** Normalises a parsed binding: default id, shorthand members, `constructor.requires`. */\nexport function normalizeBinding(input: z.output<typeof BindingSchema>, index: number): Binding {\n const { id, constructor, members, ...rest } = input;\n const binding: Binding = {\n ...stripUndefined(rest),\n id: id ?? defaultBindingId(input.symbol),\n members: (members ?? []).map((m) =>\n typeof m === \"string\" ? { name: m, optional: false } : stripUndefined(m),\n ),\n index,\n };\n if (constructor) binding.constructorRequires = constructor.requires;\n return binding;\n}\n\n/** `Identity.Handlers.UserUpdatedHandler` → `UserUpdatedHandler`; `src/a#Name.member` → `member`. */\nexport const defaultBindingId = (symbol: string): string =>\n symbol.split(\"#\").pop()!.split(\".\").pop() || symbol;\n\n/** `T` without explicit `undefined` values: optional keys stay optional but can't be undefined. */\nexport type DropUndefined<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K];\n} & { [K in keyof T as undefined extends T[K] ? K : never]?: Exclude<T[K], undefined> };\n\n/** Removes keys whose value is undefined (for `exactOptionalPropertyTypes`). */\nexport function stripUndefined<T extends object>(value: T): DropUndefined<T> {\n return Object.fromEntries(\n Object.entries(value).filter(([, v]) => v !== undefined),\n ) as DropUndefined<T>;\n}\n\n/** JSON Schema of the spec frontmatter. */\nexport const specJsonSchema = (): Record<string, unknown> =>\n z.toJSONSchema(SpecFrontmatterSchema, {\n io: \"input\",\n target: \"draft-2020-12\",\n override: (ctx) => {\n // The preprocess step of `constructor` has no JSON Schema; describe the value it accepts.\n if (ctx.zodSchema !== constructorField) return;\n Object.assign(ctx.jsonSchema, z.toJSONSchema(ConstructorSchema, { io: \"input\" }));\n delete ctx.jsonSchema.$schema;\n },\n });\n","/**\n * The language-independent facts model (plan §D11.2, ADR-003). Language adapters turn a source\n * file into `FileFacts`; rules and binding resolution read only these facts, never syntax trees,\n * so `core` stays free of Tree-sitter and of every adapter.\n */\nimport { createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport { BINDING_KINDS, MEMBER_KINDS } from \"./spec-schema.js\";\n\n/** Every kind a symbol fact can have: the binding kinds plus the member kinds. */\nexport const SYMBOL_KINDS = [...new Set([...BINDING_KINDS, ...MEMBER_KINDS])] as const;\nexport type SymbolKind = (typeof SYMBOL_KINDS)[number];\n\n/** A position in a source file: 1-based line, 1-based column in UTF-16 code units. */\nexport interface Position {\n line: number;\n column: number;\n}\n\n/** A span of a source file; `end` is exclusive. */\nexport interface Range {\n start: Position;\n end: Position;\n}\n\n/** A source file handed to an adapter. */\nexport interface SourceFile {\n /** Path relative to the repository root, with forward slashes. */\n path: string;\n text: string;\n /** Git blob SHA of `text`: the cache key of the facts. */\n blobSha: string;\n}\n\n/**\n * A type reference as written, normalised by the adapter: `Contracts.IHandler<Events.Created>`\n * is `{ name: [\"Contracts\", \"IHandler\"], args: [{ name: [\"Events\", \"Created\"], … }] }`. Types that\n * aren't a (generic) name, such as unions or function types, have an empty `name` and keep their\n * normalised `text`.\n */\nexport interface TypeRef {\n /** The normalised type text. */\n text: string;\n /** Qualified name segments. */\n name: string[];\n /** Generic type arguments. */\n args: TypeRef[];\n}\n\n/** A decorator (TypeScript) or attribute (C#), with its arguments as source text. */\nexport interface AttributeFact {\n name: string;\n args: string[];\n range: Range;\n}\n\nexport interface ParamFact {\n name: string;\n type?: TypeRef;\n /** e.g. `readonly`, `private` on a TypeScript parameter property; `ref`, `out` in C#. */\n modifiers: string[];\n optional?: boolean;\n rest?: boolean;\n attributes: AttributeFact[];\n}\n\nexport interface SymbolFact {\n /** `${path}#${qualifiedName}`, plus `(${arity})` for overload signatures and `#${n}` when arities repeat. */\n id: string;\n name: string;\n /** Name qualified by its enclosing declarations, e.g. `Outer.Inner.method`. */\n qualifiedName: string;\n kind: SymbolKind;\n range: Range;\n nameRange: Range;\n modifiers: string[];\n attributes: AttributeFact[];\n /** Base classes and implemented interfaces. */\n bases: TypeRef[];\n typeParams: string[];\n params?: ParamFact[];\n /** Return type; for a property, its declared type. */\n returns?: TypeRef;\n /** Nested declarations and members. */\n members: SymbolFact[];\n /** C# `partial` declarations, merged during binding resolution. */\n partial?: boolean;\n exported?: boolean;\n /** Body tokens, for rename similarity only; never cached or written to lock files. */\n bodyTokens?: string[];\n}\n\nexport type ImportKind = \"static\" | \"type\" | \"dynamic\" | \"require\" | \"reexport\";\n\nexport interface ImportedName {\n /** The exported name, `default` or `*`. */\n name: string;\n /** The local name when it differs. */\n alias?: string;\n}\n\nexport interface ImportFact {\n /** Module specifier as written, e.g. `./auth` or `System.Linq`. */\n module: string;\n kind: ImportKind;\n /** Imported names; empty for a side-effect import. */\n names: ImportedName[];\n range: Range;\n}\n\nexport interface CallFact {\n /** Callee as written, whitespace removed, e.g. `console.log` or `this.repo.save`. */\n callee: string;\n /** Id of the innermost enclosing symbol; undefined at the top level. */\n enclosing?: string;\n range: Range;\n}\n\nexport interface FileFacts {\n path: string;\n blobSha: string;\n /** Id of the adapter that produced the facts. */\n lang: string;\n /** Top-level declarations; nested ones are in `members`. */\n symbols: SymbolFact[];\n imports: ImportFact[];\n calls: CallFact[];\n /** Syntax errors; the facts around them are still extracted (see `parseErrorDiagnostics`). */\n parseErrors: Range[];\n /**\n * Why the file wasn't parsed (it is larger than `MAX_SOURCE_BYTES`, or the adapter failed on\n * it); the facts are then empty and the file gets one CS0901 warning.\n */\n skipped?: string;\n}\n\n/** Source files larger than this (in bytes) aren't parsed (CS0901). */\nexport const MAX_SOURCE_BYTES = 1024 * 1024;\n\n/** A language plug-in. `core` defines the interface; `cli` and `mcp` inject implementations. */\nexport interface LanguageAdapter {\n /** Language id, also its key under `languages` in `catspec.yaml`. */\n readonly id: string;\n /** File extensions with the dot, e.g. `.ts`. */\n readonly extensions: readonly string[];\n /** Adapter and grammar version; cached facts of another version are extracted again. */\n readonly version: string;\n /** Loads the grammar and compiles the queries. Called once before `extract`. */\n load(): Promise<void>;\n /** Extracts the facts of one file. Pure, so the result can be cached by blob SHA. */\n extract(file: SourceFile): FileFacts;\n /** Normalises a type as written in this language. */\n normalizeType(text: string): TypeRef;\n /** The qualified name of a symbol of `file`. */\n qualify(symbol: SymbolFact, file: SourceFile): string;\n /**\n * Compiles the raw Tree-sitter query of a `query` rule (plan §D6.3; the only place rules see\n * syntax, ADR-003). Returns the error message, or undefined when the query compiles. An adapter\n * without it doesn't support `query` rules (CS0130).\n */\n checkQuery?(query: string): string | undefined;\n /**\n * Runs a compiled query on a file: the range of each `@hit` capture, or of each match's first\n * capture when the query has no `@hit`.\n */\n runQuery?(file: SourceFile, query: string): Range[];\n}\n\n/**\n * One CS0901 warning per syntax error of the file, at the error's location; one at the start of a\n * skipped file.\n */\nexport function parseErrorDiagnostics(facts: FileFacts): Diagnostic[] {\n if (facts.skipped !== undefined) {\n return [\n createDiagnostic(\"CS0901\", {\n codeLocation: { file: facts.path, line: 1, column: 1 },\n message: `file not parsed: ${facts.skipped}`,\n }),\n ];\n }\n return facts.parseErrors.map(({ start, end }) =>\n createDiagnostic(\"CS0901\", {\n codeLocation: {\n file: facts.path,\n line: start.line,\n column: start.column,\n endLine: end.line,\n endColumn: end.column,\n },\n message: \"syntax error; the declarations before and after it are still read\",\n }),\n );\n}\n","/**\n * Syntactic name and type matching (plan §D11.5, analysis F-5, ADR-002), shared by the binding\n * resolver and the rules: a name written in a spec matches a declaration when it is a segment-wise\n * suffix of the declaration's qualified name.\n */\nimport type { TypeRef } from \"./facts.js\";\n\n/** True when `suffix` equals the last segments of `name`. */\nexport function isSegmentSuffix(suffix: readonly string[], name: readonly string[]): boolean {\n if (suffix.length === 0 || suffix.length > name.length) return false;\n const offset = name.length - suffix.length;\n return suffix.every((segment, i) => segment === name[offset + i]);\n}\n\n/**\n * True when the type found in code satisfies the expected one: the expected name is a\n * segment-wise suffix of the found name and the generic arguments match pairwise, recursively.\n * Types without a name match only by equal normalised text.\n */\nexport function typeMatches(expected: TypeRef, found: TypeRef): boolean {\n if (expected.name.length === 0 || found.name.length === 0) {\n return expected.name.length === found.name.length && expected.text === found.text;\n }\n return (\n isSegmentSuffix(expected.name, found.name) &&\n expected.args.length === found.args.length &&\n expected.args.every((arg, i) => typeMatches(arg, found.args[i]!))\n );\n}\n\n/**\n * True when a symbol's qualified name (`Outer.Inner.method`) ends with the expected name\n * (`Inner.method`), segment by segment: `Handler` doesn't match `MyHandler`.\n */\nexport const nameMatches = (expected: string, qualifiedName: string): boolean =>\n isSegmentSuffix(expected.split(\".\"), qualifiedName.split(\".\"));\n\nconst escapeRegExp = (text: string): string => text.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * A matcher for a pattern in which `*` stands for any text, dots included: `console.*` matches\n * `console.log`, `IMessageHandler<*>` matches `IMessageHandler<UserUpdated>`. Without a `*` the\n * text must equal the pattern.\n */\nexport function wildcard(pattern: string): (text: string) => boolean {\n const regex = new RegExp(`^${pattern.split(\"*\").map(escapeRegExp).join(\"[^]*\")}$`);\n return (text) => regex.test(text);\n}\n\n/**\n * True when a qualified name matches a pattern written in a spec: segment-wise suffix match\n * without `*`; with `*`, the pattern must match the name or the name without some leading\n * segments (`*Handler` matches `Handlers.UserHandler`).\n */\nexport function qualifiedNameMatches(pattern: string, qualifiedName: string): boolean {\n if (!pattern.includes(\"*\")) return nameMatches(pattern, qualifiedName);\n const matches = wildcard(pattern);\n const segments = qualifiedName.split(\".\");\n return segments.some((_, i) => matches(segments.slice(i).join(\".\")));\n}\n\n/**\n * True when a type found in code matches a type pattern from a spec: `*` matches any text and the\n * pattern may omit leading namespace segments of the found type.\n */\nexport function typePatternMatches(pattern: string, found: TypeRef): boolean {\n const matches = wildcard(pattern.replace(/\\s+/g, \"\").replace(/,/g, \", \"));\n if (matches(found.text)) return true;\n const args = found.text.slice(found.name.join(\".\").length);\n return found.name.some((_, i) => matches(found.name.slice(i).join(\".\") + args));\n}\n","/**\n * The code a check runs on (plan §D11.3): the facts of every source file of the configured\n * languages and the adapters that produced them. `cli` and `mcp` build it with the adapters they\n * inject (ADR-003); the rule engine reads only these facts, plus raw syntax for `query` rules\n * through the adapter.\n */\nimport type { Location } from \"./diagnostics.js\";\nimport type { FileFacts, LanguageAdapter, Range, SourceFile, SymbolFact } from \"./facts.js\";\nimport { qualifiedNameMatches } from \"./match.js\";\n\nexport interface Codebase {\n /** Facts of every source file, sorted by path. */\n readonly files: readonly FileFacts[];\n /** The adapter of a language id, if one is installed. */\n adapter(lang: string): LanguageAdapter | undefined;\n /** The source of a file of `files`, for `query` rules. */\n source(path: string): Promise<SourceFile>;\n}\n\n/** A declaration with the file it is in. */\nexport interface SymbolEntry {\n symbol: SymbolFact;\n file: FileFacts;\n}\n\n/** Every declaration of a codebase, top-level and nested, indexed by simple name. */\nexport class SymbolTable {\n readonly entries: SymbolEntry[] = [];\n private readonly byName = new Map<string, SymbolEntry[]>();\n readonly byPath = new Map<string, FileFacts>();\n\n constructor(files: readonly FileFacts[]) {\n const add = (symbol: SymbolFact, file: FileFacts): void => {\n const entry = { symbol, file };\n this.entries.push(entry);\n const named = this.byName.get(symbol.name);\n if (named) named.push(entry);\n else this.byName.set(symbol.name, [entry]);\n for (const member of symbol.members) add(member, file);\n };\n for (const file of files) {\n this.byPath.set(file.path, file);\n for (const symbol of file.symbols) add(symbol, file);\n }\n }\n\n /**\n * Declarations whose qualified name matches `name` (segment-wise suffix; `*` wildcards), in\n * file order.\n */\n find(name: string): SymbolEntry[] {\n if (name.includes(\"*\")) {\n return this.entries.filter((e) => qualifiedNameMatches(name, e.symbol.qualifiedName));\n }\n const last = name.slice(name.lastIndexOf(\".\") + 1);\n return (this.byName.get(last) ?? []).filter((e) =>\n qualifiedNameMatches(name, e.symbol.qualifiedName),\n );\n }\n}\n\n/** A location in the code. */\nexport const codeLocation = (file: string, range: Range): Location => ({\n file,\n line: range.start.line,\n column: range.start.column,\n endLine: range.end.line,\n endColumn: range.end.column,\n});\n\n/** `file:line:column` of a range, for messages. */\nexport const formatLocation = (file: string, range: Range): string =>\n `${file}:${range.start.line}:${range.start.column}`;\n\nconst comparePositions = (a: Range[\"start\"], b: Range[\"start\"]): number =>\n a.line - b.line || a.column - b.column;\n\n/** True when `outer` contains `inner`. */\nexport const rangeContains = (outer: Range, inner: Range): boolean =>\n comparePositions(outer.start, inner.start) <= 0 && comparePositions(inner.end, outer.end) <= 0;\n","/**\n * Reads one spec file into the normalised model (PBI `spec-schema`): validates the frontmatter\n * field by field, so one mistake doesn't hide the others, maps every problem to its line, expands\n * shorthand forms, and checks the body's references (PBI `body-parser`).\n */\nimport { isMap } from \"yaml\";\nimport type * as z from \"zod\";\n\nimport {\n createDiagnostic,\n type Diagnostic,\n type DiagnosticCode,\n type Location,\n type PatchPath,\n} from \"./diagnostics.js\";\nimport { frontmatterLocation, parseSpecSource, type SpecSource } from \"./frontmatter.js\";\nimport { describeValue, locate, schemaIssues, valueAt, type SchemaIssue } from \"./schema-issues.js\";\nimport { parseBody, type SpecBody } from \"./spec-body.js\";\nimport {\n BindingSchema,\n defaultBindingId,\n FRONTMATTER_KEYS,\n RULE_CLASSES,\n RULE_SCHEMAS,\n SpecFrontmatterSchema,\n normalizeBinding,\n stripUndefined,\n type Binding,\n type Links,\n type Rule,\n type SpecStatus,\n type SpecType,\n type Waiver,\n} from \"./spec-schema.js\";\nimport { didYouMean, listOf } from \"./util.js\";\n\nexport interface Spec {\n id: string;\n /** Path relative to the repository root, with forward slashes. */\n file: string;\n title: string;\n type: SpecType;\n status: SpecStatus;\n dependsOn: string[];\n owners: string[];\n scope: string[];\n bindings: Binding[];\n rules: Rule[];\n infrastructure: Record<string, unknown>[];\n waivers: Waiver[];\n links?: Links;\n /** Unknown top-level keys and their values (CS0102). */\n extra: Record<string, unknown>;\n /** No bindings and no rules, only `depends_on` (plan §D17.1). */\n aggregate: boolean;\n /**\n * False when the frontmatter has errors (CS0101, CS0103). The model then holds what could be\n * read; a missing `type` or `status` reads as `feature` / `draft`.\n */\n valid: boolean;\n body: SpecBody;\n source: SpecSource;\n}\n\nexport interface ReadSpecOptions {\n /** `enforcement.unenforced_prose`: `off` skips CS0111. Default `warn`. */\n unenforcedProse?: \"off\" | \"warn\";\n}\n\n/** Location of a frontmatter path (`[\"bindings\", 0, \"kind\"]`) in the spec file. */\nexport function specLocation(source: SpecSource, path: PatchPath, atKey = false): Location {\n const range = locate(source.document, path, atKey);\n return range\n ? frontmatterLocation(source, range.start, range.end)\n : { file: source.file, line: 1, column: 1 };\n}\n\n/**\n * Parses and validates a spec file. Returns the spec whenever its `id` can be read, together with\n * every diagnostic found (CS0101, CS0102, CS0103, CS0110, CS0111).\n */\nexport function readSpec(\n text: string,\n file: string,\n options: ReadSpecOptions = {},\n): { spec?: Spec; diagnostics: Diagnostic[] } {\n const parsed = parseSpecSource(text, file);\n const diagnostics = [...parsed.diagnostics];\n const source = parsed.source;\n if (!source || diagnostics.length > 0) return { diagnostics };\n\n const doc = source.document;\n const report = (\n code: DiagnosticCode,\n path: PatchPath,\n message: string,\n atKey = false,\n extra = {},\n ) =>\n diagnostics.push(\n createDiagnostic(code, {\n specLocation: specLocation(source, path, atKey),\n message,\n ...extra,\n }),\n );\n const reportIssues = (issues: SchemaIssue[]): void => {\n for (const issue of issues) {\n report(\"CS0101\", issue.path, issue.message, issue.atKey, issueDetails(issue));\n }\n };\n\n let root: unknown;\n try {\n root = toPlain(doc.toJS());\n } catch (error) {\n // For example \"Excessive alias count\": report the file instead of failing the whole check.\n const reason = error instanceof Error ? error.message : String(error);\n report(\"CS0101\", [], `${file}: the frontmatter can't be read: ${reason}`);\n return { diagnostics };\n }\n if (!isMap(doc.contents) || !root || typeof root !== \"object\" || Array.isArray(root)) {\n report(\"CS0101\", [], `${file}: the frontmatter must be a YAML map of keys and values`);\n return { diagnostics };\n }\n const data = root as Record<string, unknown>;\n\n // Unknown top-level keys only warn, so teams can keep their own metadata (CS0102).\n const extra: Record<string, unknown> = {};\n for (const key of Object.keys(data)) {\n if (FRONTMATTER_KEYS.includes(key)) continue;\n extra[key] = data[key];\n const close = didYouMean(key, FRONTMATTER_KEYS);\n report(\"CS0102\", [key], `unknown key \"${key}\" is ignored`, true, {\n actual: key,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n });\n }\n\n // Scalar and list fields, one by one.\n const shape = SpecFrontmatterSchema.shape;\n const field = <S extends z.ZodType>(schema: S, key: string): z.output<S> | undefined => {\n const result = schema.safeParse(data[key]);\n if (result.success) return result.data;\n reportIssues(schemaIssues(result.error.issues, doc, schema, [key]));\n return undefined;\n };\n const errorsBefore = (): number => diagnostics.filter((d) => d.severity === \"error\").length;\n const initialErrors = errorsBefore();\n\n field(shape.catspec, \"catspec\");\n const id = field(shape.id, \"id\");\n const title = field(shape.title, \"title\");\n const type = field(shape.type, \"type\");\n const status = field(shape.status, \"status\");\n const dependsOn = field(shape.depends_on, \"depends_on\") ?? [];\n const owners = field(shape.owners, \"owners\") ?? [];\n const scope = field(shape.scope, \"scope\") ?? [];\n const infrastructure = field(shape.infrastructure, \"infrastructure\") ?? [];\n const links = field(shape.links, \"links\");\n\n // Lists of objects, element by element, so valid elements are kept.\n const bindings: Binding[] = [];\n forEachItem(data.bindings, \"bindings\", (item, index) => {\n const result = BindingSchema.safeParse(item);\n if (result.success) bindings.push(normalizeBinding(result.data, index));\n else reportIssues(schemaIssues(result.error.issues, doc, BindingSchema, [\"bindings\", index]));\n });\n\n const rules: Rule[] = [];\n forEachItem(data.rules, \"rules\", (item, index) => {\n const cls = (item as { class?: unknown }).class;\n if (!RULE_CLASSES.includes(cls as never)) {\n const where = [\"rules\", index, \"class\"];\n const message =\n cls === undefined\n ? `rules[${index}]: missing required key \"class\"; allowed values: ${listOf(RULE_CLASSES)}`\n : `rules[${index}].class: invalid value ${JSON.stringify(cls)}; allowed: ${listOf(RULE_CLASSES)}`;\n const close = typeof cls === \"string\" ? didYouMean(cls, RULE_CLASSES) : [];\n report(\"CS0101\", cls === undefined ? [\"rules\", index] : where, message, false, {\n expected: [...RULE_CLASSES],\n ...(cls === undefined ? {} : { actual: cls }),\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n });\n return;\n }\n const schema = RULE_SCHEMAS[cls as keyof typeof RULE_SCHEMAS];\n const result = schema.safeParse(item);\n if (result.success) rules.push({ ...stripUndefined(result.data), index });\n else reportIssues(schemaIssues(result.error.issues, doc, schema, [\"rules\", index]));\n });\n\n const waivers: Waiver[] = [];\n forEachItem(data.waivers, \"waivers\", (item, index) => {\n const schema = shape.waivers.unwrap().element;\n const result = schema.safeParse(item);\n if (result.success) waivers.push({ ...stripUndefined(result.data), index });\n else reportIssues(schemaIssues(result.error.issues, doc, schema, [\"waivers\", index]));\n });\n\n function forEachItem(value: unknown, key: string, fn: (item: unknown, index: number) => void) {\n if (value === undefined) return;\n if (!Array.isArray(value)) {\n report(\"CS0101\", [key], `${key}: expected a list, found ${describeValue(value)}`);\n return;\n }\n value.forEach((item, index) => {\n if (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n report(\n \"CS0101\",\n [key, index],\n `${key}[${index}]: expected a map, found ${describeValue(item)}`,\n );\n } else {\n fn(item, index);\n }\n });\n }\n\n // Local ids are unique, and rules point at existing bindings.\n checkUnique(\n bindings.map((b) => ({\n id: b.id,\n path:\n valueAt(doc, [\"bindings\", b.index, \"id\"]) === undefined\n ? [\"bindings\", b.index, \"symbol\"]\n : [\"bindings\", b.index, \"id\"],\n })),\n \"binding\",\n );\n checkUnique(\n rules.map((r) => ({ id: r.id, path: [\"rules\", r.index, \"id\"] })),\n \"rule\",\n );\n const bindingIds = bindings.map((b) => b.id);\n const writtenBindingIds = rawBindingIds(data.bindings);\n for (const rule of rules) {\n if (!(\"within\" in rule) || rule.within === undefined) continue;\n if (resolveBindingRef(rule.within, writtenBindingIds) !== undefined) continue;\n const target = unknownBindingName(rule.within, writtenBindingIds);\n const close = didYouMean(target, writtenBindingIds);\n report(\n \"CS0101\",\n [\"rules\", rule.index, \"within\"],\n `rule \"${rule.id}\": within names an unknown binding \"${target}\"` +\n (writtenBindingIds.length > 0\n ? `; bindings: ${listOf(writtenBindingIds)}`\n : \"; the spec has no bindings\"),\n false,\n {\n ruleId: rule.id,\n expected: writtenBindingIds,\n actual: target,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n },\n );\n }\n\n function checkUnique(items: { id: string; path: PatchPath }[], what: string): void {\n const seen = new Map<string, PatchPath>();\n for (const item of items) {\n const first = seen.get(item.id);\n if (!first) {\n seen.set(item.id, item.path);\n continue;\n }\n const firstLine = specLocation(source!, first).line;\n report(\n \"CS0103\",\n item.path,\n `duplicate ${what} id \"${item.id}\" (first used on line ${firstLine})`,\n );\n }\n }\n\n const valid = errorsBefore() === initialErrors;\n\n // Body: references must name existing rules and bindings; contract bullets need one.\n const body = parseBody(source.body.text, source.body.line);\n const known = { rule: rules.map((r) => r.id), binding: bindingIds };\n const knownRaw = { rule: rawIds(data.rules, \"id\"), binding: writtenBindingIds };\n for (const ref of body.references) {\n const found =\n ref.kind === \"binding\"\n ? resolveBindingRef(ref.id, knownRaw.binding)\n : knownRaw.rule.find((id) => id === ref.id);\n if (found !== undefined) continue;\n const target = ref.kind === \"binding\" ? unknownBindingName(ref.id, knownRaw.binding) : ref.id;\n const close = didYouMean(target, known[ref.kind]);\n diagnostics.push(\n createDiagnostic(\"CS0110\", {\n specLocation: { file, line: ref.line, column: ref.column },\n message: `[${ref.kind}:${ref.id}] references an unknown ${ref.kind} \"${target}\"`,\n expected: known[ref.kind],\n actual: target,\n ...(ref.kind === \"rule\" ? { ruleId: target } : { bindingId: target }),\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean [${ref.kind}:${c}]?` })) }\n : {}),\n }),\n );\n }\n if ((options.unenforcedProse ?? \"warn\") === \"warn\") {\n for (const bullet of body.contracts) {\n if (bullet.references.length > 0) continue;\n diagnostics.push(\n createDiagnostic(\"CS0111\", {\n specLocation: { file, line: bullet.line, column: bullet.column },\n message: `unenforced prose invariant: \"${truncate(bullet.text)}\" has no [rule:<id>] or [binding:<id>] reference`,\n suggestions: [\n {\n message:\n \"add a rule that checks it (a manual rule if it can't be checked from code) and reference it\",\n },\n ],\n }),\n );\n }\n }\n\n if (id === undefined) return { diagnostics };\n\n const spec: Spec = {\n id,\n file,\n title: title ?? body.title ?? id,\n type: type ?? \"feature\",\n status: status ?? \"draft\",\n dependsOn,\n owners,\n scope,\n bindings,\n rules,\n infrastructure,\n waivers,\n extra,\n aggregate: dependsOn.length > 0 && bindings.length === 0 && rules.length === 0 && valid,\n valid,\n body,\n source,\n };\n if (links) spec.links = stripUndefined(links);\n return { spec, diagnostics: withSpec(diagnostics, id) };\n}\n\nfunction withSpec(diagnostics: Diagnostic[], id: string): Diagnostic[] {\n return diagnostics.map((d) => ({ ...d, spec: id }));\n}\n\nfunction issueDetails(issue: SchemaIssue): Partial<Diagnostic> {\n const details: Partial<Diagnostic> = {};\n if (issue.expected !== undefined) details.expected = issue.expected;\n if (issue.actual !== undefined) details.actual = issue.actual;\n if (issue.suggestions.length > 0) {\n details.suggestions = issue.suggestions.map((s) => ({ message: `did you mean \"${s}\"?` }));\n }\n return details;\n}\n\n/** Ids as written, valid or not, so a reference isn't reported twice for one broken rule. */\nfunction rawIds(list: unknown, key: string): string[] {\n if (!Array.isArray(list)) return [];\n return list.flatMap((item: unknown) => {\n const value =\n item && typeof item === \"object\" ? (item as Record<string, unknown>)[key] : undefined;\n return typeof value === \"string\" ? [value] : [];\n });\n}\n\nfunction rawBindingIds(list: unknown): string[] {\n if (!Array.isArray(list)) return [];\n return list.flatMap((item: unknown) => {\n if (!item || typeof item !== \"object\") return [];\n const { id, symbol } = item as Record<string, unknown>;\n if (typeof id === \"string\") return [id];\n if (typeof symbol === \"string\") return [defaultBindingId(symbol)];\n return [];\n });\n}\n\n/**\n * The binding a reference names: `handler` or `handler.Member`. Binding ids may contain dots, so\n * the whole reference is tried first, then the longest binding id followed by `.`.\n */\nfunction resolveBindingRef(ref: string, ids: readonly string[]): string | undefined {\n if (ids.includes(ref)) return ref;\n return ids.filter((id) => ref.startsWith(`${id}.`)).sort((a, b) => b.length - a.length)[0];\n}\n\n/** The name to report for an unresolved binding reference: the part before a member, if any. */\nconst unknownBindingName = (ref: string, ids: readonly string[]): string =>\n ref.includes(\".\") && !ids.some((id) => id.includes(\".\")) ? ref.split(\".\")[0]! : ref;\n\nconst truncate = (text: string, max = 60): string =>\n text.length > max ? `${text.slice(0, max - 1)}…` : text;\n\n/**\n * Copies a YAML value into objects without a prototype, so keys such as `constructor` or\n * `toString` are only seen when the spec sets them.\n */\nfunction toPlain(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(toPlain);\n if (value && typeof value === \"object\" && !(value instanceof Date)) {\n const out = Object.create(null) as Record<string, unknown>;\n for (const [key, item] of Object.entries(value)) out[key] = toPlain(item);\n return out;\n }\n return value;\n}\n","/**\n * Splits a spec file into its YAML frontmatter and its Markdown body (plan §D5, PBI\n * `frontmatter-parser`). The body is kept exactly as written, and every frontmatter node keeps its\n * source range, so diagnostics can point to the exact line and the CST editor can rewrite the\n * frontmatter without touching anything else.\n */\nimport { parseDocument, type Document } from \"yaml\";\n\nimport { createDiagnostic, type Diagnostic, type Location } from \"./diagnostics.js\";\nimport { LineIndex } from \"./util.js\";\n\nexport interface SpecSource {\n /** Path relative to the repository root, with forward slashes. */\n file: string;\n /** The whole file. */\n text: string;\n /** `\\r\\n` when the frontmatter uses Windows line endings, else `\\n`. */\n eol: \"\\n\" | \"\\r\\n\";\n frontmatter: {\n /** Offset of the first frontmatter line (after the opening `---` line). */\n start: number;\n /** Offset of the closing `---` line. */\n end: number;\n /** The YAML between the delimiter lines, including its last line break. */\n text: string;\n };\n body: {\n /** Offset of the body: right after the closing `---` line and its line break. */\n start: number;\n /** The Markdown after the closing `---` line, exactly as in the file. */\n text: string;\n /** 1-based line of the body's first line. */\n line: number;\n };\n /** The parsed frontmatter; node ranges are offsets into `frontmatter.text`. */\n document: Document.Parsed;\n lines: LineIndex;\n}\n\nconst DELIMITER = /^---[ \\t]*$/;\nconst CLOSING = /^(---|\\.\\.\\.)[ \\t]*$/;\n\n/** Result of splitting a file at its `---` delimiters, before the YAML is parsed. */\nexport interface SplitSource {\n eol: \"\\n\" | \"\\r\\n\";\n frontmatter: SpecSource[\"frontmatter\"];\n body: SpecSource[\"body\"];\n}\n\n/** Splits `text` at the `---` lines, or explains why it can't. */\nexport function splitFrontmatter(text: string): SplitSource | { error: string } {\n const bom = text.startsWith(\"\\uFEFF\") ? 1 : 0;\n const firstBreak = text.indexOf(\"\\n\", bom);\n const firstLine = text\n .slice(bom, firstBreak === -1 ? text.length : firstBreak)\n .replace(/\\r$/, \"\");\n if (!DELIMITER.test(firstLine)) {\n return { error: \"the file has no frontmatter: a spec must start with a '---' line\" };\n }\n if (firstBreak === -1) {\n return { error: \"the frontmatter is not closed: no '---' line after line 1\" };\n }\n const eol = text[firstBreak - 1] === \"\\r\" ? \"\\r\\n\" : \"\\n\";\n const start = firstBreak + 1;\n\n for (let lineStart = start; lineStart <= text.length;) {\n const lineBreak = text.indexOf(\"\\n\", lineStart);\n const lineEnd = lineBreak === -1 ? text.length : lineBreak;\n const line = text.slice(lineStart, lineEnd).replace(/\\r$/, \"\");\n if (CLOSING.test(line)) {\n const bodyStart = lineBreak === -1 ? text.length : lineBreak + 1;\n return {\n eol,\n frontmatter: { start, end: lineStart, text: text.slice(start, lineStart) },\n body: {\n start: bodyStart,\n text: text.slice(bodyStart),\n line: text.slice(0, bodyStart).split(\"\\n\").length,\n },\n };\n }\n if (lineBreak === -1) break;\n lineStart = lineBreak + 1;\n }\n return { error: \"the frontmatter is not closed: no '---' line after line 1\" };\n}\n\n/**\n * Parses a spec file. Returns the source when the file has a frontmatter block, even if the YAML\n * in it is invalid (those errors are in `diagnostics` as CS0101).\n */\nexport function parseSpecSource(\n text: string,\n file: string,\n): { source?: SpecSource; diagnostics: Diagnostic[] } {\n const lines = new LineIndex(text);\n const split = splitFrontmatter(text);\n if (\"error\" in split) {\n return {\n diagnostics: [\n createDiagnostic(\"CS0101\", {\n specLocation: { file, line: 1, column: 1 },\n message: `${file}: ${split.error}`,\n }),\n ],\n };\n }\n\n const document = parseDocument(split.frontmatter.text, { prettyErrors: false });\n const source: SpecSource = { file, text, ...split, document, lines };\n const diagnostics = document.errors.map((error) =>\n createDiagnostic(\"CS0101\", {\n specLocation: frontmatterLocation(source, error.pos[0], error.pos[1]),\n message: `invalid YAML: ${error.message.split(\"\\n\")[0]!.replace(/ at line \\d+.*$/, \"\")}`,\n }),\n );\n return { source, diagnostics };\n}\n\n/** File location of a range given as offsets into the frontmatter text. */\nexport function frontmatterLocation(source: SpecSource, start: number, end = start): Location {\n const from = source.lines.position(source.frontmatter.start + start);\n const to = source.lines.position(source.frontmatter.start + Math.max(start, end));\n return {\n file: source.file,\n line: from.line,\n column: from.column,\n endLine: to.line,\n endColumn: to.column,\n };\n}\n\n/** Reassembles a spec file from its parts with new frontmatter text; the rest is unchanged. */\nexport function withFrontmatter(source: SpecSource, frontmatterText: string): string {\n return (\n source.text.slice(0, source.frontmatter.start) +\n frontmatterText +\n source.text.slice(source.frontmatter.end)\n );\n}\n","/**\n * The Markdown body of a spec (plan §D5.4), PBI `body-parser`: references to rules and bindings,\n * the bullets under `Contracts` / `Invariants`, and the `Tasks` checklist. The body is otherwise\n * opaque and returned to agents as written.\n */\nimport type { Heading, List, ListItem, Nodes, RootContent } from \"mdast\";\nimport remarkParse from \"remark-parse\";\nimport { unified } from \"unified\";\n\nimport { LineIndex } from \"./util.js\";\n\nexport interface BodyReference {\n kind: \"rule\" | \"binding\";\n id: string;\n /** File position (1-based). */\n line: number;\n column: number;\n}\n\nexport interface ContractBullet {\n text: string;\n line: number;\n column: number;\n references: BodyReference[];\n}\n\nexport interface TaskItem {\n text: string;\n done: boolean;\n line: number;\n}\n\nexport interface SpecBody {\n /** Text of the first `#` heading. */\n title?: string;\n references: BodyReference[];\n /** Top-level bullets under a `Contracts` or `Invariants` heading. */\n contracts: ContractBullet[];\n /** Checklist items under a `Tasks` heading. */\n tasks: TaskItem[];\n /** `ADR-NNN` ids of the headings that start with one (the ADR log of an architecture spec). */\n adrIds: string[];\n}\n\nconst REFERENCE = /\\[(rule|binding):([^\\]\\s]+)\\]/g;\nconst CHECKBOX = /^\\[([ xX])\\](?:[ \\t]+|$)/;\nconst ADR_HEADING = /^(ADR-\\d+)\\b/;\n\n/** Parses a spec body. `firstLine` is the file line the body starts on. */\nexport function parseBody(markdown: string, firstLine: number): SpecBody {\n const tree = unified().use(remarkParse).parse(markdown);\n const toFileLine = (line: number): number => firstLine + line - 1;\n const body: SpecBody = { references: [], contracts: [], tasks: [], adrIds: [] };\n\n const lines = new LineIndex(markdown);\n const at = (offset: number): { line: number; column: number } => {\n const { line, column } = lines.position(offset);\n return { line: toFileLine(line), column };\n };\n\n const referencesIn = (node: Nodes): BodyReference[] => {\n const found: BodyReference[] = [];\n visit(node, (child) => {\n const start = child.position?.start.offset;\n if (start === undefined) return;\n if (child.type === \"text\") {\n // Positions come from the source, not from the decoded text (entities, indentation).\n const source = markdown.slice(start, child.position!.end.offset);\n let cursor = 0;\n for (const match of child.value.matchAll(REFERENCE)) {\n const index = source.indexOf(match[0], cursor);\n if (index !== -1) cursor = index + match[0].length;\n const kind = match[1] as \"rule\" | \"binding\";\n found.push({ kind, id: match[2]!, ...at(start + Math.max(index, 0)) });\n }\n } else if (child.type === \"linkReference\" || child.type === \"link\") {\n // `[rule:x][]` with a definition, or `[rule:x](#x)`.\n const label = child.type === \"linkReference\" ? (child.label ?? \"\") : plainText(child);\n const match = /^(rule|binding):(\\S+)$/.exec(label.trim());\n if (match)\n found.push({ kind: match[1] as \"rule\" | \"binding\", id: match[2]!, ...at(start) });\n }\n });\n return found;\n };\n\n body.references = referencesIn(tree);\n\n const headings: { name: string; depth: number }[] = [];\n const inSection = (...names: string[]): boolean =>\n headings.some((h) => names.includes(h.name.toLowerCase()));\n\n for (const node of tree.children) {\n if (node.type === \"heading\") {\n const name = plainText(node).trim();\n while (headings.length > 0 && headings[headings.length - 1]!.depth >= node.depth) {\n headings.pop();\n }\n headings.push({ name, depth: node.depth });\n if (node.depth === 1 && body.title === undefined) body.title = name;\n const adr = ADR_HEADING.exec(name);\n if (adr) body.adrIds.push(adr[1]!);\n continue;\n }\n if (node.type !== \"list\") continue;\n if (inSection(\"contracts\", \"invariants\")) {\n for (const item of node.children) {\n if (!item.position) continue;\n body.contracts.push({\n text: plainText(item).trim(),\n line: toFileLine(item.position.start.line),\n column: item.position.start.column,\n references: referencesIn(item),\n });\n }\n }\n if (inSection(\"tasks\")) collectTasks(node, body.tasks, toFileLine);\n }\n return body;\n}\n\nfunction collectTasks(list: List, tasks: TaskItem[], toFileLine: (line: number) => number): void {\n for (const item of list.children) {\n const text = itemText(item);\n const box = CHECKBOX.exec(text);\n if (box && item.position) {\n tasks.push({\n text: text.slice(box[0].length).trim(),\n done: box[1] !== \" \",\n line: toFileLine(item.position.start.line),\n });\n }\n for (const child of item.children) {\n if (child.type === \"list\") collectTasks(child, tasks, toFileLine);\n }\n }\n}\n\n/** Text of a list item's own first paragraph (not its nested lists). */\nfunction itemText(item: ListItem): string {\n const first = item.children[0];\n return first?.type === \"paragraph\" ? plainText(first) : \"\";\n}\n\nfunction plainText(node: Nodes | Heading | RootContent): string {\n if (\"value\" in node && typeof node.value === \"string\") return node.value;\n if (\"children\" in node) return (node.children as Nodes[]).map(plainText).join(\"\");\n return \"\";\n}\n\nfunction visit(node: Nodes, fn: (node: Nodes) => void): void {\n fn(node);\n if (\"children\" in node) for (const child of node.children as Nodes[]) visit(child, fn);\n}\n","/**\n * Binding resolution (plan §D11.5, ADR-005), PBI `binding-resolver`: finds the declaration a\n * binding points to. The `file` hint is tried first, then the files the binding resolved to last\n * time (its lock file, F5), then every source file, so a moved file still resolves. Not found →\n * CS0201 with did-you-mean; several candidates → CS0202; C# `partial` parts are merged.\n */\nimport { codeLocation, formatLocation, type SymbolEntry, type SymbolTable } from \"./codebase.js\";\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport type { FileFacts, SymbolFact } from \"./facts.js\";\nimport { BINDING_KINDS, type Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, globMatcher, listOf } from \"./util.js\";\n\nexport interface ResolvedBinding {\n binding: Binding;\n /** The declaration; for C# partial types, the parts merged into one. */\n symbol: SymbolFact;\n /** The file of the declaration (of its first part). */\n file: FileFacts;\n /** The files of every part. */\n files: string[];\n /** The declarations merged into `symbol`, each with its file; one unless C# `partial`. */\n parts: { symbol: SymbolFact; file: FileFacts }[];\n}\n\nexport interface BindingResolution {\n resolved?: ResolvedBinding;\n diagnostics: Diagnostic[];\n /**\n * True when neither the hint nor the locked files had the declaration, so every source file was\n * searched: a result that depends on the whole repository (`check --staged` reads it all then).\n */\n searched: boolean;\n}\n\nconst TYPE_KINDS = new Set<string>(BINDING_KINDS);\n\n/** `src/auth/service#AuthService.login` → module `src/auth/service`, name `AuthService.login`. */\nexport function splitSymbol(symbol: string): { module?: string; name: string } {\n const hash = symbol.lastIndexOf(\"#\");\n return hash === -1\n ? { name: symbol }\n : { module: symbol.slice(0, hash).replace(/^\\.\\//, \"\"), name: symbol.slice(hash + 1) };\n}\n\n/** True when `path` is the module `module`: with or without the extension, or ending with it. */\nexport const inModule = (path: string, module: string): boolean => {\n const bare = path.replace(/\\.[^./]+$/, \"\");\n const target = module.replace(/\\.[^./]+$/, \"\");\n return bare === target || bare.endsWith(`/${target}`);\n};\n\n/**\n * Resolves a binding in `table`. `locked` are the files the binding resolved to last time (from\n * its lock file), tried after the `file` hint.\n */\nexport function resolveBinding(\n spec: Spec,\n binding: Binding,\n table: SymbolTable,\n locked: readonly string[] = [],\n): BindingResolution {\n const { module, name } = splitSymbol(binding.symbol);\n const kindOk = (s: SymbolFact): boolean =>\n binding.kind ? s.kind === binding.kind : TYPE_KINDS.has(s.kind);\n const langOk = (f: FileFacts): boolean => !binding.lang || f.lang === binding.lang;\n const hinted = binding.file ? globMatcher(binding.file) : () => false;\n const inHint = (e: SymbolEntry): boolean =>\n binding.file !== undefined && (hinted(e.file.path) || binding.file.includes(e.file.path));\n\n const named = table\n .find(name)\n .filter((e) => langOk(e.file) && (!module || inModule(e.file.path, module)));\n const ofKind = named.filter((e) => kindOk(e.symbol));\n const inHinted = ofKind.filter(inHint);\n const inLocked = ofKind.filter((e) => locked.includes(e.file.path));\n const searched = inHinted.length === 0 && inLocked.length === 0;\n const groups = groupOverloads(\n inHinted.length > 0 ? inHinted : inLocked.length > 0 ? inLocked : ofKind,\n );\n\n const at = specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]);\n const base = {\n spec: spec.id,\n specLocation: at,\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n };\n const what = `${binding.kind ?? \"symbol\"} ${binding.symbol}`;\n\n if (groups.length === 0) {\n const otherKind = named[0];\n if (otherKind) {\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0201\", {\n ...base,\n codeLocation: codeLocation(otherKind.file.path, otherKind.symbol.nameRange),\n message:\n `binding \"${binding.id}\": no ${what}; found ${otherKind.symbol.kind} ` +\n `${otherKind.symbol.qualifiedName} at ${formatLocation(otherKind.file.path, otherKind.symbol.nameRange)}`,\n expected: what,\n actual: `${otherKind.symbol.kind} ${otherKind.symbol.qualifiedName}`,\n suggestions: [\n { message: `change the binding's kind to ${otherKind.symbol.kind}, or the code` },\n ],\n }),\n ],\n };\n }\n const close = closeNames(name, table, kindOk, langOk, inHint);\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0201\", {\n ...base,\n message:\n `binding \"${binding.id}\": ${what} not found` +\n (binding.file ? ` in ${listOf(binding.file)} or anywhere else` : \"\"),\n expected: what,\n actual: close.length > 0 ? close.map((c) => c.symbol.qualifiedName) : \"nothing\",\n suggestions:\n close.length > 0\n ? close.map((c) => ({\n message: `did you mean ${c.symbol.name}? (${formatLocation(c.file.path, c.symbol.nameRange)})`,\n }))\n : [{ message: \"fix the symbol or the file hint, or restore the code\" }],\n }),\n ],\n };\n }\n\n const parts = groups.map((g) => g[0]!);\n if (parts.length > 1 && !parts.every((p) => p.symbol.partial)) {\n const where = parts.map((p) => formatLocation(p.file.path, p.symbol.nameRange));\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0202\", {\n ...base,\n codeLocation: codeLocation(parts[0]!.file.path, parts[0]!.symbol.nameRange),\n message: `binding \"${binding.id}\": ${what} is ambiguous; ${parts.length} declarations match: ${listOf(where)}`,\n expected: what,\n actual: where,\n suggestions: [\n {\n message:\n \"qualify the symbol (Namespace.Type or path/to/module#Name) or add a file hint\",\n },\n ],\n }),\n ],\n };\n }\n\n return {\n resolved: {\n binding,\n symbol: parts.length === 1 ? parts[0]!.symbol : mergePartials(parts.map((p) => p.symbol)),\n file: parts[0]!.file,\n files: [...new Set(parts.map((p) => p.file.path))],\n parts: parts.map(({ symbol, file }) => ({ symbol, file })),\n },\n diagnostics: [],\n searched,\n };\n}\n\n/**\n * Overload signatures and their implementation are one declaration: entries with the same file,\n * qualified name and `static`-ness form a group, the implementation (plain id) first. C#\n * overloads all have bodies, so each is a declaration of its own. Every other declaration is its\n * own group, also when it shares an id (C# partial parts in one file).\n */\nexport function groupOverloads(entries: SymbolEntry[]): SymbolEntry[][] {\n const isImplementation = (e: SymbolEntry): boolean =>\n e.symbol.id === `${e.file.path}#${e.symbol.qualifiedName}`;\n const groups = new Map<string | SymbolEntry, SymbolEntry[]>();\n for (const entry of entries) {\n const { symbol, file } = entry;\n const callable = symbol.kind === \"function\" || symbol.kind === \"method\";\n const key = callable\n ? `${file.path}\\0${symbol.qualifiedName}\\0${symbol.modifiers.includes(\"static\")}`\n : entry;\n groups.set(key, [...(groups.get(key) ?? []), entry]);\n }\n return [...groups.values()].flatMap((group) =>\n group[0]!.file.lang !== \"csharp\"\n ? [[...group].sort((a, b) => Number(isImplementation(b)) - Number(isImplementation(a)))]\n : group.map((entry) => [entry]),\n );\n}\n\n/** C# partial parts as one type: members, bases, attributes and modifiers of every part. */\nexport function mergePartials(parts: SymbolFact[]): SymbolFact {\n const [first, ...rest] = parts as [SymbolFact, ...SymbolFact[]];\n const merged: SymbolFact = {\n ...first,\n members: [...first.members],\n bases: [...first.bases],\n attributes: [...first.attributes],\n modifiers: [...first.modifiers],\n };\n for (const part of rest) {\n merged.members.push(...part.members);\n for (const base of part.bases) {\n if (!merged.bases.some((b) => b.text === base.text)) merged.bases.push(base);\n }\n merged.attributes.push(...part.attributes);\n for (const modifier of part.modifiers) {\n if (!merged.modifiers.includes(modifier)) merged.modifiers.push(modifier);\n }\n if (part.exported) merged.exported = true;\n }\n return merged;\n}\n\n/**\n * Up to 3 declarations of the right kind whose names are close to `name` (Damerau-Levenshtein),\n * the hinted files first.\n */\nfunction closeNames(\n name: string,\n table: SymbolTable,\n kindOk: (s: SymbolFact) => boolean,\n langOk: (f: FileFacts) => boolean,\n inHint: (e: SymbolEntry) => boolean,\n): SymbolEntry[] {\n const last = name.slice(name.lastIndexOf(\".\") + 1);\n const candidates = table.entries.filter((e) => kindOk(e.symbol) && langOk(e.file));\n const firstByName = (entries: SymbolEntry[]): Map<string, SymbolEntry> => {\n const map = new Map<string, SymbolEntry>();\n for (const e of entries) if (!map.has(e.symbol.name)) map.set(e.symbol.name, e);\n return map;\n };\n const hinted = firstByName(candidates.filter(inHint));\n const all = firstByName(candidates);\n const names = [\n ...didYouMean(last, [...hinted.keys()].sort(compareStrings)),\n ...didYouMean(last, [...all.keys()].sort(compareStrings)),\n ];\n return [...new Set(names)].slice(0, 3).map((n) => hinted.get(n) ?? all.get(n)!);\n}\n","/**\n * The contract evaluator (plan §D5.3, §D11.5, analysis F-5), PBI `contract-evaluator`: checks a\n * resolved declaration against its binding: kind (in the resolver), export, base types,\n * attributes, constructor dependencies and members with their signatures. What syntax alone\n * can't decide is CS0220, never a failure (ADR-002). Every diagnostic names its contract item:\n * `binding:<id>` for the declaration, `binding:<id>.<member>` for each member.\n */\nimport { codeLocation, formatLocation, type SymbolTable } from \"./codebase.js\";\nimport { createDiagnostic, type Diagnostic, type DiagnosticCode } from \"./diagnostics.js\";\nimport type {\n AttributeFact,\n FileFacts,\n LanguageAdapter,\n ParamFact,\n SymbolFact,\n TypeRef,\n} from \"./facts.js\";\nimport { isSegmentSuffix, typeMatches } from \"./match.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Member, MemberKind } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, editDistance, listOf } from \"./util.js\";\n\nexport interface ContractContext {\n table: SymbolTable;\n adapter?: LanguageAdapter | undefined;\n /** `enforcement.unresolvable`: the severity of CS0220. */\n unresolvable: \"warn\" | \"error\";\n}\n\n/** Contract items of a binding: the declaration, then each member. */\nexport const bindingItems = (binding: { id: string; members: { name: string }[] }): string[] => [\n `binding:${binding.id}`,\n ...binding.members.map((m) => `binding:${binding.id}.${m.name}`),\n];\n\nconst VISIBILITY = new Set([\"public\", \"private\", \"protected\", \"internal\"]);\n\n/** Evaluates the contract of a resolved binding. */\nexport function evaluateContract(\n spec: Spec,\n resolved: ResolvedBinding,\n context: ContractContext,\n): Diagnostic[] {\n const { binding, symbol, file } = resolved;\n const diagnostics: Diagnostic[] = [];\n const where = codeLocation(file.path, symbol.nameRange);\n /** The file a member is declared in: the file of its part, for a C# partial type. */\n const pathOf = (member: SymbolFact): string =>\n resolved.parts.find((p) => p.symbol.members.includes(member))?.file.path ?? file.path;\n const subject = `${symbol.kind} ${symbol.qualifiedName}`;\n const normalize = (text: string): TypeRef =>\n context.adapter?.normalizeType(text) ?? plainType(text);\n const report = (\n code: DiagnosticCode,\n path: (string | number)[],\n item: string,\n message: string,\n extra: Partial<Diagnostic> = {},\n ): void => {\n diagnostics.push(\n createDiagnostic(code, {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, ...path]),\n codeLocation: where,\n bindingId: binding.id,\n item,\n message,\n ...(code === \"CS0220\" ? { severity: unresolvableSeverity(context) } : {}),\n ...extra,\n }),\n );\n };\n const item = `binding:${binding.id}`;\n\n // exported: TypeScript `export`, C# `public`.\n if (binding.exported !== undefined) {\n const exported = symbol.exported === true || symbol.modifiers.includes(\"public\");\n if (exported !== binding.exported) {\n report(\n \"CS0208\",\n [\"exported\"],\n item,\n `${subject} must ${binding.exported ? \"\" : \"not \"}be exported`,\n {\n expected: binding.exported ? \"exported\" : \"not exported\",\n actual: exported ? \"exported\" : \"not exported\",\n suggestions: [\n {\n message: binding.exported\n ? `export ${symbol.name} (TypeScript) or make it public (C#)`\n : `remove the export of ${symbol.name}, or set exported: true`,\n },\n ],\n },\n );\n }\n }\n\n // implements / extends: direct base types, by qualified-name suffix.\n const bases = symbol.bases.map((b) => ({\n base: b,\n variants: resolved.parts.flatMap((p) => baseVariants(b, p.file)),\n }));\n const foundBases = symbol.bases.length > 0 ? listOf(symbol.bases.map((b) => b.text)) : \"none\";\n const checkBase = (\n expectedText: string,\n path: (string | number)[],\n verb: string,\n candidates = bases,\n ): void => {\n const expected = normalize(expectedText);\n if (candidates.some(({ variants }) => variants.some((v) => typeMatches(expected, v)))) return;\n const unsure = candidates.filter(({ variants }) =>\n variants.some((v) => undecidableBase(v, context)),\n );\n if (unsure.length > 0) {\n report(\n \"CS0220\",\n path,\n item,\n `can't tell whether ${subject} ${verb} ${expected.text}: its base ${listOf(unsure.map((u) => u.base.text))} is a type alias or not a plain name`,\n {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [{ message: `name ${expected.text} directly in the declaration` }],\n },\n );\n return;\n }\n report(\"CS0204\", path, item, `${subject} does not ${verb} ${expected.text}`, {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [\n {\n message: `found base types: ${foundBases}; add ${expected.text} to the declaration of ${symbol.name}, or update the spec`,\n },\n ],\n });\n };\n binding.implements?.forEach((t, i) => checkBase(t, [\"implements\", i], \"implement\"));\n // C# doesn't mark the base class in a base list. A class or record has at most one, first in\n // the base list of the part that declares it, and a struct has none. An interface extends\n // every interface in its base list. Syntax can't tell a first base named like an interface\n // (`IFoo`, but also `IOException`) from a base class, so a match on one is CS0220.\n const csharpClass = file.lang === \"csharp\" && symbol.kind !== \"interface\";\n const extendable = !csharpClass\n ? bases\n : symbol.kind === \"struct\"\n ? []\n : bases.filter(({ base }) =>\n resolved.parts.some((p) => p.symbol.bases[0]?.text === base.text),\n );\n if (binding.extends !== undefined) {\n const expected = normalize(binding.extends);\n const interfaceLike = csharpClass\n ? extendable.find(\n ({ base, variants }) =>\n /^I[A-Z]/.test(base.name.at(-1) ?? \"\") &&\n variants.some((v) => typeMatches(expected, v)),\n )\n : undefined;\n if (interfaceLike) {\n report(\n \"CS0220\",\n [\"extends\"],\n item,\n `can't tell whether ${subject} extends ${expected.text}: ${interfaceLike.base.text} comes first in its base list but may be an interface`,\n {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [\n { message: `use implements: [${expected.text}] if it is an interface, or waive this` },\n ],\n },\n );\n } else {\n checkBase(binding.extends, [\"extends\"], \"extend\", extendable);\n }\n }\n\n // attributes / decorators.\n binding.attributes?.forEach((text, i) => {\n if (symbol.attributes.some((a) => attributeMatches(text, a))) return;\n report(\"CS0206\", [\"attributes\", i], item, `${subject} lacks attribute ${text}`, {\n expected: text,\n actual: symbol.attributes.map(attributeText),\n suggestions: [{ message: `add ${text} to ${symbol.name}` }],\n });\n });\n\n // constructor.requires: types a constructor must take (dependency injection).\n if (binding.constructorRequires && binding.constructorRequires.length > 0) {\n checkConstructor(binding.constructorRequires);\n }\n\n function checkConstructor(required: string[]): void {\n const path = [\"constructor\", \"requires\"];\n const ctors = symbol.members.filter((m) => m.kind === \"constructor\");\n if (ctors.length === 0) {\n if (symbol.bases.length > 0) {\n report(\n \"CS0220\",\n path,\n item,\n `can't tell whether ${subject} takes ${listOf(required)}: it has no constructor of its own and may inherit one from ${foundBases}`,\n {\n expected: required,\n suggestions: [{ message: `declare a constructor in ${symbol.name}` }],\n },\n );\n return;\n }\n required.forEach((type, i) =>\n report(\"CS0207\", [...path, i], item, `${subject} has no constructor taking ${type}`, {\n expected: type,\n actual: \"no constructor\",\n suggestions: [{ message: `add a constructor to ${symbol.name} that takes ${type}` }],\n }),\n );\n return;\n }\n const scored = ctors.map((ctor) => {\n const params = ctor.params ?? [];\n const status = required.map((type) => {\n const expected = normalize(type);\n if (params.some((p) => p.type && typeMatches(expected, p.type))) return \"ok\";\n return params.some((p) => !p.type) ? \"unsure\" : \"missing\";\n });\n return { ctor, status, ok: status.filter((s) => s === \"ok\").length };\n });\n if (scored.some((s) => s.ok === required.length)) return;\n const best = scored.reduce((a, b) => (b.ok > a.ok ? b : a));\n const found = `constructor(${(best.ctor.params ?? []).map(paramText).join(\", \")})`;\n best.status.forEach((status, i) => {\n if (status === \"ok\") return;\n const type = required[i]!;\n if (status === \"unsure\") {\n report(\n \"CS0220\",\n [...path, i],\n item,\n `can't tell whether ${subject} takes ${type}: ${found} has parameters without a type`,\n {\n expected: type,\n actual: found,\n suggestions: [{ message: \"add type annotations to the constructor parameters\" }],\n },\n );\n } else {\n report(\"CS0207\", [...path, i], item, `${subject}: constructor dependency ${type} missing`, {\n codeLocation: codeLocation(pathOf(best.ctor), best.ctor.nameRange),\n expected: type,\n actual: found,\n suggestions: [\n { message: `add a parameter of type ${type} to the constructor of ${symbol.name}` },\n ],\n });\n }\n });\n }\n\n // Members.\n const claimed = new Set(binding.members.map((m) => m.name));\n // Required members with no declaration of their name, by kind: the fallback suggestion below\n // is only safe when a single one of a kind is missing.\n const missingByKind = new Map<string | undefined, number>();\n for (const m of binding.members) {\n if (m.optional || m.kind === \"constructor\") continue;\n if (symbol.members.some((c) => c.name === m.name && c.kind !== \"constructor\")) continue;\n missingByKind.set(m.kind, (missingByKind.get(m.kind) ?? 0) + 1);\n }\n binding.members.forEach((member, i) => {\n const memberItem = `binding:${binding.id}.${member.name}`;\n const path = [\"members\", i];\n const candidates = symbol.members.filter((m) =>\n member.kind === \"constructor\"\n ? m.kind === \"constructor\"\n : m.name === member.name && m.kind !== \"constructor\",\n );\n if (candidates.length === 0) {\n if (member.optional) return;\n const close = closeMembers(member, symbol, claimed, missingByKind.get(member.kind) === 1);\n report(\n \"CS0203\",\n path,\n memberItem,\n `member ${member.name} missing in ${symbol.qualifiedName}`,\n {\n expected: memberText(member),\n actual: close.length > 0 ? close.map((c) => signatureText(c)) : \"nothing\",\n suggestions: [\n ...close.map((c) => ({\n message: `did you mean ${c.name}? (${formatLocation(pathOf(c), c.nameRange)})`,\n })),\n { message: `add ${member.name} to ${symbol.name}, or update the spec` },\n ],\n },\n );\n return;\n }\n const results = candidates.map((c) => ({\n candidate: c,\n ...compareMember(member, c, normalize, file),\n }));\n if (results.some((r) => r.mismatches.length === 0 && r.unsure.length === 0)) return;\n const best = results.reduce((a, b) =>\n b.mismatches.length + b.unsure.length < a.mismatches.length + a.unsure.length ? b : a,\n );\n const at = codeLocation(pathOf(best.candidate), best.candidate.nameRange);\n const found = signatureText(best.candidate);\n const visibility = best.mismatches.filter((m) => m.code === \"CS0208\");\n const signature = best.mismatches.filter((m) => m.code !== \"CS0208\");\n for (const group of [visibility, signature]) {\n if (group.length === 0) continue;\n const code = group[0]!.code;\n report(\n code,\n path,\n memberItem,\n `member ${member.name} ${code === \"CS0208\" ? \"visibility\" : code === \"CS0206\" ? \"attributes\" : \"signature\"} mismatch: ${group.map((m) => m.text).join(\"; \")}`,\n {\n codeLocation: at,\n expected: memberText(member),\n actual: found,\n suggestions: [\n { message: `change ${member.name} to ${memberText(member)}, or update the spec` },\n ],\n },\n );\n }\n if (best.mismatches.length === 0) {\n report(\n \"CS0220\",\n path,\n memberItem,\n `can't check member ${member.name} from syntax: ${best.unsure.join(\"; \")}`,\n {\n codeLocation: at,\n expected: memberText(member),\n actual: found,\n suggestions: [{ message: \"write the types explicitly in the code\" }],\n },\n );\n }\n });\n\n return diagnostics;\n}\n\ninterface Mismatch {\n code: DiagnosticCode;\n text: string;\n}\n\n/** Differences between a member entry and one declaration of that name. */\nfunction compareMember(\n member: Member,\n found: SymbolFact,\n normalize: (text: string) => TypeRef,\n file: FileFacts,\n): { mismatches: Mismatch[]; unsure: string[] } {\n const mismatches: Mismatch[] = [];\n const unsure: string[] = [];\n if (member.kind && !kindMatches(member.kind, found.kind, file.lang)) {\n mismatches.push({ code: \"CS0205\", text: `kind: expected ${member.kind}, found ${found.kind}` });\n }\n if (member.params) {\n const params = found.params;\n if (!params) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameters: expected (${member.params.join(\", \")}), found a ${found.kind}`,\n });\n } else if (params.length !== member.params.length) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameters: expected ${member.params.length}, found ${params.length}`,\n });\n } else {\n member.params.forEach((type, i) => {\n const param = params[i]!;\n if (type === \"*\") return;\n if (!param.type) {\n unsure.push(`parameter ${param.name} has no type`);\n return;\n }\n const expected = normalize(type);\n if (!typeMatches(expected, param.type)) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameter ${i + 1} (${param.name}): expected ${expected.text}, found ${param.type.text}`,\n });\n }\n });\n }\n }\n if (member.returns !== undefined) {\n const expected = normalize(member.returns);\n if (!found.returns)\n unsure.push(\n `${found.name} has no declared ${found.kind === \"property\" ? \"type\" : \"return type\"}`,\n );\n else if (!typeMatches(expected, found.returns)) {\n mismatches.push({\n code: \"CS0205\",\n text: `returns: expected ${expected.text}, found ${found.returns.text}`,\n });\n }\n }\n for (const modifier of member.modifiers ?? []) {\n if (hasModifier(found, modifier, file.lang)) continue;\n mismatches.push({\n code: VISIBILITY.has(modifier) ? \"CS0208\" : \"CS0205\",\n text: `modifier ${modifier} missing`,\n });\n }\n for (const attribute of member.attributes ?? []) {\n if (found.attributes.some((a) => attributeMatches(attribute, a))) continue;\n mismatches.push({ code: \"CS0206\", text: `attribute ${attribute} missing` });\n }\n return { mismatches, unsure };\n}\n\n/** TypeScript has no fields apart from properties. */\nconst kindMatches = (expected: MemberKind, found: string, lang: string): boolean =>\n expected === found ||\n (lang === \"typescript\" &&\n (expected === \"field\" || expected === \"property\") &&\n found === \"property\");\n\n/** A modifier on a declaration; TypeScript class members without one are public. */\nfunction hasModifier(symbol: SymbolFact, modifier: string, lang: string): boolean {\n if (symbol.modifiers.includes(modifier)) return true;\n return (\n lang === \"typescript\" &&\n modifier === \"public\" &&\n !symbol.modifiers.some((m) => m === \"private\" || m === \"protected\")\n );\n}\n\n/**\n * Members of the declaration close to a missing member's name, of a compatible kind and not\n * required by another entry: by edit distance, else by a shared word (`checkToken` for\n * `validateToken`).\n */\nfunction closeMembers(\n member: Member,\n symbol: SymbolFact,\n claimed: Set<string>,\n onlyMissingOfKind: boolean,\n): SymbolFact[] {\n const candidates = symbol.members.filter(\n (m) =>\n m.kind !== \"constructor\" &&\n !claimed.has(m.name) &&\n (!member.kind ||\n m.kind === member.kind ||\n (member.kind !== \"method\" && m.kind === \"property\")),\n );\n const byName = new Map<string, SymbolFact>();\n for (const c of candidates) if (!byName.has(c.name)) byName.set(c.name, c);\n let names = didYouMean(member.name, byName.keys());\n if (names.length === 0) {\n const words = new Set(wordsOf(member.name));\n names = [...byName.keys()]\n .filter((name) => wordsOf(name).some((w) => words.has(w)))\n .sort(\n (a, b) =>\n editDistance(member.name.toLowerCase(), a.toLowerCase()) -\n editDistance(member.name.toLowerCase(), b.toLowerCase()),\n )\n .slice(0, 3);\n }\n // No similar name: when this is the only missing member of its kind and the declaration has a\n // single unclaimed member of that kind, that one is most likely meant (`login` written as\n // `signIn`).\n if (names.length === 0 && member.kind && onlyMissingOfKind) {\n const sameKind = [...byName.values()].filter((m) => m.kind === member.kind);\n if (sameKind.length === 1) names = [sameKind[0]!.name];\n }\n return names.map((n) => byName.get(n)!);\n}\n\n/** Lowercase words of an identifier of 3+ letters: `validateToken` → validate, token. */\nconst wordsOf = (name: string): string[] =>\n name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[\\s_$-]+/)\n .map((w) => w.toLowerCase())\n .filter((w) => w.length >= 3);\n\n/**\n * A base type as written and as resolved through the file's imports: `Base` imported as\n * `import { IHandler as Base }` is also `IHandler`; `ns.IHandler` from `import * as ns` is also\n * `IHandler`.\n */\nfunction baseVariants(base: TypeRef, file: FileFacts): TypeRef[] {\n const variants = [base];\n const head = base.name[0];\n if (head === undefined) return variants;\n for (const imp of file.imports) {\n for (const imported of imp.names) {\n if ((imported.alias ?? imported.name) !== head) continue;\n if (imported.name === \"*\" && base.name.length > 1) {\n const name = base.name.slice(1);\n variants.push({ ...base, name, text: base.text.slice(head.length + 1) });\n } else if (imported.name !== \"*\" && imported.name !== \"default\" && imported.name !== head) {\n const name = [imported.name, ...base.name.slice(1)];\n variants.push({ ...base, name, text: imported.name + base.text.slice(head.length) });\n }\n }\n }\n return variants;\n}\n\n/** A base type syntax can't compare: not a plain name, or a type alias declared in the code. */\nfunction undecidableBase(base: TypeRef, context: ContractContext): boolean {\n if (base.name.length === 0) return true;\n const declared = context.table.find(base.name.join(\".\"));\n return declared.length > 0 && declared.every((e) => e.symbol.kind === \"type\");\n}\n\nconst unresolvableSeverity = (context: ContractContext): \"warning\" | \"error\" =>\n context.unresolvable === \"error\" ? \"error\" : \"warning\";\n\n/** A type reference from text without an adapter: only equal text matches. */\nconst plainType = (text: string): TypeRef => ({\n text: text.replace(/\\s+/g, \"\"),\n name: [],\n args: [],\n});\n\n/** `HttpGet(\"users\")` matches an attribute named `HttpGet`/`HttpGetAttribute` with that argument. */\nexport function attributeMatches(expected: string, found: AttributeFact): boolean {\n const match = /^\\s*([^(]+?)\\s*(?:\\((.*)\\))?\\s*$/s.exec(expected);\n if (!match) return false;\n const name = match[1]!.replace(/Attribute$/, \"\").split(\".\");\n const foundName = found.name.replace(/Attribute$/, \"\").split(\".\");\n if (!isSegmentSuffix(name, foundName)) return false;\n if (match[2] === undefined) return true;\n const args = splitArgs(match[2]).map(normalizeArg);\n const foundArgs = found.args.map(normalizeArg);\n return args.length === foundArgs.length && args.every((a, i) => a === foundArgs[i]);\n}\n\nconst normalizeArg = (arg: string): string => arg.replace(/\\s+/g, \"\").replace(/'/g, '\"');\n\n/** Splits arguments at top-level commas. */\nfunction splitArgs(text: string): string[] {\n if (text.trim() === \"\") return [];\n const args: string[] = [];\n let depth = 0;\n let quote: string | undefined;\n let current = \"\";\n for (const char of text) {\n if (quote) {\n if (char === quote) quote = undefined;\n } else if (char === '\"' || char === \"'\" || char === \"`\") quote = char;\n else if (\"([{<\".includes(char)) depth++;\n else if (\")]}>\".includes(char)) depth--;\n else if (char === \",\" && depth === 0) {\n args.push(current);\n current = \"\";\n continue;\n }\n current += char;\n }\n args.push(current);\n return args;\n}\n\nconst attributeText = (a: AttributeFact): string =>\n a.args.length > 0 ? `${a.name}(${a.args.join(\", \")})` : a.name;\n\nconst paramText = (p: ParamFact): string => (p.type ? `${p.name}: ${p.type.text}` : p.name);\n\n/** `login(string, number): Promise<boolean>`, as a spec writes it. */\nfunction memberText(member: Member): string {\n const params = member.params ? `(${member.params.join(\", \")})` : \"\";\n const returns = member.returns ? `: ${member.returns}` : \"\";\n const modifiers =\n member.modifiers && member.modifiers.length > 0 ? `${member.modifiers.join(\" \")} ` : \"\";\n return `${modifiers}${member.kind ? `${member.kind} ` : \"\"}${member.name}${params}${returns}`;\n}\n\n/** A declaration's signature: `method login(user: string): Promise<boolean>`. */\nexport function signatureText(symbol: SymbolFact): string {\n const modifiers = symbol.modifiers.length > 0 ? `${symbol.modifiers.join(\" \")} ` : \"\";\n const params = symbol.params ? `(${symbol.params.map(paramText).join(\", \")})` : \"\";\n const returns = symbol.returns ? `: ${symbol.returns.text}` : \"\";\n return `${modifiers}${symbol.kind} ${symbol.name}${params}${returns}`;\n}\n","/**\n * Rule evaluation (plan §D6), PBIs `structural-rules`, `query-and-test-rules` and\n * `architecture-rules`: the structural catalogue (§D6.2), raw Tree-sitter `query` rules (§D6.3)\n * through the adapter, and `test` rules. A rule's scope is its `within` binding or member, else\n * the spec's files (all sources for the architecture spec), narrowed by `paths`.\n */\nimport { builtinModules } from \"node:module\";\nimport { posix } from \"node:path\";\n\nimport {\n codeLocation,\n rangeContains,\n type Codebase,\n type SymbolEntry,\n type SymbolTable,\n} from \"./codebase.js\";\nimport { attributeMatches } from \"./contracts.js\";\nimport {\n createDiagnostic,\n type Diagnostic,\n type DiagnosticCode,\n type Location,\n} from \"./diagnostics.js\";\nimport type { CallFact, FileFacts, Range } from \"./facts.js\";\nimport { typePatternMatches, wildcard, qualifiedNameMatches } from \"./match.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Rule, StructuralRule } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/** The result of running the test command for one test. */\nexport interface TestRun {\n passed: boolean;\n /** The command line that ran. */\n command: string;\n /** The end of the command's output, for the report. */\n output: string;\n}\n\nexport interface RuleContext {\n codebase: Codebase;\n table: SymbolTable;\n /** The spec's resolved bindings, by id. */\n bindings: ReadonlyMap<string, ResolvedBinding>;\n /** The files the spec's rules apply to without `within`. */\n files: readonly FileFacts[];\n /** Runs a test rule's test (`check --run-tests`); undefined when tests aren't run. */\n runTest?: (symbol: string) => Promise<TestRun>;\n}\n\n/** The code a rule looks at: files, and inside them only `ranges` when `within` is set. */\ninterface Scope {\n files: FileFacts[];\n ranges?: Map<string, Range[]>;\n}\n\n/** Evaluates one rule of a spec. `manual` rules are never evaluated (ADR-007). */\nexport async function evaluateRule(\n spec: Spec,\n rule: Rule,\n context: RuleContext,\n): Promise<Diagnostic[]> {\n if (rule.class === \"manual\") return [];\n const scope = scopeOf(rule, context);\n if (!scope) return []; // `within` names a binding that didn't resolve; CS0201 says why.\n const diagnostics: Diagnostic[] = [];\n const report = (\n code: DiagnosticCode,\n message: string,\n extra: Partial<Diagnostic> & { codeLocation?: Location } = {},\n path: (string | number)[] = [],\n ): void => {\n diagnostics.push(\n createDiagnostic(code, {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, ...path]),\n ruleId: rule.id,\n item: `rule:${rule.id}`,\n message: rule.message ? `${rule.message} (${message})` : message,\n ...extra,\n }),\n );\n };\n const inScope = (path: string, range: Range): boolean => {\n const ranges = scope.ranges?.get(path);\n return !scope.ranges || (ranges ?? []).some((r) => rangeContains(r, range));\n };\n const adr = rule.adr ? `, ${rule.adr}` : \"\";\n\n if (rule.class === \"structural\") {\n evaluateStructural(rule, scope, context.table, inScope, report, adr);\n } else if (rule.class === \"query\") {\n const adapter = context.codebase.adapter(rule.lang);\n if (!adapter?.runQuery || adapter.checkQuery?.(rule.query) !== undefined) return []; // CS0130\n const hits: { path: string; range: Range }[] = [];\n for (const file of scope.files) {\n if (file.lang !== rule.lang || file.skipped !== undefined) continue;\n const source = await context.codebase.source(file.path);\n for (const range of adapter.runQuery(source, rule.query)) {\n if (inScope(file.path, range)) hits.push({ path: file.path, range });\n }\n }\n if (rule.expect === \"absent\") {\n for (const hit of hits) {\n report(\"CS0610\", `query rule \"${rule.id}\" matched; expected no match${adr}`, {\n codeLocation: codeLocation(hit.path, hit.range),\n expected: \"absent\",\n actual: \"match\",\n suggestions: [{ message: \"change the code so the query no longer matches\" }],\n });\n }\n } else if (hits.length === 0) {\n report(\"CS0610\", `query rule \"${rule.id}\" found no match; expected at least one${adr}`, {\n expected: \"present\",\n actual: \"no match\",\n suggestions: [{ message: \"add the code the query looks for\" }],\n });\n }\n } else {\n const { symbol, lang } = rule.test;\n const found = context.table.find(symbol).filter((e) => !lang || e.file.lang === lang);\n if (found.length === 0) {\n report(\n \"CS0620\",\n `test ${symbol} of rule \"${rule.id}\" not found`,\n {\n expected: symbol,\n actual: \"nothing\",\n suggestions: [{ message: `write the test ${symbol}, or fix the test symbol` }],\n },\n [\"test\", \"symbol\"],\n );\n } else if (context.runTest) {\n const run = await context.runTest(symbol);\n if (!run.passed) {\n report(\n \"CS0621\",\n `test ${symbol} of rule \"${rule.id}\" failed: ${run.command}`,\n {\n codeLocation: codeLocation(found[0]!.file.path, found[0]!.symbol.nameRange),\n expected: \"pass\",\n actual: run.output,\n suggestions: [{ message: `run ${run.command} and fix the test or the code` }],\n },\n [\"test\", \"symbol\"],\n );\n }\n }\n }\n return diagnostics;\n}\n\ntype Report = (\n code: DiagnosticCode,\n message: string,\n extra?: Partial<Diagnostic> & { codeLocation?: Location },\n path?: (string | number)[],\n) => void;\n\nfunction evaluateStructural(\n rule: StructuralRule,\n scope: Scope,\n table: SymbolTable,\n inScope: (path: string, range: Range) => boolean,\n report: Report,\n adr: string,\n): void {\n if (rule.forbid_call !== undefined || rule.require_call !== undefined) {\n const pattern = (rule.forbid_call ?? rule.require_call)!;\n const matches = wildcard(pattern);\n const calls: { file: FileFacts; call: CallFact; name: string }[] = [];\n for (const file of scope.files) {\n for (const call of file.calls) {\n const name = calleeNames(call.callee, file).find(matches);\n if (name !== undefined && inScope(file.path, call.range)) calls.push({ file, call, name });\n }\n }\n if (rule.forbid_call !== undefined) {\n for (const { file, call } of calls) {\n report(\n \"CS0601\",\n `call to ${call.callee} is forbidden by rule \"${rule.id}\" (${pattern}${adr})`,\n {\n codeLocation: codeLocation(file.path, call.range),\n expected: `no call matching ${pattern}`,\n actual: call.callee,\n suggestions: [\n { message: `remove the call to ${call.callee}, or add a waiver with a reason` },\n ],\n },\n [\"forbid_call\"],\n );\n }\n } else if (calls.length === 0) {\n report(\n \"CS0602\",\n `no call matching ${pattern} in the scope of rule \"${rule.id}\"${adr ? ` (${adr.slice(2)})` : \"\"}`,\n {\n expected: `a call matching ${pattern}`,\n actual: \"no such call\",\n suggestions: [{ message: `add a call matching ${pattern}` }],\n },\n [\"require_call\"],\n );\n }\n return;\n }\n\n const imports = rule.forbid_import ?? rule.allow_import_only;\n if (imports) {\n const from = globMatcher(imports.from);\n const to = globMatcher(imports.to);\n const forbid = rule.forbid_import !== undefined;\n const key = forbid ? \"forbid_import\" : \"allow_import_only\";\n for (const file of scope.files) {\n if (!from(file.path)) continue;\n for (const imp of file.imports) {\n if (!inScope(file.path, imp.range)) continue;\n const targets = importTargets(file.path, imp.module);\n const listed = targets.some(to);\n const violation = forbid ? listed : !listed && !isStdlib(imp.module, file.lang);\n if (!violation) continue;\n report(\n \"CS0603\",\n forbid\n ? `${file.path} imports ${imp.module}; rule \"${rule.id}\" forbids imports from ${listOf(imports.from)} to ${listOf(imports.to)}${adr}`\n : `${file.path} imports ${imp.module}; rule \"${rule.id}\" allows files in ${listOf(imports.from)} to import only ${listOf(imports.to)}${adr}`,\n {\n codeLocation: codeLocation(file.path, imp.range),\n expected: forbid\n ? `no import of ${listOf(imports.to)}`\n : `imports of ${listOf(imports.to)} only`,\n actual: imp.module,\n suggestions: [\n { message: `remove the import of ${imp.module} from ${file.path}, or move the code` },\n ],\n },\n [key],\n );\n }\n }\n return;\n }\n\n if (rule.naming) {\n const naming = rule.naming;\n const nameMatches = wildcard(naming.name);\n const inPath = naming.in_path ? globMatcher(naming.in_path) : undefined;\n for (const { symbol, file } of entriesIn(scope, table, inScope)) {\n if (naming.kind ? symbol.kind !== naming.kind : symbol.kind === \"constructor\") continue;\n if (!nameMatches(symbol.name)) continue;\n const problems: string[] = [];\n for (const type of naming.implements ?? []) {\n if (!symbol.bases.some((b) => typePatternMatches(type, b)))\n problems.push(`implement ${type}`);\n }\n if (\n naming.extends !== undefined &&\n !symbol.bases.some((b) => typePatternMatches(naming.extends!, b))\n ) {\n problems.push(`extend ${naming.extends}`);\n }\n for (const attribute of naming.attributes ?? []) {\n if (!symbol.attributes.some((a) => attributeMatches(attribute, a)))\n problems.push(`have attribute ${attribute}`);\n }\n if (inPath && !inPath(file.path)) problems.push(`live in ${listOf(naming.in_path!)}`);\n if (problems.length === 0) continue;\n report(\n \"CS0604\",\n `${symbol.kind} ${symbol.qualifiedName} must ${problems.join(\", \")} (rule \"${rule.id}\": ${naming.name}${adr})`,\n {\n codeLocation: codeLocation(file.path, symbol.nameRange),\n expected: problems,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [{ message: `make ${symbol.name} ${problems.join(\", \")}, or rename it` }],\n },\n [\"naming\"],\n );\n }\n return;\n }\n\n if (rule.must_not_exist) {\n const { symbol: pattern, kind } = rule.must_not_exist;\n for (const { symbol, file } of entriesIn(scope, table, inScope)) {\n if (kind ? symbol.kind !== kind : symbol.kind === \"constructor\") continue;\n if (!qualifiedNameMatches(pattern, symbol.qualifiedName)) continue;\n report(\n \"CS0605\",\n `${symbol.kind} ${symbol.qualifiedName} must not exist (rule \"${rule.id}\"${adr})`,\n {\n codeLocation: codeLocation(file.path, symbol.nameRange),\n expected: `no ${kind ?? \"symbol\"} ${pattern}`,\n actual: symbol.qualifiedName,\n suggestions: [{ message: `remove or rename ${symbol.qualifiedName}` }],\n },\n [\"must_not_exist\"],\n );\n }\n }\n}\n\n/** The declarations in a scope. */\nfunction entriesIn(\n scope: Scope,\n table: SymbolTable,\n inScope: (path: string, range: Range) => boolean,\n): SymbolEntry[] {\n const files = new Set(scope.files.map((f) => f.path));\n return table.entries.filter(\n (e) => files.has(e.file.path) && inScope(e.file.path, e.symbol.range),\n );\n}\n\n/** The files and ranges a rule applies to; undefined when its `within` binding didn't resolve. */\nfunction scopeOf(rule: Rule, context: RuleContext): Scope | undefined {\n const paths = rule.paths ? globMatcher(rule.paths) : undefined;\n const narrow = (files: readonly FileFacts[]): FileFacts[] =>\n paths ? files.filter((f) => paths(f.path)) : [...files];\n const within = \"within\" in rule ? rule.within : undefined;\n if (within === undefined) return { files: narrow(context.files) };\n const bindingId = context.bindings.has(within)\n ? within\n : [...context.bindings.keys()]\n .filter((id) => within.startsWith(`${id}.`))\n .sort((a, b) => b.length - a.length)[0];\n const resolved = bindingId === undefined ? undefined : context.bindings.get(bindingId);\n if (!resolved) return undefined;\n const memberName =\n within.length > bindingId!.length ? within.slice(bindingId!.length + 1) : undefined;\n // Each part of a C# partial type is in its own file, with its own members.\n const ranges = new Map<string, Range[]>();\n for (const part of resolved.parts) {\n const targets = memberName\n ? part.symbol.members.filter((m) => m.name === memberName)\n : [part.symbol];\n if (targets.length === 0) continue;\n ranges.set(part.file.path, [\n ...(ranges.get(part.file.path) ?? []),\n ...targets.map((t) => t.range),\n ]);\n }\n if (ranges.size === 0) return undefined; // the missing member is CS0203\n const files = context.codebase.files.filter((f) => ranges.has(f.path));\n return { files: narrow(files), ranges };\n}\n\n/**\n * Names a call matches by: the callee as written, and with its first segment resolved through\n * the file's imports (`exec` imported from `node:child_process` is also `child_process.exec`).\n * An import of every name without an alias (C# `using System;`, `using static System.Console;`)\n * also prefixes the callee with the module. In C#, names starting with `System.` also match\n * without it, as types do.\n */\nexport function calleeNames(callee: string, file: FileFacts): string[] {\n const names = [callee];\n const [head, ...rest] = callee.split(\".\");\n for (const imp of file.imports) {\n const module = imp.module.replace(/^node:/, \"\");\n for (const imported of imp.names) {\n if (imported.name === \"*\" && imported.alias === undefined && imp.kind !== \"reexport\") {\n names.push(`${module}.${callee}`);\n continue;\n }\n if ((imported.alias ?? imported.name) !== head) continue;\n const name =\n imported.name === \"*\" || imported.name === \"default\"\n ? [module, ...rest]\n : [module, imported.name, ...rest];\n names.push(name.join(\".\"));\n }\n }\n if (file.lang === \"csharp\") {\n for (const name of [...names]) if (name.startsWith(\"System.\")) names.push(name.slice(7));\n }\n return names;\n}\n\nconst SOURCE_EXTENSIONS = [\".ts\", \".tsx\", \".mts\", \".cts\", \".d.ts\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\n\n/**\n * What an import can be matched against: a relative specifier as a repository path (with and\n * without an extension, `./x.js` also as `x.ts`), a package specifier as written, without\n * `node:`, and as its package name.\n */\nexport function importTargets(fromFile: string, module: string): string[] {\n if (module.startsWith(\".\")) {\n const resolved = posix.normalize(posix.join(posix.dirname(fromFile), module));\n const bare = resolved.replace(/\\.(?:[mc]?[jt]sx?)$/, \"\");\n return [\n ...new Set([\n resolved,\n bare,\n ...SOURCE_EXTENSIONS.map((e) => bare + e),\n ...SOURCE_EXTENSIONS.map((e) => `${bare}/index${e}`),\n ]),\n ];\n }\n const name = module.replace(/^node:/, \"\");\n const segments = name.split(\"/\");\n const pkg = name.startsWith(\"@\") ? segments.slice(0, 2).join(\"/\") : segments[0]!;\n return [...new Set([module, name, pkg])];\n}\n\nconst BUILTINS = new Set(builtinModules);\n\n/** Node.js built-in modules (`fs`, `node:fs`); in C#, the `System` namespaces. */\nconst isStdlib = (module: string, lang: string): boolean =>\n lang === \"csharp\"\n ? module === \"System\" || module.startsWith(\"System.\")\n : module.startsWith(\"node:\") || BUILTINS.has(module.split(\"/\")[0]!);\n","/**\n * The check pipeline (plan §D11.3), PBIs `status-and-waivers` and `check-command`: resolves the\n * bindings of each spec, evaluates contracts and rules, applies the enforcement matrix by spec\n * status (§D8) and the waivers (§D6.5), and records every contract item's result. Architecture\n * rules apply to every source file unless the architecture spec is a draft (§D6.4).\n */\nimport { execFile } from \"node:child_process\";\n\nimport { SymbolTable, type Codebase } from \"./codebase.js\";\nimport { bindingItems, evaluateContract } from \"./contracts.js\";\nimport {\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n type DiagnosticCode,\n} from \"./diagnostics.js\";\nimport { parseErrorDiagnostics, type FileFacts, type LanguageAdapter } from \"./facts.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { applyLock, lockedFiles, type LockFile } from \"./lock.js\";\nimport { resolveBinding, type ResolvedBinding } from \"./resolve.js\";\nimport { evaluateRule, type TestRun } from \"./rules.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/**\n * `status`: enforcement by spec status (§D8): draft, ready and deprecated specs aren't checked,\n * failures of in-progress specs are warnings. `full`: every selected spec is checked as if it\n * were implemented (`check --spec`, `status … implemented`, `coverage`).\n */\nexport type CheckMode = \"status\" | \"full\";\n\nexport interface CheckOptions {\n /** Only these spec ids; repository-wide diagnostics are left out. */\n specs?: readonly string[];\n mode?: CheckMode;\n /** Today, for waiver expiry. */\n now?: Date;\n /** Runs a test rule's test (`--run-tests`). */\n runTest?: (symbol: string) => Promise<TestRun>;\n /**\n * Lock files by spec id (plan §D7), for the ratchet (CS0301), drift (CS0300) and the locked\n * files of bindings. Default: the lock files of the model.\n */\n locks?: ReadonlyMap<string, LockFile>;\n}\n\n/** The result of one contract item: a binding, a member or a rule. */\nexport interface ItemResult {\n spec: string;\n /** `binding:<id>`, `binding:<id>.<member>` or `rule:<id>`. */\n item: string;\n /** False for `manual` rules: nothing checks them (ADR-007). */\n enforceable: boolean;\n /** Checked and nothing failed (an active waiver counts as passing); false for manual rules. */\n passed: boolean;\n}\n\nexport interface CheckResult {\n /** The specs whose contracts were evaluated. */\n checked: Spec[];\n items: ItemResult[];\n /** Spec diagnostics (`--specs-only`) and code diagnostics, sorted. */\n diagnostics: Diagnostic[];\n /** Resolved bindings by spec id, then binding id. */\n resolved: Map<string, Map<string, ResolvedBinding>>;\n /**\n * True when a result depends on more than the files of the checked specs: a binding was looked\n * up in every source file, or a check consulted every declaration (ambiguity, type aliases,\n * test symbols). A check on part of the code (`check --staged`) is then repeated on all of it.\n */\n repositoryWide: boolean;\n}\n\n/** Codes whose result depends on every declaration of the repository, not only a spec's files. */\nconst REPOSITORY_WIDE_CODES = new Set<DiagnosticCode>([\"CS0202\", \"CS0204\", \"CS0220\", \"CS0620\"]);\n\n/** True when a spec's contracts are evaluated in `status` mode (§D6.4, §D8). */\nexport function isEnforced(spec: Spec): boolean {\n if (spec.type === \"architecture\") return spec.status !== \"draft\";\n return spec.status === \"in-progress\" || spec.status === \"implemented\";\n}\n\n/** CS0130: query rules whose query doesn't compile, checked when the specs load. */\nexport function queryDiagnostics(\n model: SpecModel,\n adapter: (lang: string) => LanguageAdapter | undefined,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const spec of model.specs.byFile.values()) {\n for (const rule of spec.rules) {\n if (rule.class !== \"query\") continue;\n const lang = adapter(rule.lang);\n const error = !lang\n ? `no language adapter for \"${rule.lang}\"`\n : !lang.checkQuery\n ? `the ${rule.lang} adapter doesn't support query rules`\n : lang.checkQuery(rule.query);\n if (error === undefined) continue;\n diagnostics.push(\n createDiagnostic(\"CS0130\", {\n spec: spec.id,\n ruleId: rule.id,\n item: `rule:${rule.id}`,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, \"query\"]),\n message: `rule \"${rule.id}\": invalid ${rule.lang} query: ${error}`,\n actual: rule.query,\n suggestions: [{ message: \"fix the query; check its parentheses and node types\" }],\n }),\n );\n }\n }\n return diagnostics;\n}\n\n/** Runs the check: spec diagnostics of `model` plus the evaluation of the code. */\nexport async function checkCode(\n model: SpecModel,\n codebase: Codebase,\n options: CheckOptions = {},\n): Promise<CheckResult> {\n const mode = options.mode ?? \"status\";\n const now = options.now ?? new Date();\n const locks = options.locks ?? model.locks;\n let repositoryWide = false;\n const table = new SymbolTable(codebase.files);\n const selected = options.specs ? new Set(options.specs) : undefined;\n const specs = model.specs\n .all()\n .filter((s) => (selected ? selected.has(s.id) : true))\n .filter(\n (s) =>\n s.valid &&\n (mode === \"full\" ? selected !== undefined || s.status !== \"deprecated\" : isEnforced(s)),\n );\n\n const specDiagnostics = [\n ...model.diagnostics,\n ...queryDiagnostics(model, (lang) => codebase.adapter(lang)),\n ].filter((d) => !selected || (d.spec !== undefined && selected.has(d.spec)));\n\n const diagnostics: Diagnostic[] = [];\n const items: ItemResult[] = [];\n const resolvedBySpec = new Map<string, Map<string, ResolvedBinding>>();\n const testRuns = new Map<string, Promise<TestRun>>();\n const runTest = options.runTest\n ? (symbol: string): Promise<TestRun> => {\n let run = testRuns.get(symbol);\n if (!run) testRuns.set(symbol, (run = options.runTest!(symbol)));\n return run;\n }\n : undefined;\n const failedSpecs = new Set(\n specDiagnostics.filter((d) => d.code === \"CS0130\").map((d) => `${d.spec}\\0${d.ruleId}`),\n );\n\n for (const spec of specs) {\n const raw: Diagnostic[] = [];\n const resolved = new Map<string, ResolvedBinding>();\n const lock = locks.get(spec.id);\n for (const binding of spec.bindings) {\n const resolution = resolveBinding(spec, binding, table, lockedFiles(lock, binding.id));\n raw.push(...resolution.diagnostics);\n if (resolution.searched) repositoryWide = true;\n if (!resolution.resolved) continue;\n resolved.set(binding.id, resolution.resolved);\n raw.push(\n ...evaluateContract(spec, resolution.resolved, {\n table,\n adapter: codebase.adapter(resolution.resolved.file.lang),\n unresolvable: model.config.enforcement.unresolvable,\n }),\n );\n }\n resolvedBySpec.set(spec.id, resolved);\n const files = specFiles(spec, resolved, codebase.files);\n for (const rule of spec.rules) {\n if (failedSpecs.has(`${spec.id}\\0${rule.id}`)) continue;\n raw.push(\n ...(await evaluateRule(spec, rule, {\n codebase,\n table,\n bindings: resolved,\n files,\n ...(runTest ? { runTest } : {}),\n })),\n );\n }\n\n if (raw.some((d) => REPOSITORY_WIDE_CODES.has(d.code))) repositoryWide = true;\n const enforced = enforce(spec, raw, mode, now);\n diagnostics.push(\n ...applyLock(spec, enforced, resolved, lock, {\n drift: model.config.enforcement.drift,\n asImplemented: mode === \"full\",\n }),\n );\n\n const unresolved = new Set(spec.bindings.filter((b) => !resolved.has(b.id)).map((b) => b.id));\n const failing = new Set(\n enforced.filter((d) => d.item && d.severity !== \"info\").map((d) => d.item!),\n );\n for (const binding of spec.bindings) {\n for (const item of bindingItems(binding)) {\n items.push({\n spec: spec.id,\n item,\n enforceable: true,\n passed: !unresolved.has(binding.id) && !failing.has(item),\n });\n }\n }\n for (const rule of spec.rules) {\n const item = `rule:${rule.id}`;\n const within = \"within\" in rule ? rule.within : undefined;\n const blocked =\n within !== undefined &&\n [...unresolved].some((id) => within === id || within.startsWith(`${id}.`));\n items.push({\n spec: spec.id,\n item,\n enforceable: rule.class !== \"manual\",\n passed:\n rule.class !== \"manual\" &&\n !blocked &&\n !failing.has(item) &&\n !failedSpecs.has(`${spec.id}\\0${rule.id}`),\n });\n }\n }\n\n // Syntax errors of the files the selected specs bind (all files without --spec).\n const boundFiles = new Set(\n [...resolvedBySpec.values()].flatMap((m) => [...m.values()].flatMap((r) => r.files)),\n );\n const parseErrors = codebase.files\n .filter((f) => !selected || boundFiles.has(f.path))\n .flatMap(parseErrorDiagnostics);\n\n return {\n checked: specs,\n items,\n diagnostics: sortDiagnostics([...specDiagnostics, ...diagnostics, ...parseErrors]),\n resolved: resolvedBySpec,\n repositoryWide,\n };\n}\n\n/** Files a spec's rules apply to by default: every source for the architecture spec, else the\n * files of its resolved bindings and its `scope` globs. */\nfunction specFiles(\n spec: Spec,\n resolved: ReadonlyMap<string, ResolvedBinding>,\n files: readonly FileFacts[],\n): FileFacts[] {\n if (spec.type === \"architecture\") return [...files];\n const bound = new Set([...resolved.values()].flatMap((r) => r.files));\n const inScope = spec.scope.length > 0 ? globMatcher(spec.scope) : () => false;\n return files.filter((f) => bound.has(f.path) || inScope(f.path));\n}\n\n/** Codes of contract failures, which the status matrix lowers for in-progress specs. */\nconst isContractFailure = (code: DiagnosticCode): boolean =>\n code.startsWith(\"CS02\") || code.startsWith(\"CS06\");\n\n/** Applies waivers (§D6.5) and the enforcement matrix (§D8) to a spec's raw diagnostics. */\nfunction enforce(spec: Spec, raw: Diagnostic[], mode: CheckMode, now: Date): Diagnostic[] {\n const today = isoDate(now);\n const out: Diagnostic[] = [];\n const active = spec.waivers.filter((w) => w.until === undefined || w.until >= today);\n for (const waiver of spec.waivers) {\n if (waiver.until === undefined || waiver.until >= today) continue;\n out.push(\n createDiagnostic(\"CS0401\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"waivers\", waiver.index, \"until\"]),\n ruleId: waiver.rule,\n message: `the waiver for rule \"${waiver.rule}\" expired on ${waiver.until} (${waiver.reason}); its violations are reported again`,\n expected: `until ≥ ${today}`,\n actual: waiver.until,\n suggestions: [\n { message: \"fix the violations and remove the waiver, or extend until with a reason\" },\n ],\n }),\n );\n }\n for (const d of raw) {\n const waiver = active.find(\n (w) =>\n d.ruleId === w.rule &&\n (!w.paths || (d.codeLocation !== undefined && globMatcher(w.paths)(d.codeLocation.file))),\n );\n if (waiver) {\n out.push({\n ...d,\n code: \"CS0400\",\n severity: \"info\",\n message: `waived${waiver.until ? ` until ${waiver.until}` : \"\"} (${waiver.reason}): ${d.code} ${d.message}`,\n actual: d.code,\n });\n continue;\n }\n const lowered =\n mode === \"status\" &&\n spec.type !== \"architecture\" &&\n spec.status === \"in-progress\" &&\n d.severity === \"error\" &&\n isContractFailure(d.code);\n out.push(lowered ? { ...d, severity: \"warning\" } : d);\n }\n return out;\n}\n\nconst isoDate = (date: Date): string =>\n `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}-${String(date.getDate()).padStart(2, \"0\")}`;\n\n/** `tests.command` as arguments: a string is split at whitespace. */\nexport const testCommandArgs = (command: string | readonly string[]): string[] =>\n typeof command === \"string\" ? command.trim().split(/\\s+/) : [...command];\n\n/**\n * Runs `tests.command` for one test, without a shell (ADR-009): `{test}` in an argument is\n * replaced with the test symbol. The test passes when the command exits with 0.\n */\nexport function runTestCommand(\n root: string,\n command: string | readonly string[],\n symbol: string,\n timeoutMs = 10 * 60_000,\n): Promise<TestRun> {\n const [file, ...args] = testCommandArgs(command).map((a) => a.replaceAll(\"{test}\", symbol));\n const line = [file, ...args].join(\" \");\n return new Promise((resolvePromise) => {\n execFile(\n file!,\n args,\n { cwd: root, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, windowsHide: true },\n (error, stdout, stderr) => {\n const output = `${stdout}${stderr}`.trim().split(/\\r?\\n/).slice(-20).join(\"\\n\");\n resolvePromise({\n passed: !error,\n command: line,\n output: error && !output ? error.message : output,\n });\n },\n );\n });\n}\n\n/** Specs a status change depends on, for `catspec status` (§D8). */\nexport interface StatusGate {\n allowed: boolean;\n diagnostics: Diagnostic[];\n}\n\n/**\n * Whether `spec` may move to `target` (§D8): `ready` needs every dependency to exist,\n * `in-progress` and `implemented` need them implemented and passing (CS0502; `force` skips this),\n * and `implemented` needs the spec's own contracts to pass (never forced).\n */\nexport async function statusGate(\n model: SpecModel,\n codebase: Codebase,\n spec: Spec,\n target: Spec[\"status\"],\n options: { force?: boolean; now?: Date } = {},\n): Promise<StatusGate> {\n const diagnostics: Diagnostic[] = [];\n const now = options.now ?? new Date();\n if (\n !options.force &&\n (target === \"ready\" || target === \"in-progress\" || target === \"implemented\")\n ) {\n const problems: string[] = [];\n for (const dep of spec.dependsOn) {\n const other = model.specs.get(dep);\n if (!other) {\n problems.push(`${dep} does not exist`);\n continue;\n }\n if (target === \"ready\") continue;\n if (other.status !== \"implemented\") {\n problems.push(`${dep} is ${other.status}, not implemented`);\n continue;\n }\n const result = await checkCode(model, codebase, { specs: [dep], mode: \"full\", now });\n if (result.diagnostics.some((d) => d.severity === \"error\")) {\n problems.push(\n `${dep} is implemented but its contracts fail (run \\`catspec check --spec ${dep}\\`)`,\n );\n }\n }\n if (problems.length > 0) {\n diagnostics.push(\n createDiagnostic(\"CS0502\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"depends_on\"]),\n message: `\"${spec.id}\" can't become ${target}: ${listOf(problems)}`,\n expected:\n target === \"ready\"\n ? \"every dependency exists\"\n : \"every dependency implemented and passing\",\n actual: problems,\n suggestions: [{ message: \"finish the dependencies first, or use --force\" }],\n }),\n );\n }\n }\n if (target === \"implemented\") {\n const result = await checkCode(model, codebase, { specs: [spec.id], mode: \"full\", now });\n diagnostics.push(...result.diagnostics.filter((d) => d.severity === \"error\"));\n }\n return {\n allowed: !diagnostics.some((d) => d.severity === \"error\"),\n diagnostics: sortDiagnostics(diagnostics),\n };\n}\n","/**\n * Lock files (plan §D7, ADR-004), PBIs `lock-files`, `ratchet` and `drift-and-accept`: the\n * observed state of a spec, generated next to it as `<spec-id>.lock.json` and committed.\n *\n * - `items`: a hash of each contract item as the spec declares it, so a change to one item resets\n * only that item (§D7.1).\n * - `satisfied`: items that passed once. A failure of one of them is a regression, CS0301, even\n * while the spec is in progress (ADR-006).\n * - `symbols`: where each binding resolved, and the shape of the declaration (bodies excluded)\n * with its fingerprint. A shape change of an implemented spec is drift, CS0300 (§D7.2), until\n * `catspec accept` records it.\n *\n * The writer is deterministic: keys are sorted and lists ordered, so the same state gives the same\n * bytes on every platform.\n */\nimport { createHash } from \"node:crypto\";\nimport { posix } from \"node:path\";\n\nimport type { ItemResult } from \"./check.js\";\nimport { bindingItems } from \"./contracts.js\";\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport type { ParamFact, SymbolFact } from \"./facts.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { listOf } from \"./util.js\";\n\n/** The shape of a declaration: what a caller depends on, without bodies (§D7.2). */\nexport interface Shape {\n kind: string;\n name: string;\n bases: string[];\n attributes: string[];\n modifiers: string[];\n /** Parameters and return type of a function binding: `(string,number):boolean`. */\n signature?: string;\n /** Member signatures, sorted: `public method login(string):Promise<boolean>`. */\n members: string[];\n}\n\nexport interface LockedSymbol {\n /** `path#QualifiedName` of the declaration (of its first part). */\n resolved: string;\n /** Every file of a C# partial type, when there is more than one. */\n files?: string[];\n fingerprint: string;\n shape: Shape;\n}\n\nexport interface LockFile {\n spec: string;\n /** Hash of the spec's bindings and rules. */\n specHash: string;\n /** Hash of each contract item as declared, by item. */\n items: Record<string, string>;\n /** Items that passed at least once, sorted. */\n satisfied: string[];\n /** Observed declarations, by binding id. */\n symbols: Record<string, LockedSymbol>;\n}\n\n/** The lock file of a spec: `<spec-id>.lock.json` in the spec's folder. */\nexport const lockPathOf = (spec: { id: string; file: string }): string =>\n posix.join(posix.dirname(spec.file), `${spec.id}.lock.json`);\n\n/** Specs that have lock files: every spec except the architecture spec. */\nexport const hasLockFile = (spec: Spec): boolean => spec.type !== \"architecture\";\n\nconst sha256 = (value: unknown): string =>\n `sha256:${createHash(\"sha256\").update(canonicalJson(value)).digest(\"hex\")}`;\n\n/** JSON with sorted object keys and no undefined values. */\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value === null || typeof value !== \"object\") return value;\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => compareStrings(a, b))\n .map(([k, v]) => [k, sortKeys(v)]),\n );\n}\n\n/** A frontmatter entry without its position in the list. */\nfunction declared<T extends { index: number }>(entry: T): Omit<T, \"index\"> {\n const copy: Partial<T> = { ...entry };\n delete copy.index;\n return copy as Omit<T, \"index\">;\n}\n\n/**\n * The declared contract of a binding item. `symbol` and `file` are locations, not contract\n * (ADR-008): `catspec sync` rewrites them without resetting the ratchet.\n */\nconst bindingContract = (binding: Binding): unknown => ({\n kind: binding.kind,\n lang: binding.lang,\n implements: binding.implements,\n extends: binding.extends,\n attributes: binding.attributes,\n constructorRequires: binding.constructorRequires,\n exported: binding.exported,\n});\n\n/** The hash of every contract item of a spec, by item (§D7.1). */\nexport function itemHashes(spec: Spec): Record<string, string> {\n const hashes: Record<string, string> = {};\n for (const binding of spec.bindings) {\n hashes[`binding:${binding.id}`] = sha256(bindingContract(binding));\n for (const member of binding.members) {\n hashes[`binding:${binding.id}.${member.name}`] = sha256(member);\n }\n }\n for (const rule of spec.rules) hashes[`rule:${rule.id}`] = sha256(declared(rule));\n return hashes;\n}\n\n/** Hash of the whole contract of a spec. */\nexport const specHash = (spec: Spec): string =>\n sha256({\n bindings: spec.bindings.map(declared),\n rules: spec.rules.map(declared),\n });\n\nconst paramType = (p: ParamFact): string =>\n `${p.rest ? \"...\" : \"\"}${p.type?.text ?? \"?\"}${p.optional ? \"?\" : \"\"}`;\n\nconst callSignature = (s: SymbolFact): string =>\n `(${(s.params ?? []).map(paramType).join(\",\")})${s.returns ? `:${s.returns.text}` : \"\"}`;\n\nconst sortedModifiers = (s: SymbolFact): string[] => [...s.modifiers].sort(compareStrings);\n\nconst attributeText = (a: { name: string; args: string[] }): string =>\n a.args.length > 0 ? `${a.name}(${a.args.join(\",\")})` : a.name;\n\n/** The shape of a declaration: kind, name, bases, attributes, modifiers and member signatures. */\nexport function shapeOf(symbol: SymbolFact): Shape {\n const member = (m: SymbolFact): string => {\n const modifiers = sortedModifiers(m);\n const head = [...modifiers, m.kind, m.name].join(\" \");\n return m.params !== undefined\n ? `${head}${callSignature(m)}`\n : `${head}${m.returns ? `:${m.returns.text}` : \"\"}`;\n };\n const shape: Shape = {\n kind: symbol.kind,\n name: symbol.qualifiedName,\n bases: symbol.bases.map((b) => b.text),\n attributes: symbol.attributes.map(attributeText).sort(compareStrings),\n modifiers: sortedModifiers(symbol),\n members: symbol.members.map(member).sort(compareStrings),\n };\n if (symbol.params !== undefined) shape.signature = callSignature(symbol);\n return shape;\n}\n\nexport const fingerprintOf = (shape: Shape): string => sha256(shape);\n\n/** The files a locked binding resolved to, for binding resolution (§D11.5 step 2). */\nexport function lockedFiles(lock: LockFile | undefined, bindingId: string): string[] {\n const entry = lock?.symbols[bindingId];\n if (!entry) return [];\n if (entry.files && entry.files.length > 0) return entry.files;\n const hash = entry.resolved.lastIndexOf(\"#\");\n return [hash === -1 ? entry.resolved : entry.resolved.slice(0, hash)];\n}\n\n/** Parses a lock file; undefined when it isn't a valid lock file (it is then rebuilt). */\nexport function parseLock(text: string): LockFile | undefined {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (value === null || typeof value !== \"object\") return undefined;\n const lock = value as Partial<LockFile>;\n const isRecord = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === \"object\" && !Array.isArray(v);\n if (\n typeof lock.spec !== \"string\" ||\n !Array.isArray(lock.satisfied) ||\n !lock.satisfied.every((s) => typeof s === \"string\") ||\n !isRecord(lock.items) ||\n !isRecord(lock.symbols) ||\n !Object.values(lock.symbols).every(\n (s) =>\n isRecord(s) &&\n typeof s.resolved === \"string\" &&\n typeof s.fingerprint === \"string\" &&\n isRecord(s.shape),\n )\n ) {\n return undefined;\n }\n return {\n spec: lock.spec,\n specHash: typeof lock.specHash === \"string\" ? lock.specHash : \"\",\n items: lock.items,\n satisfied: lock.satisfied,\n symbols: lock.symbols,\n };\n}\n\n/**\n * The lock file's text: the fields in the order of plan §D7, every map sorted by key, two-space\n * indent, `\\n` line endings and a final newline.\n */\nexport function serializeLock(lock: LockFile): string {\n const symbols = Object.fromEntries(\n Object.keys(lock.symbols)\n .sort(compareStrings)\n .map((id) => {\n const { resolved, files, fingerprint, shape } = lock.symbols[id]!;\n return [id, { resolved, files, fingerprint, shape: sortKeys(shape) }];\n }),\n );\n const ordered = {\n spec: lock.spec,\n specHash: lock.specHash,\n items: sortKeys(lock.items),\n satisfied: lock.satisfied,\n symbols,\n };\n return `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\n/** Items of the lock that still mean what the spec declares: same hash as when they passed. */\nfunction stillSatisfied(lock: LockFile | undefined, hashes: Record<string, string>): Set<string> {\n if (!lock) return new Set();\n return new Set(\n lock.satisfied.filter(\n (item) => hashes[item] !== undefined && lock.items[item] === hashes[item],\n ),\n );\n}\n\n/** True when a binding's declared contract (its item and every member item) is unchanged. */\nfunction bindingUnchanged(\n binding: Binding,\n lock: LockFile,\n hashes: Record<string, string>,\n): boolean {\n const items = bindingItems(binding);\n const locked = Object.keys(lock.items).filter(\n (item) => item === `binding:${binding.id}` || item.startsWith(`binding:${binding.id}.`),\n );\n return locked.length === items.length && items.every((item) => lock.items[item] === hashes[item]);\n}\n\nexport interface LockCheckOptions {\n /** Severity of drift for implemented specs (`enforcement.drift`). */\n drift: \"off\" | \"warn\" | \"strict\";\n /** `full`: the spec is checked as if implemented (`check --spec`). */\n asImplemented?: boolean;\n}\n\n/**\n * The ratchet and drift for one spec (§D7.1, §D7.2, §D8): a failure of an item that passed\n * before becomes CS0301 (an error, also in progress), and a shape change of a binding whose\n * contract didn't change is CS0300 (info in progress, `enforcement.drift` when implemented).\n */\nexport function applyLock(\n spec: Spec,\n diagnostics: Diagnostic[],\n resolved: ReadonlyMap<string, ResolvedBinding>,\n lock: LockFile | undefined,\n options: LockCheckOptions,\n): Diagnostic[] {\n if (!lock || spec.type === \"architecture\") return diagnostics;\n const hashes = itemHashes(spec);\n const satisfied = stillSatisfied(lock, hashes);\n const out = diagnostics.map((d) =>\n d.item !== undefined &&\n satisfied.has(d.item) &&\n d.severity !== \"info\" &&\n d.code !== \"CS0220\" &&\n d.code !== \"CS0401\"\n ? {\n ...d,\n code: \"CS0301\" as const,\n severity: \"error\" as const,\n message: `regression: ${d.item} passed before and now fails: ${d.code} ${d.message}`,\n }\n : d,\n );\n\n const implemented = options.asImplemented === true || spec.status === \"implemented\";\n const severity = implemented\n ? options.drift === \"off\"\n ? undefined\n : options.drift === \"strict\"\n ? (\"error\" as const)\n : (\"warning\" as const)\n : (\"info\" as const);\n if (severity === undefined) return out;\n for (const binding of spec.bindings) {\n const entry = lock.symbols[binding.id];\n const current = resolved.get(binding.id);\n if (!entry || !current || !bindingUnchanged(binding, lock, hashes)) continue;\n const shape = shapeOf(current.symbol);\n if (fingerprintOf(shape) === entry.fingerprint) continue;\n const changes = shapeChanges(entry.shape, shape);\n out.push(\n createDiagnostic(\"CS0300\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n codeLocation: {\n file: current.file.path,\n line: current.symbol.nameRange.start.line,\n column: current.symbol.nameRange.start.column,\n },\n bindingId: binding.id,\n severity,\n message: `binding \"${binding.id}\": the shape of ${current.symbol.qualifiedName} changed and the spec doesn't mention it: ${listOf(changes)}`,\n expected: entry.shape,\n actual: shape,\n suggestions: [\n { message: `run \\`catspec accept ${spec.id}\\` if the change is intended` },\n { message: \"or update the spec, or change the code back\" },\n ],\n }),\n );\n }\n return out;\n}\n\n/** Human-readable differences between two shapes. */\nfunction shapeChanges(before: Shape, after: Shape): string[] {\n const changes: string[] = [];\n if (before.kind !== after.kind) changes.push(`kind ${before.kind} → ${after.kind}`);\n if (before.name !== after.name) changes.push(`name ${before.name} → ${after.name}`);\n if ((before.signature ?? \"\") !== (after.signature ?? \"\")) {\n changes.push(`signature ${before.signature ?? \"none\"} → ${after.signature ?? \"none\"}`);\n }\n const lists: [string, keyof Shape][] = [\n [\"base\", \"bases\"],\n [\"attribute\", \"attributes\"],\n [\"modifier\", \"modifiers\"],\n [\"member\", \"members\"],\n ];\n for (const [label, key] of lists) {\n const a = (before[key] as string[] | undefined) ?? [];\n const b = (after[key] as string[] | undefined) ?? [];\n for (const removed of a.filter((x) => !b.includes(x))) changes.push(`- ${label} ${removed}`);\n for (const added of b.filter((x) => !a.includes(x))) changes.push(`+ ${label} ${added}`);\n }\n return changes.length > 0 ? changes : [\"the shape changed\"];\n}\n\nexport interface NextLockOptions {\n /**\n * `update` (the hook): keeps the ratchet history, and the accepted shapes of an implemented\n * spec until they are accepted. `accept`: records the current shapes. `rebuild`: from the\n * current code only, without history.\n */\n mode: \"update\" | \"accept\" | \"rebuild\";\n}\n\n/** The lock file after a check of `spec`. */\nexport function nextLock(\n spec: Spec,\n items: readonly ItemResult[],\n resolved: ReadonlyMap<string, ResolvedBinding>,\n previous: LockFile | undefined,\n options: NextLockOptions,\n): LockFile {\n const hashes = itemHashes(spec);\n const prev = options.mode === \"rebuild\" ? undefined : previous;\n const satisfied = stillSatisfied(prev, hashes);\n for (const item of items) {\n if (item.spec === spec.id && item.passed && hashes[item.item] !== undefined) {\n satisfied.add(item.item);\n }\n }\n const symbols: Record<string, LockedSymbol> = {};\n for (const binding of spec.bindings) {\n const current = resolved.get(binding.id);\n const old = prev?.symbols[binding.id];\n if (!current) {\n if (old) symbols[binding.id] = old;\n continue;\n }\n const shape = shapeOf(current.symbol);\n const location: Pick<LockedSymbol, \"resolved\" | \"files\"> = {\n resolved: `${current.file.path}#${current.symbol.qualifiedName}`,\n ...(current.files.length > 1 ? { files: [...current.files].sort(compareStrings) } : {}),\n };\n const keepAccepted =\n options.mode === \"update\" &&\n old !== undefined &&\n prev !== undefined &&\n spec.status === \"implemented\" &&\n bindingUnchanged(binding, prev, hashes);\n symbols[binding.id] = keepAccepted\n ? { ...location, fingerprint: old.fingerprint, shape: old.shape }\n : { ...location, fingerprint: fingerprintOf(shape), shape };\n }\n return {\n spec: spec.id,\n specHash: specHash(spec),\n items: hashes,\n satisfied: [...satisfied].sort(compareStrings),\n symbols,\n };\n}\n","/**\n * Git access (plan §D11.3, ADR-009), PBI `git-access`: git runs with `execFile` / `spawn` and an\n * argument list, never through a shell, so a file name is never interpreted as a command. Object\n * contents are read through one long-lived `git cat-file --batch` process. Every listing uses\n * `-z`, so names with spaces, quotes or newlines arrive unchanged.\n */\nimport { execFile, spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { resolve } from \"node:path\";\n\n/** Git isn't installed or isn't on PATH (CS0902). */\nexport class GitUnavailableError extends Error {\n constructor(cause?: unknown) {\n super(\"git is required but was not found on PATH\", { cause });\n this.name = \"GitUnavailableError\";\n }\n}\n\n/** A git command failed. */\nexport class GitError extends Error {\n constructor(\n readonly args: readonly string[],\n readonly exitCode: number | null,\n readonly stderr: string,\n ) {\n super(`git ${args[0] ?? \"\"} failed${stderr ? `: ${stderr.trim().split(\"\\n\")[0]}` : \"\"}`);\n this.name = \"GitError\";\n }\n}\n\n/** An entry of the index (`ls-files -s`) or of a tree (`ls-tree -r`). */\nexport interface TreeEntry {\n /** Octal file mode: `100644`, `100755`, `120000` (symbolic link), `160000` (submodule). */\n mode: string;\n blobSha: string;\n /** Merge stage: 0 normally, 1–3 for a conflicted file. Always 0 for a tree. */\n stage: number;\n /** Path relative to the folder git runs in, with forward slashes. */\n path: string;\n}\n\n/** A staged change (`diff --cached -M --name-status`). */\nexport interface StagedChange {\n /** `A` added, `M` modified, `D` deleted, `R` renamed, `C` copied, `T` type changed, … */\n status: string;\n path: string;\n /** The old path of a rename or copy. */\n from?: string;\n}\n\n/** A git object read by `cat-file --batch`. */\ninterface PendingRead {\n resolve: (content: Buffer | undefined) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * A long-lived `git cat-file --batch`: object ids go in on stdin, contents come back in order.\n * Requests are pipelined, so reading many files costs one process.\n */\nclass CatFileBatch {\n private readonly child: ChildProcessWithoutNullStreams;\n private readonly pending: PendingRead[] = [];\n private buffer: Buffer = Buffer.alloc(0);\n private failure?: Error;\n private readonly exited: Promise<void>;\n\n constructor(cwd: string, env: NodeJS.ProcessEnv | undefined) {\n this.child = spawn(\"git\", [\"cat-file\", \"--batch\"], {\n cwd,\n ...(env ? { env } : {}),\n windowsHide: true,\n });\n this.child.stdout.on(\"data\", (chunk: Buffer) => {\n this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);\n this.drain();\n });\n let stderr = \"\";\n this.child.stderr.on(\"data\", (chunk: Buffer) => (stderr += chunk.toString(\"utf8\")));\n this.child.on(\"error\", (error: NodeJS.ErrnoException) =>\n this.fail(error.code === \"ENOENT\" ? new GitUnavailableError(error) : error),\n );\n this.exited = new Promise((resolveExit) => {\n this.child.on(\"close\", (code) => {\n this.fail(new GitError([\"cat-file\", \"--batch\"], code, stderr || \"exited\"));\n resolveExit();\n });\n // A process that never started has nothing to wait for.\n this.child.on(\"error\", () => resolveExit());\n });\n // A closed pipe is reported through `close`; don't let it throw.\n this.child.stdin.on(\"error\", () => undefined);\n }\n\n /** True once the process has failed or exited; every later read would fail. */\n get failed(): boolean {\n return this.failure !== undefined;\n }\n\n /** The content of a blob, or undefined when the object doesn't exist. */\n read(sha: string): Promise<Buffer | undefined> {\n if (this.failure) return Promise.reject(this.failure);\n if (!/^[0-9a-f]{40,64}$/.test(sha)) {\n return Promise.reject(new Error(`not an object id: ${sha}`));\n }\n return new Promise((resolvePromise, reject) => {\n this.pending.push({ resolve: resolvePromise, reject });\n this.child.stdin.write(`${sha}\\n`);\n });\n }\n\n /** Ends the process and waits for it to exit (on Windows its folder stays locked until then). */\n close(): Promise<void> {\n this.child.stdin.end();\n return this.exited;\n }\n\n private drain(): void {\n for (;;) {\n const request = this.pending[0];\n if (!request) return;\n const newline = this.buffer.indexOf(0x0a);\n if (newline === -1) return;\n const header = this.buffer.subarray(0, newline).toString(\"utf8\");\n const parts = header.split(\" \");\n if (parts[1] === \"missing\" || parts[1] === \"ambiguous\") {\n this.buffer = this.buffer.subarray(newline + 1);\n this.pending.shift();\n request.resolve(undefined);\n continue;\n }\n const size = Number(parts[2]);\n if (parts.length !== 3 || !Number.isInteger(size)) {\n this.fail(new Error(`unexpected git cat-file output: ${header}`));\n return;\n }\n const end = newline + 1 + size;\n if (this.buffer.length < end + 1) return;\n const content = Buffer.from(this.buffer.subarray(newline + 1, end));\n this.buffer = this.buffer.subarray(end + 1);\n this.pending.shift();\n request.resolve(content);\n }\n }\n\n private fail(error: Error): void {\n this.failure ??= error;\n for (const request of this.pending.splice(0)) request.reject(this.failure);\n }\n}\n\n/** Git commands for one folder of a repository. Paths are relative to that folder. */\nexport class Git {\n private batch?: CatFileBatch;\n\n /**\n * @param cwd The folder git runs in; listings are relative to it.\n * @param env The environment of the git processes (default: this process's).\n */\n constructor(\n readonly cwd: string,\n readonly env?: NodeJS.ProcessEnv,\n ) {}\n\n /** Runs git with `args` (no shell) and returns its standard output. */\n run(args: readonly string[], options: { input?: string } = {}): Promise<Buffer> {\n return new Promise((resolvePromise, reject) => {\n const child = execFile(\n \"git\",\n [...args],\n {\n cwd: this.cwd,\n encoding: \"buffer\",\n maxBuffer: 256 * 1024 * 1024,\n windowsHide: true,\n ...(this.env ? { env: this.env } : {}),\n },\n (error, stdout, stderr) => {\n if (!error) {\n resolvePromise(stdout);\n return;\n }\n const code = (error as NodeJS.ErrnoException).code;\n reject(\n code === \"ENOENT\"\n ? new GitUnavailableError(error)\n : new GitError(\n args,\n typeof code === \"number\" ? code : null,\n stderr.toString(\"utf8\") || error.message,\n ),\n );\n },\n );\n if (options.input !== undefined) child.stdin?.end(options.input);\n });\n }\n\n /**\n * The repository's top-level folder and git common dir (shared by every worktree), as paths\n * from `cwd` (so they stay comparable with it where the temp folder is a symbolic link).\n */\n async repository(): Promise<{ topLevel: string; commonDir: string; prefix: string }> {\n const out = (await this.run([\"rev-parse\", \"--show-cdup\", \"--git-common-dir\", \"--show-prefix\"]))\n .toString(\"utf8\")\n .split(\"\\n\");\n return {\n topLevel: resolve(this.cwd, out[0]!),\n commonDir: resolve(this.cwd, out[1]!),\n prefix: out[2] ?? \"\",\n };\n }\n\n /** True when `cwd` is inside a git work tree. Throws `GitUnavailableError` without git. */\n async isRepository(): Promise<boolean> {\n try {\n return (await this.run([\"rev-parse\", \"--is-inside-work-tree\"])).toString().trim() === \"true\";\n } catch (error) {\n if (error instanceof GitError) return false;\n throw error;\n }\n }\n\n /** The index (`ls-files -s -z`): files under `cwd`, relative to it. */\n async lsFiles(): Promise<TreeEntry[]> {\n const out = await this.run([\"ls-files\", \"-s\", \"-z\"]);\n return records(out).map((record) => {\n const tab = record.indexOf(\"\\t\");\n const [mode, blobSha, stage] = record.slice(0, tab).split(\" \");\n return { mode: mode!, blobSha: blobSha!, stage: Number(stage), path: record.slice(tab + 1) };\n });\n }\n\n /** The files of a revision (`ls-tree -r -z`): files under `cwd`, relative to it. */\n async lsTree(revision: string): Promise<TreeEntry[]> {\n const out = await this.run([\"ls-tree\", \"-r\", \"-z\", revision, \"--\"]);\n return records(out).map((record) => {\n const tab = record.indexOf(\"\\t\");\n const [mode, , blobSha] = record.slice(0, tab).split(\" \");\n return { mode: mode!, blobSha: blobSha!, stage: 0, path: record.slice(tab + 1) };\n });\n }\n\n /**\n * The staged changes (`diff --cached -M --name-status -z --relative`): changes under `cwd`\n * against HEAD (an empty tree before the first commit), relative to `cwd`.\n */\n async stagedChanges(): Promise<StagedChange[]> {\n return nameStatus(\n await this.run([\n \"diff\",\n \"--cached\",\n \"-M\",\n \"--name-status\",\n \"-z\",\n \"--relative\",\n \"--no-ext-diff\",\n \"--no-color\",\n ]),\n );\n }\n\n /**\n * The changes from `revision` to the index (`cached`) or to the working tree\n * (`diff -M --name-status -z --relative <revision>`), relative to `cwd`. Files git doesn't track\n * yet aren't listed.\n */\n async changesSince(\n revision: string,\n options: { cached?: boolean } = {},\n ): Promise<StagedChange[]> {\n return nameStatus(\n await this.run([\n \"diff\",\n ...(options.cached ? [\"--cached\"] : []),\n \"-M\",\n \"--name-status\",\n \"-z\",\n \"--relative\",\n \"--no-ext-diff\",\n \"--no-color\",\n revision,\n \"--\",\n ]),\n );\n }\n\n /** The commit id `revision` names, or undefined when it names none (e.g. HEAD before the first commit). */\n async commitId(revision: string): Promise<string | undefined> {\n try {\n const out = await this.run([\"rev-parse\", \"--verify\", \"-q\", `${revision}^{commit}`]);\n return out.toString(\"utf8\").trim() || undefined;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** The current branch's short name, or undefined when HEAD is detached. */\n async currentBranch(): Promise<string | undefined> {\n try {\n const out = await this.run([\"symbolic-ref\", \"-q\", \"--short\", \"HEAD\"]);\n return out.toString(\"utf8\").trim() || undefined;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** The content of a blob through the long-lived `cat-file --batch`; undefined if missing. */\n readBlob(sha: string): Promise<Buffer | undefined> {\n // A batch that failed (its process exited or misbehaved) is replaced by a new one.\n if (this.batch?.failed) void this.batch.close();\n if (!this.batch || this.batch.failed) this.batch = new CatFileBatch(this.cwd, this.env);\n return this.batch.read(sha);\n }\n\n /**\n * The paths among `paths` whose working-tree content differs from the index, as git sees it\n * (`git diff`): line-ending conversion and clean filters applied, untracked files not listed.\n */\n async unstagedFiles(paths: readonly string[]): Promise<Set<string>> {\n if (paths.length === 0) return new Set();\n const out = await this.run([\n \"--literal-pathspecs\",\n \"diff\",\n \"--name-only\",\n \"-z\",\n \"--no-renames\",\n \"--\",\n ...paths,\n ]);\n return new Set(\n out\n .toString(\"utf8\")\n .split(\"\\0\")\n .filter((p) => p !== \"\"),\n );\n }\n\n /** Stages files (`git add`); paths are literal, never pathspec patterns. */\n async add(paths: readonly string[]): Promise<void> {\n if (paths.length === 0) return;\n await this.run([\"--literal-pathspecs\", \"add\", \"--\", ...paths]);\n }\n\n /** A config value, or undefined when it isn't set. */\n async config(key: string): Promise<string | undefined> {\n try {\n const value = (await this.run([\"config\", \"--get\", key])).toString(\"utf8\").trim();\n return value === \"\" ? undefined : value;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** A path inside the git dir (`rev-parse --git-path`), e.g. `hooks`; honours core.hooksPath. */\n async gitPath(path: string): Promise<string> {\n const out = (await this.run([\"rev-parse\", \"--git-path\", path])).toString(\"utf8\").trim();\n return resolve(this.cwd, out);\n }\n\n /** Stops the `cat-file --batch` process and waits for it to exit. */\n async close(): Promise<void> {\n const batch = this.batch;\n delete this.batch;\n await batch?.close();\n }\n}\n\n/** Parses `diff --name-status -z` output. */\nfunction nameStatus(out: Buffer): StagedChange[] {\n const fields = records(out);\n const changes: StagedChange[] = [];\n for (let i = 0; i < fields.length;) {\n const status = fields[i++]!;\n if (status.startsWith(\"R\") || status.startsWith(\"C\")) {\n const from = fields[i++]!;\n changes.push({ status: status[0]!, from, path: fields[i++]! });\n } else {\n changes.push({ status: status[0]!, path: fields[i++]! });\n }\n }\n return changes;\n}\n\n/** NUL-separated records, without the trailing empty one. */\nfunction records(out: Buffer): string[] {\n const text = out.toString(\"utf8\");\n const fields = text.split(\"\\0\");\n if (fields.at(-1) === \"\") fields.pop();\n return fields;\n}\n","/**\n * Source providers (plan §D11.3, analysis F-9), PBI `source-providers`: one interface to read the\n * files of a repository from the working tree, the git index or a revision, so every check runs\n * the same way on each. Listings skip `node_modules`, dot-folders, symbolic links, submodules\n * and nested projects, like `listFiles`.\n */\nimport { readFile } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport { compareStrings } from \"../diagnostics.js\";\nimport { isListedPath, listFiles, withoutNestedProjects } from \"../util.js\";\nimport type { Git, TreeEntry } from \"./git.js\";\n\n// The callback API, promisified: `fs/promises` opens a FileHandle per file, which costs more per\n// file than the read itself in a cold run over thousands of files (plan §D11.7).\nconst readFileAsync = promisify(readFile);\n\n/** A file of a source: its root-relative POSIX path and, when known, its git blob SHA. */\nexport interface SourceEntry {\n path: string;\n /** Known for the index and revisions without reading the file, so caches can skip reading. */\n blobSha?: string;\n}\n\nexport interface SourceProvider {\n readonly kind: \"worktree\" | \"index\" | \"revision\";\n /** Every file, sorted by path. */\n list(): Promise<SourceEntry[]>;\n /** A file's content, or undefined when the source has no such file. */\n read(path: string): Promise<Buffer | undefined>;\n}\n\n/** The files on disk under `root`. */\nexport class WorkingTreeProvider implements SourceProvider {\n readonly kind = \"worktree\";\n\n constructor(readonly root: string) {}\n\n async list(): Promise<SourceEntry[]> {\n return (await listFiles(this.root)).map((path) => ({ path }));\n }\n\n read(path: string): Promise<Buffer | undefined> {\n return readFileAsync(join(this.root, path)).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\" || error.code === \"EISDIR\" || error.code === \"ENOTDIR\") {\n return undefined;\n }\n throw error;\n });\n }\n}\n\n/** Files of a git tree listing, read through `cat-file --batch`. */\nabstract class GitTreeProvider implements SourceProvider {\n abstract readonly kind: \"index\" | \"revision\";\n private listing?: Promise<Map<string, string>>;\n\n constructor(readonly git: Git) {}\n\n protected abstract entries(): Promise<TreeEntry[]>;\n\n async list(): Promise<SourceEntry[]> {\n const files = await this.files();\n return [...files].map(([path, blobSha]) => ({ path, blobSha }));\n }\n\n async read(path: string): Promise<Buffer | undefined> {\n const sha = (await this.files()).get(path);\n return sha === undefined ? undefined : this.git.readBlob(sha);\n }\n\n private files(): Promise<Map<string, string>> {\n this.listing ??= this.entries().then((entries) => {\n const regular = entries\n .filter((e) => e.stage === 0 && (e.mode === \"100644\" || e.mode === \"100755\"))\n .filter((e) => isListedPath(e.path))\n .sort((a, b) => compareStrings(a.path, b.path));\n const listed = new Set(withoutNestedProjects(regular.map((e) => e.path)));\n return new Map(regular.filter((e) => listed.has(e.path)).map((e) => [e.path, e.blobSha]));\n });\n return this.listing;\n }\n}\n\n/**\n * The git index: what the next commit will contain. Conflicted files (merge stages 1–3) have no\n * staged content yet and aren't listed.\n */\nexport class IndexProvider extends GitTreeProvider {\n readonly kind = \"index\";\n\n protected entries(): Promise<TreeEntry[]> {\n return this.git.lsFiles();\n }\n}\n\n/** The files of a revision, e.g. `HEAD`. */\nexport class RevisionProvider extends GitTreeProvider {\n readonly kind = \"revision\";\n\n constructor(\n git: Git,\n readonly revision: string,\n ) {\n super(git);\n }\n\n protected entries(): Promise<TreeEntry[]> {\n return this.git.lsTree(this.revision);\n }\n}\n","/**\n * The scope of `catspec check --staged` (plan §D11.3, §D11.7, §D13), PBI `staged-check`: the\n * commit being made, and only what it touches. A spec is checked when the commit changes its spec\n * file or lock file, a file its bindings resolved to (from the lock file), a file of its `file`\n * hints or `scope`, or declares a name one of its not-yet-located bindings looks for. The files\n * read are the changed files plus the files of those specs.\n */\nimport { SymbolTable } from \"./codebase.js\";\nimport { sortDiagnostics, type Diagnostic } from \"./diagnostics.js\";\nimport { parseErrorDiagnostics, type FileFacts } from \"./facts.js\";\nimport type { StagedChange } from \"./git/git.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { lockedFiles, lockPathOf } from \"./lock.js\";\nimport { splitSymbol } from \"./resolve.js\";\nimport { globMatcher } from \"./util.js\";\n\nexport interface StagedScope {\n /** Paths the commit adds, changes or deletes (both sides of a rename). */\n changed: Set<string>;\n /** Ids of the specs to check, the architecture spec included when its rules apply. */\n specs: string[];\n /** Source files to read; undefined means every file (the architecture spec changed). */\n files?: Set<string>;\n}\n\n/**\n * The specs and files a staged check needs. `changedFacts` are the facts of the changed source\n * files; `paths` every file of the index.\n */\nexport function stagedScope(\n model: SpecModel,\n changes: readonly StagedChange[],\n changedFacts: readonly FileFacts[],\n paths: readonly string[],\n): StagedScope {\n const changed = new Set(\n changes.flatMap((c) => (c.from === undefined ? [c.path] : [c.path, c.from])),\n );\n const changedList = [...changed];\n const declared = new SymbolTable(changedFacts);\n const touches = (globs: readonly string[]): boolean =>\n globs.length > 0 && changedList.some(globMatcher(globs));\n\n const specs: string[] = [];\n const files = new Set(changedList);\n for (const spec of model.specs.all()) {\n if (!spec.valid || spec.type === \"architecture\") continue;\n const lock = model.locks.get(spec.id);\n const located = spec.bindings.map((b) => ({ binding: b, files: lockedFiles(lock, b.id) }));\n const selected =\n changed.has(spec.file) ||\n changed.has(lockPathOf(spec)) ||\n located.some((l) => l.files.some((f) => changed.has(f))) ||\n spec.bindings.some((b) => b.file !== undefined && touches(b.file)) ||\n touches(spec.scope) ||\n located.some(\n (l) => l.files.length === 0 && declared.find(splitSymbol(l.binding.symbol).name).length > 0,\n );\n if (!selected) continue;\n specs.push(spec.id);\n for (const l of located) for (const f of l.files) files.add(f);\n const globs = [...spec.scope, ...spec.bindings.flatMap((b) => b.file ?? [])];\n if (globs.length > 0) {\n const match = globMatcher(globs);\n for (const path of paths) if (match(path)) files.add(path);\n }\n }\n\n const architecture = model.architecture?.valid ? model.architecture : undefined;\n const architectureChanged = architecture !== undefined && changed.has(architecture.file);\n if (architecture && (architectureChanged || changedFacts.length > 0)) specs.push(architecture.id);\n return { changed, specs, ...(architectureChanged ? {} : { files }) };\n}\n\n/**\n * The diagnostics a staged check reports: those of the checked specs, spec diagnostics of the\n * changed spec and lock files, syntax errors of the changed files, and architecture rule\n * violations in the changed files (in every file when the architecture spec itself changed).\n */\nexport function stagedDiagnostics(\n model: SpecModel,\n scope: StagedScope,\n checked: readonly Diagnostic[],\n changedFacts: readonly FileFacts[],\n): Diagnostic[] {\n const architecture = model.architecture?.id;\n const selected = new Set(scope.specs);\n const inChanged = (d: Diagnostic): boolean =>\n (d.codeLocation !== undefined && scope.changed.has(d.codeLocation.file)) ||\n (d.specLocation !== undefined && scope.changed.has(d.specLocation.file));\n const kept = checked.filter((d) => {\n if (d.spec === undefined || !selected.has(d.spec)) return inChanged(d);\n if (d.spec !== architecture || scope.files === undefined || d.code.startsWith(\"CS01\")) {\n return true;\n }\n return d.codeLocation !== undefined && scope.changed.has(d.codeLocation.file);\n });\n const extra = [\n ...model.diagnostics.filter(\n (d) => inChanged(d) || (d.spec === undefined && d.specLocation === undefined),\n ),\n ...changedFacts.flatMap(parseErrorDiagnostics),\n ];\n const seen = new Set(kept.map(key));\n for (const d of extra) {\n if (seen.has(key(d))) continue;\n seen.add(key(d));\n kept.push(d);\n }\n return sortDiagnostics(kept);\n}\n\nconst key = (d: Diagnostic): string =>\n JSON.stringify([d.code, d.spec, d.specLocation, d.codeLocation, d.message]);\n","/**\n * `catspec coverage` (analysis F-3, plan §D10), PBI `check-command`: how much of the specs is\n * met, how much of them is machine-checked, and how much of the code is bound by a spec.\n */\nimport type { Codebase } from \"./codebase.js\";\nimport { checkCode, type CheckOptions, type ItemResult } from \"./check.js\";\nimport type { SpecModel } from \"./load.js\";\n\nexport interface Ratio {\n count: number;\n total: number;\n /** `count / total` in percent, rounded to one decimal; 100 when `total` is 0. */\n percent: number;\n}\n\nexport interface SpecCoverage {\n spec: string;\n status: string;\n satisfaction: Ratio;\n enforceable: number;\n manual: number;\n unenforcedProse: number;\n}\n\nexport interface CoverageReport {\n /** Passing enforceable contract items out of all enforceable items. */\n satisfaction: Ratio;\n /** Enforceable items out of all contract statements: enforceable, manual and unenforced prose (CS0111). */\n enforcement: Ratio & { manual: number; unenforcedProse: number };\n /** Source files with a bound declaration out of all source files. */\n reverse: Ratio;\n specs: SpecCoverage[];\n items: ItemResult[];\n}\n\nconst ratio = (count: number, total: number): Ratio => ({\n count,\n total,\n percent: total === 0 ? 100 : Math.round((count / total) * 1000) / 10,\n});\n\n/**\n * Evaluates every spec except deprecated ones as if implemented, whatever its status, and\n * counts the results.\n */\nexport async function coverage(\n model: SpecModel,\n codebase: Codebase,\n options: Pick<CheckOptions, \"now\"> = {},\n): Promise<CoverageReport> {\n const result = await checkCode(model, codebase, { ...options, mode: \"full\" });\n const unenforced = (id: string): number =>\n model.config.enforcement.unenforced_prose === \"off\"\n ? 0\n : (model.specs.get(id)?.body.contracts.filter((c) => c.references.length === 0).length ?? 0);\n\n const specs = result.checked.map((spec): SpecCoverage => {\n const items = result.items.filter((i) => i.spec === spec.id);\n const enforceable = items.filter((i) => i.enforceable);\n return {\n spec: spec.id,\n status: spec.status,\n satisfaction: ratio(enforceable.filter((i) => i.passed).length, enforceable.length),\n enforceable: enforceable.length,\n manual: items.length - enforceable.length,\n unenforcedProse: unenforced(spec.id),\n };\n });\n const sum = (key: \"enforceable\" | \"manual\" | \"unenforcedProse\"): number =>\n specs.reduce((n, s) => n + s[key], 0);\n const enforceable = sum(\"enforceable\");\n const manual = sum(\"manual\");\n const unenforcedProse = sum(\"unenforcedProse\");\n const bound = new Set(\n [...result.resolved.values()].flatMap((bindings) =>\n [...bindings.values()].flatMap((r) => r.files),\n ),\n );\n return {\n satisfaction: ratio(result.items.filter((i) => i.enforceable && i.passed).length, enforceable),\n enforcement: {\n ...ratio(enforceable, enforceable + manual + unenforcedProse),\n manual,\n unenforcedProse,\n },\n reverse: ratio(codebase.files.filter((f) => bound.has(f.path)).length, codebase.files.length),\n specs,\n items: result.items,\n };\n}\n","/**\n * The dependency graph of specs (plan §D8, analysis F-11), PBI `dependency-graph`: `depends_on`\n * edges, unknown dependencies (CS0104), cycles with their full path (CS0105), a topological order\n * and which specs are ready to start.\n */\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean } from \"./util.js\";\n\nexport class DependencyGraph {\n /** Specs by id, sorted by id. */\n readonly specs: ReadonlyMap<string, Spec>;\n /** CS0104 and CS0105 diagnostics. */\n readonly diagnostics: Diagnostic[] = [];\n /** Each cycle as a path that ends where it starts: `[\"a\", \"b\", \"c\", \"a\"]`. */\n readonly cycles: string[][] = [];\n\n private readonly edges = new Map<string, string[]>();\n /** Strongly connected components (each sorted by id); a cycle is a component of 2+ specs. */\n private readonly components: string[][] = [];\n private readonly reverse = new Map<string, string[]>();\n\n constructor(specs: Iterable<Spec>) {\n const sorted = [...specs].sort((a, b) => compareStrings(a.id, b.id));\n this.specs = new Map(sorted.map((s) => [s.id, s]));\n\n for (const spec of sorted) {\n const deps: string[] = [];\n spec.dependsOn.forEach((dep, index) => {\n if (this.specs.has(dep)) {\n if (!deps.includes(dep)) deps.push(dep);\n return;\n }\n const close = didYouMean(dep, this.specs.keys());\n this.diagnostics.push(\n createDiagnostic(\"CS0104\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"depends_on\", index]),\n message: `\"${spec.id}\" depends on \"${dep}\", but there is no spec with that id`,\n actual: dep,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n }),\n );\n });\n deps.sort(compareStrings);\n this.edges.set(spec.id, deps);\n for (const dep of deps) {\n this.reverse.set(dep, [...(this.reverse.get(dep) ?? []), spec.id]);\n }\n }\n for (const list of this.reverse.values()) list.sort(compareStrings);\n this.findCycles();\n }\n\n /** Known specs `id` depends on, sorted. */\n dependencies(id: string): string[] {\n return this.edges.get(id) ?? [];\n }\n\n /** Specs that depend on `id`, sorted. */\n dependents(id: string): string[] {\n return this.reverse.get(id) ?? [];\n }\n\n /** Every edge as `{ spec, dependsOn }`, sorted. */\n edgeList(): { spec: string; dependsOn: string }[] {\n return [...this.edges].flatMap(([spec, deps]) =>\n deps.map((dependsOn) => ({ spec, dependsOn })),\n );\n }\n\n /**\n * True when every dependency exists and is satisfied. Until contracts are checked, a dependency\n * is satisfied when its status is `implemented`.\n */\n depsSatisfied(id: string): boolean {\n const spec = this.specs.get(id);\n if (!spec) return false;\n return spec.dependsOn.every((dep) => this.specs.get(dep)?.status === \"implemented\");\n }\n\n /** A spec is ready to start when its status is `ready` and its dependencies are satisfied. */\n isReady(id: string): boolean {\n return this.specs.get(id)?.status === \"ready\" && this.depsSatisfied(id);\n }\n\n /**\n * Specs in dependency order: every spec comes after the specs it depends on, the members of a\n * cycle together. Among the specs that can come next, the smallest id goes first.\n */\n topologicalOrder(): string[] {\n const componentOf = new Map<string, number>();\n this.components.forEach((members, index) => {\n for (const id of members) componentOf.set(id, index);\n });\n const waitingOn = this.components.map(() => new Set<number>());\n const neededBy = this.components.map(() => new Set<number>());\n for (const { spec, dependsOn } of this.edgeList()) {\n const from = componentOf.get(spec)!;\n const to = componentOf.get(dependsOn)!;\n if (from === to) continue;\n waitingOn[from]!.add(to);\n neededBy[to]!.add(from);\n }\n const order: string[] = [];\n const available = this.components.map((_, i) => i).filter((i) => waitingOn[i]!.size === 0);\n while (available.length > 0) {\n available.sort((a, b) => compareStrings(this.components[a]![0]!, this.components[b]![0]!));\n const next = available.shift()!;\n order.push(...this.components[next]!);\n for (const dependent of neededBy[next]!) {\n waitingOn[dependent]!.delete(next);\n if (waitingOn[dependent]!.size === 0) available.push(dependent);\n }\n }\n return order;\n }\n\n /** Tarjan's strongly connected components; reports one cycle per component. */\n private findCycles(): void {\n let counter = 0;\n const index = new Map<string, number>();\n const low = new Map<string, number>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const components = this.components;\n\n const connect = (id: string): void => {\n index.set(id, counter);\n low.set(id, counter);\n counter++;\n stack.push(id);\n onStack.add(id);\n for (const dep of this.dependencies(id)) {\n if (!index.has(dep)) {\n connect(dep);\n low.set(id, Math.min(low.get(id)!, low.get(dep)!));\n } else if (onStack.has(dep)) {\n low.set(id, Math.min(low.get(id)!, index.get(dep)!));\n }\n }\n if (low.get(id) === index.get(id)) {\n const component: string[] = [];\n let member: string;\n do {\n member = stack.pop()!;\n onStack.delete(member);\n component.push(member);\n } while (member !== id);\n components.push(component.sort(compareStrings));\n }\n };\n for (const id of this.edges.keys()) if (!index.has(id)) connect(id);\n\n for (const component of components) {\n const members = new Set(component);\n const start = [...members].sort(compareStrings)[0]!;\n if (members.size === 1 && !this.dependencies(start).includes(start)) continue;\n const cycle = this.shortestCycle(start, members);\n this.cycles.push(cycle);\n const spec = this.specs.get(start)!;\n const next = cycle[1]!;\n this.diagnostics.push(\n createDiagnostic(\"CS0105\", {\n spec: start,\n specLocation: specLocation(spec.source, [\"depends_on\", spec.dependsOn.indexOf(next)]),\n message: `dependency cycle: ${cycle.join(\" → \")}`,\n actual: cycle,\n suggestions: [{ message: \"remove one of the dependencies in the cycle\" }],\n }),\n );\n }\n this.cycles.sort((a, b) => compareStrings(a[0]!, b[0]!));\n }\n\n /** Shortest path from `start` back to itself inside one component (breadth-first). */\n private shortestCycle(start: string, members: Set<string>): string[] {\n const previous = new Map<string, string>();\n const queue = [start];\n for (let i = 0; i < queue.length; i++) {\n const id = queue[i]!;\n for (const dep of this.dependencies(id)) {\n if (!members.has(dep)) continue;\n if (dep === start) {\n const path = [start];\n for (let at = id; at !== start; at = previous.get(at)!) path.splice(1, 0, at);\n return [...path, start];\n }\n if (!previous.has(dep)) {\n previous.set(dep, id);\n queue.push(dep);\n }\n }\n }\n return [start, start];\n }\n}\n","/**\n * Finds and loads every spec of a repository (plan §D3, §D4, §D6.4), PBI `spec-loader`, and runs\n * the repository-level checks of `catspec check --specs-only`: unique ids (CS0103), the\n * feature-folder layout (CS0106), the architecture spec (CS0107), lock files without a spec\n * (CS0108) and ADR ids (CS0112). Specs and lock files are read from a source provider: the\n * working tree, or the git index for `check --staged` (F5).\n */\nimport { posix } from \"node:path\";\n\nimport { workflowProfile, type CatspecConfig } from \"./config.js\";\nimport { featureFolderOf } from \"./workflow/schema.js\";\nimport {\n compareStrings,\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n} from \"./diagnostics.js\";\nimport { WorkingTreeProvider, type SourceProvider } from \"./git/providers.js\";\nimport { DependencyGraph } from \"./graph.js\";\nimport { hasLockFile, lockPathOf, parseLock, type LockFile } from \"./lock.js\";\nimport { readSpec, specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, globMatcher, listFiles, listOf } from \"./util.js\";\n\n/** All specs of a repository, by id and by file. */\nexport class SpecSet {\n readonly byId = new Map<string, Spec>();\n readonly byFile = new Map<string, Spec>();\n\n /** Adds a spec; returns the spec that already has its id, if any (the new one isn't indexed by id). */\n add(spec: Spec): Spec | undefined {\n this.byFile.set(spec.file, spec);\n const existing = this.byId.get(spec.id);\n if (!existing) this.byId.set(spec.id, spec);\n return existing;\n }\n\n get(id: string): Spec | undefined {\n return this.byId.get(id);\n }\n\n /** Specs with a unique id, sorted by id. */\n all(): Spec[] {\n return [...this.byId.values()].sort((a, b) => compareStrings(a.id, b.id));\n }\n\n get size(): number {\n return this.byId.size;\n }\n}\n\nexport interface SpecModel {\n root: string;\n config: CatspecConfig;\n specs: SpecSet;\n graph: DependencyGraph;\n /** The architecture spec (`type: architecture` at `specs.architecture`), if exactly one exists. */\n architecture?: Spec;\n /** ADR ids of the architecture spec's log. */\n adrIds: string[];\n /** Every diagnostic of `catspec check --specs-only`, sorted. */\n diagnostics: Diagnostic[];\n /** Valid lock files (plan §D7) by spec id. */\n locks: Map<string, LockFile>;\n /** The text of each lock file read, by path, to write only what changed. */\n lockTexts: Map<string, string>;\n /** Where the specs were read from. */\n source: SourceProvider;\n}\n\nconst SPEC_FILE = /(^|\\/)[^/]+\\.spec\\.md$/;\n\n/**\n * Loads every spec under `root` with `config` and runs the spec checks (the pipeline of\n * `catspec check --specs-only`). Spec errors of `deprecated` specs are lowered to warnings (§D8).\n */\nexport async function loadSpecModel(\n root: string,\n config: CatspecConfig,\n source: SourceProvider = new WorkingTreeProvider(root),\n): Promise<SpecModel> {\n const files = (await source.list()).map((entry) => entry.path);\n const diagnostics: Diagnostic[] = [];\n const specs = new SpecSet();\n const options = { unenforcedProse: config.enforcement.unenforced_prose };\n\n const isIncluded = globMatcher(config.specs.include);\n const isArchitecture = globMatcher(config.specs.architecture);\n const architectureFiles = files.filter((f) => isArchitecture(f));\n const specFiles = files.filter((f) => isIncluded(f) && !architectureFiles.includes(f));\n\n /** The specs a diagnostic is about, when it is about more than the one in its file. */\n const involved = new Map<Diagnostic, Spec[]>();\n\n const read = async (file: string): Promise<Spec | undefined> => {\n const text = (await source.read(file))?.toString(\"utf8\") ?? \"\";\n const result = readSpec(text, file, options);\n diagnostics.push(...result.diagnostics);\n return result.spec;\n };\n\n // The architecture spec: exactly one file at `specs.architecture` (CS0107).\n let architecture: Spec | undefined;\n // In the git index (`check --staged`), an ADR log that exists on disk but isn't staged yet,\n // e.g. right after `catspec init`, is a warning: it doesn't block a commit that leaves it out.\n const unstagedLog =\n architectureFiles.length === 0 && source.kind === \"index\"\n ? (await listFiles(root)).find((f) => isArchitecture(f))\n : undefined;\n if (unstagedLog) {\n diagnostics.push(\n createDiagnostic(\"CS0107\", {\n severity: \"warning\",\n message: `the ADR log ${unstagedLog} isn't staged, so this commit is checked without it`,\n suggestions: [{ message: `stage it: git add ${unstagedLog}` }],\n }),\n );\n } else if (architectureFiles.length === 0) {\n diagnostics.push(\n createDiagnostic(\"CS0107\", {\n message: `no architecture spec: no file matches specs.architecture \"${config.specs.architecture}\"`,\n suggestions: [\n {\n message: \"run `catspec init` to create one, or set specs.architecture in catspec.yaml\",\n },\n ],\n }),\n );\n } else if (architectureFiles.length > 1) {\n diagnostics.push(\n createDiagnostic(\"CS0107\", {\n specLocation: { file: architectureFiles[0]!, line: 1, column: 1 },\n message:\n `more than one architecture spec matches specs.architecture \"${config.specs.architecture}\": ` +\n listOf(architectureFiles),\n actual: architectureFiles,\n suggestions: [\n { message: \"keep one ADR log, or narrow specs.architecture in catspec.yaml\" },\n ],\n }),\n );\n } else {\n const spec = await read(architectureFiles[0]!);\n if (spec) {\n if (spec.type === \"architecture\") {\n architecture = spec;\n } else if (spec.valid) {\n diagnostics.push(\n createDiagnostic(\"CS0101\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"type\"]),\n message: `the architecture spec must have type \"architecture\", found \"${spec.type}\"`,\n expected: \"architecture\",\n actual: spec.type,\n }),\n );\n }\n addSpec(spec);\n }\n }\n\n // Read in parallel, index in file order (the first file keeps a duplicated id).\n for (const spec of await Promise.all(specFiles.map(read))) {\n if (spec) addSpec(spec);\n }\n\n function addSpec(spec: Spec): void {\n const existing = specs.add(spec);\n if (!existing) return;\n for (const [here, other] of [\n [existing, spec],\n [spec, existing],\n ] as const) {\n const duplicate = createDiagnostic(\"CS0103\", {\n spec: here.id,\n specLocation: specLocation(here.source, [\"id\"]),\n message: `duplicate spec id \"${here.id}\" in ${here.file} and ${other.file}`,\n actual: [existing.file, spec.file],\n });\n involved.set(duplicate, [existing, spec]);\n diagnostics.push(duplicate);\n }\n }\n\n // Layout (CS0106): machine specs live directly in a feature folder (`docs/spec/<feature>/`, or\n // the workflow's `feature_dir`), and the architecture spec at specs.architecture.\n if (config.layout === \"feature-folders\") {\n const profile = workflowProfile(config);\n const generic = profile.featureDir.replaceAll(\"{feature}\", \"<feature>\");\n for (const file of files) {\n if (!SPEC_FILE.test(file) || architectureFiles.includes(file)) continue;\n const name = file.split(\"/\").pop()!;\n const folder = featureFolderOf(profile.featureDirs, file);\n if (folder && file === `${folder.dir}/${name}`) continue;\n const deeper = folder?.dir;\n const target = deeper ? `${deeper}/${name}` : `${generic}/${name}`;\n const where = deeper\n ? deeper.slice(0, deeper.lastIndexOf(\"/\")) || \".\"\n : generic.replace(/\\/?<feature>.*$/, \"\") || \".\";\n diagnostics.push(\n createDiagnostic(\"CS0106\", {\n ...(specs.byFile.get(file) ? { spec: specs.byFile.get(file)!.id } : {}),\n specLocation: { file, line: 1, column: 1 },\n message: deeper\n ? `${file} is more than one folder deep in ${where}/; move it to ${target}`\n : `${file} is outside a feature folder; move it to ${target}`,\n expected: `${generic}/<id>.spec.md`,\n actual: file,\n suggestions: [{ message: `move it to ${target}, or set layout: free in catspec.yaml` }],\n }),\n );\n }\n for (const spec of specs.byFile.values()) {\n if (spec.type !== \"architecture\" || spec === architecture) continue;\n diagnostics.push(\n createDiagnostic(\"CS0106\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"type\"]),\n message:\n `${spec.file} is an architecture spec outside specs.architecture ` +\n `(\"${config.specs.architecture}\"); its rules belong in the ADR log`,\n actual: spec.file,\n }),\n );\n }\n }\n\n // ADR ids referenced by rules must exist in the ADR log (CS0112).\n const adrIds = architecture?.body.adrIds ?? [];\n if (architecture) {\n for (const spec of specs.byFile.values()) {\n for (const rule of spec.rules) {\n if (rule.adr === undefined || adrIds.includes(rule.adr)) continue;\n const close = didYouMean(rule.adr, adrIds);\n diagnostics.push(\n createDiagnostic(\"CS0112\", {\n spec: spec.id,\n ruleId: rule.id,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, \"adr\"]),\n message: `rule \"${rule.id}\" enforces ${rule.adr}, which is not in the ADR log ${architecture.file}`,\n expected: adrIds,\n actual: rule.adr,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean ${c}?` })) }\n : {}),\n }),\n );\n }\n }\n }\n\n // Lock files (CS0108): `<spec-id>.lock.json` next to a spec with that id.\n const locks = new Map<string, LockFile>();\n const lockTexts = new Map<string, string>();\n const listed = new Set(files);\n for (const spec of specs.all()) {\n if (!hasLockFile(spec)) continue;\n const path = lockPathOf(spec);\n if (!listed.has(path)) continue;\n const text = (await source.read(path))?.toString(\"utf8\");\n if (text === undefined) continue;\n lockTexts.set(path, text);\n const lock = parseLock(text);\n if (lock?.spec === spec.id) locks.set(spec.id, lock);\n }\n const lockOwners = new Set(\n [...specs.byFile.values()].filter(hasLockFile).map((spec) => lockPathOf(spec)),\n );\n for (const file of files) {\n if (!file.endsWith(\".lock.json\") || lockOwners.has(file)) continue;\n if (!isIncluded(file.replace(/\\.lock\\.json$/, \".spec.md\"))) continue;\n const id = posix.basename(file).replace(/\\.lock\\.json$/, \"\");\n diagnostics.push(\n createDiagnostic(\"CS0108\", {\n specLocation: { file, line: 1, column: 1 },\n message: `${file} has no spec with id \"${id}\" in ${posix.dirname(file)}/`,\n expected: `a spec with id \"${id}\" in ${posix.dirname(file)}/`,\n actual: file,\n suggestions: [\n {\n message:\n \"delete the lock file, or move it next to its spec (named <spec-id>.lock.json)\",\n },\n ],\n }),\n );\n }\n\n const graph = new DependencyGraph(specs.all());\n diagnostics.push(...graph.diagnostics);\n\n for (const d of graph.diagnostics) {\n if (d.code === \"CS0105\" && Array.isArray(d.actual)) {\n involved.set(\n d,\n (d.actual as string[]).flatMap((id) => specs.get(id) ?? []),\n );\n }\n }\n\n // Spec errors of deprecated specs are warnings (plan §D8), unless the error also involves a\n // spec that isn't deprecated (a cycle through an implemented spec, a duplicated id).\n const lowered = diagnostics.map((d) => {\n if (d.severity !== \"error\" || !d.code.startsWith(\"CS01\")) return d;\n const own = (d.specLocation && specs.byFile.get(d.specLocation.file)) ?? undefined;\n const about = involved.get(d) ?? (own ? [own] : []);\n const deprecated = about.length > 0 && about.every((s) => s.status === \"deprecated\");\n return deprecated ? { ...d, severity: \"warning\" as const } : d;\n });\n\n return {\n root,\n config,\n specs,\n graph,\n ...(architecture ? { architecture } : {}),\n adrIds,\n diagnostics: sortDiagnostics(lowered),\n locks,\n lockTexts,\n source,\n };\n}\n","/**\n * Edits spec frontmatter without destroying its formatting (plan §D11.6, ADR-008), PBI\n * `spec-cst-editor`.\n *\n * Each operation is applied twice: with the `yaml` Document API (`setIn` / `deleteIn`), which\n * defines what the result must mean, and as a minimal splice of the source text at the node's\n * range, which keeps comments, key order, quoting and blank lines everywhere else. The spliced\n * text is parsed again and must equal the Document result; otherwise the edit is refused rather\n * than written. The Markdown body is never touched.\n */\nimport { isDeepStrictEqual } from \"node:util\";\n\nimport {\n Document,\n isCollection,\n isMap,\n isScalar,\n isSeq,\n parseDocument,\n Scalar,\n visit,\n type Node,\n type Pair,\n type ToStringOptions,\n type YAMLMap,\n type YAMLSeq,\n} from \"yaml\";\n\nimport type { PatchOp, PatchPath } from \"./diagnostics.js\";\nimport { withFrontmatter, type SpecSource } from \"./frontmatter.js\";\nimport { formatPath } from \"./schema-issues.js\";\n\n/**\n * `location` edits only say where the code is (`bindings[i].symbol`, `bindings[i].file`); auto-heal\n * and agents may apply them. Everything else changes the contract and needs a human (ADR-008).\n */\nexport type EditClass = \"location\" | \"contract\";\n\nexport function classifyOp(op: PatchOp, source: SpecSource): EditClass {\n const [list, index, key, item] = op.path;\n if (list !== \"bindings\" || typeof index !== \"number\") return \"contract\";\n // Only an existing binding can be moved; anything that adds a binding changes the contract.\n const binding = source.document.getIn([\"bindings\", index], true) as Node | undefined;\n if (!isMap(binding)) return \"contract\";\n const isText = (value: unknown): boolean => typeof value === \"string\" && value.length > 0;\n\n if (key === \"symbol\" && op.path.length === 3) {\n return op.op === \"set\" && isText(op.value) && binding.has(\"symbol\") ? \"location\" : \"contract\";\n }\n if (key === \"file\" && op.path.length === 3) {\n if (op.op === \"delete\") return \"location\";\n const list = Array.isArray(op.value) && op.value.length > 0 && op.value.every(isText);\n return isText(op.value) || list ? \"location\" : \"contract\";\n }\n if (key === \"file\" && op.path.length === 4 && typeof item === \"number\") {\n const files = binding.get(\"file\", true) as Node | undefined;\n if (!isSeq(files)) return \"contract\";\n if (op.op === \"delete\") return item < files.items.length ? \"location\" : \"contract\";\n return item <= files.items.length && isText(op.value) ? \"location\" : \"contract\";\n }\n return \"contract\";\n}\n\n/** A patch is a location edit only when every operation is one. */\nexport const classifyPatch = (ops: readonly PatchOp[], source: SpecSource): EditClass =>\n ops.every((op) => classifyOp(op, source) === \"location\") ? \"location\" : \"contract\";\n\n/** An edit that can't be applied without risking the file; nothing is written. */\nexport class SpecEditError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecEditError\";\n }\n}\n\n/** Applies `ops` to a spec and returns the new file text. The body stays byte-for-byte the same. */\nexport function applyPatch(source: SpecSource, ops: readonly PatchOp[]): string {\n if (ops.length === 0) return source.text;\n return withFrontmatter(source, editYaml(source.frontmatter.text, ops, source.eol));\n}\n\n/** Applies `ops` to a YAML document's text, keeping everything the operations don't change. */\nexport function editYaml(text: string, ops: readonly PatchOp[], eol: \"\\n\" | \"\\r\\n\" = \"\\n\"): string {\n let current = text;\n for (const op of ops) {\n try {\n current = applyOp(current, op, eol);\n } catch (error) {\n if (error instanceof SpecEditError) throw error;\n // e.g. \"Excessive alias count\" from the yaml library: refuse instead of crashing.\n const reason = error instanceof Error ? error.message : String(error);\n throw new SpecEditError(`can't edit ${formatPath(op.path)}: ${reason}`);\n }\n }\n return current;\n}\n\n/** The plain value at `path` of a YAML document's text, or undefined. Throws `SpecEditError`. */\nexport function readYaml(text: string, path: PatchPath): unknown {\n let value: unknown = parseYaml(text).toJS();\n for (const segment of path) {\n if (value === null || typeof value !== \"object\") return undefined;\n value = (value as Record<string | number, unknown>)[segment];\n }\n return value;\n}\n\nfunction applyOp(text: string, op: PatchOp, eol: string): string {\n const doc = parseYaml(text);\n if (op.path.length === 0) throw new SpecEditError(\"an edit needs a non-empty path\");\n\n const expected = doc.clone();\n const target = op.op === \"set\" ? normaliseSet(doc, op.path, op.value) : op;\n if (target.op === \"set\") expected.setIn(target.path, toNode(expected, target.value));\n else {\n if (!expected.hasIn(target.path)) {\n throw new SpecEditError(`nothing to delete at ${formatPath(target.path)}`);\n }\n expected.deleteIn(target.path);\n }\n\n // An edit that doesn't change the data doesn't change the text.\n if (isDeepStrictEqual(expected.toJS(), doc.toJS())) return text;\n\n const splice = new Splicer(text, doc, expected, eol);\n const next =\n target.op === \"set\" ? splice.set(target.path, target.value) : splice.delete(target.path);\n\n const check = parseDocument(next);\n if (check.errors.length > 0 || !isDeepStrictEqual(check.toJS(), expected.toJS())) {\n throw new SpecEditError(\n `refusing to edit ${formatPath(op.path)}: the result would not match the requested change; ` +\n \"edit the spec by hand\",\n );\n }\n return next;\n}\n\nfunction parseYaml(text: string): Document.Parsed {\n // Source tokens give the exact start of list items and keys (after anchors, tags, comments).\n const doc = parseDocument(text, { keepSourceTokens: true });\n if (doc.errors.length > 0) {\n throw new SpecEditError(\n `the frontmatter has YAML errors: ${doc.errors[0]!.message.split(\"\\n\")[0]}`,\n );\n }\n return doc;\n}\n\nconst toNode = (doc: Document, value: unknown): unknown =>\n value !== null && typeof value === \"object\" ? doc.createNode(value) : value;\n\n/**\n * Makes sure the parent of a `set` path exists: setting `links.pr` without `links`, or under\n * `links:` with no value, becomes setting `links` to `{ pr: … }`.\n */\nfunction normaliseSet(\n doc: Document,\n path: PatchPath,\n value: unknown,\n): { op: \"set\"; path: PatchPath; value: unknown } {\n for (let i = 0; i < path.length - 1; i++) {\n const prefix = path.slice(0, i + 1);\n const node = doc.getIn(prefix, true) as Node | null | undefined;\n if (node === undefined || node === null || (isScalar(node) && node.value === null)) {\n let nested = value;\n for (const segment of [...path.slice(i + 1)].reverse()) {\n if (typeof segment === \"number\") {\n if (segment !== 0) throw new SpecEditError(`no item ${segment} at ${formatPath(path)}`);\n nested = [nested];\n } else {\n nested = { [segment]: nested };\n }\n }\n return { op: \"set\", path: prefix, value: nested };\n }\n if (!isCollection(node)) {\n throw new SpecEditError(`${formatPath(prefix)} is a value, not a map or list`);\n }\n }\n const parent = path.length > 1 ? (doc.getIn(path.slice(0, -1), true) as Node) : doc.contents;\n const last = path[path.length - 1]!;\n if (isSeq(parent) && (typeof last !== \"number\" || last > parent.items.length || last < 0)) {\n throw new SpecEditError(`${formatPath(path)}: list index out of range`);\n }\n return { op: \"set\", path, value };\n}\n\n/** Text splices for one operation, driven by the node ranges of the parsed document. */\nclass Splicer {\n private readonly indentSeq: boolean;\n\n constructor(\n private readonly text: string,\n private readonly doc: Document.Parsed,\n private readonly expected: Document,\n private readonly eol: string,\n ) {\n this.indentSeq = detectIndentSeq(text, doc);\n }\n\n set(path: PatchPath, value: unknown): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n const key = path[path.length - 1]!;\n if (parent === null) return this.insertIntoEmptyRoot(key, value);\n if (!isMap(parent) && !isSeq(parent)) {\n throw new SpecEditError(`${formatPath(parentPath)} is not a map or list`);\n }\n\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n if (index < 0 || index >= parent.items.length) {\n return parent.flow\n ? this.flowAppend(parent, parentPath, key, value)\n : this.append(parent, key, value);\n }\n const node = isMap(parent)\n ? (parent.items[index]!.value as Node | null)\n : (parent.items[index] as Node | null);\n if (isScalar(node) && isScalarValue(value) && !isBlockScalar(node) && node.range) {\n return this.replaceScalar(node, value, parent.flow === true);\n }\n return parent.flow\n ? this.flowReplace(parent, index, key, value)\n : this.replaceItem(parent, index, key, value);\n }\n\n delete(path: PatchPath): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n const key = path[path.length - 1]!;\n if (!isMap(parent) && !isSeq(parent)) {\n throw new SpecEditError(`${formatPath(parentPath)} is not a map or list`);\n }\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n if (parent.flow) return this.flowDelete(parent, index);\n\n if (parent.items.length === 1) {\n // Removing the only item: rewrite the parent as an empty collection.\n if (parentPath.length === 0) throw new SpecEditError(\"can't remove the last frontmatter key\");\n return this.replaceInParent(parentPath);\n }\n\n const start = itemStart(this.text, parent, index);\n const end = itemEnd(this.text, parent, index);\n if (isLineStart(this.text, start)) {\n return this.text.slice(0, lineStart(this.text, start)) + this.text.slice(end);\n }\n // The item shares its line with the parent's indicator (`- key: value`): pull the next one up.\n const next = itemStart(this.text, parent, index + 1);\n return this.text.slice(0, start) + this.text.slice(next);\n }\n\n /** Rewrites the item at `path` (a key or list item of a block collection) with its expected value. */\n private replaceInParent(path: PatchPath): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n if (!isMap(parent) && !isSeq(parent)) throw new SpecEditError(\"unexpected document shape\");\n const key = path[path.length - 1]!;\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n const value = this.expectedValue(path);\n return parent.flow\n ? this.flowReplace(parent, index, key, value)\n : this.replaceItem(parent, index, key, value);\n }\n\n /** Replaces a scalar's text, keeping its quoting style when the new value allows it. */\n private replaceScalar(node: Scalar, value: unknown, inFlow: boolean): string {\n const [start, end] = node.range!;\n let rendered = renderScalar(value, node.type, inFlow);\n if (start === end && this.text[start - 1] === \":\") rendered = ` ${rendered}`;\n return this.text.slice(0, start) + rendered + this.text.slice(end);\n }\n\n /** Replaces a whole pair or list item with a block rendering of its new value. */\n private replaceItem(\n parent: YAMLMap | YAMLSeq,\n index: number,\n key: string | number,\n value: unknown,\n ): string {\n const start = itemStart(this.text, parent, index);\n const end = itemEnd(this.text, parent, index);\n const column = start - lineStart(this.text, start);\n const lines = isMap(parent) ? this.render({ [String(key)]: value }) : this.render([value]);\n // A comment at the end of the item's first line (`key: [] # note`) stays on that line.\n const comment = trailingComment(this.text, start);\n if (comment && trailingComment(lines[0]!, 0) === undefined) lines[0] += comment;\n const endsWithBreak = this.text[end - 1] === \"\\n\";\n const replacement =\n lines.map((line, i) => (i === 0 ? line : \" \".repeat(column) + line)).join(this.eol) +\n (endsWithBreak ? this.eol : \"\");\n return this.text.slice(0, start) + replacement + this.text.slice(end);\n }\n\n /** Adds a new key at the end of a block map, or a new item at the end of a block list. */\n private append(parent: YAMLMap | YAMLSeq, key: string | number, value: unknown): string {\n const last = parent.items.length - 1;\n const first = itemStart(this.text, parent, 0);\n const column = first - lineStart(this.text, first);\n const at = itemEnd(this.text, parent, last);\n const lines = isMap(parent) ? this.render({ [String(key)]: value }) : this.render([value]);\n const prefix = at > 0 && this.text[at - 1] !== \"\\n\" ? this.eol : \"\";\n const block = lines.map((line) => \" \".repeat(column) + line).join(this.eol) + this.eol;\n return this.text.slice(0, at) + prefix + block + this.text.slice(at);\n }\n\n private insertIntoEmptyRoot(key: string | number, value: unknown): string {\n if (typeof key !== \"string\") throw new SpecEditError(\"the frontmatter must be a map\");\n const lines = this.render({ [key]: value });\n const prefix = this.text.length > 0 && !this.text.endsWith(\"\\n\") ? this.eol : \"\";\n return this.text + prefix + lines.join(this.eol) + this.eol;\n }\n\n /** Source range of item `index` of a flow collection, without the separating comma. */\n private flowRange(parent: YAMLMap | YAMLSeq, index: number): [number, number] {\n const item = parent.items[index];\n const first = (isMap(parent) ? (item as Pair).key : item) as Node | null;\n const last = (\n isMap(parent) ? ((item as Pair).value ?? (item as Pair).key) : item\n ) as Node | null;\n if (!first?.range || !last?.range)\n throw new SpecEditError(\"can't locate a flow collection item\");\n return [first.range[0], last.range[1]];\n }\n\n /** Text of one flow collection entry: `value`, or `key: value` in a map. */\n private flowEntry(parent: YAMLMap | YAMLSeq, key: string | number, value: unknown): string {\n const rendered = this.renderFlow(value);\n return isMap(parent)\n ? `${renderScalar(String(key), Scalar.PLAIN, true)}: ${rendered}`\n : rendered;\n }\n\n private flowReplace(\n parent: YAMLMap | YAMLSeq,\n index: number,\n key: string | number,\n value: unknown,\n ): string {\n const [start, end] = this.flowRange(parent, index);\n return this.text.slice(0, start) + this.flowEntry(parent, key, value) + this.text.slice(end);\n }\n\n private flowDelete(parent: YAMLMap | YAMLSeq, index: number): string {\n const count = parent.items.length;\n const [start, end] = this.flowRange(parent, index);\n if (count === 1) return this.text.slice(0, start) + this.text.slice(end);\n if (index < count - 1) {\n return this.text.slice(0, start) + this.text.slice(this.flowRange(parent, index + 1)[0]);\n }\n return this.text.slice(0, this.flowRange(parent, index - 1)[1]) + this.text.slice(end);\n }\n\n /**\n * Adds an entry at the end of a flow collection. An empty `[]` / `{}` under a block map or list\n * becomes a block collection instead, the way it would be written by hand.\n */\n private flowAppend(\n parent: YAMLMap | YAMLSeq,\n parentPath: PatchPath,\n key: string | number,\n value: unknown,\n ): string {\n const count = parent.items.length;\n const entry = this.flowEntry(parent, key, value);\n if (count > 0) {\n const end = this.flowRange(parent, count - 1)[1];\n return this.text.slice(0, end) + `, ${entry}` + this.text.slice(end);\n }\n if (parentPath.length > 0) {\n const grand = this.nodeAt(parentPath.slice(0, -1));\n if ((isMap(grand) || isSeq(grand)) && !grand.flow) return this.replaceInParent(parentPath);\n }\n const open = parent.range![0] + 1;\n return this.text.slice(0, open) + entry + this.text.slice(open);\n }\n\n /** One-line flow YAML for `value`. */\n private renderFlow(value: unknown): string {\n if (isScalarValue(value)) return renderScalar(value, Scalar.PLAIN, true);\n const doc = new Document(value);\n visit(doc, {\n Map: (_, node) => void (node.flow = true),\n Seq: (_, node) => void (node.flow = true),\n });\n const rendered = doc.toString(this.options()).trimEnd();\n if (rendered.includes(\"\\n\"))\n throw new SpecEditError(\"the value is too complex for a flow collection\");\n return rendered;\n }\n\n private expectedValue(path: PatchPath): unknown {\n const node = this.expected.getIn(path, true) as Node | undefined;\n return isScalar(node) ? node.value : (node?.toJSON() as unknown);\n }\n\n private nodeAt(path: PatchPath): Node | null {\n return path.length === 0\n ? this.doc.contents\n : ((this.doc.getIn(path, true) as Node | undefined) ?? null);\n }\n\n private options(): ToStringOptions {\n return { lineWidth: 0, flowCollectionPadding: false, indentSeq: this.indentSeq };\n }\n\n /** Block YAML for `value`, as lines without line breaks. */\n private render(value: unknown): string[] {\n return new Document(value).toString(this.options()).replace(/\\n$/, \"\").split(\"\\n\");\n }\n}\n\nconst isScalarValue = (value: unknown): boolean =>\n value === null || [\"string\", \"number\", \"boolean\"].includes(typeof value);\n\nconst isBlockScalar = (node: Scalar): boolean =>\n node.type === Scalar.BLOCK_LITERAL || node.type === Scalar.BLOCK_FOLDED;\n\n/** Renders a scalar in the style of the value it replaces, quoting only when needed. */\nfunction renderScalar(value: unknown, type: Scalar[\"type\"], inFlow: boolean): string {\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (typeof value !== \"string\") return \"null\";\n if (value.includes(\"\\n\") || type === Scalar.QUOTE_DOUBLE) return JSON.stringify(value);\n if (type === Scalar.QUOTE_SINGLE) return `'${value.replace(/'/g, \"''\")}'`;\n const plain = new Document(value).toString({ lineWidth: 0 }).replace(/\\n$/, \"\");\n // Inside `[...]` or `{...}`, a plain scalar can't contain the flow indicators , [ ] { }.\n const unsafe = plain.includes(\"\\n\") || (inFlow && /[,[\\]{}]/.test(plain));\n return unsafe ? JSON.stringify(value) : plain;\n}\n\nfunction findPair(map: YAMLMap, key: string | number): number {\n return map.items.findIndex(\n (pair: Pair) => isScalar(pair.key) && String(pair.key.value) === String(key),\n );\n}\n\n/** Offset where item `index` starts: the key of a pair, or the `-` of a list item. */\nfunction itemStart(text: string, parent: YAMLMap | YAMLSeq, index: number): number {\n const token = parent.srcToken;\n if (token?.type === \"block-seq\") {\n // Every list item has a `-`; comment-only entries of the token list don't.\n const items = token.items.filter((it) => it.start.some((t) => t.type === \"seq-item-ind\"));\n const dash = items[index]?.start.find((t) => t.type === \"seq-item-ind\");\n if (dash) return dash.offset;\n } else if (token?.type === \"block-map\" && isMap(parent)) {\n const key = parent.items[index]?.key as Node | null | undefined;\n const item = token.items.find((it) => it.key && it.key === key?.srcToken);\n if (item?.key) {\n // An anchor, tag or `?` before the key belongs to the item.\n const prop = item.start.find((t) => ![\"space\", \"newline\", \"comment\"].includes(t.type));\n return prop?.offset ?? item.key.offset;\n }\n }\n if (isMap(parent)) {\n const key = parent.items[index]!.key as Node | null;\n if (!key?.range) throw new SpecEditError(\"can't locate a key in the frontmatter\");\n return key.range[0];\n }\n const item = parent.items[index] as Node | null;\n if (!item?.range) throw new SpecEditError(\"can't locate a list item in the frontmatter\");\n let at = item.range[0] - 1;\n while (at >= 0 && (text[at] === \" \" || text[at] === \"\\t\")) at--;\n if (text[at] !== \"-\")\n throw new SpecEditError(\"can't locate a list item's '-' in the frontmatter\");\n return at;\n}\n\n/** Offset right after the line break that ends item `index` (its trailing comment included). */\nfunction itemEnd(text: string, parent: YAMLMap | YAMLSeq, index: number): number {\n const item = parent.items[index];\n const node = (isMap(parent) ? ((item as Pair).value ?? (item as Pair).key) : item) as Node | null;\n const start = itemStart(text, parent, index);\n let end = node?.range?.[2] ?? start;\n while (end > start && /\\s/.test(text[end - 1]!)) end--;\n const lineBreak = text.indexOf(\"\\n\", end);\n return lineBreak === -1 ? text.length : lineBreak + 1;\n}\n\nconst lineStart = (text: string, offset: number): number => text.lastIndexOf(\"\\n\", offset - 1) + 1;\n\n/** The comment at the end of the line `offset` is on, with the spaces before it (`\" # note\"`). */\nfunction trailingComment(text: string, offset: number): string | undefined {\n const lineBreak = text.indexOf(\"\\n\", offset);\n const line = text.slice(offset, lineBreak === -1 ? text.length : lineBreak).replace(/\\r$/, \"\");\n let quote: string | undefined;\n for (let i = 0; i < line.length; i++) {\n const char = line[i]!;\n if (quote) {\n if (char === quote && !(quote === \"'\" && line[i + 1] === \"'\")) quote = undefined;\n else if (quote === \"'\" && char === \"'\") i++;\n else if (quote === '\"' && char === \"\\\\\") i++;\n } else if (char === \"'\" || char === '\"') {\n if (i === 0 || /[\\s[{,:-]/.test(line[i - 1]!)) quote = char;\n } else if (char === \"#\" && i > 0 && /[ \\t]/.test(line[i - 1]!)) {\n let from = i;\n while (from > 0 && /[ \\t]/.test(line[from - 1]!)) from--;\n return line.slice(from);\n }\n }\n return undefined;\n}\n\nconst isLineStart = (text: string, offset: number): boolean =>\n text.slice(lineStart(text, offset), offset).trim() === \"\";\n\n/** Whether block lists inside maps are indented under their key (`key:\\n - a`), as in most specs. */\nfunction detectIndentSeq(text: string, doc: Document.Parsed): boolean {\n let indented: boolean | undefined;\n visit(doc, {\n Pair: (_, pair) => {\n const key = pair.key as Node | null;\n const value = pair.value as Node | null;\n if (!isSeq(value) || value.flow || !key?.range || value.items.length === 0) return;\n let dash: number;\n try {\n dash = itemStart(text, value, 0);\n } catch {\n return undefined;\n }\n const keyColumn = key.range[0] - lineStart(text, key.range[0]);\n indented = dash - lineStart(text, dash) > keyColumn;\n return visit.BREAK;\n },\n });\n return indented ?? true;\n}\n","/**\n * Rename and move detection (plan §D11.4, §D11.8, analysis F-7, ADR-013), PBIs `rename-detection`\n * and `batch-rename-mapping`: works out where the declarations that bindings pointed to went.\n *\n * The input is a baseline: what each binding resolved to before the change (from the refactor\n * baseline, or from the lock file and `HEAD`). Every baseline declaration that no longer resolves\n * is matched to a declaration of the current code, using the strongest evidence first:\n *\n * 1. the rename map (`--map`): symbols, namespaces, paths;\n * 2. the same qualified name in another file (moved);\n * 3. a namespace or module prefix change shared by several declarations (`Identity.*` →\n * `Accounts.*`);\n * 4. a file rename from `git diff -M`, same name in the new file;\n * 5. an identical name-free fingerprint, unique on both sides;\n * 6. the similarity score `0.5·jaccard(member names) + 0.4·jaccard(body token 3-grams) +\n * 0.1·same file`.\n *\n * Rows 5 and 6 are a global one-to-one assignment: a new declaration is used at most once, and a\n * pair is taken only when both are each other's unique best match at or above `heal.threshold`.\n * Every declaration ends up mapped, ambiguous (CS0216) or lost (CS0217); nothing is guessed.\n */\nimport { createHash } from \"node:crypto\";\n\nimport type { SymbolEntry, SymbolTable } from \"./codebase.js\";\nimport { compareStrings } from \"./diagnostics.js\";\nimport type { FileFacts, Range, SourceFile, SymbolFact } from \"./facts.js\";\nimport { fingerprintOf, shapeOf, type LockedSymbol, type Shape } from \"./lock.js\";\nimport { nameMatches } from \"./match.js\";\nimport { groupOverloads, inModule, mergePartials, splitSymbol } from \"./resolve.js\";\nimport { escapeRegExp, LineIndex } from \"./util.js\";\n\n/** A declaration a binding resolved to before the change. */\nexport interface BaselineSymbol {\n /** Spec id. */\n spec: string;\n /** Binding id. */\n binding: string;\n /** `path#QualifiedName` of the declaration. */\n resolved: string;\n /** Every file of a C# partial type, when there is more than one. */\n files?: string[];\n fingerprint: string;\n /** Fingerprint of the shape without the declaration's own name and namespace. */\n nameFree: string;\n shape: Shape;\n /** Body tokens without the declaration's own name; empty when its source wasn't available. */\n tokens: string[];\n}\n\n/** The rename map of `catspec sync --map` (plan §D11.8). */\nexport interface RenameMap {\n /** Old qualified name (or `path#Name`) → new qualified name. */\n symbols?: Record<string, string>;\n /** Old namespace or name prefix → new one, segment-wise: `Identity` → `Accounts`. */\n namespaces?: Record<string, string>;\n /** Old path prefix → new one: `src/Identity/` → `src/Accounts/`. */\n paths?: Record<string, string>;\n}\n\n/** How a mapping was found, strongest first (the rows of plan §D11.8). */\nexport type Evidence = \"map\" | \"moved\" | \"prefix\" | \"file-rename\" | \"fingerprint\" | \"similarity\";\n\n/** A candidate with its similarity score. */\nexport interface ScoredCandidate {\n entry: SymbolEntry;\n score: number;\n}\n\n/** A baseline declaration mapped to a declaration of the current code. */\nexport interface Mapping {\n /** The bindings that pointed to the old declaration (one declaration can be bound twice). */\n bindings: BaselineSymbol[];\n target: SymbolEntry;\n /** Every file of the target when it is a C# partial type in several files. */\n files?: string[];\n evidence: Evidence;\n /** The similarity score, when computed. */\n score?: number;\n /** What the evidence was, e.g. `namespace Identity → Accounts`. */\n detail?: string;\n}\n\nexport interface Ambiguity {\n bindings: BaselineSymbol[];\n /** Best first. */\n candidates: ScoredCandidate[];\n detail?: string;\n}\n\nexport interface Lost {\n bindings: BaselineSymbol[];\n /** The closest candidate, below the threshold. */\n best?: ScoredCandidate;\n detail?: string;\n}\n\nexport interface RenameReport {\n mapped: Mapping[];\n ambiguous: Ambiguity[];\n lost: Lost[];\n}\n\nexport interface RenameInput {\n /** The bindings that no longer resolve, with what they resolved to before. */\n broken: readonly BaselineSymbol[];\n /** Every declaration of the current code. */\n table: SymbolTable;\n /** Current files that the baseline revision doesn't have, or has with other content. */\n changed: ReadonlySet<string>;\n /** Facts of the baseline versions of the files that changed or were deleted. */\n before: readonly FileFacts[];\n /** File renames from `git diff -M`: old path → new path. */\n renames?: ReadonlyMap<string, string>;\n map?: RenameMap;\n /** `heal.threshold`. */\n threshold: number;\n /** Body tokens of a current declaration (`bodyTokens`), computed only for scored candidates. */\n tokens: (entry: SymbolEntry) => Promise<string[]>;\n /** Ids (`path#id`) of current declarations that other bindings resolve to; never candidates. */\n taken?: ReadonlySet<string>;\n}\n\nconst sha256 = (value: unknown): string =>\n `sha256:${createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\")}`;\n\n/** The last segment of a qualified name. */\nconst simpleName = (qualifiedName: string): string =>\n qualifiedName.slice(qualifiedName.lastIndexOf(\".\") + 1);\n\n/** `path#QualifiedName` → path and qualified name. */\nexport function splitResolved(resolved: string): { file: string; qualifiedName: string } {\n const hash = resolved.lastIndexOf(\"#\");\n return hash === -1\n ? { file: resolved, qualifiedName: \"\" }\n : { file: resolved.slice(0, hash), qualifiedName: resolved.slice(hash + 1) };\n}\n\n/** Whole-word matches of any of `words`, tried in the order given; `extraBefore` also blocks. */\nexport const wordPattern = (words: string | readonly string[], extraBefore = \"\"): RegExp =>\n new RegExp(\n `(?<![\\\\p{L}\\\\p{N}_$${extraBefore}])(?:${(typeof words === \"string\" ? [words] : words)\n .map(escapeRegExp)\n .join(\"|\")})(?![\\\\p{L}\\\\p{N}_$])`,\n \"gu\",\n );\n\n/**\n * A shape without the declaration's own name: the qualified name is dropped and the simple name\n * is blanked where members repeat it (C# constructors), so a rename alone keeps the fingerprint.\n */\nexport function nameFreeFingerprint(shape: Shape): string {\n const name = simpleName(shape.name);\n const pattern = name ? wordPattern(name) : undefined;\n const blank = (text: string): string => (pattern ? text.replace(pattern, \"∅\") : text);\n return sha256([\n shape.kind,\n [...shape.bases].sort(compareStrings),\n [...shape.attributes].sort(compareStrings),\n [...shape.modifiers].sort(compareStrings),\n shape.signature === undefined ? null : blank(shape.signature),\n shape.members.map(blank).sort(compareStrings),\n ]);\n}\n\n/**\n * The member names of a shape (`public method login(string):boolean` → `login`). A member named\n * like the declaration itself (a C# constructor) is `∅`, so a rename alone keeps the names.\n */\nexport function memberNames(shape: Shape): string[] {\n const own = simpleName(shape.name);\n return shape.members.map((member) => {\n const head = member.split(/[(:]/)[0]!.trim();\n const name = head.slice(head.lastIndexOf(\" \") + 1);\n return name === own ? \"∅\" : name;\n });\n}\n\nconst TOKEN =\n /[\\p{L}_$][\\p{L}\\p{N}_$]*|\\d[\\p{L}\\p{N}_.]*|\"(?:[^\"\\\\\\n]|\\\\.)*\"|'(?:[^'\\\\\\n]|\\\\.)*'|`(?:[^`\\\\]|\\\\.)*`|\\S/gu;\n\n/**\n * The tokens of a declaration's source, without its own name: identifiers, numbers, strings and\n * punctuation. Language-independent, for the similarity score only (never written anywhere).\n */\nexport function bodyTokens(source: SourceFile, symbol: SymbolFact): string[] {\n const text = sliceRange(source, symbol.range);\n const tokens = text.match(TOKEN) ?? [];\n return tokens.filter((t) => t !== symbol.name);\n}\n\n/** Line indexes of the files tokenised, so the declarations of one file share one. */\nconst lineIndexes = new WeakMap<SourceFile, LineIndex>();\n\nfunction sliceRange(source: SourceFile, range: Range): string {\n const { text } = source;\n let lines = lineIndexes.get(source);\n if (!lines) lineIndexes.set(source, (lines = new LineIndex(text)));\n const offset = (p: Range[\"start\"]): number => lines.lineStart(p.line) + p.column - 1;\n return text.slice(offset(range.start), offset(range.end));\n}\n\n/** Jaccard index of two sets; two empty sets are equal. */\nexport function jaccard(a: ReadonlySet<string>, b: ReadonlySet<string>): number {\n if (a.size === 0 && b.size === 0) return 1;\n let common = 0;\n for (const x of a) if (b.has(x)) common++;\n return common / (a.size + b.size - common);\n}\n\nconst trigramSets = new WeakMap<readonly string[], Set<string>>();\n\n/** Token 3-grams (or the tokens themselves when there are fewer than three), cached per array. */\nconst trigrams = (tokens: readonly string[]): Set<string> => {\n let grams = trigramSets.get(tokens);\n if (grams) return grams;\n if (tokens.length < 3) grams = new Set(tokens);\n else {\n grams = new Set<string>();\n for (let i = 0; i + 2 < tokens.length; i++) {\n grams.add(`${tokens[i]}\\u0000${tokens[i + 1]}\\u0000${tokens[i + 2]}`);\n }\n }\n trigramSets.set(tokens, grams);\n return grams;\n};\n\n/** Similarity of two bodies: Jaccard over token 3-grams; 0 when either body is unknown. */\nexport function tokenSimilarity(a: readonly string[], b: readonly string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n return jaccard(trigrams(a), trigrams(b));\n}\n\n/**\n * The rename score of plan §D11.4: `0.5·jaccard(member names) + 0.4·tokenSimilarity(body) +\n * 0.1·sameFile`. Declarations without members (functions) compare their signatures instead.\n */\nexport function renameScore(\n before: { shape: Shape; tokens: readonly string[] },\n after: { shape: Shape; tokens: readonly string[] },\n sameFile: boolean,\n): number {\n const a = new Set(memberNames(before.shape));\n const b = new Set(memberNames(after.shape));\n const members =\n a.size === 0 && b.size === 0\n ? (before.shape.signature ?? \"\") === (after.shape.signature ?? \"\")\n ? 1\n : 0\n : jaccard(a, b);\n const score = 0.5 * members + 0.4 * tokenSimilarity(before.tokens, after.tokens);\n return Math.round((score + (sameFile ? 0.1 : 0)) * 1e6) / 1e6;\n}\n\n/** A baseline entry from a lock file's `symbols` entry and, when available, the old source. */\nexport function baselineFromLock(\n spec: string,\n binding: string,\n locked: LockedSymbol,\n tokens: string[] = [],\n): BaselineSymbol {\n return {\n spec,\n binding,\n resolved: locked.resolved,\n ...(locked.files ? { files: locked.files } : {}),\n fingerprint: locked.fingerprint,\n nameFree: nameFreeFingerprint(locked.shape),\n shape: locked.shape,\n tokens,\n };\n}\n\n/** A baseline entry from a declaration resolved in the baseline revision. */\nexport function baselineFromSymbol(\n spec: string,\n binding: string,\n resolved: { symbol: SymbolFact; file: { path: string }; files: string[] },\n source?: SourceFile,\n): BaselineSymbol {\n const shape = shapeOf(resolved.symbol);\n return {\n spec,\n binding,\n resolved: `${resolved.file.path}#${resolved.symbol.qualifiedName}`,\n ...(resolved.files.length > 1 ? { files: [...resolved.files].sort(compareStrings) } : {}),\n fingerprint: fingerprintOf(shape),\n nameFree: nameFreeFingerprint(shape),\n shape,\n tokens: source ? bodyTokens(source, resolved.symbol) : [],\n };\n}\n\n/** An old declaration and every binding that pointed to it. */\ninterface Group {\n key: string;\n file: string;\n qualifiedName: string;\n kind: string;\n bindings: BaselineSymbol[];\n /** The first binding's baseline entry (shape and tokens are the same for all). */\n first: BaselineSymbol;\n}\n\nconst entryKey = (e: SymbolEntry): string => `${e.file.path}#${e.symbol.id}`;\n\n/** True when a path segment prefix applies: `Identity` is a prefix of `Identity.Users.X`. */\nconst segmentPrefix = (prefix: string, name: string, sep: string): boolean =>\n prefix === \"\" || name === prefix || name.startsWith(prefix + sep);\n\n/** Replaces the longest matching prefix of `name` from `prefixes`; undefined when none applies. */\nfunction replacePrefix(\n name: string,\n prefixes: Record<string, string> | undefined,\n sep: string,\n): string | undefined {\n if (!prefixes) return undefined;\n const keys = Object.keys(prefixes)\n .filter((k) => k !== \"\" && (sep === \"/\" ? name.startsWith(k) : segmentPrefix(k, name, sep)))\n .sort((a, b) => b.length - a.length);\n const key = keys[0];\n return key === undefined ? undefined : prefixes[key]! + name.slice(key.length);\n}\n\n/** Maps every broken binding of `input` to its new declaration, or reports why it can't. */\nexport async function detectRenames(input: RenameInput): Promise<RenameReport> {\n const groups = groupBroken(input.broken);\n const report: RenameReport = { mapped: [], ambiguous: [], lost: [] };\n if (groups.length === 0) return report;\n\n const taken = input.taken ?? new Set<string>();\n const changedEntries = input.table.entries.filter(\n (e) => input.changed.has(e.file.path) && !taken.has(entryKey(e)),\n );\n // Declarations of the changed files that the baseline didn't have: rename candidates.\n const before = new Set<string>();\n const beforeAt = new Set<string>();\n const addBefore = (path: string, s: SymbolFact): void => {\n before.add(`${s.kind}\\u0000${s.qualifiedName}`);\n beforeAt.add(`${path}\\u0000${s.kind}\\u0000${s.qualifiedName}`);\n s.members.forEach((m) => addBefore(path, m));\n };\n for (const file of input.before) file.symbols.forEach((s) => addBefore(file.path, s));\n const fresh = changedEntries.filter(\n (e) => !before.has(`${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`),\n );\n /** A declaration its file didn't have before (a new file, or one it moved into). */\n const newHere = (e: SymbolEntry): boolean =>\n input.changed.has(e.file.path) &&\n !beforeAt.has(`${e.file.path}\\u0000${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`);\n\n // Body tokens of current declarations, computed once each.\n const tokenCache = new Map<SymbolEntry, Promise<string[]>>();\n const tokensOf = (e: SymbolEntry): Promise<string[]> => {\n let tokens = tokenCache.get(e);\n if (!tokens) tokenCache.set(e, (tokens = input.tokens(e)));\n return tokens;\n };\n\n /** A mapping by exact evidence, before the conflict check; or an outcome that ends the search. */\n type Exact =\n | { kind: \"mapped\"; target: SymbolEntry; evidence: Evidence; detail?: string }\n | { kind: \"ambiguous\"; candidates: SymbolEntry[]; detail: string }\n | { kind: \"lost\"; detail: string };\n const exact = new Map<Group, Exact>();\n const ofKind = (entries: readonly SymbolEntry[], g: Group): SymbolEntry[] =>\n entries.filter((e) => e.symbol.kind === g.kind && !taken.has(entryKey(e)));\n const decide = (\n g: Group,\n found: SymbolEntry[],\n evidence: Evidence,\n detail: string,\n ): Exact | undefined => {\n const unique = dedupe(found);\n if (unique.length === 1) return { kind: \"mapped\", target: unique[0]!, evidence, detail };\n if (unique.length > 1) return { kind: \"ambiguous\", candidates: unique, detail };\n return undefined;\n };\n\n // Rows 1 and 2: the rename map, then the same qualified name elsewhere.\n for (const g of groups) {\n const result = fromMap(g) ?? moved(g);\n if (result) exact.set(g, result);\n }\n\n function fromMap(g: Group): Exact | undefined {\n const map = input.map;\n if (!map) return undefined;\n for (const [from, to] of Object.entries(map.symbols ?? {})) {\n const { module, name } = splitSymbol(from);\n if (module !== undefined && !inModule(g.file, module)) continue;\n if (!nameMatches(name, g.qualifiedName)) continue;\n const target = splitSymbol(to);\n const found = ofKind(input.table.find(target.name), g).filter(\n (e) => target.module === undefined || inModule(e.file.path, target.module),\n );\n return (\n decide(g, found, \"map\", `rename map: ${from} → ${to}`) ?? {\n kind: \"lost\",\n detail: `the rename map names ${to}, which isn't in the code`,\n }\n );\n }\n const name = replacePrefix(g.qualifiedName, map.namespaces, \".\");\n const file = replacePrefix(g.file, map.paths, \"/\");\n if (name === undefined && file === undefined) return undefined;\n const qualifiedName = name ?? g.qualifiedName;\n const inFile = file ?? g.file;\n const exactly = ofKind(input.table.find(qualifiedName), g).filter(\n (e) => e.symbol.qualifiedName === qualifiedName,\n );\n const detail = [\n name !== undefined ? `namespace ${g.qualifiedName} → ${qualifiedName}` : undefined,\n file !== undefined ? `path ${g.file} → ${inFile}` : undefined,\n ]\n .filter(Boolean)\n .join(\", \");\n const there = exactly.filter((e) => e.file.path === inFile);\n return (\n decide(g, there.length > 0 ? there : exactly, \"map\", `rename map: ${detail}`) ??\n (file !== undefined && name === undefined\n ? decide(\n g,\n ofKind(input.table.entries, g).filter(\n (e) => e.file.path === inFile && e.symbol.name === simpleName(g.qualifiedName),\n ),\n \"map\",\n `rename map: ${detail}`,\n )\n : undefined)\n );\n }\n\n /**\n * The same qualified name in another file, only when it moved there: the declaration is gone\n * from its old file and new in the other one. An older, unrelated declaration of the same name\n * is not a move (TypeScript qualified names have no module part).\n */\n function moved(g: Group): Exact | undefined {\n const named = ofKind(input.table.find(g.qualifiedName), g).filter(\n (e) => e.symbol.qualifiedName === g.qualifiedName,\n );\n if (named.some((e) => e.file.path === g.file)) return undefined;\n return decide(g, named.filter(newHere), \"moved\", `moved from ${g.file}`);\n }\n\n // Row 3: a prefix change shared by several declarations (`Identity.*` → `Accounts.*`).\n const remaining = (): Group[] => groups.filter((g) => !exact.has(g));\n const prefixVotes = new Map<string, Set<Group>>();\n for (const g of remaining()) {\n const oldSegments = g.qualifiedName.split(\".\");\n for (const e of ofKind(fresh, g)) {\n if (e.symbol.name !== simpleName(g.qualifiedName)) continue;\n const newSegments = e.symbol.qualifiedName.split(\".\");\n let common = 0;\n while (\n common < oldSegments.length &&\n common < newSegments.length &&\n oldSegments[oldSegments.length - 1 - common] ===\n newSegments[newSegments.length - 1 - common]\n ) {\n common++;\n }\n const from = oldSegments.slice(0, oldSegments.length - common).join(\".\");\n const to = newSegments.slice(0, newSegments.length - common).join(\".\");\n if (from === to) continue;\n const key = `${from}\\u0000${to}`;\n prefixVotes.set(key, (prefixVotes.get(key) ?? new Set()).add(g));\n }\n }\n const prefixes = [...prefixVotes.entries()]\n .filter(([, voters]) => voters.size >= 2)\n .map(([key]) => key.split(\"\\u0000\") as [string, string])\n .sort((a, b) => b[0].length - a[0].length);\n for (const g of remaining()) {\n // Every rule that applies is tried: one namespace can be split into several.\n const hits: { found: SymbolEntry[]; detail: string }[] = [];\n for (const [from, to] of prefixes) {\n if (from === \"\" || !segmentPrefix(from, g.qualifiedName, \".\")) continue;\n const qualifiedName = to + g.qualifiedName.slice(from.length);\n const found = ofKind(fresh, g).filter((e) => e.symbol.qualifiedName === qualifiedName);\n if (found.length > 0) hits.push({ found, detail: `namespace ${from} → ${to}` });\n }\n if (hits.length === 0) continue;\n const result = decide(\n g,\n hits.flatMap((h) => h.found),\n \"prefix\",\n hits.length === 1\n ? hits[0]!.detail\n : `several prefix rules apply: ${hits.map((h) => h.detail).join(\"; \")}`,\n );\n if (result) exact.set(g, result);\n }\n\n // Row 4: the file was renamed; the same name in the new file.\n for (const g of remaining()) {\n const renamed = input.renames?.get(g.file);\n if (renamed === undefined) continue;\n const found = ofKind(changedEntries, g).filter(\n (e) => e.file.path === renamed && e.symbol.name === simpleName(g.qualifiedName),\n );\n const result = decide(g, found, \"file-rename\", `file renamed: ${g.file} → ${renamed}`);\n if (result) exact.set(g, result);\n }\n\n // Exact evidence must not use one declaration twice either.\n const claims = new Map<string, Group[]>();\n for (const [g, result] of exact) {\n if (result.kind !== \"mapped\") continue;\n const key = entryKey(result.target);\n claims.set(key, [...(claims.get(key) ?? []), g]);\n }\n const used = new Set<string>();\n for (const [g, result] of exact) {\n if (result.kind === \"lost\") {\n report.lost.push({ bindings: g.bindings, detail: result.detail });\n } else if (result.kind === \"ambiguous\") {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: result.candidates.map((entry) => ({ entry, score: 1 })),\n detail: result.detail,\n });\n } else if (claims.get(entryKey(result.target))!.length > 1) {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: [{ entry: result.target, score: 1 }],\n detail: `${result.target.symbol.qualifiedName} is also the target of ${listOfNames(\n claims.get(entryKey(result.target))!.filter((other) => other !== g),\n )}`,\n });\n used.add(entryKey(result.target));\n } else {\n const files = partialFiles.get(result.target.symbol);\n report.mapped.push({\n bindings: g.bindings,\n target: result.target,\n ...(files ? { files } : {}),\n evidence: result.evidence,\n ...(result.detail !== undefined ? { detail: result.detail } : {}),\n });\n used.add(entryKey(result.target));\n }\n }\n\n // Rows 5 and 6: global one-to-one assignment over the remaining declarations.\n const open = remaining();\n const pool = fresh.filter((e) => !used.has(entryKey(e)));\n const shapes = new Map<SymbolEntry, Shape>();\n const shapeFor = (e: SymbolEntry): Shape => {\n let shape = shapes.get(e);\n if (!shape) shapes.set(e, (shape = shapeOf(e.symbol)));\n return shape;\n };\n const nameFree = new Map<SymbolEntry, string>();\n const nameFreeFor = (e: SymbolEntry): string => {\n let fp = nameFree.get(e);\n if (fp === undefined) nameFree.set(e, (fp = nameFreeFingerprint(shapeFor(e))));\n return fp;\n };\n\n // Row 5: the name-free fingerprint is identical, and unique on both sides.\n const assigned = new Map<Group, Mapping>();\n const byPrint = new Map<string, { groups: Group[]; entries: SymbolEntry[] }>();\n for (const g of open) {\n const slot = byPrint.get(`${g.kind}\\u0000${g.first.nameFree}`) ?? { groups: [], entries: [] };\n slot.groups.push(g);\n byPrint.set(`${g.kind}\\u0000${g.first.nameFree}`, slot);\n }\n for (const e of pool) {\n const slot = byPrint.get(`${e.symbol.kind}\\u0000${nameFreeFor(e)}`);\n if (slot) slot.entries.push(e);\n }\n for (const { groups: gs, entries } of byPrint.values()) {\n if (gs.length !== 1 || entries.length !== 1) continue;\n const g = gs[0]!;\n const target = entries[0]!;\n const score = renameScore(\n g.first,\n { shape: shapeFor(target), tokens: await tokensOf(target) },\n sameFile(g, target),\n );\n // A shape without members is little more than a signature, which unrelated declarations\n // share: it maps by fingerprint only when the score reaches the threshold too.\n if (g.first.shape.members.length === 0 && score < input.threshold) continue;\n assigned.set(g, {\n bindings: g.bindings,\n target,\n evidence: \"fingerprint\",\n score,\n detail: \"only the name changed\",\n });\n }\n\n // Row 6: similarity, mutual unique best matches at or above the threshold.\n const unassigned = open.filter((g) => !assigned.has(g));\n const targets = new Set(pool.filter((e) => ![...assigned.values()].some((m) => m.target === e)));\n const scores = new Map<Group, ScoredCandidate[]>();\n for (const g of unassigned) {\n const scored: ScoredCandidate[] = [];\n for (const e of targets) {\n if (e.symbol.kind !== g.kind) continue;\n const score = renameScore(\n g.first,\n { shape: shapeFor(e), tokens: await tokensOf(e) },\n sameFile(g, e),\n );\n scored.push({ entry: e, score });\n }\n scored.sort(\n (a, b) => b.score - a.score || compareStrings(entryKey(a.entry), entryKey(b.entry)),\n );\n scores.set(g, scored);\n }\n const EPSILON = 1e-9;\n for (;;) {\n const free = unassigned.filter((g) => !assigned.has(g));\n const best = (g: Group): ScoredCandidate[] => {\n const live = scores.get(g)!.filter((c) => targets.has(c.entry) && c.score >= input.threshold);\n return live.filter((c) => c.score >= live[0]!.score - EPSILON);\n };\n const bestOld = new Map<SymbolEntry, { score: number; groups: Group[] }>();\n for (const g of free) {\n for (const c of scores.get(g)!) {\n if (!targets.has(c.entry) || c.score < input.threshold) continue;\n const slot = bestOld.get(c.entry);\n if (!slot || c.score > slot.score + EPSILON)\n bestOld.set(c.entry, { score: c.score, groups: [g] });\n else if (Math.abs(c.score - slot.score) <= EPSILON) slot.groups.push(g);\n }\n }\n let progress = false;\n for (const g of free) {\n const top = scores.get(g)!.length > 0 ? best(g) : [];\n if (top.length !== 1) continue;\n const candidate = top[0]!;\n const mutual = bestOld.get(candidate.entry);\n if (!mutual || mutual.groups.length !== 1 || mutual.groups[0] !== g) continue;\n assigned.set(g, {\n bindings: g.bindings,\n target: candidate.entry,\n evidence: \"similarity\",\n score: candidate.score,\n });\n targets.delete(candidate.entry);\n progress = true;\n }\n if (!progress) break;\n }\n\n for (const g of open) {\n const mapping = assigned.get(g);\n if (mapping) {\n report.mapped.push(mapping);\n continue;\n }\n // Candidates a closer match took are no longer candidates.\n const scored = (scores.get(g) ?? []).filter((c) => targets.has(c.entry));\n const above = scored.filter((c) => c.score >= input.threshold);\n if (above.length > 0) {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: above.slice(0, 5),\n detail: \"several candidates are equally close\",\n });\n } else {\n report.lost.push({\n bindings: g.bindings,\n ...(scored[0] && scored[0].score > 0 ? { best: scored[0] } : {}),\n });\n }\n }\n const order = (bindings: BaselineSymbol[]): string =>\n `${bindings[0]!.spec}\\u0000${bindings[0]!.binding}`;\n report.mapped.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n report.ambiguous.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n report.lost.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n return report;\n\n function sameFile(g: Group, e: SymbolEntry): boolean {\n return e.file.path === g.file || input.renames?.get(g.file) === e.file.path;\n }\n}\n\nfunction groupBroken(broken: readonly BaselineSymbol[]): Group[] {\n const groups = new Map<string, Group>();\n for (const b of broken) {\n const group = groups.get(b.resolved);\n if (group) {\n group.bindings.push(b);\n continue;\n }\n const { file, qualifiedName } = splitResolved(b.resolved);\n groups.set(b.resolved, {\n key: b.resolved,\n file,\n qualifiedName: qualifiedName || b.shape.name,\n kind: b.shape.kind,\n bindings: [b],\n first: b,\n });\n }\n return [...groups.values()].sort((a, b) => compareStrings(a.key, b.key));\n}\n\n/** The files of the C# partial types `dedupe` merged, by merged declaration. */\nconst partialFiles = new WeakMap<SymbolFact, string[]>();\n\n/**\n * The distinct declarations among `entries`, grouped as binding resolution groups them: overload\n * signatures and their implementation are one, and the parts of a C# partial type are one\n * (merged, at the part in the first file).\n */\nfunction dedupe(entries: SymbolEntry[]): SymbolEntry[] {\n const out: SymbolEntry[] = [];\n const partials = new Map<string, SymbolEntry[]>();\n for (const group of groupOverloads(entries)) {\n const e = group[0]!;\n if (out.some((o) => o.file.path === e.file.path && o.symbol === e.symbol)) continue;\n if (!e.symbol.partial) out.push(e);\n else {\n const key = `${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`;\n const parts = partials.get(key) ?? [];\n if (!parts.some((p) => p.symbol === e.symbol)) partials.set(key, [...parts, e]);\n }\n }\n for (const parts of partials.values()) {\n const sorted = [...parts].sort((a, b) => compareStrings(a.file.path, b.file.path));\n if (sorted.length === 1) {\n out.push(sorted[0]!);\n continue;\n }\n const symbol = mergePartials(sorted.map((p) => p.symbol));\n partialFiles.set(symbol, [...new Set(sorted.map((p) => p.file.path))]);\n out.push({ file: sorted[0]!.file, symbol });\n }\n return out;\n}\n\nconst listOfNames = (groups: Group[]): string => groups.map((g) => g.qualifiedName).join(\", \");\n","/**\n * `catspec sync` (plan §D10, §D11.4, §D11.6, §D11.8, ADR-008), PBIs `sync-command` and\n * `batch-rename-mapping`: turns a rename report into spec edits, lock-file moves and diagnostics.\n *\n * Edits are location-only `SpecPatch`es: a binding's `symbol` and `file` values, never a contract\n * field (every patch is checked with `classifyPatch`). Backticked mentions of old names in the\n * spec body are reported as info and rewritten only with `updateMentions`. Lock entries move to\n * the new declaration, so `satisfied` (the ratchet) survives; a shape that changed only by its\n * name is accepted, any other change stays drift (CS0300).\n */\nimport { posix } from \"node:path\";\n\nimport type { SymbolEntry } from \"./codebase.js\";\nimport { codeLocation, formatLocation } from \"./codebase.js\";\nimport {\n createDiagnostic,\n type Diagnostic,\n type PatchOp,\n type Severity,\n type SpecPatch,\n} from \"./diagnostics.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { fingerprintOf, shapeOf, type LockedSymbol, type LockFile } from \"./lock.js\";\nimport {\n nameFreeFingerprint,\n splitResolved,\n type Ambiguity,\n type BaselineSymbol,\n type Lost,\n type Mapping,\n type RenameReport,\n wordPattern,\n} from \"./rename.js\";\nimport { inModule, splitSymbol } from \"./resolve.js\";\nimport { applyPatch, classifyPatch, readYaml, SpecEditError } from \"./spec-editor.js\";\nimport type { Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/** The edit of one spec file. */\nexport interface SpecEdit {\n spec: Spec;\n /** Frontmatter operations (location fields only). */\n ops: PatchOp[];\n /** The file text after the edit. */\n text: string;\n}\n\nexport interface SyncPlan {\n report: RenameReport;\n edits: SpecEdit[];\n /** Lock files with entries moved to the new declarations, by spec id (only specs with a lock). */\n locks: Map<string, LockFile>;\n /** CS0210 for each mapped binding, CS0216 ambiguous, CS0217 lost, CS0210 info for mentions. */\n diagnostics: Diagnostic[];\n}\n\nexport interface SyncOptions {\n /** Severity of the CS0210 of a mapped binding (default info: `sync` fixes it). */\n mappedSeverity?: Severity;\n /** Rewrite backticked mentions of old names in the spec bodies (`--update-mentions`). */\n updateMentions?: boolean;\n /** The `paths` of the rename map, to rewrite `file` globs. */\n paths?: Record<string, string>;\n /**\n * Bindings that still resolve, but outside their `file` hint (a moved file): their hint is\n * updated too. By spec id, then binding id.\n */\n movedHints?: ReadonlyMap<string, ReadonlyMap<string, SymbolEntry>>;\n}\n\nconst EVIDENCE: Record<Mapping[\"evidence\"], string> = {\n map: \"rename map\",\n moved: \"moved\",\n prefix: \"prefix rule\",\n \"file-rename\": \"file renamed\",\n fingerprint: \"same shape\",\n similarity: \"similarity\",\n};\n\n/** Plans the spec edits, lock moves and diagnostics of a rename report. */\nexport function planSync(\n model: SpecModel,\n report: RenameReport,\n options: SyncOptions = {},\n): SyncPlan {\n const diagnostics: Diagnostic[] = [];\n const ops = new Map<Spec, PatchOp[]>();\n const renamed = new Map<Spec, { from: string[]; to: string }[]>();\n const locks = new Map<string, LockFile>();\n const addOps = (spec: Spec, more: PatchOp[]): void => {\n if (more.length > 0) ops.set(spec, [...(ops.get(spec) ?? []), ...more]);\n };\n\n for (const mapping of report.mapped) {\n for (const old of mapping.bindings) {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) continue;\n const bindingOps = relocate(spec, binding, old, mapping.target, options.paths);\n addOps(spec, bindingOps);\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n renamed.set(spec, [\n ...(renamed.get(spec) ?? []),\n {\n from: [...new Set([oldName, splitSymbol(binding.symbol).name])],\n to: mapping.target.symbol.qualifiedName,\n },\n ]);\n moveLock(model, locks, old, mapping.target, mapping.files);\n const how =\n `${EVIDENCE[mapping.evidence]}${mapping.score !== undefined ? `, score ${mapping.score.toFixed(2)}` : \"\"}` +\n (mapping.detail ? `: ${mapping.detail}` : \"\");\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n codeLocation: codeLocation(mapping.target.file.path, mapping.target.symbol.nameRange),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n severity: options.mappedSeverity ?? \"info\",\n message: `binding \"${binding.id}\": ${oldName} is now ${mapping.target.symbol.qualifiedName} at ${formatLocation(mapping.target.file.path, mapping.target.symbol.nameRange)} (${how})`,\n expected: binding.symbol,\n actual: `${mapping.target.file.path}#${mapping.target.symbol.qualifiedName}`,\n suggestions: [\n {\n message: \"run `catspec sync --apply` to update the spec\",\n patch: { file: spec.file, ops: bindingOps },\n },\n ],\n }),\n );\n }\n }\n\n for (const [specId, hints] of options.movedHints ?? []) {\n const spec = model.specs.get(specId);\n if (!spec) continue;\n for (const [bindingId, entry] of hints) {\n const binding = spec.bindings.find((b) => b.id === bindingId);\n if (!binding) continue;\n const hintOps = rewriteHints(spec, binding, undefined, entry.file.path, options.paths);\n if (hintOps.length === 0) continue;\n addOps(spec, hintOps);\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"file\"]),\n codeLocation: codeLocation(entry.file.path, entry.symbol.nameRange),\n bindingId: binding.id,\n severity: \"info\",\n message: `binding \"${binding.id}\": ${binding.symbol} moved to ${entry.file.path}, outside its file hint (moved, score 1.00)`,\n suggestions: [\n {\n message: \"run `catspec sync --apply` to update the hint\",\n patch: { file: spec.file, ops: hintOps },\n },\n ],\n }),\n );\n }\n }\n\n for (const ambiguity of report.ambiguous) diagnostics.push(...ambiguous(model, ambiguity));\n for (const lost of report.lost) diagnostics.push(...lostDiagnostics(model, lost));\n\n const edits: SpecEdit[] = [];\n for (const spec of model.specs.byFile.values()) {\n const specOps = ops.get(spec) ?? [];\n const mentions = mentionsOf(spec, renamed.get(spec) ?? []);\n for (const m of mentions) {\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: { file: spec.file, line: m.line, column: m.column },\n severity: \"info\",\n message: options.updateMentions\n ? `the body mentions \\`${m.text}\\`; rewritten to \\`${m.replacement}\\``\n : `the body mentions \\`${m.text}\\`, now \\`${m.replacement}\\`; \\`catspec sync --apply --update-mentions\\` rewrites it`,\n }),\n );\n }\n if (specOps.length === 0 && !(options.updateMentions && mentions.length > 0)) continue;\n if (specOps.length > 0 && classifyPatch(specOps, spec.source) !== \"location\") {\n throw new SpecEditError(`${spec.file}: a sync edit would change the contract (ADR-008)`);\n }\n let text = applyPatch(spec.source, specOps);\n if (options.updateMentions && mentions.length > 0) text = rewriteMentions(text, spec, mentions);\n edits.push({ spec, ops: specOps, text });\n }\n return { report, edits, locks, diagnostics };\n}\n\n/** The ops that point `binding` at `target`: its `symbol`, and its `file` hint if it has one. */\nfunction relocate(\n spec: Spec,\n binding: Binding,\n old: BaselineSymbol,\n target: SymbolEntry,\n paths: Record<string, string> | undefined,\n): PatchOp[] {\n const oldFile = splitResolved(old.resolved).file;\n const symbol = rewriteSymbol(binding.symbol, old, target);\n const out: PatchOp[] = [];\n if (symbol !== binding.symbol) {\n out.push({ op: \"set\", path: [\"bindings\", binding.index, \"symbol\"], value: symbol });\n }\n out.push(...rewriteHints(spec, binding, oldFile, target.file.path, paths));\n return out;\n}\n\n/**\n * The binding's `symbol` for the new declaration, written the way it was: as many name segments\n * as before (all of them when it was fully qualified), and the module path when it had one.\n */\nexport function rewriteSymbol(written: string, old: BaselineSymbol, target: SymbolEntry): string {\n const { module, name } = splitSymbol(written);\n const before = (splitResolved(old.resolved).qualifiedName || old.shape.name).split(\".\");\n const after = target.symbol.qualifiedName.split(\".\");\n const count = name.split(\".\").length;\n const newName = count >= before.length ? after.join(\".\") : after.slice(-count).join(\".\");\n if (module === undefined) return newName;\n const oldFile = splitResolved(old.resolved).file;\n const newModule = inModule(target.file.path, module)\n ? module\n : rewriteModule(module, oldFile, target.file.path);\n return `${written.startsWith(\"./\") ? \"./\" : \"\"}${newModule}#${newName}`;\n}\n\n/** A module path for `newFile` with as many segments as `module` had, and its extension style. */\nfunction rewriteModule(module: string, oldFile: string, newFile: string): string {\n const withoutExt = (p: string): string => p.replace(/\\.[^./]+$/, \"\");\n const hasExt = withoutExt(module) !== module && oldFile.endsWith(module);\n const target = hasExt ? newFile : withoutExt(newFile);\n const segments = module.split(\"/\").length;\n const all = target.split(\"/\");\n return segments >= all.length ? target : all.slice(-segments).join(\"/\");\n}\n\n/**\n * Ops that make the binding's `file` hint match `newFile`: an entry that named the old file is\n * replaced; a glob that matched it is moved with the rename map's `paths` or with the old file's\n * folder; an entry about other files (another partial part) is left alone.\n */\nfunction rewriteHints(\n spec: Spec,\n binding: Binding,\n oldFile: string | undefined,\n newFile: string,\n paths: Record<string, string> | undefined,\n): PatchOp[] {\n if (!binding.file) return [];\n const raw = readYaml(spec.source.frontmatter.text, [\"bindings\", binding.index, \"file\"]);\n const hints = typeof raw === \"string\" ? [raw] : Array.isArray(raw) ? (raw as unknown[]) : [];\n const matches = (hint: string, file: string): boolean => hint === file || globMatcher(hint)(file);\n if (hints.some((h) => typeof h === \"string\" && matches(h, newFile))) return [];\n const out: PatchOp[] = [];\n hints.forEach((hint, i) => {\n if (typeof hint !== \"string\") return;\n const matchedOld = oldFile !== undefined ? matches(hint, oldFile) : !matches(hint, newFile);\n if (!matchedOld) return;\n const next = moveHint(hint, oldFile, newFile, paths);\n if (next === hint) return;\n out.push({\n op: \"set\",\n path:\n typeof raw === \"string\"\n ? [\"bindings\", binding.index, \"file\"]\n : [\"bindings\", binding.index, \"file\", i],\n value: next,\n });\n });\n return out;\n}\n\nfunction moveHint(\n hint: string,\n oldFile: string | undefined,\n newFile: string,\n paths: Record<string, string> | undefined,\n): string {\n if (hint === oldFile || !/[*?[\\]{}!]/.test(hint)) return newFile;\n const mapped = Object.entries(paths ?? {})\n .filter(([from]) => from !== \"\" && hint.startsWith(from))\n .sort((a, b) => b[0].length - a[0].length)[0];\n if (mapped) {\n const moved = mapped[1] + hint.slice(mapped[0].length);\n if (globMatcher(moved)(newFile)) return moved;\n }\n if (oldFile !== undefined) {\n const from = `${posix.dirname(oldFile)}/`;\n const to = `${posix.dirname(newFile)}/`;\n if (hint.startsWith(from)) {\n const moved = to + hint.slice(from.length);\n if (globMatcher(moved)(newFile)) return moved;\n }\n }\n return newFile;\n}\n\n/**\n * The lock entry of a moved binding: the new location, and the new shape when it differs from the\n * accepted (locked) shape only by the name. Drift that was never accepted stays drift.\n */\nfunction moveLock(\n model: SpecModel,\n locks: Map<string, LockFile>,\n old: BaselineSymbol,\n target: SymbolEntry,\n files: string[] | undefined,\n): void {\n const lock = locks.get(old.spec) ?? model.locks.get(old.spec);\n if (!lock) return;\n const shape = shapeOf(target.symbol);\n const previous = lock.symbols[old.binding];\n const accepted = previous ? nameFreeFingerprint(previous.shape) : old.nameFree;\n const nameOnly = nameFreeFingerprint(shape) === accepted;\n const entry: LockedSymbol = {\n resolved: `${target.file.path}#${target.symbol.qualifiedName}`,\n ...(files ? { files } : {}),\n fingerprint: nameOnly ? fingerprintOf(shape) : (previous?.fingerprint ?? old.fingerprint),\n shape: nameOnly ? shape : (previous?.shape ?? old.shape),\n };\n locks.set(old.spec, { ...lock, symbols: { ...lock.symbols, [old.binding]: entry } });\n}\n\nfunction ambiguous(model: SpecModel, ambiguity: Ambiguity): Diagnostic[] {\n const names = ambiguity.candidates.map(\n (c) =>\n `${c.entry.symbol.qualifiedName} (${formatLocation(c.entry.file.path, c.entry.symbol.nameRange)}${c.score < 1 ? `, score ${c.score.toFixed(2)}` : \"\"})`,\n );\n return ambiguity.bindings.flatMap((old) => {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) return [];\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n return [\n createDiagnostic(\"CS0216\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n message: `binding \"${binding.id}\": can't tell where ${oldName} went${ambiguity.detail ? ` (${ambiguity.detail})` : \"\"}; candidates: ${listOf(names)}; the spec is not changed`,\n expected: oldName,\n actual: ambiguity.candidates.map(\n (c) => `${c.entry.file.path}#${c.entry.symbol.qualifiedName}`,\n ),\n suggestions: [\n {\n message: `name the rename in a map: { \"symbols\": { \"${oldName}\": \"<new name>\" } } and run \\`catspec sync --apply --map <file>\\``,\n },\n { message: \"or fix the binding's symbol by hand\" },\n ],\n }),\n ];\n });\n}\n\nfunction lostDiagnostics(model: SpecModel, lost: Lost): Diagnostic[] {\n return lost.bindings.flatMap((old) => {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) return [];\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n const best = lost.best\n ? `; the closest candidate, ${lost.best.entry.symbol.qualifiedName} (${formatLocation(lost.best.entry.file.path, lost.best.entry.symbol.nameRange)}), scores ${lost.best.score.toFixed(2)}, below heal.threshold`\n : \"\";\n return [\n createDiagnostic(\"CS0217\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n message: `binding \"${binding.id}\": ${oldName} is gone and nothing replaces it${lost.detail ? ` (${lost.detail})` : \"\"}${best}`,\n expected: oldName,\n actual: \"nothing\",\n suggestions: [\n { message: \"restore the code, add the rename to a map (--map), or change the spec\" },\n ],\n }),\n ];\n });\n}\n\ninterface Mention {\n line: number;\n column: number;\n /** Offset of the code span's content in the file. */\n offset: number;\n text: string;\n replacement: string;\n}\n\n/** Backticked mentions of renamed names in the spec body, outside fenced code blocks. */\nfunction mentionsOf(spec: Spec, renames: { from: string[]; to: string }[]): Mention[] {\n if (renames.length === 0) return [];\n const { body } = spec.source;\n const mentions: Mention[] = [];\n let fenced = false;\n let offset = body.start;\n for (const [i, line] of body.text.split(\"\\n\").entries()) {\n if (/^\\s*(```|~~~)/.test(line)) fenced = !fenced;\n else if (!fenced) {\n for (const match of line.matchAll(/`([^`\\n]+)`/g)) {\n const text = match[1]!;\n const replacement = replaceNames(text, renames);\n if (replacement === text) continue;\n mentions.push({\n line: body.line + i,\n column: match.index + 2,\n offset: offset + match.index + 1,\n text,\n replacement,\n });\n }\n }\n offset += line.length + 1;\n }\n return mentions;\n}\n\n/**\n * `text` with every old name replaced, whole words only, in one pass (a replacement is never\n * replaced again); at each place the longest (qualified) form wins.\n */\nfunction replaceNames(text: string, renames: { from: string[]; to: string }[]): string {\n const replacements = new Map<string, string>();\n for (const r of renames) {\n for (const from of r.from) {\n const count = from.split(\".\").length;\n const to = r.to.split(\".\");\n const next = count >= to.length ? r.to : to.slice(-count).join(\".\");\n if (from !== next && !replacements.has(from)) replacements.set(from, next);\n }\n }\n if (replacements.size === 0) return text;\n const names = [...replacements.keys()].sort((a, b) => b.length - a.length);\n return text.replace(wordPattern(names, \".\"), (name) => replacements.get(name) ?? name);\n}\n\n/** Writes the mention replacements into the body of `text` (the edited file). */\nfunction rewriteMentions(text: string, spec: Spec, mentions: Mention[]): string {\n const shift = text.length - spec.source.text.length;\n let body = text.slice(spec.source.body.start + shift);\n for (const m of [...mentions].reverse()) {\n const at = m.offset - spec.source.body.start;\n body = body.slice(0, at) + m.replacement + body.slice(at + m.text.length);\n }\n const frontmatter = text.slice(0, spec.source.body.start + shift);\n return frontmatter + body;\n}\n\n/** A `SpecPatch` for one edit, for diagnostics and the MCP layer. */\nexport const editPatch = (edit: SpecEdit): SpecPatch => ({ file: edit.spec.file, ops: edit.ops });\n","/**\n * Workflow profiles at work (plan §D17.1, §D17.4, §D17.5), PBIs `stage-resolution`, `gate-runner`\n * and `workflow-cli`: which features exist, where each feature and work item is in the workflow,\n * the gates, and `stage start|finish`.\n *\n * The current stage is derived, never stored (ADR-004): it is the first stage whose finish gates\n * don't pass yet or whose status its specs haven't reached. Deriving never runs `command:` gates.\n * CatSpec never performs a stage itself; it describes it, checks it and sets the status.\n */\nimport { execFile } from \"node:child_process\";\nimport { appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { checkCode, statusGate, testCommandArgs, type CheckResult } from \"../check.js\";\nimport type { Codebase } from \"../codebase.js\";\nimport { findGitCommonDir } from \"../config.js\";\nimport {\n compareStrings,\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n} from \"../diagnostics.js\";\nimport type { SpecModel } from \"../load.js\";\nimport { applyPatch } from \"../spec-editor.js\";\nimport type { SpecStatus } from \"../spec-schema.js\";\nimport type { Spec } from \"../spec.js\";\nimport { didYouMean, globMatcher, listOf } from \"../util.js\";\nimport {\n driverText,\n featureDirsText,\n featureFolderOf,\n gateName,\n type Driver,\n type Gate,\n type Stage,\n type Transition,\n type WorkflowProfile,\n} from \"./schema.js\";\nimport { findProgram, isBatchScript } from \"./doctor.js\";\n\n/** A workflow command that can't run: an unknown stage or target (a usage error). */\nexport class WorkflowError extends Error {}\n\nexport interface Feature {\n name: string;\n /** The feature folder, relative to the repository root. */\n dir: string;\n /** Its machine specs (valid, not the architecture spec), sorted by id. */\n specs: Spec[];\n}\n\n/** What a stage command is run for: a feature, or one spec (with its feature, if it has one). */\nexport interface Target {\n name: string;\n feature?: Feature;\n spec?: Spec;\n}\n\nexport type Phase = \"start\" | \"finish\";\n\nexport interface GateResult {\n gate: string;\n passed: boolean;\n /** A `command:` gate that wasn't run (`allow_commands` false): CS0706, doesn't block. */\n skipped?: boolean;\n /** Why it failed or was skipped, or what it checked. */\n detail: string;\n /** The diagnostics behind a failure (the underlying check). */\n diagnostics: Diagnostic[];\n}\n\n/** How a command gate runs; replaced in tests. */\nexport type CommandRunner = (\n root: string,\n args: string[],\n) => Promise<{ exitCode: number; output: string }>;\n\nexport interface WorkflowOptions {\n now?: Date;\n runCommand?: CommandRunner;\n}\n\nconst STATUS_RANK: Record<SpecStatus, number> = {\n draft: 0,\n ready: 1,\n \"in-progress\": 2,\n implemented: 3,\n deprecated: 4,\n};\n\n/** True when `status` is `target` or a later status. */\nexport const reached = (status: SpecStatus, target: SpecStatus): boolean =>\n STATUS_RANK[status] >= STATUS_RANK[target];\n\n/** The status a stage sets: at finish, else at start. */\nexport const stageStatus = (stage: Stage): SpecStatus | undefined =>\n stage.finish.status ?? stage.start.status;\n\n/**\n * A repository seen through its workflow profile: features, targets, gates and stage positions.\n * Check results are computed once per set of specs.\n */\nexport class Workflow {\n readonly features: Feature[];\n private readonly checks = new Map<string, Promise<CheckResult>>();\n\n constructor(\n readonly model: SpecModel,\n readonly codebase: Codebase,\n readonly profile: WorkflowProfile,\n /** Every file of the repository (root-relative POSIX paths). */\n readonly files: readonly string[],\n readonly options: WorkflowOptions = {},\n ) {\n const byName = new Map<string, Feature>();\n for (const file of files) {\n const folder = featureFolderOf(profile.featureDirs, file);\n if (!folder) continue;\n if (profile.notFeatures.includes(folder.name) || byName.has(folder.name)) continue;\n byName.set(folder.name, { ...folder, specs: [] });\n }\n for (const spec of this.specs()) {\n const feature = this.featureNameOf(spec);\n if (feature !== undefined) byName.get(feature)?.specs.push(spec);\n }\n this.features = [...byName.values()].sort((a, b) => compareStrings(a.name, b.name));\n }\n\n /** The work items: valid specs other than the architecture spec, sorted by id. */\n specs(): Spec[] {\n return this.model.specs.all().filter((s) => s.valid && s.type !== \"architecture\");\n }\n\n feature(name: string): Feature | undefined {\n return this.features.find((f) => f.name === name);\n }\n\n private featureNameOf(spec: Spec): string | undefined {\n const name = featureFolderOf(this.profile.featureDirs, spec.file)?.name;\n return name !== undefined && !this.profile.notFeatures.includes(name) ? name : undefined;\n }\n\n /** The feature a spec belongs to: the feature folder it is in. */\n featureOf(spec: Spec): Feature | undefined {\n const name = this.featureNameOf(spec);\n return name === undefined ? undefined : this.feature(name);\n }\n\n stage(id: string): Stage {\n const stage = this.profile.stages.find((s) => s.id === id);\n if (stage) return stage;\n const ids = this.profile.stages.map((s) => s.id);\n const close = didYouMean(id, ids);\n throw new WorkflowError(\n `no stage \"${id}\" in the workflow (${listOf(ids)})` +\n (close.length > 0 ? `; did you mean \"${close[0]}\"?` : \"\"),\n );\n }\n\n /** A feature name or a spec id; a feature wins when a name is both. */\n target(name: string): Target {\n const feature = this.feature(name);\n if (feature) return { name, feature };\n const spec = this.model.specs.get(name);\n if (spec && spec.type !== \"architecture\") {\n const owner = this.featureOf(spec);\n return { name, spec, ...(owner ? { feature: owner } : {}) };\n }\n const close = didYouMean(name, [\n ...this.features.map((f) => f.name),\n ...this.model.specs.byId.keys(),\n ]);\n throw new WorkflowError(\n `\"${name}\" is neither a feature (a folder ${featureDirsText(this.profile)}) nor a spec id` +\n (close.length > 0 ? `; did you mean ${close.map((c) => `\"${c}\"`).join(\", \")}?` : \"\"),\n );\n }\n\n /**\n * True for a per-spec stage before the one that sets `implemented`: aggregate specs (plan\n * §D17.1) have no work of their own, so they skip it and go straight to that stage.\n */\n skipsAggregates(stage: Stage): boolean {\n if (stage.per !== \"spec\") return false;\n const stages = this.profile.stages;\n const final = stages.findIndex(\n (s) => s.start.status === \"implemented\" || s.finish.status === \"implemented\",\n );\n return final >= 0 && stages.indexOf(stage) < final;\n }\n\n /** The specs a stage runs on for a target. */\n scope(stage: Stage, target: Target): { feature?: Feature; specs: Spec[] } {\n if (stage.per === \"spec\") {\n if (target.spec?.aggregate && this.skipsAggregates(stage)) {\n throw new WorkflowError(\n `\"${target.name}\" is an aggregate spec: it has no stage \"${stage.id}\" of its own; ` +\n \"it is closed once its dependencies are implemented\",\n );\n }\n const specs = target.spec ? [target.spec] : (target.feature?.specs ?? []);\n return {\n ...(target.feature ? { feature: target.feature } : {}),\n specs: specs.filter(\n (s) => s.status !== \"deprecated\" && !(s.aggregate && this.skipsAggregates(stage)),\n ),\n };\n }\n if (!target.feature) {\n throw new WorkflowError(\n `stage \"${stage.id}\" runs per feature, and spec \"${target.name}\" isn't in a feature folder (${featureDirsText(this.profile)})`,\n );\n }\n return {\n feature: target.feature,\n specs: target.feature.specs.filter((s) => s.status !== \"deprecated\"),\n };\n }\n\n /** The check of `ids` as if implemented, computed once. */\n check(ids: readonly string[]): Promise<CheckResult> {\n const key = [...ids].sort(compareStrings).join(\"\\0\");\n let result = this.checks.get(key);\n if (!result) {\n result = checkCode(this.model, this.codebase, {\n specs: ids,\n mode: \"full\",\n ...(this.options.now ? { now: this.options.now } : {}),\n });\n this.checks.set(key, result);\n }\n return result;\n }\n\n /** Path templates with the placeholders filled in; `{spec}` repeats for every spec. */\n expand(template: string, feature: Feature | undefined, specs: readonly Spec[]): string[] {\n const base = template\n .replaceAll(\"{feature_dir}\", feature?.dir ?? \"\")\n .replaceAll(\"{feature}\", feature?.name ?? \"\");\n return base.includes(\"{spec}\") ? specs.map((s) => base.replaceAll(\"{spec}\", s.id)) : [base];\n }\n\n /** The files a template names that exist: a plain path, or every match of a glob. */\n existing(path: string): string[] {\n if (!/[*?[\\]{}]/.test(path)) return this.files.includes(path) ? [path] : [];\n const matches = globMatcher(path);\n return this.files.filter((f) => matches(f));\n }\n\n // Gates -----------------------------------------------------------------------------------\n\n /**\n * Runs one gate for a stage over `specs` (of `feature`). `commands`: run `command:` gates\n * (with `allow_commands`), else report them skipped.\n */\n async gate(\n gate: Gate,\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult> {\n const ids = specs.map((s) => s.id);\n const name = gateName(gate);\n const result = (passed: boolean, detail: string, diagnostics: Diagnostic[] = []) => ({\n gate: name,\n passed,\n detail,\n diagnostics,\n });\n if (typeof gate !== \"string\") return this.commandGate(gate.command, feature, specs, commands);\n\n switch (gate) {\n case \"specs_valid\": {\n const inFeature = (file: string | undefined) =>\n feature !== undefined && file !== undefined && file.startsWith(`${feature.dir}/`);\n const errors = this.model.diagnostics.filter(\n (d) =>\n d.severity === \"error\" &&\n ((d.spec !== undefined && ids.includes(d.spec)) || inFeature(d.specLocation?.file)),\n );\n return errors.length === 0\n ? result(true, `${ids.length} spec(s) valid`)\n : result(\n false,\n `${errors.length} spec error(s); run \\`catspec check --specs-only\\``,\n errors,\n );\n }\n case \"artifacts\": {\n const missing: string[] = [];\n for (const template of stage.produces) {\n for (const path of this.expand(template, feature, specs)) {\n const found = [];\n for (const file of this.existing(path)) {\n const content = await this.model.source.read(file);\n if (content && content.toString(\"utf8\").trim().length > 0) found.push(file);\n }\n if (found.length === 0) missing.push(path);\n }\n }\n return missing.length === 0\n ? result(true, stage.produces.length > 0 ? \"every artifact exists\" : \"nothing to produce\")\n : result(false, `missing or empty: ${listOf(missing)}`);\n }\n case \"contracts_declared\": {\n if (specs.length === 0) return result(false, \"no machine spec (*.spec.md) yet\");\n const empty = specs.filter(\n (s) =>\n !s.aggregate && s.bindings.length === 0 && !s.rules.some((r) => r.class !== \"manual\"),\n );\n return empty.length === 0\n ? result(true, \"every spec declares a contract\")\n : result(false, `no binding or enforceable rule in ${listOf(empty.map((s) => s.id))}`);\n }\n case \"deps_known\": {\n const unknown = specs.flatMap((s) =>\n s.dependsOn.filter((d) => !this.model.specs.get(d)).map((d) => `${s.id} → ${d}`),\n );\n const errors = this.model.diagnostics.filter(\n (d) => d.code === \"CS0104\" && d.spec !== undefined && ids.includes(d.spec),\n );\n return unknown.length === 0\n ? result(true, \"every dependency exists\")\n : result(false, `unknown dependencies: ${listOf(unknown)}`, errors);\n }\n case \"deps_ready\": {\n // For a stage over a whole feature, dependencies inside the feature move together.\n const inScope = new Set(stage.per === \"feature\" ? ids : []);\n const problems: string[] = [];\n const diagnostics: Diagnostic[] = [];\n const deps = [...new Set(specs.flatMap((s) => s.dependsOn))]\n .filter((d) => !inScope.has(d))\n .sort(compareStrings);\n for (const dep of deps) {\n const other = this.model.specs.get(dep);\n if (!other) problems.push(`${dep} does not exist`);\n else if (other.status !== \"implemented\") {\n problems.push(`${dep} is ${other.status}, not implemented`);\n } else {\n const check = await this.check([dep]);\n const errors = check.diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n problems.push(`${dep} is implemented but its contracts fail`);\n diagnostics.push(...errors);\n }\n }\n }\n return problems.length === 0\n ? result(true, deps.length > 0 ? `${listOf(deps)} implemented` : \"no dependencies\")\n : result(false, listOf(problems), diagnostics);\n }\n case \"contracts_pass\": {\n if (ids.length === 0) return result(true, \"no spec to check\");\n const check = await this.check(ids);\n const errors = check.diagnostics.filter((d) => d.severity === \"error\");\n const waiting = specs.flatMap((s) =>\n s.aggregate\n ? s.dependsOn\n .filter((d) => this.model.specs.get(d)?.status !== \"implemented\")\n .map((d) => `${s.id} waits for ${d} to be implemented`)\n : [],\n );\n const failing = [...new Set(errors.flatMap((d) => (d.spec ? [d.spec] : [])))].sort(\n compareStrings,\n );\n if (errors.length === 0 && waiting.length === 0) {\n return result(true, `${listOf(ids)}: DONE`);\n }\n const parts = [\n ...(failing.length > 0\n ? [`contracts fail in ${listOf(failing)} (run \\`catspec check --spec <id>\\`)`]\n : errors.length > 0\n ? [`${errors.length} error(s)`]\n : []),\n ...waiting,\n ];\n return result(false, parts.join(\"; \"), errors);\n }\n case \"tasks_done\": {\n const open: string[] = [];\n if (stage.per === \"spec\") {\n for (const spec of specs) {\n const count = spec.body.tasks.filter((t) => !t.done).length;\n if (count > 0) open.push(`${spec.id}: ${count} open task(s) in ${spec.file}`);\n }\n } else if (feature) {\n const file = `${feature.dir}/tasks.md`;\n const text = (await this.model.source.read(file))?.toString(\"utf8\");\n const count = text === undefined ? 0 : openCheckboxes(text);\n if (count > 0) open.push(`${count} open task(s) in ${file}`);\n }\n return open.length === 0\n ? result(true, \"every task is ticked\")\n : result(false, listOf(open));\n }\n case \"no_drift\": {\n if (ids.length === 0) return result(true, \"no spec to check\");\n const check = await this.check(ids);\n const drift = check.diagnostics.filter((d) => d.code === \"CS0300\" && d.severity !== \"info\");\n return drift.length === 0\n ? result(true, \"no drift\")\n : result(\n false,\n `drift in ${listOf([...new Set(drift.map((d) => d.spec ?? \"?\"))])}; run \\`catspec accept <id>\\` for an intended change`,\n drift,\n );\n }\n case \"adr_valid\": {\n const architecture = this.model.architecture;\n const errors = this.model.diagnostics.filter(\n (d) =>\n d.severity === \"error\" &&\n (d.code === \"CS0107\" ||\n d.code === \"CS0112\" ||\n (architecture !== undefined &&\n (d.spec === architecture.id || d.specLocation?.file === architecture.file))),\n );\n return errors.length === 0 && architecture\n ? result(true, `${architecture.file} is valid`)\n : result(\n false,\n architecture ? `${errors.length} error(s) in the ADR log` : \"no ADR log\",\n errors,\n );\n }\n }\n }\n\n private async commandGate(\n command: string,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult> {\n const gate = `command: ${command}`;\n const args = testCommandArgs(command).flatMap((arg) =>\n arg.includes(\"{spec}\")\n ? specs.map((s) => this.expand(arg, feature, [s])[0]!)\n : this.expand(arg, feature, specs),\n );\n if (!commands) {\n return { gate, passed: true, skipped: true, detail: \"not run\", diagnostics: [] };\n }\n if (!this.profile.allowCommands) {\n return {\n gate,\n passed: true,\n skipped: true,\n detail: \"not run: workflow.allow_commands is false\",\n diagnostics: [\n createDiagnostic(\"CS0706\", {\n message: `the gate \\`${args.join(\" \")}\\` was not run: workflow.allow_commands is false`,\n actual: args,\n suggestions: [\n { message: \"run it yourself, or set workflow.allow_commands: true in catspec.yaml\" },\n ],\n }),\n ],\n };\n }\n const run = await (this.options.runCommand ?? runCommand)(this.model.root, args);\n return run.exitCode === 0\n ? { gate, passed: true, detail: `\\`${args.join(\" \")}\\` exited with 0`, diagnostics: [] }\n : {\n gate,\n passed: false,\n detail: `\\`${args.join(\" \")}\\` exited with ${run.exitCode}${run.output ? `:\\n${run.output}` : \"\"}`,\n diagnostics: [],\n };\n }\n\n /** Runs the gates of a transition. */\n async gates(\n transition: Transition,\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult[]> {\n const results: GateResult[] = [];\n for (const gate of transition.gates) {\n results.push(await this.gate(gate, stage, feature, specs, commands));\n }\n return results;\n }\n\n // Stage resolution ------------------------------------------------------------------------\n\n /** True when a stage is done for these specs: finish gates pass and its status is reached. */\n async done(stage: Stage, feature: Feature | undefined, all: readonly Spec[]): Promise<boolean> {\n const specs = this.skipsAggregates(stage) ? all.filter((s) => !s.aggregate) : all;\n const status = stageStatus(stage);\n if (status !== undefined && !specs.every((s) => reached(s.status, status))) return false;\n if (stage.per === \"spec\" && specs.length === 0) return true;\n const results = await this.gates(stage.finish, stage, feature, specs, false);\n return results.every((r) => r.passed);\n }\n\n /** Where a feature is: its current stage, and each work item's stage. */\n async position(feature: Feature): Promise<FeaturePosition> {\n const stages = this.profile.stages;\n const specs = feature.specs.filter((s) => s.status !== \"deprecated\");\n for (const [index, stage] of stages.entries()) {\n if (stage.per === \"feature\") {\n if (await this.done(stage, feature, specs)) continue;\n return { feature: feature.name, dir: feature.dir, stage, items: [] };\n }\n // A run of per-spec stages: each work item is at its own stage.\n let end = index;\n while (end < stages.length && stages[end]!.per === \"spec\") end++;\n const run = stages.slice(index, end);\n const items: ItemPosition[] = [];\n for (const spec of specs) items.push(await this.item(spec, run));\n const first = run.find((s) => items.some((i) => i.stage === s.id));\n if (first) return { feature: feature.name, dir: feature.dir, stage: first, items };\n }\n return { feature: feature.name, dir: feature.dir, items: [] };\n }\n\n /** A work item's stage among a run of per-spec stages, and whether it can start. */\n async item(spec: Spec, run: readonly Stage[]): Promise<ItemPosition> {\n const feature = this.featureOf(spec);\n let current: Stage | undefined;\n for (const stage of run) {\n if (!(await this.done(stage, feature, [spec]))) {\n current = stage;\n break;\n }\n }\n const waitingOn = spec.dependsOn\n .filter((d) => this.model.specs.get(d)?.status !== \"implemented\")\n .sort(compareStrings);\n const state: ItemPosition[\"state\"] = !current\n ? \"done\"\n : spec.status === \"in-progress\"\n ? \"in-progress\"\n : waitingOn.length > 0\n ? \"waiting\"\n : \"ready\";\n return {\n spec: spec.id,\n status: spec.status,\n ...(current ? { stage: current.id } : {}),\n state,\n waitingOn: state === \"waiting\" ? waitingOn : [],\n };\n }\n\n /** The per-spec stages from a stage's run (the stages a work item goes through). */\n private specRun(stage: Stage): Stage[] {\n const stages = this.profile.stages;\n let start = stages.indexOf(stage);\n while (start > 0 && stages[start - 1]!.per === \"spec\") start--;\n let end = stages.indexOf(stage);\n while (end < stages.length && stages[end]!.per === \"spec\") end++;\n return stages.slice(start, end);\n }\n\n /** What to do next for a feature or a work item (`catspec next`, MCP `next_step`). */\n async next(name: string): Promise<NextStep> {\n const target = this.target(name);\n const spec = target.spec;\n if (!spec) {\n const feature = target.feature!;\n const position = await this.position(feature);\n return this.describeNext(name, feature, position.stage, position.items, feature.specs);\n }\n // One work item: the first stage not done for its feature (per-feature stages) or for it.\n const feature = target.feature;\n const all = feature?.specs.filter((s) => s.status !== \"deprecated\") ?? [];\n for (const stage of this.profile.stages) {\n if (stage.per === \"feature\") {\n if (!feature || (await this.done(stage, feature, all))) continue;\n return this.describeNext(name, feature, stage, [], [spec]);\n }\n if (await this.done(stage, feature, [spec])) continue;\n const item = await this.item(spec, this.specRun(stage));\n return this.describeNext(name, feature, stage, [item], [spec]);\n }\n const item = await this.item(spec, []);\n return this.describeNext(name, feature, undefined, [item], [spec]);\n }\n\n private describeNext(\n target: string,\n feature: Feature | undefined,\n stage: Stage | undefined,\n items: ItemPosition[],\n specs: readonly Spec[],\n ): NextStep {\n if (!stage) {\n return { target, ...(feature ? { feature: feature.name } : {}), done: true, items };\n }\n const index = this.profile.stages.indexOf(stage);\n const inputs = [\n ...this.profile.context.filter((f) => this.files.includes(f)),\n ...this.profile.stages\n .slice(0, index)\n .flatMap((s) => s.produces.flatMap((t) => this.expand(t, feature, specs)))\n .flatMap((p) => this.existing(p)),\n ...(stage.per === \"spec\" ? specs.map((s) => s.file) : []),\n ];\n return {\n target,\n ...(feature ? { feature: feature.name } : {}),\n done: false,\n stage: describeStage(stage),\n inputs: [...new Set(inputs)],\n produces: stage.produces.flatMap((t) => this.expand(t, feature, specs)),\n items,\n };\n }\n\n /**\n * The stages before `stage` that aren't done for the target (CS0705): earlier per-feature stages\n * for the feature, earlier per-spec stages for each spec.\n */\n private async outOfOrder(\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n ): Promise<string[]> {\n const pending: string[] = [];\n for (const earlier of this.profile.stages.slice(0, this.profile.stages.indexOf(stage))) {\n if (earlier.per === \"feature\") {\n if (!feature) continue;\n const all = feature.specs.filter((s) => s.status !== \"deprecated\");\n if (!(await this.done(earlier, feature, all))) pending.push(earlier.id);\n } else {\n const behind = [];\n for (const spec of specs) {\n if (!(await this.done(earlier, this.featureOf(spec), [spec]))) behind.push(spec.id);\n }\n if (behind.length > 0) pending.push(`${earlier.id} (${listOf(behind)})`);\n }\n }\n return pending;\n }\n\n /**\n * `catspec stage start|finish <stage> <target>`: checks the order (CS0705) and the gates\n * (CS0701, CS0702), then works out the status change. Nothing is written: `writeStage` does\n * that. With `force`, failures become warnings and the run is marked forced; `implemented` is\n * still never set while a spec's contracts fail.\n */\n async run(\n phase: Phase,\n stageId: string,\n targetName: string,\n options: { force?: boolean } = {},\n ): Promise<StageRun> {\n const stage = this.stage(stageId);\n const target = this.target(targetName);\n const { feature, specs } = this.scope(stage, target);\n const force = Boolean(options.force);\n const transition = stage[phase];\n const diagnostics: Diagnostic[] = [];\n const where = `${stage.id} ${targetName}`;\n const failCode = phase === \"start\" ? \"CS0701\" : \"CS0702\";\n\n const pending = await this.outOfOrder(stage, feature, specs);\n if (pending.length > 0) {\n diagnostics.push(\n createDiagnostic(\"CS0705\", {\n ...(force ? { severity: \"warning\" as const } : {}),\n message: `stage \"${stage.id}\" for \"${targetName}\" is out of order: ${listOf(pending)} not done yet`,\n expected: \"every earlier stage done\",\n actual: pending,\n suggestions: [\n {\n message: `run \\`catspec next ${feature?.name ?? targetName}\\` to see the current stage`,\n },\n ],\n }),\n );\n }\n\n const gates = await this.gates(transition, stage, feature, specs, true);\n for (const gate of gates) {\n diagnostics.push(...gate.diagnostics.filter((d) => d.code === \"CS0706\"));\n if (gate.passed) continue;\n diagnostics.push(\n createDiagnostic(failCode, {\n ...(force ? { severity: \"warning\" as const } : {}),\n message: `stage \"${stage.id}\" can't ${phase} for \"${targetName}\": gate ${gate.gate} failed: ${gate.detail}`,\n expected: gate.gate,\n actual: gate.detail,\n suggestions: [{ message: `fix it, then run \\`catspec stage ${phase} ${where}\\` again` }],\n }),\n ...gate.diagnostics,\n );\n }\n\n const blocked = diagnostics.some((d) => d.severity === \"error\");\n const changes: StatusChange[] = [];\n if (transition.status !== undefined && !blocked) {\n const status = transition.status;\n const inScope = new Set(specs.map((s) => s.id));\n for (const spec of specs) {\n if (reached(spec.status, status)) continue;\n // Dependencies inside a per-feature stage move together; statusGate checks the rest.\n const outside: Spec =\n stage.per === \"feature\"\n ? { ...spec, dependsOn: spec.dependsOn.filter((d) => !inScope.has(d)) }\n : spec;\n const gate = await statusGate(this.model, this.codebase, outside, status, {\n force,\n ...(this.options.now ? { now: this.options.now } : {}),\n });\n if (!gate.allowed) {\n diagnostics.push(...gate.diagnostics);\n continue;\n }\n changes.push({\n spec: spec.id,\n file: spec.file,\n from: spec.status,\n to: status,\n text: applyPatch(spec.source, [{ op: \"set\", path: [\"status\"], value: status }]),\n });\n }\n }\n\n const ok = !diagnostics.some((d) => d.severity === \"error\");\n return {\n phase,\n stage: describeStage(stage),\n target: targetName,\n ...(feature ? { feature: feature.name } : {}),\n specs: specs.map((s) => s.id),\n gates: gates.map(({ gate, passed, skipped, detail }) => ({\n gate,\n passed,\n ...(skipped ? { skipped } : {}),\n detail,\n })),\n produces: stage.produces.flatMap((t) => this.expand(t, feature, specs)),\n ok,\n forced:\n ok && force && diagnostics.some((d) => d.severity === \"warning\" && FORCED.has(d.code)),\n changes: ok ? changes : [],\n diagnostics: sortDiagnostics(diagnostics),\n };\n }\n}\n\nconst FORCED = new Set([\"CS0701\", \"CS0702\", \"CS0705\"]);\n\n/** Open checkboxes (`- [ ]`) in a Markdown file, outside code fences. */\nexport function openCheckboxes(markdown: string): number {\n let fenced = false;\n let count = 0;\n for (const line of markdown.split(/\\r?\\n/)) {\n if (/^\\s*(```|~~~)/.test(line)) fenced = !fenced;\n else if (!fenced && /^\\s*(?:[-*+]|\\d+[.)])\\s+\\[ \\]/.test(line)) count++;\n }\n return count;\n}\n\nexport interface StageInfo {\n id: string;\n per: Stage[\"per\"];\n driver: Driver;\n /** The driver in words: \"skill sdd-plan\", \"slash command /opsx:apply\". */\n driverText: string;\n start: { gates: string[]; status?: SpecStatus };\n finish: { gates: string[]; status?: SpecStatus };\n}\n\nexport const describeStage = (stage: Stage): StageInfo => ({\n id: stage.id,\n per: stage.per,\n driver: stage.driver,\n driverText: driverText(stage.driver),\n start: {\n gates: stage.start.gates.map(gateName),\n ...(stage.start.status ? { status: stage.start.status } : {}),\n },\n finish: {\n gates: stage.finish.gates.map(gateName),\n ...(stage.finish.status ? { status: stage.finish.status } : {}),\n },\n});\n\nexport interface ItemPosition {\n spec: string;\n status: SpecStatus;\n /** Its current stage; absent when it went through every stage. */\n stage?: string;\n /** ready: can start; waiting: on dependencies not implemented yet. */\n state: \"ready\" | \"waiting\" | \"in-progress\" | \"done\";\n waitingOn: string[];\n}\n\nexport interface FeaturePosition {\n feature: string;\n dir: string;\n /** The current stage; absent when the feature went through every stage. */\n stage?: Stage;\n /** Each work item's stage, while the current stage runs per spec. */\n items: ItemPosition[];\n}\n\nexport interface NextStep {\n target: string;\n feature?: string;\n /** Every stage is done. */\n done: boolean;\n stage?: StageInfo;\n /** Files to read first: the earlier stages' artifacts, the work items, extra context. */\n inputs?: string[];\n /** Files the stage must leave behind. */\n produces?: string[];\n items: ItemPosition[];\n}\n\nexport interface StatusChange {\n spec: string;\n file: string;\n from: SpecStatus;\n to: SpecStatus;\n /** The spec file with the new status. */\n text: string;\n}\n\nexport interface StageRun {\n phase: Phase;\n stage: StageInfo;\n target: string;\n feature?: string;\n specs: string[];\n gates: { gate: string; passed: boolean; skipped?: boolean; detail: string }[];\n produces: string[];\n /** No errors: the stage may start or finish. */\n ok: boolean;\n /** `--force` let failing gates or the order through. */\n forced: boolean;\n /** Status changes to write (none unless `ok`). */\n changes: StatusChange[];\n diagnostics: Diagnostic[];\n}\n\n/**\n * Writes a stage run's status changes, and logs a forced run in the runtime store\n * (`<git-common-dir>/catspec/workflow-overrides.log`, ADR-004).\n */\nexport async function writeStage(root: string, run: StageRun, now = new Date()): Promise<void> {\n for (const change of run.changes) await writeFile(join(root, change.file), change.text, \"utf8\");\n if (!run.forced) return;\n const common = findGitCommonDir(root);\n if (!common) return;\n const dir = join(common, \"catspec\");\n await mkdir(dir, { recursive: true });\n const entry = {\n at: now.toISOString(),\n phase: run.phase,\n stage: run.stage.id,\n target: run.target,\n overridden: run.diagnostics\n .filter((d) => FORCED.has(d.code))\n .map((d) => `${d.code} ${d.message}`),\n };\n await appendFile(join(dir, \"workflow-overrides.log\"), `${JSON.stringify(entry)}\\n`, \"utf8\");\n}\n\n/**\n * Runs a `command:` gate without a shell (ADR-009). On Windows the program is looked up with\n * PATHEXT; a batch script (`.cmd`, `.bat`, e.g. an npm shim) can't start without a shell, so the\n * gate fails with a message saying so.\n */\nexport function runCommand(\n root: string,\n args: string[],\n timeoutMs = 10 * 60_000,\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<{ exitCode: number; output: string }> {\n const [file, ...rest] = args;\n const found = platform === \"win32\" ? findProgram(file!, root, env, platform) : undefined;\n if (found && isBatchScript(found)) {\n return Promise.resolve({\n exitCode: 1,\n output:\n `${file} is the batch script ${found}, which CatSpec can't start without a shell ` +\n \"(ADR-009); run the command yourself, or point the gate at the program it wraps\",\n });\n }\n return new Promise((resolve) => {\n execFile(\n found ?? file!,\n rest,\n { cwd: root, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, windowsHide: true },\n (error, stdout, stderr) => {\n const output = `${stdout}${stderr}`.trim().split(/\\r?\\n/).slice(-20).join(\"\\n\");\n const code = error ? (typeof error.code === \"number\" ? error.code : 1) : 0;\n resolve({ exitCode: code, output: error && !output ? error.message : output });\n },\n );\n });\n}\n","/**\n * `catspec workflow doctor`, `workflow snippet` and preset detection (plan §D17.3, §D17.5), PBIs\n * `workflow-cli`, `workflow-presets` and `workflow-hook`: checks that the workflow fits the\n * repository, prints the lines to paste into a skill, finds an existing SDD workflow for\n * `catspec init`, and the final gates the pre-commit hook re-checks (CS0703).\n */\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { delimiter, isAbsolute, join } from \"node:path\";\n\nimport { LineCounter, parseDocument } from \"yaml\";\n\nimport {\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n type Location,\n} from \"../diagnostics.js\";\nimport type { SpecModel } from \"../load.js\";\nimport { locate } from \"../schema-issues.js\";\nimport type { Spec } from \"../spec.js\";\nimport { testCommandArgs } from \"../check.js\";\nimport { listOf } from \"../util.js\";\nimport {\n gateName,\n SDD_SKILLS,\n type BuiltinGate,\n type PresetName,\n type Stage,\n type Transition,\n type WorkflowProfile,\n} from \"./schema.js\";\n\n/** Where a `workflow.stages[i]` key is in the config file, when the config lists the stages. */\nfunction configLocator(\n configFile: { path: string; text: string } | undefined,\n): (path: (string | number)[]) => Location | undefined {\n if (!configFile) return () => undefined;\n const lineCounter = new LineCounter();\n const doc = parseDocument(configFile.text, { lineCounter });\n return (path) => {\n if (!doc.hasIn([\"workflow\", ...path.slice(0, 2)])) return undefined;\n const range = locate(doc, [\"workflow\", ...path]);\n if (!range) return undefined;\n const { line, col } = lineCounter.linePos(range.start);\n return { file: configFile.path, line, column: col };\n };\n}\n\n/**\n * Where a program is: a path (relative to `root`), or the first match on PATH, with the PATHEXT\n * extensions on Windows. Undefined when it isn't found.\n */\nexport function findProgram(\n name: string,\n root: string,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n): string | undefined {\n if (name.includes(\"/\") || name.includes(\"\\\\\")) {\n const path = isAbsolute(name) ? name : join(root, name);\n return existsSync(path) ? path : undefined;\n }\n const extensions =\n platform === \"win32\"\n ? [\"\", ...(env.PATHEXT ?? \".EXE;.CMD;.BAT;.COM\").split(\";\").map((e) => e.toLowerCase())]\n : [\"\"];\n const dirs = (env.PATH ?? env.Path ?? \"\").split(delimiter).filter(Boolean);\n for (const dir of dirs) {\n for (const ext of extensions) {\n const file = join(dir, name + ext);\n try {\n if (statSync(file).isFile()) return file;\n } catch {\n // not here\n }\n }\n }\n return undefined;\n}\n\n/** True when `name` is a program on PATH (or a path to a file). */\nexport const onPath = (name: string, root: string, env: NodeJS.ProcessEnv = process.env): boolean =>\n findProgram(name, root, env) !== undefined;\n\n/**\n * A Windows batch script (`.cmd`, `.bat`, e.g. an npm shim): Node can't start one without a\n * shell, and CatSpec runs commands without one (ADR-009).\n */\nexport const isBatchScript = (path: string): boolean => /\\.(cmd|bat)$/i.test(path);\n\n/** Where agent skills usually live: Claude Code's folder, then the one shared by all agents. */\nexport const SKILL_DIRS = [\".claude/skills\", \".agents/skills\"] as const;\n\n/** The `sdd-*` skill folders of a skills folder, sorted. */\nconst sddSkillsIn = (root: string, skillsDir: string): string[] => {\n const dir = join(root, skillsDir);\n return existsSync(dir)\n ? readdirSync(dir)\n .filter((n) => n.startsWith(\"sdd-\"))\n .sort()\n : [];\n};\n\n/** The first of `SKILL_DIRS` with `sdd-*` skills, and those skills. */\nexport function findSddSkills(root: string): { skillsDir: string; skills: string[] } | undefined {\n for (const skillsDir of SKILL_DIRS) {\n const skills = sddSkillsIn(root, skillsDir);\n if (skills.length > 0) return { skillsDir, skills };\n }\n return undefined;\n}\n\n/**\n * The SDD workflow a repository already uses, by what is on disk (plan §D17.3). `sdd-*` skills\n * are looked for in `skillsDir`, or in each of `SKILL_DIRS` without it.\n */\nexport function detectPreset(root: string, skillsDir?: string): PresetName | undefined {\n if (existsSync(join(root, \"openspec\"))) return \"openspec\";\n if (existsSync(join(root, \".specify\"))) return \"spec-kit\";\n const found = skillsDir ? sddSkillsIn(root, skillsDir).length > 0 : findSddSkills(root);\n return found ? \"custom\" : undefined;\n}\n\n/** The skill file a `skill:` driver needs. */\nexport const skillFile = (profile: WorkflowProfile, name: string): string =>\n `${profile.skillsDir}/${name}/SKILL.md`;\n\n/**\n * `catspec workflow doctor`: every skill exists (CS0704), every command is on PATH (CS0704), and\n * the preset matches the repository (CS0700 warnings).\n */\nexport function workflowDoctor(\n root: string,\n profile: WorkflowProfile,\n options: { configFile?: { path: string; text: string }; env?: NodeJS.ProcessEnv } = {},\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const at = configLocator(options.configFile);\n const location = (path: (string | number)[]) => {\n const found = at(path);\n return found ? { specLocation: found } : {};\n };\n for (const [index, stage] of profile.stages.entries()) {\n const driver = stage.driver;\n if (driver.kind === \"skill\") {\n const file = skillFile(profile, driver.name);\n if (!existsSync(join(root, file))) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...location([\"stages\", index, \"driver\", \"skill\"]),\n message: `stage \"${stage.id}\": skill ${driver.name} not found; expected ${file}`,\n expected: file,\n actual: driver.name,\n suggestions: [\n {\n message: `create ${file}, fix the skill name, or set workflow.skills_dir in catspec.yaml`,\n },\n ],\n }),\n );\n }\n } else if (driver.kind === \"command\") {\n const program = testCommandArgs(driver.command)[0]!;\n if (!onPath(program, root, options.env)) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...location([\"stages\", index, \"driver\", \"command\"]),\n message: `stage \"${stage.id}\": command ${program} is not installed (not on PATH)`,\n actual: program,\n suggestions: [{ message: `install ${program}, or change the stage's driver` }],\n }),\n );\n }\n }\n for (const phase of [\"start\", \"finish\"] as const) {\n for (const [g, gate] of stage[phase].gates.entries()) {\n if (typeof gate === \"string\") continue;\n const program = testCommandArgs(gate.command)[0]!;\n const found = findProgram(program, root, options.env);\n if (found && process.platform === \"win32\" && isBatchScript(found)) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n severity: \"warning\",\n ...location([\"stages\", index, phase, \"gates\", g]),\n message: `stage \"${stage.id}\": the ${phase} gate \\`${gate.command}\\` would start ${found}, a batch script, which CatSpec can't run without a shell; run the command yourself`,\n actual: found,\n }),\n );\n continue;\n }\n if (found) continue;\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...(profile.allowCommands ? {} : { severity: \"warning\" as const }),\n ...location([\"stages\", index, phase, \"gates\", g]),\n message: `stage \"${stage.id}\": the ${phase} gate \\`${gate.command}\\` needs ${program}, which is not installed (not on PATH)`,\n actual: program,\n suggestions: [{ message: `install ${program}, or remove the gate` }],\n }),\n );\n }\n }\n }\n\n const detected = detectPreset(root, profile.skillsDir);\n const expected: Partial<Record<PresetName, string>> = {\n openspec: \"openspec/\",\n \"spec-kit\": \".specify/\",\n };\n const folder = expected[profile.preset];\n if (folder && !existsSync(join(root, folder))) {\n diagnostics.push(\n createDiagnostic(\"CS0700\", {\n severity: \"warning\",\n ...location([\"preset\"]),\n message: `workflow.preset is ${profile.preset}, but the repository has no ${folder} folder`,\n expected: folder,\n suggestions: [{ message: `set up ${profile.preset}, or change workflow.preset` }],\n }),\n );\n } else if (detected && detected !== profile.preset && profile.preset === \"catspec\") {\n diagnostics.push(\n createDiagnostic(\"CS0700\", {\n severity: \"warning\",\n ...location([\"preset\"]),\n message: `the repository looks like it uses ${detected === \"custom\" ? \"sdd-* skills\" : detected}, but workflow.preset is catspec`,\n actual: detected,\n suggestions: [{ message: `set workflow.preset: ${detected} in catspec.yaml` }],\n }),\n );\n }\n return sortDiagnostics(diagnostics);\n}\n\n/** `<feature>` or `<spec-id>`: what a stage command is run for. */\nconst targetWord = (stage: Stage): string => (stage.per === \"spec\" ? \"<spec-id>\" : \"<feature>\");\n\n/** True when a stage writes the machine specs (`*.spec.md`), so its agent writes the contract. */\nexport const writesSpecs = (stage: Stage): boolean =>\n stage.produces.some((p) => p.endsWith(\".spec.md\")) ||\n stage.finish.gates.includes(\"contracts_declared\");\n\n/**\n * How the agent of a stage that writes the machine specs writes them: CatSpec never calls an AI,\n * so the spec-writing skill or prompt says what goes into `<spec-id>.spec.md`.\n */\nexport const SPEC_WRITING_STEP =\n \"Next to the feature's spec, write `<spec-id>.spec.md`: in its YAML header, list as `bindings` \" +\n \"every class, interface and method this feature adds or changes, and under `rules` what must \" +\n \"stay true. `catspec guide spec-format` and `catspec guide rules` show the format; for a class \" +\n \"that already exists, `catspec bind <ClassName> --spec <spec-id>` writes its contract.\";\n\n/** `catspec workflow snippet <stage>`: the lines to paste into the stage's skill. */\nexport function stageSnippet(stage: Stage): string {\n const target = targetWord(stage);\n return [\n `First run \\`catspec stage start ${stage.id} ${target}\\`. If it fails, stop and report what it says.`,\n ...(writesSpecs(stage) ? [SPEC_WRITING_STEP] : []),\n `End with \\`catspec stage finish ${stage.id} ${target}\\` and fix everything it reports until it passes.`,\n ].join(\"\\n\");\n}\n\n/**\n * The steps of the `AGENTS.md` block (plan §D14.3) for this workflow: the stage that puts a work\n * item in progress, then the commands that finish it up to `implemented`.\n */\nexport function agentSteps(profile: WorkflowProfile): { begin: string; end: string[] } {\n const stages = profile.stages;\n const work = stages.findIndex(\n (s) => s.start.status === \"in-progress\" || s.finish.status === \"in-progress\",\n );\n if (work < 0) {\n return { begin: \"catspec status <id> in-progress\", end: [\"catspec status <id> implemented\"] };\n }\n const workStage = stages[work]!;\n const target = (s: Stage) => (s.per === \"spec\" ? \"<id>\" : \"<feature>\");\n const begin =\n workStage.start.status === \"in-progress\"\n ? `catspec stage start ${workStage.id} ${target(workStage)}`\n : `catspec stage finish ${workStage.id} ${target(workStage)}`;\n const end: string[] = [];\n for (const stage of stages.slice(work)) {\n if (stage !== workStage && (stage.start.gates.length > 0 || stage.start.status)) {\n end.push(`catspec stage start ${stage.id} ${target(stage)}`);\n }\n if (stage.finish.gates.length > 0 || stage.finish.status) {\n end.push(`catspec stage finish ${stage.id} ${target(stage)}`);\n }\n if (stageSetsImplemented(stage)) break;\n }\n return { begin, end };\n}\n\nconst stageSetsImplemented = (stage: Stage): boolean =>\n stage.start.status === \"implemented\" || stage.finish.status === \"implemented\";\n\n/**\n * The final gates (plan §D17.5): those of the transition that sets `implemented`, else the last\n * stage's finish gates.\n */\nexport function finalGates(\n profile: WorkflowProfile,\n): { stage: Stage; transition: Transition } | undefined {\n for (const stage of [...profile.stages].reverse()) {\n if (stage.finish.status === \"implemented\") return { stage, transition: stage.finish };\n if (stage.start.status === \"implemented\") return { stage, transition: stage.start };\n }\n const last = profile.stages.at(-1);\n return last ? { stage: last, transition: last.finish } : undefined;\n}\n\n/** Gates the hook can decide from a check it already ran (never `command:` or file lookups). */\nconst HOOK_GATES = new Set<BuiltinGate>([\n \"specs_valid\",\n \"contracts_pass\",\n \"tasks_done\",\n \"no_drift\",\n \"deps_known\",\n \"contracts_declared\",\n]);\n\n/**\n * CS0703 for the pre-commit hook (`workflow.enforce_in_hook`): `implemented` specs among `specs`\n * that no longer pass their final stage's built-in gates, decided from the diagnostics the staged\n * check computed. `command:` gates never run here.\n */\nexport function hookWorkflowDiagnostics(\n model: SpecModel,\n profile: WorkflowProfile,\n specs: readonly Spec[],\n diagnostics: readonly Diagnostic[],\n): Diagnostic[] {\n if (profile.enforceInHook === \"off\") return [];\n const final = finalGates(profile);\n if (!final) return [];\n const severity = profile.enforceInHook === \"error\" ? \"error\" : \"warning\";\n const out: Diagnostic[] = [];\n for (const spec of specs) {\n if (spec.status !== \"implemented\" || !spec.valid || spec.type === \"architecture\") continue;\n const own = diagnostics.filter((d) => d.spec === spec.id);\n const failed: string[] = [];\n for (const gate of final.transition.gates) {\n if (typeof gate !== \"string\" || !HOOK_GATES.has(gate)) continue;\n const passes = (() => {\n switch (gate) {\n case \"specs_valid\":\n return !model.diagnostics.some((d) => d.spec === spec.id && d.severity === \"error\");\n case \"contracts_pass\":\n return !own.some((d) => d.severity === \"error\");\n case \"tasks_done\":\n return spec.body.tasks.every((t) => t.done);\n case \"no_drift\":\n return !own.some((d) => d.code === \"CS0300\" && d.severity !== \"info\");\n case \"deps_known\":\n return spec.dependsOn.every((d) => model.specs.get(d));\n default:\n return (\n spec.aggregate ||\n spec.bindings.length > 0 ||\n spec.rules.some((r) => r.class !== \"manual\")\n );\n }\n })();\n if (!passes) failed.push(gateName(gate));\n }\n if (failed.length === 0) continue;\n out.push(\n createDiagnostic(\"CS0703\", {\n severity,\n spec: spec.id,\n specLocation: { file: spec.file, line: 1, column: 1 },\n message: `\"${spec.id}\" is implemented but no longer passes the ${final.stage.id} gates: ${listOf(failed)}`,\n expected: final.transition.gates.map(gateName),\n actual: failed,\n suggestions: [\n { message: \"fix the code or the spec, or move the spec back to in-progress\" },\n ],\n }),\n );\n }\n return out;\n}\n\n/**\n * The `feature_dir:` line `catspec init` writes, with a commented example of a list, for features\n * at several depths (domain folders). The example is a comment, so it never names a missing folder.\n */\nexport const featureDirYaml = (featureDir: string): string =>\n [\n \" # Where features live. A list for features at several depths, e.g.\",\n ` # feature_dir: [\"${featureDir.replace(\"{feature}\", \"billing/{feature}\")}\", \"${featureDir}\"]`,\n ` feature_dir: \"${featureDir}\"`,\n ].join(\"\\n\");\n\n/**\n * The `custom` preset's stages as YAML, for `catspec init` (plan §D17.2). Each stage uses the\n * repository's skill of its name (`sdd-task`, or the plural `sdd-tasks`) from `skills`; a stage\n * without one gets a manual driver, so the new config passes `catspec workflow doctor`.\n */\nexport const customWorkflowYaml = (\n skills: readonly string[] = SDD_SKILLS,\n skillsDir = \".claude/skills\",\n): string => {\n const driver = (name: string): string => {\n const skill = skills.find((s) => s === name || s === `${name}s`);\n return skill\n ? ` driver: { skill: ${skill} }`\n : ` driver: manual # no ${name} skill found; name your skill here: { skill: <name> }`;\n };\n return [\n \"workflow:\",\n \" preset: custom\",\n featureDirYaml(\"docs/spec/{feature}\"),\n ` skills_dir: \"${skillsDir}\" # where \\`skill:\\` drivers are found`,\n \" stages:\",\n \" - id: spec\",\n \" per: feature\",\n driver(SDD_SKILLS[0]),\n ' produces: [\"{feature_dir}/spec.md\", \"{feature_dir}/*.spec.md\"]',\n \" finish: { gates: [specs_valid, artifacts, contracts_declared] }\",\n \" - id: plan\",\n \" per: feature\",\n driver(SDD_SKILLS[1]),\n ' produces: [\"{feature_dir}/plan.md\"]',\n \" finish: { gates: [artifacts, deps_known], status: ready }\",\n \" - id: task\",\n \" per: spec\",\n driver(SDD_SKILLS[2]),\n \" start: { gates: [deps_ready], status: in-progress }\",\n \" finish: { gates: [contracts_pass] }\",\n \" - id: close\",\n \" per: spec\",\n driver(SDD_SKILLS[3]),\n \" finish: { gates: [contracts_pass, tasks_done, no_drift], status: implemented }\",\n \"\",\n ].join(\"\\n\");\n};\n","/**\n * Plain-text answers of the workflow commands (plan §D17.5), shared by the CLI and the MCP server\n * so both say the same thing: `catspec next` / `next_step` and `catspec stage` / `start_stage`,\n * `finish_stage`.\n */\nimport { listOf } from \"../util.js\";\nimport type { ItemPosition, NextStep, StageInfo, StageRun } from \"./engine.js\";\n\nconst gatesText = (gates: string[]): string => (gates.length > 0 ? listOf(gates) : \"none\");\n\n/** The stage's driver, gates and status changes, one per line. */\nexport function stageLines(stage: StageInfo): string[] {\n return [\n ` driver: ${stage.driverText}`,\n ` start gates: ${gatesText(stage.start.gates)}${stage.start.status ? ` → ${stage.start.status}` : \"\"}`,\n ` finish gates: ${gatesText(stage.finish.gates)}${stage.finish.status ? ` → ${stage.finish.status}` : \"\"}`,\n ];\n}\n\nconst itemLine = (item: ItemPosition): string => {\n switch (item.state) {\n case \"ready\":\n return ` ready: ${item.spec} → stage ${item.stage}`;\n case \"in-progress\":\n return ` in progress: ${item.spec} → stage ${item.stage}`;\n case \"waiting\":\n return ` waiting: ${item.spec} (on ${listOf(item.waitingOn)})`;\n case \"done\":\n return ` done: ${item.spec}`;\n }\n};\n\n/** `catspec next`: the current stage, how to run it, and each work item. */\nexport function formatNextStep(next: NextStep, driverFor?: (stage: string) => string): string {\n const lines: string[] = [];\n if (next.done || !next.stage) {\n lines.push(`${next.target}: every stage is done`);\n } else {\n const stage = next.stage;\n lines.push(`${next.target}: stage ${stage.id} (per ${stage.per}), use ${stage.driverText}`);\n lines.push(...stageLines(stage).slice(1));\n if (next.inputs && next.inputs.length > 0) lines.push(` read: ${listOf(next.inputs)}`);\n if (next.produces && next.produces.length > 0) {\n lines.push(` produce: ${listOf(next.produces)}`);\n }\n if (stage.per === \"feature\") {\n lines.push(\n ` run \\`catspec stage start ${stage.id} ${next.target}\\` first and ` +\n `\\`catspec stage finish ${stage.id} ${next.target}\\` at the end`,\n );\n }\n }\n if (next.items.length > 0) {\n lines.push(\"work items:\");\n for (const item of next.items) {\n const driver = item.stage && driverFor ? `, use ${driverFor(item.stage)}` : \"\";\n lines.push(\n itemLine(item) + (item.state === \"ready\" || item.state === \"in-progress\" ? driver : \"\"),\n );\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** `catspec stage start|finish`: the stage's context and each gate's result. */\nexport function formatStageRun(run: StageRun): string {\n const lines = [\n `stage ${run.stage.id} ${run.phase} for ${run.target}` +\n (run.specs.length > 0 ? ` (${listOf(run.specs)})` : \"\"),\n ` driver: ${run.stage.driverText}`,\n ];\n if (run.produces.length > 0) lines.push(` produce: ${listOf(run.produces)}`);\n for (const gate of run.gates) {\n const mark = gate.skipped ? \"-\" : gate.passed ? \"✔\" : \"✖\";\n lines.push(` ${mark} ${gate.gate}: ${gate.detail.split(\"\\n\").join(\"\\n \")}`);\n }\n if (run.gates.length === 0) lines.push(` no ${run.phase} gates`);\n for (const change of run.changes) lines.push(` ${change.spec}: ${change.from} → ${change.to}`);\n if (run.phase === \"start\" && run.ok) {\n const finish = run.stage.finish.gates;\n lines.push(\n ` when done run \\`catspec stage finish ${run.stage.id} ${run.target}\\`` +\n (finish.length > 0 ? ` (gates: ${listOf(finish)})` : \"\"),\n );\n }\n lines.push(\n run.ok\n ? run.forced\n ? `${run.phase === \"start\" ? \"started\" : \"finished\"} with --force (the override is logged)`\n : run.phase === \"start\"\n ? \"started\"\n : \"finished\"\n : `refused: the stage can't ${run.phase}`,\n );\n return `${lines.join(\"\\n\")}\\n`;\n}\n","/** Package name. */\nexport const packageName = \"@catspec/core\";\n\nexport * from \"./diagnostics.js\";\nexport * from \"./config.js\";\nexport * from \"./facts.js\";\nexport * from \"./match.js\";\nexport {\n codeLocation,\n formatLocation,\n SymbolTable,\n type Codebase,\n type SymbolEntry,\n} from \"./codebase.js\";\nexport {\n inModule,\n resolveBinding,\n splitSymbol,\n type BindingResolution,\n type ResolvedBinding,\n} from \"./resolve.js\";\nexport { attributeMatches, bindingItems, evaluateContract, signatureText } from \"./contracts.js\";\nexport { calleeNames, evaluateRule, importTargets, type TestRun } from \"./rules.js\";\nexport {\n checkCode,\n isEnforced,\n queryDiagnostics,\n runTestCommand,\n statusGate,\n testCommandArgs,\n type CheckMode,\n type CheckOptions,\n type CheckResult,\n type ItemResult,\n type StatusGate,\n} from \"./check.js\";\nexport {\n Git,\n GitError,\n GitUnavailableError,\n type StagedChange,\n type TreeEntry,\n} from \"./git/git.js\";\nexport {\n IndexProvider,\n RevisionProvider,\n WorkingTreeProvider,\n type SourceEntry,\n type SourceProvider,\n} from \"./git/providers.js\";\nexport {\n applyLock,\n fingerprintOf,\n hasLockFile,\n itemHashes,\n lockedFiles,\n lockPathOf,\n nextLock,\n parseLock,\n serializeLock,\n shapeOf,\n specHash,\n type LockCheckOptions,\n type LockedSymbol,\n type LockFile,\n type NextLockOptions,\n type Shape,\n} from \"./lock.js\";\nexport { stagedDiagnostics, stagedScope, type StagedScope } from \"./staged.js\";\nexport { coverage, type CoverageReport, type Ratio, type SpecCoverage } from \"./coverage.js\";\nexport {\n frontmatterLocation,\n parseSpecSource,\n splitFrontmatter,\n withFrontmatter,\n type SpecSource,\n type SplitSource,\n} from \"./frontmatter.js\";\nexport * from \"./spec-schema.js\";\nexport * from \"./spec-body.js\";\nexport { readSpec, specLocation, type ReadSpecOptions, type Spec } from \"./spec.js\";\nexport { DependencyGraph } from \"./graph.js\";\nexport { loadSpecModel, SpecSet, type SpecModel } from \"./load.js\";\nexport {\n applyPatch,\n classifyOp,\n classifyPatch,\n editYaml,\n readYaml,\n SpecEditError,\n type EditClass,\n} from \"./spec-editor.js\";\nexport { formatPath } from \"./schema-issues.js\";\nexport {\n didYouMean,\n gitBlobSha,\n globMatcher,\n isListedPath,\n kebabCase,\n listFiles,\n LineIndex,\n relativePosix,\n toPosix,\n} from \"./util.js\";\nexport {\n baselineFromLock,\n baselineFromSymbol,\n bodyTokens,\n detectRenames,\n jaccard,\n memberNames,\n nameFreeFingerprint,\n renameScore,\n splitResolved,\n tokenSimilarity,\n type Ambiguity,\n type BaselineSymbol,\n type Evidence,\n type Lost,\n type Mapping,\n type RenameInput,\n type RenameMap,\n type RenameReport,\n type ScoredCandidate,\n} from \"./rename.js\";\nexport {\n editPatch,\n planSync,\n rewriteSymbol,\n type SpecEdit,\n type SyncOptions,\n type SyncPlan,\n} from \"./sync.js\";\nexport * from \"./workflow/schema.js\";\nexport * from \"./workflow/engine.js\";\nexport * from \"./workflow/doctor.js\";\nexport * from \"./workflow/format.js\";\n"],"mappings":"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","names":["key","join","z","text","_","key","z","key","text","stage","text","join","escapeRegExp","text","isMap","parseDocument","text","lineStart","parseDocument","text","text","extra","isMap","key","id","key","text","item","declared","key","nameMatches","files","createHash","posix","posix","createHash","attributeText","text","key","isoDate","execFile","resolve","record","stage","key","text","readFile","join","readFile","join","declared","enforceable","key","posix","specFiles","text","posix","isMap","isScalar","isSeq","parseDocument","visit","key","isMap","list","isSeq","text","parseDocument","isScalar","visit","item","createHash","sha256","createHash","text","sep","key","name","posix","specId","text","posix","execFile","join","existsSync","statSync","join","LineCounter","parseDocument","LineCounter","parseDocument","join","existsSync","statSync","stage","stage","key","template","unknown","text","transition","feature","item","join","resolve","execFile","stage"]}
1
+ {"version":3,"sources":["../src/diagnostics.ts","../src/config.ts","../src/schema-issues.ts","../src/util.ts","../src/workflow/schema.ts","../src/spec-schema.ts","../src/facts.ts","../src/match.ts","../src/codebase.ts","../src/spec.ts","../src/frontmatter.ts","../src/spec-body.ts","../src/resolve.ts","../src/contracts.ts","../src/rules.ts","../src/check.ts","../src/lock.ts","../src/git/git.ts","../src/git/providers.ts","../src/staged.ts","../src/coverage.ts","../src/graph.ts","../src/load.ts","../src/spec-editor.ts","../src/rename.ts","../src/sync.ts","../src/workflow/engine.ts","../src/workflow/doctor.ts","../src/workflow/format.ts","../src/index.ts"],"sourcesContent":["/**\n * Diagnostics (plan §D12, ADR-011): every problem CatSpec reports has a stable `CSxxxx` code, a\n * severity, a location and a message. The registry below is the single source of the codes: a\n * code that isn't registered can't be emitted, and the docs are generated from it.\n */\n\nexport type Severity = \"error\" | \"warning\" | \"info\";\n\nexport interface CodeInfo {\n /** Default severity; a check may lower or raise it (config, spec status, plan §D8). */\n severity: Severity;\n title: string;\n /** Reference text for the diagnostics docs: what the code means and how to fix it. */\n docs: string;\n}\n\n/** The code registry. Codes are never reused and their meaning never changes (ADR-011). */\nexport const CODES = {\n CS0101: {\n severity: \"error\",\n title: \"invalid spec\",\n docs:\n \"The spec can't be read as a valid spec: the file has no `---` frontmatter or it isn't \" +\n \"closed, the YAML is invalid, a required field is missing, or a value has the wrong type or \" +\n \"isn't one of the allowed values. The message names the field and the allowed values. Fix \" +\n \"the frontmatter at the reported line.\",\n },\n CS0102: {\n severity: \"warning\",\n title: \"unknown key\",\n docs:\n \"A top-level frontmatter key that CatSpec doesn't know. It is ignored, so teams can keep \" +\n \"their own metadata in the spec. Check the spelling if it was meant to be a CatSpec key.\",\n },\n CS0103: {\n severity: \"error\",\n title: \"duplicate id\",\n docs:\n \"Spec ids must be unique across the repository, and binding and rule ids unique within \" +\n \"their spec. Rename one of them; the message names every place that uses the id.\",\n },\n CS0104: {\n severity: \"error\",\n title: \"unknown dependency\",\n docs:\n \"`depends_on` names a spec id that doesn't exist. Fix the id (the message suggests close \" +\n \"matches) or add the missing spec.\",\n },\n CS0105: {\n severity: \"error\",\n title: \"dependency cycle\",\n docs:\n \"The `depends_on` relations form a cycle, so no spec in it can ever be started. The message \" +\n \"shows the full cycle (`a → b → c → a`); remove one of its dependencies.\",\n },\n CS0106: {\n severity: \"warning\",\n title: \"spec outside a feature folder\",\n docs:\n \"With `layout: feature-folders`, every `*.spec.md` lives directly in `docs/spec/<feature>/`, \" +\n \"and the architecture spec at the path in `specs.architecture`. Move the file as suggested, \" +\n \"or set `layout: free` in `catspec.yaml` if the repository uses another layout.\",\n },\n CS0107: {\n severity: \"error\",\n title: \"architecture spec ambiguous or not staged\",\n docs:\n \"The architecture spec is optional. If you have one, it is the one file at \" +\n \"`specs.architecture` (default `docs/architecture/adr/*-adr.md`; a file, a glob or a \" +\n \"folder) whose frontmatter has `catspec:` or `type: architecture`. More than one such \" +\n \"file is an error: keep the repository-wide rules in one file, or narrow \" +\n \"`specs.architecture` in `catspec.yaml`. Plain ADR files without CatSpec frontmatter are \" +\n \"fine. In `check --staged`, an architecture spec that exists on disk but isn't staged yet \" +\n \"is a warning that names the file to stage, so the commit isn't blocked.\",\n },\n CS0108: {\n severity: \"warning\",\n title: \"lock file without spec\",\n docs:\n \"A generated `<spec-id>.lock.json` has no spec with that id in its folder, usually because \" +\n \"the spec was deleted, renamed or moved without its lock file. Delete the lock file, or \" +\n \"move it next to its spec (a spec's lock file is named after its id).\",\n },\n CS0110: {\n severity: \"error\",\n title: \"unknown reference\",\n docs:\n \"The spec body references `[rule:<id>]` or `[binding:<id>]`, but the frontmatter has no \" +\n \"rule or binding with that id. Fix the reference or add the rule or binding.\",\n },\n CS0111: {\n severity: \"warning\",\n title: \"unenforced prose invariant\",\n docs:\n \"A bullet under a `Contracts` or `Invariants` heading has no `[rule:<id>]` or \" +\n \"`[binding:<id>]` reference, so nothing checks it. Add a rule (a `manual` rule if it can't \" +\n \"be checked from code) and reference it. Controlled by `enforcement.unenforced_prose`.\",\n },\n CS0112: {\n severity: \"error\",\n title: \"unknown ADR id\",\n docs:\n \"A rule's `adr` field names a decision that isn't among your ADRs: a `## ADR-NNN: <title>` \" +\n \"heading of the architecture spec, or a plain ADR file at `specs.architecture` (its file \" +\n \"name, such as `0007-use-postgres.md`, or an `ADR-NNN` heading). Ids compare by number, \" +\n \"so ADR-7 and ADR-0007 are the same. Fix the id or add the decision. Without any ADRs, \" +\n \"`adr` isn't checked.\",\n },\n CS0130: {\n severity: \"error\",\n title: \"invalid query\",\n docs:\n \"A `query` rule's Tree-sitter query doesn't compile for its language (for example unbalanced \" +\n \"parentheses or an unknown node type), or no language adapter is installed for its `lang`. \" +\n \"Queries are compiled when the specs load, before any code is read. Fix the query at the \" +\n \"reported line.\",\n },\n CS0201: {\n severity: \"error\",\n title: \"binding not found\",\n docs:\n \"No declaration in the code matches the binding's `symbol` (and `kind`). CatSpec looks in \" +\n \"the files of the `file` hint first, then in every source file, so a moved file is still \" +\n \"found. The message suggests close names of the same kind, in the hinted files first. Fix \" +\n \"the symbol, restore the code, or run `catspec sync` after a rename.\",\n },\n CS0202: {\n severity: \"error\",\n title: \"binding ambiguous\",\n docs:\n \"More than one declaration matches the binding's `symbol` and they aren't C# `partial` \" +\n \"parts of one type. The message lists every location. Qualify the symbol \" +\n \"(`Namespace.Type` or `path/to/module#Name`) or add a `file` hint.\",\n },\n CS0203: {\n severity: \"error\",\n title: \"member missing\",\n docs:\n \"The bound declaration has no member with the name a `members` entry requires. The message \" +\n \"suggests the closest existing members with their location. Add the member, rename it back, \" +\n \"mark the entry `optional: true`, or update the spec.\",\n },\n CS0204: {\n severity: \"error\",\n title: \"base type missing\",\n docs:\n \"The bound declaration doesn't directly extend or implement a type listed in `implements` \" +\n \"or `extends`. Types match by qualified-name suffix and generic arguments. Add the base \" +\n \"type or update the spec.\",\n },\n CS0205: {\n severity: \"error\",\n title: \"signature mismatch\",\n docs:\n \"A member exists but its kind, parameter types, return type or modifiers differ from the \" +\n \"spec. The message shows the expected and the found signature. `*` in `params` matches any \" +\n \"type.\",\n },\n CS0206: {\n severity: \"error\",\n title: \"attribute missing\",\n docs:\n \"The declaration or member lacks a C# attribute or TypeScript decorator that the spec \" +\n \"requires in `attributes`. Names match without a trailing `Attribute`; arguments are \" +\n \"compared only when the spec gives them.\",\n },\n CS0207: {\n severity: \"error\",\n title: \"constructor dependency missing\",\n docs:\n \"No constructor of the bound class takes every type in `constructor.requires` (dependency \" +\n \"injection). The message names the missing types for the closest constructor.\",\n },\n CS0208: {\n severity: \"error\",\n title: \"visibility or export mismatch\",\n docs:\n \"`exported` requires the declaration to be exported (TypeScript) or `public` (C#), or not, \" +\n \"or a member lacks a required visibility modifier (`public`, `private`, `protected`, \" +\n \"`internal`).\",\n },\n CS0210: {\n severity: \"error\",\n title: \"renamed\",\n docs:\n \"A declaration a binding pointed to was renamed or moved, and CatSpec found where it went \" +\n \"(a rename map, the same name in another file, a namespace or path prefix change, a git \" +\n \"file rename, the same shape, or a similarity score at or above `heal.threshold`). The \" +\n \"diagnostic carries the location-only patch (`symbol` and `file` only, never the \" +\n \"contract). Run `catspec sync --apply`; with `heal.mode: auto` the pre-commit hook applies \" +\n \"it and stages the spec. As info, it also reports backticked mentions of the old name in \" +\n \"the spec body, rewritten only with `catspec sync --apply --update-mentions`.\",\n },\n CS0215: {\n severity: \"error\",\n title: \"large refactor\",\n docs:\n \"Many bindings broke at once: more than `refactor.detect_threshold` in one commit, or any \" +\n \"while a refactor (`catspec refactor`) is in progress. The hook reports this one summary \" +\n \"instead of a binding, drift or ratchet error per binding. Run `catspec sync` to see the \" +\n \"mapping and `catspec sync --apply` to update every spec in one batch. During a refactor \" +\n \"started with `--allow-wip` it is a warning on the refactor's branch, so intermediate \" +\n \"commits go through.\",\n },\n CS0216: {\n severity: \"error\",\n title: \"ambiguous rename\",\n docs:\n \"`catspec sync` can't tell which declaration a binding's old declaration became: several \" +\n \"candidates are equally close, or a closer match took the only one. CatSpec never guesses: \" +\n \"no spec is changed. The message lists the candidates. Name the rename in a rename map \" +\n '(`{ \"symbols\": { \"Old.Name\": \"New.Name\" } }`) and run `catspec sync --apply --map ' +\n \"<file>`, or fix the binding by hand.\",\n },\n CS0217: {\n severity: \"error\",\n title: \"binding lost in refactor\",\n docs:\n \"A binding's declaration is gone and no candidate replaces it (the closest candidate, if \" +\n \"any, scores below `heal.threshold`). During a refactor this keeps the refactor open. \" +\n \"Restore the code, add the rename to a rename map (`--map`), or change the spec; \" +\n \"`catspec sync --apply --partial` applies the rest meanwhile.\",\n },\n CS0220: {\n severity: \"warning\",\n title: \"unresolvable\",\n docs:\n \"CatSpec can't decide the check from syntax alone, for example a base type that is a type \" +\n \"alias, a parameter without a type annotation, or a class without its own constructor that \" +\n \"inherits one. It is never reported as a failure of the contract; its severity is \" +\n \"`enforcement.unresolvable` (`warn` or `error`). Write the type explicitly to make it \" +\n \"checkable.\",\n },\n CS0300: {\n severity: \"warning\",\n title: \"drift\",\n docs:\n \"The shape of a bound declaration (kind, name, bases, attributes, modifiers and member \" +\n \"signatures; bodies excluded) changed since it was recorded in the spec's lock file, and the \" +\n \"spec's binding didn't change with it. Implemented specs report it with the severity of \" +\n \"`enforcement.drift` (`off`, `warn`, `strict`), in-progress specs as info. Run \" +\n \"`catspec accept <spec-id>` to record an intended change, update the spec, or change the \" +\n \"code back.\",\n },\n CS0301: {\n severity: \"error\",\n title: \"regression of a satisfied item\",\n docs:\n \"A contract item that passed before (recorded in `satisfied` of the spec's lock file) fails \" +\n \"now. This is an error even while the spec is in progress (the ratchet, ADR-006): work in \" +\n \"progress may be incomplete, but what already worked must not break. The message keeps the \" +\n \"original code and text. Fix the code, or change the spec item (a changed item leaves \" +\n \"`satisfied` until it passes again).\",\n },\n CS0400: {\n severity: \"info\",\n title: \"waived\",\n docs:\n \"A rule violation covered by a waiver (`waivers` in the spec, with a reason and an \" +\n \"optional `until` date). It doesn't fail the check. The message keeps the original code \" +\n \"and text.\",\n },\n CS0401: {\n severity: \"error\",\n title: \"waiver expired\",\n docs:\n \"A waiver's `until` date has passed. The violations it covered are reported again. Fix \" +\n \"them and remove the waiver, or extend `until` with a reason.\",\n },\n CS0502: {\n severity: \"error\",\n title: \"dependencies not satisfied\",\n docs:\n \"`catspec status` refuses the transition: `ready` needs every `depends_on` spec to exist, \" +\n \"`in-progress` and `implemented` need them `implemented` with passing contracts. The \" +\n \"message names each dependency and why. `--force` skips this gate.\",\n },\n CS0601: {\n severity: \"error\",\n title: \"forbidden call\",\n docs:\n \"A `forbid_call` rule matched a call in its scope (`within` a binding or member, the \" +\n \"spec's files, or `paths`). `*` in the pattern matches any text. Remove the call or add a \" +\n \"waiver with a reason.\",\n },\n CS0602: {\n severity: \"error\",\n title: \"required call missing\",\n docs: \"A `require_call` rule found no matching call in its scope. Add the call.\",\n },\n CS0603: {\n severity: \"error\",\n title: \"forbidden import\",\n docs:\n \"A file matching the rule's `from` imports a module that `forbid_import` forbids, or that \" +\n \"`allow_import_only` doesn't allow. Relative imports are resolved to repository paths \" +\n \"before they are matched. Remove the import or move the code.\",\n },\n CS0604: {\n severity: \"error\",\n title: \"naming rule violated\",\n docs:\n \"A declaration whose kind and name match a `naming` rule doesn't satisfy its \" +\n \"`implements`, `extends`, `attributes` or `in_path` requirement.\",\n },\n CS0605: {\n severity: \"error\",\n title: \"symbol must not exist\",\n docs:\n \"A `must_not_exist` rule found a declaration it forbids (usually a deprecated API). Remove \" +\n \"it or rename it.\",\n },\n CS0610: {\n severity: \"error\",\n title: \"query match\",\n docs:\n \"A `query` rule with `expect: absent` matched, or one with `expect: present` found \" +\n \"nothing, in its scope.\",\n },\n CS0620: {\n severity: \"error\",\n title: \"test missing\",\n docs:\n \"A `test` rule names a test symbol that doesn't exist in the code. Write the test or fix \" +\n \"the symbol.\",\n },\n CS0621: {\n severity: \"error\",\n title: \"test failed\",\n docs:\n \"With `--run-tests`, the `tests.command` of `catspec.yaml` failed for a `test` rule. The \" +\n \"command runs without a shell; `{test}` in it is replaced with the test symbol.\",\n },\n CS0700: {\n severity: \"error\",\n title: \"invalid workflow config\",\n docs:\n \"The `workflow:` section of `catspec.yaml` is invalid: an unknown preset, stage key, gate, \" +\n \"status or placeholder (valid placeholders: `{feature}`, `{feature_dir}`, `{spec}`). The \" +\n \"message names the value and suggests close matches. `catspec workflow doctor` also reports \" +\n \"it as a warning when the preset doesn't match the repository (no `openspec/` folder for \" +\n \"`openspec`, no `.specify/` for `spec-kit`).\",\n },\n CS0701: {\n severity: \"error\",\n title: \"start gate failed\",\n docs:\n \"`catspec stage start` (or MCP `start_stage`) refused the stage: one of its start gates \" +\n \"failed. The message names the gate and why, followed by the diagnostics of the underlying \" +\n \"check. Fix them and start the stage again; `--force` starts it anyway and logs the override.\",\n },\n CS0702: {\n severity: \"error\",\n title: \"finish gate failed\",\n docs:\n \"`catspec stage finish` (or MCP `finish_stage`) refused the stage: one of its finish gates \" +\n \"failed, e.g. `contracts_pass` while a contract fails or `tasks_done` while a task is \" +\n \"unticked. The status isn't changed. Fix what it reports and finish the stage again.\",\n },\n CS0703: {\n severity: \"warning\",\n title: \"implemented spec fails its final gates\",\n docs:\n \"An `implemented` spec in the commit no longer passes the built-in gates of its workflow's \" +\n \"final stage (the one that sets `implemented`), e.g. a task was unticked. Reported by the \" +\n \"pre-commit hook with the severity of `workflow.enforce_in_hook`; `command:` gates never run \" +\n \"in the hook.\",\n },\n CS0704: {\n severity: \"error\",\n title: \"driver not found\",\n docs:\n \"`catspec workflow doctor` couldn't find what a stage needs: a skill's file \" +\n \"(`<skills_dir>/<name>/SKILL.md`) or a command's program on PATH. The message names the \" +\n \"skill or command and the expected path.\",\n },\n CS0705: {\n severity: \"error\",\n title: \"stage out of order\",\n docs:\n \"A stage was started or finished before an earlier stage is done (its finish gates pass and \" +\n \"its status is reached). Run `catspec next <feature>` to see the current stage. `--force` \" +\n \"overrides the order and logs the override.\",\n },\n CS0706: {\n severity: \"warning\",\n title: \"command gate skipped\",\n docs:\n \"A `command:` gate wasn't run because `workflow.allow_commands` is false (the default), so \" +\n \"it doesn't block the stage. Run the command yourself, or set `workflow.allow_commands: \" +\n \"true` to let CatSpec run it (without a shell).\",\n },\n CS0901: {\n severity: \"warning\",\n title: \"parse error in file\",\n docs:\n \"A source file has a syntax error at the reported location. CatSpec still uses the \" +\n \"declarations it could read before and after the error, so results for that file may be \" +\n \"incomplete. Fix the syntax error. A file larger than 1 MiB, or one the language adapter \" +\n \"fails on, isn't parsed at all: it gets one CS0901 at its first line and no facts.\",\n },\n CS0902: {\n severity: \"error\",\n title: \"git unavailable\",\n docs:\n \"The command reads the git index or history (`catspec check --staged`, the pre-commit \" +\n \"hook, `install-hooks`), but git can't be run: it isn't installed or isn't on PATH. Install \" +\n \"git or fix PATH. CatSpec runs git without a shell.\",\n },\n} as const satisfies Record<string, CodeInfo>;\n\nexport type DiagnosticCode = keyof typeof CODES;\n\nexport const isRegisteredCode = (code: string): code is DiagnosticCode =>\n Object.prototype.hasOwnProperty.call(CODES, code);\n\n/** A position in a file. Lines and columns are 1-based; `file` is relative to the repo root. */\nexport interface Location {\n file: string;\n line: number;\n column: number;\n endLine?: number;\n endColumn?: number;\n}\n\n/** A frontmatter edit, see `applyPatch` (spec-editor.ts). */\nexport type PatchPath = (string | number)[];\nexport type PatchOp =\n { op: \"set\"; path: PatchPath; value: unknown } | { op: \"delete\"; path: PatchPath };\n\n/** A proposed edit of one spec file. */\nexport interface SpecPatch {\n file: string;\n ops: PatchOp[];\n}\n\nexport interface Suggestion {\n message: string;\n patch?: SpecPatch;\n}\n\nexport interface Diagnostic {\n code: DiagnosticCode;\n severity: Severity;\n /** Id of the spec the diagnostic is about. */\n spec?: string;\n /** Where in the spec file: the binding, rule or key in the frontmatter, or the body line. */\n specLocation?: Location;\n /** Where in the code. */\n codeLocation?: Location;\n /** A human sentence that includes what was expected and what was found. */\n message: string;\n expected?: unknown;\n actual?: unknown;\n suggestions?: Suggestion[];\n ruleId?: string;\n bindingId?: string;\n /** The contract item checked, e.g. `binding:auth.login` or `rule:no-console` (ratchet, F5). */\n item?: string;\n}\n\nexport type DiagnosticInit = Omit<Diagnostic, \"code\" | \"severity\"> & { severity?: Severity };\n\n/** Creates a diagnostic with the registered default severity unless `severity` is given. */\nexport function createDiagnostic(code: DiagnosticCode, init: DiagnosticInit): Diagnostic {\n if (!isRegisteredCode(code)) {\n throw new Error(`unregistered diagnostic code ${String(code)}; add it to CODES`);\n }\n const { severity, ...rest } = init;\n return { code, severity: severity ?? CODES[code].severity, ...rest };\n}\n\nconst SEVERITY_RANK: Record<Severity, number> = { error: 0, warning: 1, info: 2 };\n\n/** Sorts diagnostics by file, line, column, then code, so output is deterministic. */\nexport function sortDiagnostics(diagnostics: readonly Diagnostic[]): Diagnostic[] {\n const key = (d: Diagnostic): Location =>\n d.specLocation ?? d.codeLocation ?? { file: \"\", line: 0, column: 0 };\n return [...diagnostics].sort((a, b) => {\n const la = key(a);\n const lb = key(b);\n return (\n compareStrings(la.file, lb.file) ||\n la.line - lb.line ||\n la.column - lb.column ||\n compareStrings(a.code, b.code) ||\n SEVERITY_RANK[a.severity] - SEVERITY_RANK[b.severity] ||\n compareStrings(a.message, b.message)\n );\n });\n}\n\nexport interface DiagnosticCounts {\n errors: number;\n warnings: number;\n infos: number;\n}\n\nexport function countDiagnostics(diagnostics: readonly Diagnostic[]): DiagnosticCounts {\n const counts: DiagnosticCounts = { errors: 0, warnings: 0, infos: 0 };\n for (const d of diagnostics) {\n if (d.severity === \"error\") counts.errors++;\n else if (d.severity === \"warning\") counts.warnings++;\n else counts.infos++;\n }\n return counts;\n}\n\n/** Locale-independent string comparison, for deterministic ordering on every platform. */\nexport const compareStrings = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n","/**\n * `catspec.yaml` (plan §D4): schema, defaults and discovery. Every key has a default, so a\n * repository without a config works. The `workflow` section is kept as written and validated by\n * the workflow profiles (plan §D17).\n */\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { LineCounter, parseDocument } from \"yaml\";\nimport * as z from \"zod\";\n\nimport { formatPath, locate, schemaIssues } from \"./schema-issues.js\";\nimport { listOf, relativePosix } from \"./util.js\";\nimport { resolveWorkflow, WorkflowSchema, type WorkflowProfile } from \"./workflow/schema.js\";\n\nexport const CONFIG_FILE = \"catspec.yaml\";\n\nconst globList = z.array(z.string().min(1));\n\nconst language = (include: string[], exclude: string[]) =>\n z\n .strictObject({\n include: globList.default(include).describe(\"Source files of this language (globs).\"),\n exclude: globList.default(exclude).describe(\"Files to leave out (globs).\"),\n })\n .prefault({});\n\nexport const ConfigSchema = z\n .strictObject({\n version: z.literal(1).default(1).describe(\"Config format version.\"),\n layout: z\n .enum([\"feature-folders\", \"free\"])\n .default(\"feature-folders\")\n .describe(\"feature-folders: specs live in docs/spec/<feature>/ (CS0106 otherwise).\"),\n workflow: WorkflowSchema.prefault({}),\n specs: z\n .strictObject({\n include: globList.default([\"docs/spec/*/*.spec.md\"]).describe(\"Machine spec files.\"),\n architecture: z\n .string()\n .min(1)\n .default(\"docs/architecture/adr/*-adr.md\")\n .describe(\n \"Optional. Your ADRs: a file, a glob or a folder. At most one of these files is the \" +\n \"architecture spec (CatSpec frontmatter, repository-wide rules); the others are \" +\n \"plain ADRs that rules can refer to (CS0107, CS0112).\",\n ),\n })\n .prefault({}),\n languages: z\n .strictObject({\n typescript: language([\"src/**/*.{ts,tsx}\"], [\"**/*.d.ts\", \"**/node_modules/**\"]),\n csharp: language([\"src/**/*.cs\"], [\"**/obj/**\", \"**/bin/**\", \"**/*.g.cs\"]),\n })\n .prefault({}),\n enforcement: z\n .strictObject({\n drift: z.enum([\"off\", \"warn\", \"strict\"]).default(\"warn\"),\n unresolvable: z.enum([\"warn\", \"error\"]).default(\"warn\"),\n unenforced_prose: z.enum([\"off\", \"warn\"]).default(\"warn\"),\n })\n .prefault({}),\n tests: z\n .strictObject({\n command: z\n .union([z.string().min(1), globList.min(1)])\n .optional()\n .describe(\n \"Test command run by `check --run-tests` for each test rule, without a shell: a \" +\n \"string split at spaces, or a list of arguments. `{test}` is replaced with the \" +\n \"test symbol.\",\n ),\n })\n .prefault({}),\n heal: z\n .strictObject({\n mode: z.enum([\"off\", \"suggest\", \"auto\"]).default(\"suggest\"),\n threshold: z.number().min(0).max(1).default(0.8),\n })\n .prefault({}),\n hook: z\n .strictObject({\n stage_generated: z\n .boolean()\n .default(true)\n .describe(\"Re-stage lock files and auto-healed specs.\"),\n })\n .prefault({}),\n refactor: z\n .strictObject({\n detect_threshold: z\n .number()\n .int()\n .min(1)\n .default(10)\n .describe(\"Broken bindings in one commit that count as a large refactor.\"),\n allow_wip: z.boolean().default(false),\n })\n .prefault({}),\n mcp: z\n .strictObject({\n allow_location_edits: z.boolean().default(true),\n allow_contract_edits: z.boolean().default(false),\n })\n .prefault({}),\n })\n .describe(\"CatSpec configuration (catspec.yaml).\");\n\nexport type CatspecConfig = z.output<typeof ConfigSchema>;\n\n/** The configuration used when the repository has no `catspec.yaml`. */\nexport const defaultConfig = (): CatspecConfig => ConfigSchema.parse({});\n\nexport interface ConfigIssue {\n /** The config file, relative to the repository root. */\n file: string;\n line: number;\n column: number;\n /** Dotted key path, e.g. `heal.mode`. */\n key: string;\n message: string;\n /** Allowed values, when the key has a fixed set. */\n allowed?: string[];\n /** CS0700 for a problem in the `workflow:` section (plan §D17.7). */\n code?: \"CS0700\";\n}\n\n/** An invalid `catspec.yaml`; the CLI reports it as a usage/config error (exit code 2). */\nexport class ConfigError extends Error {\n constructor(readonly issues: ConfigIssue[]) {\n super(\n issues\n .map((i) => `${i.file}:${i.line}:${i.column}: ${i.code ? `${i.code} ` : \"\"}${i.message}`)\n .join(\"\\n\"),\n );\n this.name = \"ConfigError\";\n }\n}\n\n/** Parses and validates the text of a `catspec.yaml`. Throws `ConfigError`. */\nexport function parseConfig(text: string, file = CONFIG_FILE): CatspecConfig {\n const lineCounter = new LineCounter();\n const doc = parseDocument(text, { lineCounter, prettyErrors: false });\n const at = (offset: number): { line: number; column: number } => {\n const { line, col } = lineCounter.linePos(offset);\n return { line, column: col };\n };\n\n if (doc.errors.length > 0) {\n throw new ConfigError(\n doc.errors.map((error) => ({\n file,\n ...at(error.pos[0]),\n key: \"\",\n message: `invalid YAML: ${error.message.split(\"\\n\")[0]!.replace(/ at line \\d+.*$/, \"\")}`,\n })),\n );\n }\n\n let value: unknown;\n try {\n value = (doc.toJS() as unknown) ?? {};\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n throw new ConfigError([\n { file, line: 1, column: 1, key: \"\", message: `the config can't be read: ${reason}` },\n ]);\n }\n // A `specs:` section with only comments in it (as `catspec init` writes it) is empty, not null.\n if (\n value !== null &&\n typeof value === \"object\" &&\n (value as { specs?: unknown }).specs === null\n ) {\n delete (value as { specs?: unknown }).specs;\n }\n const result = ConfigSchema.safeParse(value);\n if (result.success) return withWorkflowDefaults(result.data, value);\n\n throw new ConfigError(\n schemaIssues(result.error.issues, doc, ConfigSchema).map((issue) => {\n const range = locate(doc, issue.path, issue.atKey);\n const allowed =\n Array.isArray(issue.expected) && issue.expected.every((v) => typeof v === \"string\")\n ? issue.expected\n : undefined;\n const hint =\n issue.suggestions.length > 0 ? `; did you mean ${listOf(issue.suggestions)}?` : \"\";\n return {\n file,\n ...(range ? at(range.start) : { line: 1, column: 1 }),\n key: formatPath(issue.path),\n message: issue.message + hint,\n ...(allowed ? { allowed } : {}),\n ...(issue.path[0] === \"workflow\" ? { code: \"CS0700\" as const } : {}),\n };\n }),\n );\n}\n\n/** The workflow profile in effect (plan §D17): the preset with the config's overrides. */\nexport const workflowProfile = (config: CatspecConfig): WorkflowProfile =>\n resolveWorkflow(config.workflow);\n\n/**\n * A preset whose features live outside `docs/spec/` (OpenSpec, Spec Kit, a custom `feature_dir`)\n * changes the defaults of `specs.include` and `layout`; values written in the file win.\n */\nfunction withWorkflowDefaults(config: CatspecConfig, raw: unknown): CatspecConfig {\n const written = (raw ?? {}) as { layout?: unknown; specs?: { include?: unknown } | null };\n const profile = workflowProfile(config);\n return {\n ...config,\n layout: written.layout === undefined ? profile.layout : config.layout,\n specs: {\n ...config.specs,\n include: written.specs?.include === undefined ? profile.specsInclude : config.specs.include,\n },\n };\n}\n\nexport interface LoadedConfig {\n config: CatspecConfig;\n /**\n * Absolute path of the repository root: the folder of the `catspec.yaml` that was found, else\n * (no config, or `--config`) the git root, else `cwd`.\n */\n root: string;\n /** Absolute path of the config file, if one was found. */\n file?: string;\n}\n\n/** The closest folder at or above `dir` that contains `.git`, if any. */\nexport function findGitRoot(dir: string): string | undefined {\n for (let current = resolve(dir); ; current = dirname(current)) {\n if (existsSync(join(current, \".git\"))) return current;\n if (dirname(current) === current) return undefined;\n }\n}\n\n/**\n * The git common directory of the repository at `root` (where `.git` is): `.git` itself, or for a\n * linked worktree the main repository's `.git`, so every worktree shares one cache. Read from\n * the files git writes, without running git. Undefined outside a git repository.\n */\nexport function findGitCommonDir(root: string): string | undefined {\n const dotGit = join(root, \".git\");\n if (!existsSync(dotGit)) return undefined;\n let gitDir = dotGit;\n if (statSync(dotGit).isFile()) {\n const pointer = /^gitdir:\\s*(.+?)\\s*$/m.exec(readFileSync(dotGit, \"utf8\"));\n if (!pointer) return undefined;\n gitDir = resolve(root, pointer[1]!);\n }\n const commonDir = join(gitDir, \"commondir\");\n return existsSync(commonDir) ? resolve(gitDir, readFileSync(commonDir, \"utf8\").trim()) : gitDir;\n}\n\n/**\n * Finds `catspec.yaml` by walking up from `cwd` to the git root (or the file-system root outside\n * a git repository).\n */\nexport function findConfig(cwd: string): string | undefined {\n const stop = findGitRoot(cwd);\n for (let current = resolve(cwd); ; current = dirname(current)) {\n const candidate = join(current, CONFIG_FILE);\n if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;\n if (current === stop || dirname(current) === current) return undefined;\n }\n}\n\n/**\n * Loads the configuration for a command run in `cwd`. `configPath` (the `--config` flag) skips\n * discovery. Throws `ConfigError` for an invalid file, and when `configPath` doesn't exist.\n */\nexport async function loadConfig(cwd: string, configPath?: string): Promise<LoadedConfig> {\n const file = configPath ? resolve(cwd, configPath) : findConfig(cwd);\n if (!file) {\n return { config: defaultConfig(), root: findGitRoot(cwd) ?? resolve(cwd) };\n }\n const text = await readFile(file, \"utf8\").catch(() => undefined);\n if (text === undefined) {\n throw new ConfigError([\n { file, line: 1, column: 1, key: \"\", message: `config file not found: ${file}` },\n ]);\n }\n // A config given with --config may live anywhere (e.g. ci/catspec.yaml); the specs are still\n // found from the repository root.\n const root = configPath ? (findGitRoot(cwd) ?? resolve(cwd)) : dirname(file);\n return { config: parseConfig(text, relativePosix(root, file)), root, file };\n}\n\n/** JSON Schema of `catspec.yaml`, for editor autocompletion. */\nexport const configJsonSchema = (): Record<string, unknown> =>\n z.toJSONSchema(ConfigSchema, { io: \"input\", target: \"draft-2020-12\" });\n","/**\n * Turns zod validation issues into messages that name the YAML key, the value found and the\n * allowed values, and finds the YAML node each issue is about, so diagnostics point to the exact\n * line (plan §D5, PBIs `config-loader` and `spec-schema`).\n */\nimport { isMap, isScalar, isSeq, type Document, type Node } from \"yaml\";\nimport type * as z from \"zod\";\n\nimport type { PatchPath } from \"./diagnostics.js\";\nimport { didYouMean, listOf } from \"./util.js\";\n\nexport interface SchemaIssue {\n /** Full path of the value (or, with `atKey`, of the key) the issue is about. */\n path: PatchPath;\n /** Point at the key node instead of its value (unknown keys). */\n atKey: boolean;\n message: string;\n expected?: unknown;\n actual?: unknown;\n /** \"Did you mean\" candidates. */\n suggestions: string[];\n}\n\n/** Formats a path as `bindings[0].kind`. */\nexport function formatPath(path: PatchPath): string {\n let out = \"\";\n for (const segment of path) {\n out += typeof segment === \"number\" ? `[${segment}]` : out ? `.${segment}` : segment;\n }\n return out;\n}\n\n/** Describes a YAML value for a message: `\"klass\"`, `12`, `a list`, `a map`, `nothing`. */\nexport function describeValue(value: unknown): string {\n if (value === undefined || value === null) return \"nothing\";\n if (Array.isArray(value)) return \"a list\";\n if (typeof value === \"object\") return \"a map\";\n return JSON.stringify(value);\n}\n\ntype AnySchema = z.core.$ZodType;\n\n/** Unwraps optional / default / pipe wrappers around a schema. */\nfunction unwrap(schema: AnySchema): AnySchema {\n let current = schema;\n for (;;) {\n const def = current._zod.def as { type: string; innerType?: AnySchema; in?: AnySchema };\n if (def.innerType) current = def.innerType;\n else if (def.type === \"pipe\" && def.in) current = def.in;\n else return current;\n }\n}\n\n/** The keys an object schema at `path` accepts (for unions: the keys of every object option). */\nexport function objectKeysAt(schema: AnySchema, path: PatchPath): string[] {\n let candidates: AnySchema[] = [schema];\n for (const segment of path) {\n const next: AnySchema[] = [];\n for (const candidate of candidates.flatMap(expandUnion)) {\n const def = candidate._zod.def as {\n type: string;\n shape?: Record<string, AnySchema>;\n element?: AnySchema;\n catchall?: AnySchema;\n };\n if (def.type === \"object\" && typeof segment === \"string\") {\n const field = def.shape?.[segment] ?? def.catchall;\n if (field) next.push(field);\n } else if (def.type === \"array\" && typeof segment === \"number\" && def.element) {\n next.push(def.element);\n } else if (def.type === \"record\" && typeof segment === \"string\") {\n const value = (def as { valueType?: AnySchema }).valueType;\n if (value) next.push(value);\n }\n }\n candidates = next;\n }\n const keys = candidates\n .flatMap(expandUnion)\n .flatMap((c) => Object.keys((c._zod.def as { shape?: object }).shape ?? {}));\n return [...new Set(keys)];\n}\n\nfunction expandUnion(schema: AnySchema): AnySchema[] {\n const inner = unwrap(schema);\n const def = inner._zod.def as { type: string; options?: AnySchema[] };\n return def.type === \"union\" && def.options ? def.options.flatMap(expandUnion) : [inner];\n}\n\n/** The plain value at `path` in a YAML document, or undefined. */\nexport function valueAt(doc: Document, path: PatchPath): unknown {\n const node = doc.getIn(path, true) as Node | undefined | null;\n if (node === undefined || node === null) return undefined;\n if (isScalar(node)) return node.value;\n try {\n return node.toJSON() as unknown;\n } catch {\n return undefined; // e.g. too many aliases; the caller reports the document itself\n }\n}\n\n/**\n * The source range `[start, end)` of the node at `path` in `doc` (the key node with `atKey`). When\n * the path doesn't exist, the range of its closest existing ancestor; undefined for the root of\n * an empty document.\n */\nexport function locate(\n doc: Document,\n path: PatchPath,\n atKey = false,\n): { start: number; end: number } | undefined {\n let node = doc.contents;\n let found: [number, number, number] | undefined = node?.range ?? undefined;\n for (const [index, segment] of path.entries()) {\n const last = index === path.length - 1;\n if (isMap(node)) {\n const pair = node.items.find(\n (p) => isScalar(p.key) && String(p.key.value) === String(segment),\n );\n if (!pair || !isScalar(pair.key)) break;\n const keyRange = pair.key.range ?? found;\n if ((last && atKey) || pair.value === null || !(pair.value as Node | undefined)?.range) {\n found = keyRange;\n if (last && atKey) break;\n node = null;\n continue;\n }\n node = pair.value as Node;\n found = node.range ?? found;\n } else if (isSeq(node) && typeof segment === \"number\") {\n const item = node.items[segment] as Node | null | undefined;\n if (!item?.range) break;\n node = item;\n found = item.range;\n } else {\n break;\n }\n }\n return found ? { start: found[0], end: found[1] } : undefined;\n}\n\n/**\n * Converts zod issues for the value at `basePath` (validated by `schema`) into messages. `doc`\n * gives the values that were found; `schema` the keys that are allowed. `schemaPath` is the path\n * `schema` validates, when the issues come from a nested schema (a union branch).\n */\nexport function schemaIssues(\n issues: readonly z.core.$ZodIssue[],\n doc: Document,\n schema: AnySchema,\n basePath: PatchPath = [],\n schemaPath: PatchPath = basePath,\n): SchemaIssue[] {\n const out: SchemaIssue[] = [];\n for (const issue of issues) {\n const path = [...basePath, ...(issue.path as PatchPath)];\n const where = formatPath(path);\n const prefix = where ? `${where}: ` : \"\";\n const actual = valueAt(doc, path);\n\n switch (issue.code) {\n case \"invalid_type\": {\n if (actual === undefined && path.length > 0) {\n const parent = path.slice(0, -1);\n const key = String(path[path.length - 1]);\n const owner = formatPath(parent);\n out.push({\n path: parent,\n atKey: false,\n message: `${owner ? `${owner}: ` : \"\"}missing required key \"${key}\"`,\n expected: key,\n suggestions: [],\n });\n } else {\n out.push({\n path,\n atKey: false,\n message: `${prefix}expected ${article(issue.expected)}, found ${describeValue(actual)}`,\n expected: issue.expected,\n actual,\n suggestions: [],\n });\n }\n break;\n }\n case \"invalid_value\": {\n const values = issue.values.map((v) => (typeof v === \"string\" ? v : String(v)));\n out.push({\n path,\n atKey: false,\n message: `${prefix}invalid value ${describeValue(actual)}; allowed: ${listOf(values)}`,\n expected: issue.values,\n actual,\n suggestions: typeof actual === \"string\" ? didYouMean(actual, values) : [],\n });\n break;\n }\n case \"unrecognized_keys\": {\n const allowed = objectKeysAt(schema, path.slice(schemaPath.length)).filter(\n (k) => !issue.keys.includes(k),\n );\n for (const key of issue.keys) {\n out.push({\n path: [...path, key],\n atKey: true,\n message:\n `unknown key \"${key}\"${where ? ` in ${where}` : \"\"}` +\n (allowed.length > 0 ? `; allowed: ${listOf(allowed)}` : \"\"),\n expected: allowed,\n actual: key,\n suggestions: didYouMean(key, allowed),\n });\n }\n break;\n }\n case \"invalid_union\": {\n const discriminator = issue as typeof issue & { note?: string; options?: unknown[] };\n if (discriminator.note === \"No matching discriminator\" && discriminator.options) {\n const values = discriminator.options.map(String);\n out.push({\n path,\n atKey: false,\n message:\n actual === undefined\n ? `${formatPath(path.slice(0, -1))}: missing required key \"${String(path.at(-1))}\"; allowed values: ${listOf(values)}`\n : `${prefix}invalid value ${describeValue(actual)}; allowed: ${listOf(values)}`,\n expected: values,\n actual,\n suggestions: typeof actual === \"string\" ? didYouMean(actual, values) : [],\n });\n break;\n }\n // Report the branch that matched the value's type; if none did, name the accepted types.\n const branch = issue.errors.find(\n (errors) => !errors.some((e) => e.code === \"invalid_type\" && e.path.length === 0),\n );\n if (branch) {\n out.push(...schemaIssues(branch, doc, schema, path, schemaPath));\n } else {\n const types = issue.errors.flatMap((errors) =>\n errors.flatMap((e) => (e.code === \"invalid_type\" ? [article(e.expected)] : [])),\n );\n out.push({\n path,\n atKey: false,\n message: `${prefix}expected ${[...new Set(types)].join(\" or \")}, found ${describeValue(actual)}`,\n expected: types,\n actual,\n suggestions: [],\n });\n }\n break;\n }\n case \"too_small\":\n case \"too_big\": {\n const limit = issue.code === \"too_small\" ? issue.minimum : issue.maximum;\n const word = issue.code === \"too_small\" ? \"at least\" : \"at most\";\n const what =\n issue.origin === \"string\" && issue.code === \"too_small\" && Number(limit) === 1\n ? \"must not be empty\"\n : issue.origin === \"array\"\n ? `must have ${word} ${String(limit)} item(s)`\n : issue.origin === \"string\"\n ? `must have ${word} ${String(limit)} character(s)`\n : `must be ${word} ${String(limit)}`;\n out.push({ path, atKey: false, message: `${prefix}${what}`, actual, suggestions: [] });\n break;\n }\n default: {\n // invalid_format and custom issues carry the schema's own message.\n const message = issue.message.startsWith(\"Invalid\")\n ? `invalid value ${describeValue(actual)}`\n : issue.message;\n out.push({ path, atKey: false, message: `${prefix}${message}`, actual, suggestions: [] });\n }\n }\n }\n return out;\n}\n\nconst article = (type: string): string =>\n type === \"array\"\n ? \"a list\"\n : type === \"object\"\n ? \"a map\"\n : /^[aeiou]/.test(type)\n ? `an ${type}`\n : `a ${type}`;\n","/** Small helpers shared by the spec model: text positions, paths and \"did you mean\". */\nimport { createHash } from \"node:crypto\";\nimport { readdir } from \"node:fs/promises\";\nimport { join, relative, sep } from \"node:path\";\n\nimport picomatch from \"picomatch\";\n\nimport { compareStrings } from \"./diagnostics.js\";\n\n/** Maps string offsets to 1-based line and column numbers. Works for `\\n` and `\\r\\n` text. */\nexport class LineIndex {\n private readonly starts: number[] = [0];\n\n constructor(readonly text: string) {\n for (let i = text.indexOf(\"\\n\"); i !== -1; i = text.indexOf(\"\\n\", i + 1)) {\n this.starts.push(i + 1);\n }\n }\n\n /** 1-based line and column of `offset` (column counts UTF-16 code units). */\n position(offset: number): { line: number; column: number } {\n const clamped = Math.max(0, Math.min(offset, this.text.length));\n let low = 0;\n let high = this.starts.length - 1;\n while (low < high) {\n const mid = (low + high + 1) >> 1;\n if (this.starts[mid]! <= clamped) low = mid;\n else high = mid - 1;\n }\n return { line: low + 1, column: clamped - this.starts[low]! + 1 };\n }\n\n /** Offset of the start of a 1-based line. */\n lineStart(line: number): number {\n return this.starts[Math.max(0, Math.min(line - 1, this.starts.length - 1))]!;\n }\n}\n\n/** Converts a path to forward slashes, for output that is the same on every platform. */\nexport const toPosix = (path: string): string => (sep === \"\\\\\" ? path.replace(/\\\\/g, \"/\") : path);\n\n/** `path` relative to `root`, with forward slashes. */\nexport const relativePosix = (root: string, path: string): string => toPosix(relative(root, path));\n\n/** Joins a list as \"a, b, c\". */\n/** `text` with every regular-expression metacharacter escaped. */\nexport const escapeRegExp = (text: string): string => text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nexport const listOf = (items: readonly unknown[]): string => items.map(String).join(\", \");\n\n/** Optimal string alignment (Damerau-Levenshtein) distance between two strings. */\nexport function editDistance(a: string, b: string): number {\n const rows = a.length + 1;\n const cols = b.length + 1;\n const d: number[][] = Array.from({ length: rows }, (_, i) =>\n Array.from({ length: cols }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n );\n for (let i = 1; i < rows; i++) {\n for (let j = 1; j < cols; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n let best = Math.min(d[i - 1]![j]! + 1, d[i]![j - 1]! + 1, d[i - 1]![j - 1]! + cost);\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n best = Math.min(best, d[i - 2]![j - 2]! + 1);\n }\n d[i]![j] = best;\n }\n }\n return d[a.length]![b.length]!;\n}\n\n/**\n * Up to `max` candidates close to `input` (case-insensitive edit distance at most a third of the\n * input's length, minimum 1), closest first.\n */\nexport function didYouMean(input: string, candidates: Iterable<string>, max = 3): string[] {\n const needle = input.toLowerCase();\n const limit = Math.max(1, Math.floor(needle.length / 3));\n const scored: { candidate: string; distance: number }[] = [];\n for (const candidate of new Set(candidates)) {\n if (candidate === input) continue;\n const distance = editDistance(needle, candidate.toLowerCase());\n if (distance <= limit) scored.push({ candidate, distance });\n }\n return scored\n .sort((x, y) => x.distance - y.distance || compareStrings(x.candidate, y.candidate))\n .slice(0, max)\n .map((s) => s.candidate);\n}\n\n/** Converts a name to kebab-case: \"My Repo_2\" → \"my-repo-2\". */\nexport const kebabCase = (name: string): string =>\n name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n\n/**\n * Lists every file under `root` as a sorted, root-relative POSIX path. Skips `node_modules`,\n * dot-folders (`.git`, `.github`, …), symbolic links and nested projects (`withoutNestedProjects`).\n */\nexport async function listFiles(root: string): Promise<string[]> {\n const files: string[] = [];\n const walk = async (dir: string): Promise<void> => {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n await Promise.all(\n entries.map(async (entry) => {\n if (entry.isSymbolicLink()) return;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\" || entry.name.startsWith(\".\")) return;\n await walk(path);\n } else if (entry.isFile()) {\n files.push(relativePosix(root, path));\n }\n }),\n );\n };\n await walk(root);\n return withoutNestedProjects(files.sort(compareStrings));\n}\n\n/**\n * Leaves out the files of nested projects: a folder below the root with its own `catspec.yaml`\n * (an example repository, a vendored project) is checked on its own, not as part of the root.\n */\nexport const withoutNestedProjects = (paths: readonly string[]): string[] => {\n const nested = paths\n .filter((path) => path.endsWith(\"/catspec.yaml\"))\n .map((path) => path.slice(0, -\"catspec.yaml\".length));\n return nested.length === 0\n ? [...paths]\n : paths.filter((path) => !nested.some((folder) => path.startsWith(folder)));\n};\n\n/**\n * True for a root-relative POSIX path that `listFiles` would list: no `node_modules` and no\n * dot-folder (`.git`, `.github`, …) on the way. For listings that don't come from disk (the git\n * index), so every source sees the same files.\n */\nexport const isListedPath = (path: string): boolean =>\n path\n .split(\"/\")\n .slice(0, -1)\n .every((segment) => segment !== \"node_modules\" && !segment.startsWith(\".\"));\n\n/** A matcher for root-relative POSIX paths against globs (dot-files excluded). */\nexport const globMatcher = (patterns: string | readonly string[]): ((path: string) => boolean) =>\n picomatch(typeof patterns === \"string\" ? patterns : [...patterns], { dot: false });\n\n/** The git blob SHA-1 of a file's content: the same id `git hash-object` prints. */\nexport const gitBlobSha = (content: string | Uint8Array): string => {\n const bytes = typeof content === \"string\" ? Buffer.from(content, \"utf8\") : content;\n return createHash(\"sha1\").update(`blob ${bytes.length}\\0`).update(bytes).digest(\"hex\");\n};\n","/**\n * The `workflow:` section of `catspec.yaml` (plan §D17.1–§D17.3), PBIs `workflow-config` and\n * `workflow-presets`: stages, who drives them, what they produce, and the gates and status\n * transitions that apply when a stage starts and finishes. A preset fills in every key; the\n * config can still override any of them (`stages` replaces the preset's list as a whole).\n *\n * The section is validated with the rest of the config; its problems are config errors with the\n * code CS0700.\n */\nimport * as z from \"zod\";\n\nimport { SPEC_STATUSES, type SpecStatus } from \"../spec-schema.js\";\nimport { escapeRegExp } from \"../util.js\";\n\nexport const PRESETS = [\"catspec\", \"openspec\", \"spec-kit\", \"custom\"] as const;\nexport type PresetName = (typeof PRESETS)[number];\n\n/** The built-in gates (plan §D17.4). */\nexport const GATES = [\n \"specs_valid\",\n \"artifacts\",\n \"contracts_declared\",\n \"deps_known\",\n \"deps_ready\",\n \"contracts_pass\",\n \"tasks_done\",\n \"no_drift\",\n \"adr_valid\",\n] as const;\nexport type BuiltinGate = (typeof GATES)[number];\n\n/** Placeholders of path templates and `command:` gates. */\nexport const PLACEHOLDERS = [\"{feature}\", \"{feature_dir}\", \"{spec}\"] as const;\n\nconst PLACEHOLDER = /\\{[^{}]*\\}/g;\n\n/** The placeholders in `text` that aren't valid. */\nexport const unknownPlaceholders = (text: string): string[] =>\n [...text.matchAll(PLACEHOLDER)]\n .map((m) => m[0])\n .filter((p) => !(PLACEHOLDERS as readonly string[]).includes(p));\n\nconst template = z\n .string()\n .min(1)\n .superRefine((value, ctx) => {\n for (const placeholder of unknownPlaceholders(value)) {\n ctx.addIssue({\n code: \"custom\",\n message: `unknown placeholder \"${placeholder}\"; valid: ${PLACEHOLDERS.join(\", \")}`,\n });\n }\n });\n\nconst GateSchema = z.union([\n z.enum(GATES),\n z.strictObject({\n command: template.describe(\n \"A command that must exit with 0, run without a shell; only with workflow.allow_commands.\",\n ),\n }),\n]);\n\nconst TransitionSchema = z\n .strictObject({\n gates: z.array(GateSchema).default([]).describe(\"Gates that must pass.\"),\n status: z\n .enum(SPEC_STATUSES)\n .optional()\n .describe(\"The status the stage's specs get when the gates pass.\"),\n })\n .prefault({});\n\nconst DriverSchema = z\n .union([\n z.literal(\"manual\"),\n z.strictObject({ skill: z.string().min(1).describe(\"An agent skill, in skills_dir.\") }),\n z.strictObject({ slash: z.string().min(1).describe(\"An agent slash command.\") }),\n z.strictObject({ command: template.describe(\"A command the person or agent runs.\") }),\n z.strictObject({ manual: z.string().min(1).describe(\"What the person does.\") }),\n ])\n .describe(\"Who performs the stage.\");\n\nconst StageSchema = z.strictObject({\n id: z.string().regex(/^[a-z][a-z0-9-]*$/, { error: \"must be lowercase letters, digits and '-'\" }),\n per: z\n .enum([\"feature\", \"spec\"])\n .default(\"feature\")\n .describe(\"feature: once for the feature folder; spec: once per work item (spec).\"),\n driver: DriverSchema.default(\"manual\"),\n produces: z.array(template).default([]).describe(\"Path templates of the stage's artifacts.\"),\n start: TransitionSchema,\n finish: TransitionSchema,\n});\n\nexport const WorkflowSchema = z\n .strictObject({\n preset: z.enum(PRESETS).default(\"catspec\").describe(\"A ready-made profile, or custom.\"),\n allow_commands: z\n .boolean()\n .default(false)\n .describe(\"Let `command:` gates run commands (without a shell).\"),\n enforce_in_hook: z\n .enum([\"off\", \"warn\", \"error\"])\n .default(\"warn\")\n .describe(\"Re-check implemented specs' final gates in the pre-commit hook (CS0703).\"),\n feature_dir: z\n .union([template, z.array(template).min(1)])\n .optional()\n .describe(\n 'Where features live, e.g. \"docs/spec/{feature}\", or a list for features at several depths ' +\n '(domain folders): [\"docs/spec/billing/{feature}\", \"docs/spec/{feature}\"].',\n ),\n skills_dir: z.string().min(1).optional().describe(\"Where `skill:` drivers are found.\"),\n stages: z\n .array(StageSchema)\n .min(1)\n .optional()\n .describe(\"The stages, in order; replaces the preset's stages.\"),\n })\n .superRefine((value, ctx) => {\n const dirs = value.feature_dir;\n for (const [index, dir] of (typeof dirs === \"string\" ? [dirs] : (dirs ?? [])).entries()) {\n if (dir.split(\"{feature}\").length !== 2 || dir.includes(\"{spec}\")) {\n ctx.addIssue({\n code: \"custom\",\n path: typeof dirs === \"string\" ? [\"feature_dir\"] : [\"feature_dir\", index],\n message:\n 'feature_dir must contain \"{feature}\" exactly once and no \"{spec}\", e.g. \"docs/spec/{feature}\"',\n });\n }\n }\n const seen = new Set<string>();\n for (const [index, stage] of (value.stages ?? []).entries()) {\n if (seen.has(stage.id)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"stages\", index, \"id\"],\n message: `duplicate stage id \"${stage.id}\"`,\n });\n }\n seen.add(stage.id);\n }\n })\n .describe(\"Workflow profile (plan §D17).\");\n\nexport type WorkflowInput = z.output<typeof WorkflowSchema>;\n\nexport type Gate = BuiltinGate | { command: string };\n\nexport type Driver =\n | { kind: \"skill\"; name: string }\n | { kind: \"slash\"; name: string }\n | { kind: \"command\"; command: string }\n | { kind: \"manual\"; text?: string };\n\nexport interface Transition {\n gates: Gate[];\n status?: SpecStatus;\n}\n\nexport interface Stage {\n id: string;\n per: \"feature\" | \"spec\";\n driver: Driver;\n produces: string[];\n start: Transition;\n finish: Transition;\n}\n\n/** The workflow in effect: the preset with the config's overrides. */\nexport interface WorkflowProfile {\n preset: PresetName;\n /** The version of the third-party tool layout the preset follows. */\n presetVersion?: string;\n allowCommands: boolean;\n enforceInHook: \"off\" | \"warn\" | \"error\";\n /** The first feature folder pattern, for messages and templates. */\n featureDir: string;\n /** Every feature folder pattern, most specific first (see `featureFolderOf`). */\n featureDirs: string[];\n skillsDir: string;\n stages: Stage[];\n /** Folder names under the feature folder's parent that aren't features (OpenSpec's archive). */\n notFeatures: string[];\n /** Files every stage passes to agents as extra context (Spec Kit's constitution). */\n context: string[];\n /** The `specs.include` default that matches this workflow's feature folders. */\n specsInclude: string[];\n /** The `layout` default: `free` when specs move out of their feature folder (OpenSpec). */\n layout: \"feature-folders\" | \"free\";\n}\n\nexport const gateName = (gate: Gate): string =>\n typeof gate === \"string\" ? gate : `command: ${gate.command}`;\n\nexport const driverText = (driver: Driver): string => {\n switch (driver.kind) {\n case \"skill\":\n return `skill ${driver.name}`;\n case \"slash\":\n return `slash command ${driver.name}`;\n case \"command\":\n return `command \\`${driver.command}\\``;\n case \"manual\":\n return driver.text ? `manual: ${driver.text}` : \"manual\";\n }\n};\n\nconst driverOf = (input: z.output<typeof DriverSchema>): Driver => {\n if (input === \"manual\") return { kind: \"manual\" };\n if (\"skill\" in input) return { kind: \"skill\", name: input.skill };\n if (\"slash\" in input) return { kind: \"slash\", name: input.slash };\n if (\"command\" in input) return { kind: \"command\", command: input.command };\n return { kind: \"manual\", text: input.manual };\n};\n\nconst transition = (gates: Gate[], status?: SpecStatus): Transition =>\n status === undefined ? { gates } : { gates, status };\n\nconst stage = (\n id: string,\n per: Stage[\"per\"],\n driver: Driver,\n produces: string[],\n start: Transition,\n finish: Transition,\n): Stage => ({ id, per, driver, produces, start, finish });\n\n/** The stages of CatSpec's own flow (plan §D17.2) with the given drivers. */\nconst catspecStages = (drivers: Record<\"spec\" | \"plan\" | \"task\" | \"close\", Driver>): Stage[] => [\n stage(\n \"spec\",\n \"feature\",\n drivers.spec,\n [\"{feature_dir}/spec.md\", \"{feature_dir}/*.spec.md\"],\n transition([]),\n transition([\"specs_valid\", \"artifacts\", \"contracts_declared\"]),\n ),\n stage(\n \"plan\",\n \"feature\",\n drivers.plan,\n [\"{feature_dir}/plan.md\"],\n transition([]),\n transition([\"artifacts\", \"deps_known\"], \"ready\"),\n ),\n stage(\n \"task\",\n \"spec\",\n drivers.task,\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([\"contracts_pass\"]),\n ),\n stage(\n \"close\",\n \"spec\",\n drivers.close,\n [],\n transition([]),\n transition([\"contracts_pass\", \"tasks_done\", \"no_drift\"], \"implemented\"),\n ),\n];\n\ntype Preset = Omit<WorkflowProfile, \"allowCommands\" | \"enforceInHook\" | \"preset\" | \"featureDirs\">;\n\n/**\n * The presets (plan §D17.3). Third-party layouts and command names were checked on 2026-10-22:\n * OpenSpec 1.x (`/opsx:*` slash commands, `openspec validate`, changes archived to\n * `openspec/changes/archive/<date>-<name>/`) and Spec Kit (`/speckit.*` commands, feature folders\n * `specs/<NNN-name>/`, constitution in `.specify/memory/constitution.md`).\n */\nexport const PRESET_PROFILES: Record<Exclude<PresetName, \"custom\">, Preset> = {\n catspec: {\n featureDir: \"docs/spec/{feature}\",\n skillsDir: \".claude/skills\",\n stages: catspecStages({\n spec: {\n kind: \"manual\",\n text: \"write spec.md and the *.spec.md work items (MCP prompt stage-spec)\",\n },\n plan: {\n kind: \"manual\",\n text: \"order the work items and write plan.md (MCP prompt stage-plan)\",\n },\n task: { kind: \"manual\", text: \"implement the work item (MCP prompt stage-task)\" },\n close: {\n kind: \"manual\",\n text: \"tick the tasks and close the work item (MCP prompt stage-close)\",\n },\n }),\n notFeatures: [],\n context: [],\n specsInclude: [\"docs/spec/*/*.spec.md\"],\n layout: \"feature-folders\",\n },\n openspec: {\n presetVersion: \"openspec-1\",\n featureDir: \"openspec/changes/{feature}\",\n skillsDir: \".claude/skills\",\n stages: [\n stage(\n \"proposal\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:propose\" },\n [\"{feature_dir}/proposal.md\", \"{feature_dir}/tasks.md\"],\n transition([]),\n transition([\"artifacts\", { command: \"openspec validate {feature}\" }, \"specs_valid\"]),\n ),\n stage(\n \"apply\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:apply\" },\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([]),\n ),\n stage(\n \"archive\",\n \"feature\",\n { kind: \"slash\", name: \"/opsx:archive\" },\n [],\n transition([\"contracts_pass\", \"tasks_done\"], \"implemented\"),\n transition([]),\n ),\n ],\n notFeatures: [\"archive\"],\n context: [],\n specsInclude: [\"openspec/changes/**/*.spec.md\"],\n layout: \"free\",\n },\n \"spec-kit\": {\n presetVersion: \"spec-kit-1\",\n featureDir: \"specs/{feature}\",\n skillsDir: \".claude/skills\",\n stages: [\n stage(\n \"specify\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.specify\" },\n [\"{feature_dir}/spec.md\"],\n transition([]),\n transition([\"artifacts\", \"specs_valid\"]),\n ),\n stage(\n \"plan\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.plan\" },\n [\"{feature_dir}/plan.md\"],\n transition([]),\n transition([\"artifacts\", \"deps_known\"], \"ready\"),\n ),\n stage(\n \"tasks\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.tasks\" },\n [\"{feature_dir}/tasks.md\"],\n transition([]),\n transition([\"artifacts\"]),\n ),\n stage(\n \"implement\",\n \"feature\",\n { kind: \"slash\", name: \"/speckit.implement\" },\n [],\n transition([\"deps_ready\"], \"in-progress\"),\n transition([\"contracts_pass\", \"tasks_done\"], \"implemented\"),\n ),\n ],\n notFeatures: [],\n context: [\".specify/memory/constitution.md\"],\n specsInclude: [\"specs/*/*.spec.md\"],\n layout: \"feature-folders\",\n },\n};\n\n/** The `sdd-*` skills of the custom preset's example (plan §D17.2). */\nexport const SDD_SKILLS = [\"sdd-spec\", \"sdd-plan\", \"sdd-task\", \"sdd-close\"] as const;\n\n/** `specs.include` for machine specs directly in each feature folder. */\nconst includeFor = (featureDirs: readonly string[]): string[] =>\n featureDirs.map((dir) => `${dir.replaceAll(\"{feature}\", \"*\").replace(/\\/+$/, \"\")}/*.spec.md`);\n\n/** Feature folder patterns, most specific first: more folders, then longer. */\nconst bySpecificity = (dirs: readonly string[]): string[] =>\n [...new Set(dirs)].sort(\n (a, b) => b.split(\"/\").length - a.split(\"/\").length || b.length - a.length,\n );\n\n/** A feature folder: its name (`{feature}`) and its path. */\nexport interface FeatureFolder {\n name: string;\n dir: string;\n}\n\n/**\n * The feature folder a root-relative path is in, by the most specific matching pattern of\n * `featureDirs`. The folders that hold another pattern's features (`docs/spec/billing` for\n * `docs/spec/billing/{feature}`) are never features themselves.\n */\nexport function featureFolderOf(\n featureDirs: readonly string[],\n path: string,\n): FeatureFolder | undefined {\n const parents = new Set(\n featureDirs.map((dir) => dir.slice(0, dir.indexOf(\"{feature}\")).replace(/\\/+$/, \"\")),\n );\n for (const dir of featureDirs) {\n const [before, after] = dir.split(\"{feature}\").map(escapeRegExp);\n const match = new RegExp(`^(${before}([^/]+)${after})/`).exec(path);\n if (match && !parents.has(match[1]!)) return { name: match[2]!, dir: match[1]! };\n }\n return undefined;\n}\n\n/** The feature folder patterns in words, for messages: \"docs/spec/{feature}\". */\nexport const featureDirsText = (profile: WorkflowProfile): string => profile.featureDirs.join(\", \");\n\n/** The profile in effect for a validated `workflow:` section. */\nexport function resolveWorkflow(input: WorkflowInput): WorkflowProfile {\n const base: Preset =\n input.preset === \"custom\"\n ? {\n featureDir: \"docs/spec/{feature}\",\n skillsDir: \".claude/skills\",\n stages: catspecStages({\n spec: { kind: \"skill\", name: \"sdd-spec\" },\n plan: { kind: \"skill\", name: \"sdd-plan\" },\n task: { kind: \"skill\", name: \"sdd-task\" },\n close: { kind: \"skill\", name: \"sdd-close\" },\n }),\n notFeatures: [],\n context: [],\n specsInclude: [\"docs/spec/*/*.spec.md\"],\n layout: \"feature-folders\",\n }\n : PRESET_PROFILES[input.preset];\n const configured = input.feature_dir ?? base.featureDir;\n const dirs = (typeof configured === \"string\" ? [configured] : configured).map((d) =>\n d.replace(/\\/+$/, \"\"),\n );\n const featureDir = dirs[0]!;\n const featureDirs = bySpecificity(dirs);\n const stages =\n input.stages?.map((s) =>\n stage(\n s.id,\n s.per,\n driverOf(s.driver),\n s.produces,\n transition(s.start.gates, s.start.status),\n transition(s.finish.gates, s.finish.status),\n ),\n ) ?? base.stages;\n return {\n preset: input.preset,\n ...(base.presetVersion ? { presetVersion: base.presetVersion } : {}),\n allowCommands: input.allow_commands,\n enforceInHook: input.enforce_in_hook,\n featureDir,\n featureDirs,\n skillsDir: (input.skills_dir ?? base.skillsDir).replace(/\\/+$/, \"\"),\n stages,\n notFeatures: base.notFeatures,\n context: base.context,\n specsInclude:\n dirs.length === 1 && featureDir === base.featureDir\n ? base.specsInclude\n : includeFor(featureDirs),\n layout: base.layout,\n };\n}\n","/**\n * Schema of the spec frontmatter (plan §D5.2, §D5.3, §D6.1–6.3, §D6.5), PBI `spec-schema`.\n * The zod schemas validate; the JSON Schema exported from them documents the format.\n */\nimport * as z from \"zod\";\n\nexport const SPEC_TYPES = [\"feature\", \"component\", \"contract\", \"architecture\", \"adr\"] as const;\nexport const SPEC_STATUSES = [\n \"draft\",\n \"ready\",\n \"in-progress\",\n \"implemented\",\n \"deprecated\",\n] as const;\nexport const BINDING_KINDS = [\n \"class\",\n \"interface\",\n \"struct\",\n \"enum\",\n \"record\",\n \"function\",\n \"method\",\n \"type\",\n \"module\",\n] as const;\nexport const MEMBER_KINDS = [\"method\", \"property\", \"field\", \"event\", \"constructor\"] as const;\nexport const MODIFIERS = [\n \"public\",\n \"private\",\n \"protected\",\n \"internal\",\n \"static\",\n \"async\",\n \"abstract\",\n \"override\",\n \"readonly\",\n] as const;\nexport const RULE_CLASSES = [\"structural\", \"query\", \"test\", \"manual\"] as const;\n/** The structural rule catalogue (plan §D6.2): a structural rule uses exactly one of these keys. */\nexport const STRUCTURAL_KINDS = [\n \"forbid_call\",\n \"require_call\",\n \"forbid_import\",\n \"allow_import_only\",\n \"naming\",\n \"must_not_exist\",\n] as const;\n\nexport type SpecType = (typeof SPEC_TYPES)[number];\nexport type SpecStatus = (typeof SPEC_STATUSES)[number];\nexport type BindingKind = (typeof BINDING_KINDS)[number];\nexport type MemberKind = (typeof MEMBER_KINDS)[number];\nexport type Modifier = (typeof MODIFIERS)[number];\nexport type RuleClass = (typeof RULE_CLASSES)[number];\n\nexport const SPEC_ID_PATTERN = /^[a-z0-9][a-z0-9-]{1,63}$/;\n\nconst specId = z.string().regex(SPEC_ID_PATTERN, {\n error:\n \"must be 2–64 characters of lowercase letters, digits and '-', starting with a letter or digit\",\n});\nconst text = z.string().min(1);\nconst textList = z.array(text);\n/** A string or a list of strings; always a list in the model. */\nconst oneOrMany = z\n .union([text, textList])\n .transform((value): string[] => (typeof value === \"string\" ? [value] : value));\n\nexport const MemberSchema = z.strictObject({\n name: text,\n kind: z.enum(MEMBER_KINDS).optional(),\n params: textList.optional().describe('Parameter types, positional; \"*\" matches any type.'),\n returns: text.optional(),\n modifiers: z.array(z.enum(MODIFIERS)).optional(),\n attributes: textList.optional(),\n optional: z.boolean().default(false),\n});\n\n/** A member, or its name as shorthand for a name-only member of any kind. */\nexport const MemberEntrySchema = z.union([text, MemberSchema]);\n\nconst ConstructorSchema = z.strictObject({ requires: textList });\n/**\n * `constructor` is also the name of a property every JavaScript object inherits, which zod reads\n * when the key is missing; that inherited function means \"not set\".\n */\nconst constructorField = z.preprocess(\n (value) => (typeof value === \"function\" ? undefined : value),\n ConstructorSchema.optional(),\n);\n\nexport const BindingSchema = z.strictObject({\n id: text.optional().describe(\"Local id; defaults to the last segment of `symbol`.\"),\n symbol: text.describe(\"Qualified name, matched by suffix: Namespace.Type or path#Name.\"),\n kind: z.enum(BINDING_KINDS).optional(),\n lang: text.optional(),\n file: oneOrMany.optional().describe(\"Hint: a path, a glob, or a list of them.\"),\n implements: textList.optional(),\n extends: text.optional(),\n attributes: textList.optional(),\n constructor: constructorField,\n members: z.array(MemberEntrySchema).optional(),\n exported: z.boolean().optional(),\n});\n\nconst ruleCommon = {\n id: text,\n message: text.optional(),\n adr: z\n .string()\n .regex(/^ADR-\\d+$/, { error: \"must be an ADR id such as ADR-001\" })\n .optional(),\n paths: textList.optional(),\n};\n\nconst importRule = z.strictObject({ from: oneOrMany, to: oneOrMany });\n\nexport const StructuralRuleSchema = z\n .strictObject({\n ...ruleCommon,\n class: z.literal(\"structural\"),\n within: text.optional().describe(\"A binding id, or binding.member.\"),\n forbid_call: text.optional(),\n require_call: text.optional(),\n forbid_import: importRule.optional(),\n allow_import_only: importRule.optional(),\n naming: z\n .strictObject({\n kind: z.enum(BINDING_KINDS).optional(),\n name: text,\n implements: textList.optional(),\n extends: text.optional(),\n attributes: textList.optional(),\n in_path: oneOrMany.optional(),\n })\n .optional(),\n must_not_exist: z\n .strictObject({ symbol: text, kind: z.enum(BINDING_KINDS).optional() })\n .optional(),\n })\n .superRefine((rule, ctx) => {\n const used = STRUCTURAL_KINDS.filter((key) => rule[key] !== undefined);\n if (used.length !== 1) {\n ctx.addIssue({\n code: \"custom\",\n message:\n used.length === 0\n ? `a structural rule needs one of ${STRUCTURAL_KINDS.join(\", \")}`\n : `a structural rule uses exactly one of ${STRUCTURAL_KINDS.join(\", \")}; found ${used.join(\", \")}`,\n });\n }\n });\n\nexport const QueryRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"query\"),\n lang: text,\n query: text.describe(\"A Tree-sitter query.\"),\n expect: z.enum([\"absent\", \"present\"]).default(\"absent\"),\n within: text.optional(),\n});\n\nexport const TestRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"test\"),\n test: z.strictObject({ symbol: text, lang: text.optional() }),\n});\n\nexport const ManualRuleSchema = z.strictObject({\n ...ruleCommon,\n class: z.literal(\"manual\"),\n text,\n});\n\n/** Rule schemas by class; `class` selects the schema. */\nexport const RULE_SCHEMAS = {\n structural: StructuralRuleSchema,\n query: QueryRuleSchema,\n test: TestRuleSchema,\n manual: ManualRuleSchema,\n} as const;\n\nexport const RuleSchema = z.discriminatedUnion(\"class\", [\n StructuralRuleSchema,\n QueryRuleSchema,\n TestRuleSchema,\n ManualRuleSchema,\n]);\n\nconst isoDate = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}$/, { error: \"must be a date: YYYY-MM-DD\" })\n .refine(\n (value) => {\n const [year, month, day] = value.split(\"-\").map(Number) as [number, number, number];\n const date = new Date(Date.UTC(year, month - 1, day));\n return date.getUTCMonth() === month - 1 && date.getUTCDate() === day;\n },\n { error: \"must be a date that exists\" },\n );\n\nexport const WaiverSchema = z.strictObject({\n rule: text,\n reason: text,\n until: isoDate.optional(),\n paths: textList.optional(),\n});\n\nconst reference = z.union([text, z.number()]);\n\n/** The frontmatter. Unknown top-level keys are allowed (warning CS0102). */\nexport const SpecFrontmatterSchema = z\n .looseObject({\n catspec: z.literal(1).describe(\"Spec format version.\"),\n id: specId.describe(\"Unique across the repository.\"),\n title: text.optional().describe(\"Defaults to the first # heading.\"),\n type: z.enum(SPEC_TYPES).describe(\"architecture makes the rules global.\"),\n status: z.enum(SPEC_STATUSES),\n depends_on: z.array(text).optional().describe(\"Ids of the specs this one depends on.\"),\n owners: textList.optional(),\n scope: textList.optional().describe(\"Extra paths (globs) that belong to this spec.\"),\n bindings: z.array(BindingSchema).optional(),\n rules: z.array(RuleSchema).optional(),\n infrastructure: z.array(z.record(z.string(), z.unknown())).optional(),\n waivers: z.array(WaiverSchema).optional(),\n links: z\n .strictObject({\n pr: reference.optional(),\n issue: reference.optional(),\n commit: text.optional(),\n })\n .optional(),\n })\n .describe(\"Frontmatter of a CatSpec spec file (*.spec.md).\");\n\nexport const FRONTMATTER_KEYS = Object.keys(SpecFrontmatterSchema.shape);\n\nexport type RuleInput = z.output<typeof RuleSchema>;\nexport type Rule = RuleInput & {\n /** Position in the `rules` list. */\n index: number;\n};\nexport type StructuralRule = z.output<typeof StructuralRuleSchema> & { index: number };\nexport type Waiver = z.output<typeof WaiverSchema> & { index: number };\nexport type Links = NonNullable<z.output<typeof SpecFrontmatterSchema>[\"links\"]>;\n\nexport interface Member {\n name: string;\n /** Undefined means any kind. */\n kind?: MemberKind;\n params?: string[];\n returns?: string;\n modifiers?: Modifier[];\n attributes?: string[];\n optional: boolean;\n}\n\nexport interface Binding {\n /** Local id; the last segment of `symbol` unless set. */\n id: string;\n symbol: string;\n kind?: BindingKind;\n lang?: string;\n /** Location hints (paths or globs). */\n file?: string[];\n implements?: string[];\n extends?: string;\n attributes?: string[];\n /** `constructor.requires`: types a constructor must take. */\n constructorRequires?: string[];\n members: Member[];\n exported?: boolean;\n /** Position in the `bindings` list. */\n index: number;\n}\n\n/** Normalises a parsed binding: default id, shorthand members, `constructor.requires`. */\nexport function normalizeBinding(input: z.output<typeof BindingSchema>, index: number): Binding {\n const { id, constructor, members, ...rest } = input;\n const binding: Binding = {\n ...stripUndefined(rest),\n id: id ?? defaultBindingId(input.symbol),\n members: (members ?? []).map((m) =>\n typeof m === \"string\" ? { name: m, optional: false } : stripUndefined(m),\n ),\n index,\n };\n if (constructor) binding.constructorRequires = constructor.requires;\n return binding;\n}\n\n/** `Identity.Handlers.UserUpdatedHandler` → `UserUpdatedHandler`; `src/a#Name.member` → `member`. */\nexport const defaultBindingId = (symbol: string): string =>\n symbol.split(\"#\").pop()!.split(\".\").pop() || symbol;\n\n/** `T` without explicit `undefined` values: optional keys stay optional but can't be undefined. */\nexport type DropUndefined<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K];\n} & { [K in keyof T as undefined extends T[K] ? K : never]?: Exclude<T[K], undefined> };\n\n/** Removes keys whose value is undefined (for `exactOptionalPropertyTypes`). */\nexport function stripUndefined<T extends object>(value: T): DropUndefined<T> {\n return Object.fromEntries(\n Object.entries(value).filter(([, v]) => v !== undefined),\n ) as DropUndefined<T>;\n}\n\n/** JSON Schema of the spec frontmatter. */\nexport const specJsonSchema = (): Record<string, unknown> =>\n z.toJSONSchema(SpecFrontmatterSchema, {\n io: \"input\",\n target: \"draft-2020-12\",\n override: (ctx) => {\n // The preprocess step of `constructor` has no JSON Schema; describe the value it accepts.\n if (ctx.zodSchema !== constructorField) return;\n Object.assign(ctx.jsonSchema, z.toJSONSchema(ConstructorSchema, { io: \"input\" }));\n delete ctx.jsonSchema.$schema;\n },\n });\n","/**\n * The language-independent facts model (plan §D11.2, ADR-003). Language adapters turn a source\n * file into `FileFacts`; rules and binding resolution read only these facts, never syntax trees,\n * so `core` stays free of Tree-sitter and of every adapter.\n */\nimport { createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport { BINDING_KINDS, MEMBER_KINDS } from \"./spec-schema.js\";\n\n/** Every kind a symbol fact can have: the binding kinds plus the member kinds. */\nexport const SYMBOL_KINDS = [...new Set([...BINDING_KINDS, ...MEMBER_KINDS])] as const;\nexport type SymbolKind = (typeof SYMBOL_KINDS)[number];\n\n/** A position in a source file: 1-based line, 1-based column in UTF-16 code units. */\nexport interface Position {\n line: number;\n column: number;\n}\n\n/** A span of a source file; `end` is exclusive. */\nexport interface Range {\n start: Position;\n end: Position;\n}\n\n/** A source file handed to an adapter. */\nexport interface SourceFile {\n /** Path relative to the repository root, with forward slashes. */\n path: string;\n text: string;\n /** Git blob SHA of `text`: the cache key of the facts. */\n blobSha: string;\n}\n\n/**\n * A type reference as written, normalised by the adapter: `Contracts.IHandler<Events.Created>`\n * is `{ name: [\"Contracts\", \"IHandler\"], args: [{ name: [\"Events\", \"Created\"], … }] }`. Types that\n * aren't a (generic) name, such as unions or function types, have an empty `name` and keep their\n * normalised `text`.\n */\nexport interface TypeRef {\n /** The normalised type text. */\n text: string;\n /** Qualified name segments. */\n name: string[];\n /** Generic type arguments. */\n args: TypeRef[];\n}\n\n/** A decorator (TypeScript) or attribute (C#), with its arguments as source text. */\nexport interface AttributeFact {\n name: string;\n args: string[];\n range: Range;\n}\n\nexport interface ParamFact {\n name: string;\n type?: TypeRef;\n /** e.g. `readonly`, `private` on a TypeScript parameter property; `ref`, `out` in C#. */\n modifiers: string[];\n optional?: boolean;\n rest?: boolean;\n attributes: AttributeFact[];\n}\n\nexport interface SymbolFact {\n /** `${path}#${qualifiedName}`, plus `(${arity})` for overload signatures and `#${n}` when arities repeat. */\n id: string;\n name: string;\n /** Name qualified by its enclosing declarations, e.g. `Outer.Inner.method`. */\n qualifiedName: string;\n kind: SymbolKind;\n range: Range;\n nameRange: Range;\n modifiers: string[];\n attributes: AttributeFact[];\n /** Base classes and implemented interfaces. */\n bases: TypeRef[];\n typeParams: string[];\n params?: ParamFact[];\n /** Return type; for a property, its declared type. */\n returns?: TypeRef;\n /** Nested declarations and members. */\n members: SymbolFact[];\n /** C# `partial` declarations, merged during binding resolution. */\n partial?: boolean;\n exported?: boolean;\n /** Body tokens, for rename similarity only; never cached or written to lock files. */\n bodyTokens?: string[];\n}\n\nexport type ImportKind = \"static\" | \"type\" | \"dynamic\" | \"require\" | \"reexport\";\n\nexport interface ImportedName {\n /** The exported name, `default` or `*`. */\n name: string;\n /** The local name when it differs. */\n alias?: string;\n}\n\nexport interface ImportFact {\n /** Module specifier as written, e.g. `./auth` or `System.Linq`. */\n module: string;\n kind: ImportKind;\n /** Imported names; empty for a side-effect import. */\n names: ImportedName[];\n range: Range;\n}\n\nexport interface CallFact {\n /** Callee as written, whitespace removed, e.g. `console.log` or `this.repo.save`. */\n callee: string;\n /** Id of the innermost enclosing symbol; undefined at the top level. */\n enclosing?: string;\n range: Range;\n}\n\nexport interface FileFacts {\n path: string;\n blobSha: string;\n /** Id of the adapter that produced the facts. */\n lang: string;\n /** Top-level declarations; nested ones are in `members`. */\n symbols: SymbolFact[];\n imports: ImportFact[];\n calls: CallFact[];\n /** Syntax errors; the facts around them are still extracted (see `parseErrorDiagnostics`). */\n parseErrors: Range[];\n /**\n * Why the file wasn't parsed (it is larger than `MAX_SOURCE_BYTES`, or the adapter failed on\n * it); the facts are then empty and the file gets one CS0901 warning.\n */\n skipped?: string;\n}\n\n/** Source files larger than this (in bytes) aren't parsed (CS0901). */\nexport const MAX_SOURCE_BYTES = 1024 * 1024;\n\n/** A language plug-in. `core` defines the interface; `cli` and `mcp` inject implementations. */\nexport interface LanguageAdapter {\n /** Language id, also its key under `languages` in `catspec.yaml`. */\n readonly id: string;\n /** File extensions with the dot, e.g. `.ts`. */\n readonly extensions: readonly string[];\n /** Adapter and grammar version; cached facts of another version are extracted again. */\n readonly version: string;\n /** Loads the grammar and compiles the queries. Called once before `extract`. */\n load(): Promise<void>;\n /** Extracts the facts of one file. Pure, so the result can be cached by blob SHA. */\n extract(file: SourceFile): FileFacts;\n /** Normalises a type as written in this language. */\n normalizeType(text: string): TypeRef;\n /** The qualified name of a symbol of `file`. */\n qualify(symbol: SymbolFact, file: SourceFile): string;\n /**\n * Compiles the raw Tree-sitter query of a `query` rule (plan §D6.3; the only place rules see\n * syntax, ADR-003). Returns the error message, or undefined when the query compiles. An adapter\n * without it doesn't support `query` rules (CS0130).\n */\n checkQuery?(query: string): string | undefined;\n /**\n * Runs a compiled query on a file: the range of each `@hit` capture, or of each match's first\n * capture when the query has no `@hit`.\n */\n runQuery?(file: SourceFile, query: string): Range[];\n}\n\n/**\n * One CS0901 warning per syntax error of the file, at the error's location; one at the start of a\n * skipped file.\n */\nexport function parseErrorDiagnostics(facts: FileFacts): Diagnostic[] {\n if (facts.skipped !== undefined) {\n return [\n createDiagnostic(\"CS0901\", {\n codeLocation: { file: facts.path, line: 1, column: 1 },\n message: `file not parsed: ${facts.skipped}`,\n }),\n ];\n }\n return facts.parseErrors.map(({ start, end }) =>\n createDiagnostic(\"CS0901\", {\n codeLocation: {\n file: facts.path,\n line: start.line,\n column: start.column,\n endLine: end.line,\n endColumn: end.column,\n },\n message: \"syntax error; the declarations before and after it are still read\",\n }),\n );\n}\n","/**\n * Syntactic name and type matching (plan §D11.5, analysis F-5, ADR-002), shared by the binding\n * resolver and the rules: a name written in a spec matches a declaration when it is a segment-wise\n * suffix of the declaration's qualified name.\n */\nimport type { TypeRef } from \"./facts.js\";\n\n/** True when `suffix` equals the last segments of `name`. */\nexport function isSegmentSuffix(suffix: readonly string[], name: readonly string[]): boolean {\n if (suffix.length === 0 || suffix.length > name.length) return false;\n const offset = name.length - suffix.length;\n return suffix.every((segment, i) => segment === name[offset + i]);\n}\n\n/**\n * True when the type found in code satisfies the expected one: the expected name is a\n * segment-wise suffix of the found name and the generic arguments match pairwise, recursively.\n * Types without a name match only by equal normalised text.\n */\nexport function typeMatches(expected: TypeRef, found: TypeRef): boolean {\n if (expected.name.length === 0 || found.name.length === 0) {\n return expected.name.length === found.name.length && expected.text === found.text;\n }\n return (\n isSegmentSuffix(expected.name, found.name) &&\n expected.args.length === found.args.length &&\n expected.args.every((arg, i) => typeMatches(arg, found.args[i]!))\n );\n}\n\n/**\n * True when a symbol's qualified name (`Outer.Inner.method`) ends with the expected name\n * (`Inner.method`), segment by segment: `Handler` doesn't match `MyHandler`.\n */\nexport const nameMatches = (expected: string, qualifiedName: string): boolean =>\n isSegmentSuffix(expected.split(\".\"), qualifiedName.split(\".\"));\n\nconst escapeRegExp = (text: string): string => text.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * A matcher for a pattern in which `*` stands for any text, dots included: `console.*` matches\n * `console.log`, `IMessageHandler<*>` matches `IMessageHandler<UserUpdated>`. Without a `*` the\n * text must equal the pattern.\n */\nexport function wildcard(pattern: string): (text: string) => boolean {\n const regex = new RegExp(`^${pattern.split(\"*\").map(escapeRegExp).join(\"[^]*\")}$`);\n return (text) => regex.test(text);\n}\n\n/**\n * True when a qualified name matches a pattern written in a spec: segment-wise suffix match\n * without `*`; with `*`, the pattern must match the name or the name without some leading\n * segments (`*Handler` matches `Handlers.UserHandler`).\n */\nexport function qualifiedNameMatches(pattern: string, qualifiedName: string): boolean {\n if (!pattern.includes(\"*\")) return nameMatches(pattern, qualifiedName);\n const matches = wildcard(pattern);\n const segments = qualifiedName.split(\".\");\n return segments.some((_, i) => matches(segments.slice(i).join(\".\")));\n}\n\n/**\n * True when a type found in code matches a type pattern from a spec: `*` matches any text and the\n * pattern may omit leading namespace segments of the found type.\n */\nexport function typePatternMatches(pattern: string, found: TypeRef): boolean {\n const matches = wildcard(pattern.replace(/\\s+/g, \"\").replace(/,/g, \", \"));\n if (matches(found.text)) return true;\n const args = found.text.slice(found.name.join(\".\").length);\n return found.name.some((_, i) => matches(found.name.slice(i).join(\".\") + args));\n}\n","/**\n * The code a check runs on (plan §D11.3): the facts of every source file of the configured\n * languages and the adapters that produced them. `cli` and `mcp` build it with the adapters they\n * inject (ADR-003); the rule engine reads only these facts, plus raw syntax for `query` rules\n * through the adapter.\n */\nimport type { Location } from \"./diagnostics.js\";\nimport type { FileFacts, LanguageAdapter, Range, SourceFile, SymbolFact } from \"./facts.js\";\nimport { qualifiedNameMatches } from \"./match.js\";\n\nexport interface Codebase {\n /** Facts of every source file, sorted by path. */\n readonly files: readonly FileFacts[];\n /** The adapter of a language id, if one is installed. */\n adapter(lang: string): LanguageAdapter | undefined;\n /** The source of a file of `files`, for `query` rules. */\n source(path: string): Promise<SourceFile>;\n}\n\n/** A declaration with the file it is in. */\nexport interface SymbolEntry {\n symbol: SymbolFact;\n file: FileFacts;\n}\n\n/** Every declaration of a codebase, top-level and nested, indexed by simple name. */\nexport class SymbolTable {\n readonly entries: SymbolEntry[] = [];\n private readonly byName = new Map<string, SymbolEntry[]>();\n readonly byPath = new Map<string, FileFacts>();\n\n constructor(files: readonly FileFacts[]) {\n const add = (symbol: SymbolFact, file: FileFacts): void => {\n const entry = { symbol, file };\n this.entries.push(entry);\n const named = this.byName.get(symbol.name);\n if (named) named.push(entry);\n else this.byName.set(symbol.name, [entry]);\n for (const member of symbol.members) add(member, file);\n };\n for (const file of files) {\n this.byPath.set(file.path, file);\n for (const symbol of file.symbols) add(symbol, file);\n }\n }\n\n /**\n * Declarations whose qualified name matches `name` (segment-wise suffix; `*` wildcards), in\n * file order.\n */\n find(name: string): SymbolEntry[] {\n if (name.includes(\"*\")) {\n return this.entries.filter((e) => qualifiedNameMatches(name, e.symbol.qualifiedName));\n }\n const last = name.slice(name.lastIndexOf(\".\") + 1);\n return (this.byName.get(last) ?? []).filter((e) =>\n qualifiedNameMatches(name, e.symbol.qualifiedName),\n );\n }\n}\n\n/** A location in the code. */\nexport const codeLocation = (file: string, range: Range): Location => ({\n file,\n line: range.start.line,\n column: range.start.column,\n endLine: range.end.line,\n endColumn: range.end.column,\n});\n\n/** `file:line:column` of a range, for messages. */\nexport const formatLocation = (file: string, range: Range): string =>\n `${file}:${range.start.line}:${range.start.column}`;\n\nconst comparePositions = (a: Range[\"start\"], b: Range[\"start\"]): number =>\n a.line - b.line || a.column - b.column;\n\n/** True when `outer` contains `inner`. */\nexport const rangeContains = (outer: Range, inner: Range): boolean =>\n comparePositions(outer.start, inner.start) <= 0 && comparePositions(inner.end, outer.end) <= 0;\n","/**\n * Reads one spec file into the normalised model (PBI `spec-schema`): validates the frontmatter\n * field by field, so one mistake doesn't hide the others, maps every problem to its line, expands\n * shorthand forms, and checks the body's references (PBI `body-parser`).\n */\nimport { isMap } from \"yaml\";\nimport type * as z from \"zod\";\n\nimport {\n createDiagnostic,\n type Diagnostic,\n type DiagnosticCode,\n type Location,\n type PatchPath,\n} from \"./diagnostics.js\";\nimport { frontmatterLocation, parseSpecSource, type SpecSource } from \"./frontmatter.js\";\nimport { describeValue, locate, schemaIssues, valueAt, type SchemaIssue } from \"./schema-issues.js\";\nimport { parseBody, type SpecBody } from \"./spec-body.js\";\nimport {\n BindingSchema,\n defaultBindingId,\n FRONTMATTER_KEYS,\n RULE_CLASSES,\n RULE_SCHEMAS,\n SpecFrontmatterSchema,\n normalizeBinding,\n stripUndefined,\n type Binding,\n type Links,\n type Rule,\n type SpecStatus,\n type SpecType,\n type Waiver,\n} from \"./spec-schema.js\";\nimport { didYouMean, listOf } from \"./util.js\";\n\nexport interface Spec {\n id: string;\n /** Path relative to the repository root, with forward slashes. */\n file: string;\n title: string;\n type: SpecType;\n status: SpecStatus;\n dependsOn: string[];\n owners: string[];\n scope: string[];\n bindings: Binding[];\n rules: Rule[];\n infrastructure: Record<string, unknown>[];\n waivers: Waiver[];\n links?: Links;\n /** Unknown top-level keys and their values (CS0102). */\n extra: Record<string, unknown>;\n /** No bindings and no rules, only `depends_on` (plan §D17.1). */\n aggregate: boolean;\n /**\n * False when the frontmatter has errors (CS0101, CS0103). The model then holds what could be\n * read; a missing `type` or `status` reads as `feature` / `draft`.\n */\n valid: boolean;\n body: SpecBody;\n source: SpecSource;\n}\n\nexport interface ReadSpecOptions {\n /** `enforcement.unenforced_prose`: `off` skips CS0111. Default `warn`. */\n unenforcedProse?: \"off\" | \"warn\";\n}\n\n/** Location of a frontmatter path (`[\"bindings\", 0, \"kind\"]`) in the spec file. */\nexport function specLocation(source: SpecSource, path: PatchPath, atKey = false): Location {\n const range = locate(source.document, path, atKey);\n return range\n ? frontmatterLocation(source, range.start, range.end)\n : { file: source.file, line: 1, column: 1 };\n}\n\n/**\n * Parses and validates a spec file. Returns the spec whenever its `id` can be read, together with\n * every diagnostic found (CS0101, CS0102, CS0103, CS0110, CS0111).\n */\nexport function readSpec(\n text: string,\n file: string,\n options: ReadSpecOptions = {},\n): { spec?: Spec; diagnostics: Diagnostic[] } {\n const parsed = parseSpecSource(text, file);\n const diagnostics = [...parsed.diagnostics];\n const source = parsed.source;\n if (!source || diagnostics.length > 0) return { diagnostics };\n\n const doc = source.document;\n const report = (\n code: DiagnosticCode,\n path: PatchPath,\n message: string,\n atKey = false,\n extra = {},\n ) =>\n diagnostics.push(\n createDiagnostic(code, {\n specLocation: specLocation(source, path, atKey),\n message,\n ...extra,\n }),\n );\n const reportIssues = (issues: SchemaIssue[]): void => {\n for (const issue of issues) {\n report(\"CS0101\", issue.path, issue.message, issue.atKey, issueDetails(issue));\n }\n };\n\n let root: unknown;\n try {\n root = toPlain(doc.toJS());\n } catch (error) {\n // For example \"Excessive alias count\": report the file instead of failing the whole check.\n const reason = error instanceof Error ? error.message : String(error);\n report(\"CS0101\", [], `${file}: the frontmatter can't be read: ${reason}`);\n return { diagnostics };\n }\n if (!isMap(doc.contents) || !root || typeof root !== \"object\" || Array.isArray(root)) {\n report(\"CS0101\", [], `${file}: the frontmatter must be a YAML map of keys and values`);\n return { diagnostics };\n }\n const data = root as Record<string, unknown>;\n\n // Unknown top-level keys only warn, so teams can keep their own metadata (CS0102).\n const extra: Record<string, unknown> = {};\n for (const key of Object.keys(data)) {\n if (FRONTMATTER_KEYS.includes(key)) continue;\n extra[key] = data[key];\n const close = didYouMean(key, FRONTMATTER_KEYS);\n report(\"CS0102\", [key], `unknown key \"${key}\" is ignored`, true, {\n actual: key,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n });\n }\n\n // Scalar and list fields, one by one.\n const shape = SpecFrontmatterSchema.shape;\n const field = <S extends z.ZodType>(schema: S, key: string): z.output<S> | undefined => {\n const result = schema.safeParse(data[key]);\n if (result.success) return result.data;\n reportIssues(schemaIssues(result.error.issues, doc, schema, [key]));\n return undefined;\n };\n const errorsBefore = (): number => diagnostics.filter((d) => d.severity === \"error\").length;\n const initialErrors = errorsBefore();\n\n field(shape.catspec, \"catspec\");\n const id = field(shape.id, \"id\");\n const title = field(shape.title, \"title\");\n const type = field(shape.type, \"type\");\n const status = field(shape.status, \"status\");\n const dependsOn = field(shape.depends_on, \"depends_on\") ?? [];\n const owners = field(shape.owners, \"owners\") ?? [];\n const scope = field(shape.scope, \"scope\") ?? [];\n const infrastructure = field(shape.infrastructure, \"infrastructure\") ?? [];\n const links = field(shape.links, \"links\");\n\n // Lists of objects, element by element, so valid elements are kept.\n const bindings: Binding[] = [];\n forEachItem(data.bindings, \"bindings\", (item, index) => {\n const result = BindingSchema.safeParse(item);\n if (result.success) bindings.push(normalizeBinding(result.data, index));\n else reportIssues(schemaIssues(result.error.issues, doc, BindingSchema, [\"bindings\", index]));\n });\n\n const rules: Rule[] = [];\n forEachItem(data.rules, \"rules\", (item, index) => {\n const cls = (item as { class?: unknown }).class;\n if (!RULE_CLASSES.includes(cls as never)) {\n const where = [\"rules\", index, \"class\"];\n const message =\n cls === undefined\n ? `rules[${index}]: missing required key \"class\"; allowed values: ${listOf(RULE_CLASSES)}`\n : `rules[${index}].class: invalid value ${JSON.stringify(cls)}; allowed: ${listOf(RULE_CLASSES)}`;\n const close = typeof cls === \"string\" ? didYouMean(cls, RULE_CLASSES) : [];\n report(\"CS0101\", cls === undefined ? [\"rules\", index] : where, message, false, {\n expected: [...RULE_CLASSES],\n ...(cls === undefined ? {} : { actual: cls }),\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n });\n return;\n }\n const schema = RULE_SCHEMAS[cls as keyof typeof RULE_SCHEMAS];\n const result = schema.safeParse(item);\n if (result.success) rules.push({ ...stripUndefined(result.data), index });\n else reportIssues(schemaIssues(result.error.issues, doc, schema, [\"rules\", index]));\n });\n\n const waivers: Waiver[] = [];\n forEachItem(data.waivers, \"waivers\", (item, index) => {\n const schema = shape.waivers.unwrap().element;\n const result = schema.safeParse(item);\n if (result.success) waivers.push({ ...stripUndefined(result.data), index });\n else reportIssues(schemaIssues(result.error.issues, doc, schema, [\"waivers\", index]));\n });\n\n function forEachItem(value: unknown, key: string, fn: (item: unknown, index: number) => void) {\n if (value === undefined) return;\n if (!Array.isArray(value)) {\n report(\"CS0101\", [key], `${key}: expected a list, found ${describeValue(value)}`);\n return;\n }\n value.forEach((item, index) => {\n if (item === null || typeof item !== \"object\" || Array.isArray(item)) {\n report(\n \"CS0101\",\n [key, index],\n `${key}[${index}]: expected a map, found ${describeValue(item)}`,\n );\n } else {\n fn(item, index);\n }\n });\n }\n\n // Local ids are unique, and rules point at existing bindings.\n checkUnique(\n bindings.map((b) => ({\n id: b.id,\n path:\n valueAt(doc, [\"bindings\", b.index, \"id\"]) === undefined\n ? [\"bindings\", b.index, \"symbol\"]\n : [\"bindings\", b.index, \"id\"],\n })),\n \"binding\",\n );\n checkUnique(\n rules.map((r) => ({ id: r.id, path: [\"rules\", r.index, \"id\"] })),\n \"rule\",\n );\n const bindingIds = bindings.map((b) => b.id);\n const writtenBindingIds = rawBindingIds(data.bindings);\n for (const rule of rules) {\n if (!(\"within\" in rule) || rule.within === undefined) continue;\n if (resolveBindingRef(rule.within, writtenBindingIds) !== undefined) continue;\n const target = unknownBindingName(rule.within, writtenBindingIds);\n const close = didYouMean(target, writtenBindingIds);\n report(\n \"CS0101\",\n [\"rules\", rule.index, \"within\"],\n `rule \"${rule.id}\": within names an unknown binding \"${target}\"` +\n (writtenBindingIds.length > 0\n ? `; bindings: ${listOf(writtenBindingIds)}`\n : \"; the spec has no bindings\"),\n false,\n {\n ruleId: rule.id,\n expected: writtenBindingIds,\n actual: target,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n },\n );\n }\n\n function checkUnique(items: { id: string; path: PatchPath }[], what: string): void {\n const seen = new Map<string, PatchPath>();\n for (const item of items) {\n const first = seen.get(item.id);\n if (!first) {\n seen.set(item.id, item.path);\n continue;\n }\n const firstLine = specLocation(source!, first).line;\n report(\n \"CS0103\",\n item.path,\n `duplicate ${what} id \"${item.id}\" (first used on line ${firstLine})`,\n );\n }\n }\n\n const valid = errorsBefore() === initialErrors;\n\n // Body: references must name existing rules and bindings; contract bullets need one.\n const body = parseBody(source.body.text, source.body.line);\n const known = { rule: rules.map((r) => r.id), binding: bindingIds };\n const knownRaw = { rule: rawIds(data.rules, \"id\"), binding: writtenBindingIds };\n for (const ref of body.references) {\n const found =\n ref.kind === \"binding\"\n ? resolveBindingRef(ref.id, knownRaw.binding)\n : knownRaw.rule.find((id) => id === ref.id);\n if (found !== undefined) continue;\n const target = ref.kind === \"binding\" ? unknownBindingName(ref.id, knownRaw.binding) : ref.id;\n const close = didYouMean(target, known[ref.kind]);\n diagnostics.push(\n createDiagnostic(\"CS0110\", {\n specLocation: { file, line: ref.line, column: ref.column },\n message: `[${ref.kind}:${ref.id}] references an unknown ${ref.kind} \"${target}\"`,\n expected: known[ref.kind],\n actual: target,\n ...(ref.kind === \"rule\" ? { ruleId: target } : { bindingId: target }),\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean [${ref.kind}:${c}]?` })) }\n : {}),\n }),\n );\n }\n if ((options.unenforcedProse ?? \"warn\") === \"warn\") {\n for (const bullet of body.contracts) {\n if (bullet.references.length > 0) continue;\n diagnostics.push(\n createDiagnostic(\"CS0111\", {\n specLocation: { file, line: bullet.line, column: bullet.column },\n message: `unenforced prose invariant: \"${truncate(bullet.text)}\" has no [rule:<id>] or [binding:<id>] reference`,\n suggestions: [\n {\n message:\n \"add a rule that checks it (a manual rule if it can't be checked from code) and reference it\",\n },\n ],\n }),\n );\n }\n }\n\n if (id === undefined) return { diagnostics };\n\n const spec: Spec = {\n id,\n file,\n title: title ?? body.title ?? id,\n type: type ?? \"feature\",\n status: status ?? \"draft\",\n dependsOn,\n owners,\n scope,\n bindings,\n rules,\n infrastructure,\n waivers,\n extra,\n aggregate: dependsOn.length > 0 && bindings.length === 0 && rules.length === 0 && valid,\n valid,\n body,\n source,\n };\n if (links) spec.links = stripUndefined(links);\n return { spec, diagnostics: withSpec(diagnostics, id) };\n}\n\nfunction withSpec(diagnostics: Diagnostic[], id: string): Diagnostic[] {\n return diagnostics.map((d) => ({ ...d, spec: id }));\n}\n\nfunction issueDetails(issue: SchemaIssue): Partial<Diagnostic> {\n const details: Partial<Diagnostic> = {};\n if (issue.expected !== undefined) details.expected = issue.expected;\n if (issue.actual !== undefined) details.actual = issue.actual;\n if (issue.suggestions.length > 0) {\n details.suggestions = issue.suggestions.map((s) => ({ message: `did you mean \"${s}\"?` }));\n }\n return details;\n}\n\n/** Ids as written, valid or not, so a reference isn't reported twice for one broken rule. */\nfunction rawIds(list: unknown, key: string): string[] {\n if (!Array.isArray(list)) return [];\n return list.flatMap((item: unknown) => {\n const value =\n item && typeof item === \"object\" ? (item as Record<string, unknown>)[key] : undefined;\n return typeof value === \"string\" ? [value] : [];\n });\n}\n\nfunction rawBindingIds(list: unknown): string[] {\n if (!Array.isArray(list)) return [];\n return list.flatMap((item: unknown) => {\n if (!item || typeof item !== \"object\") return [];\n const { id, symbol } = item as Record<string, unknown>;\n if (typeof id === \"string\") return [id];\n if (typeof symbol === \"string\") return [defaultBindingId(symbol)];\n return [];\n });\n}\n\n/**\n * The binding a reference names: `handler` or `handler.Member`. Binding ids may contain dots, so\n * the whole reference is tried first, then the longest binding id followed by `.`.\n */\nfunction resolveBindingRef(ref: string, ids: readonly string[]): string | undefined {\n if (ids.includes(ref)) return ref;\n return ids.filter((id) => ref.startsWith(`${id}.`)).sort((a, b) => b.length - a.length)[0];\n}\n\n/** The name to report for an unresolved binding reference: the part before a member, if any. */\nconst unknownBindingName = (ref: string, ids: readonly string[]): string =>\n ref.includes(\".\") && !ids.some((id) => id.includes(\".\")) ? ref.split(\".\")[0]! : ref;\n\nconst truncate = (text: string, max = 60): string =>\n text.length > max ? `${text.slice(0, max - 1)}…` : text;\n\n/**\n * Copies a YAML value into objects without a prototype, so keys such as `constructor` or\n * `toString` are only seen when the spec sets them.\n */\nfunction toPlain(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(toPlain);\n if (value && typeof value === \"object\" && !(value instanceof Date)) {\n const out = Object.create(null) as Record<string, unknown>;\n for (const [key, item] of Object.entries(value)) out[key] = toPlain(item);\n return out;\n }\n return value;\n}\n","/**\n * Splits a spec file into its YAML frontmatter and its Markdown body (plan §D5, PBI\n * `frontmatter-parser`). The body is kept exactly as written, and every frontmatter node keeps its\n * source range, so diagnostics can point to the exact line and the CST editor can rewrite the\n * frontmatter without touching anything else.\n */\nimport { parseDocument, type Document } from \"yaml\";\n\nimport { createDiagnostic, type Diagnostic, type Location } from \"./diagnostics.js\";\nimport { LineIndex } from \"./util.js\";\n\nexport interface SpecSource {\n /** Path relative to the repository root, with forward slashes. */\n file: string;\n /** The whole file. */\n text: string;\n /** `\\r\\n` when the frontmatter uses Windows line endings, else `\\n`. */\n eol: \"\\n\" | \"\\r\\n\";\n frontmatter: {\n /** Offset of the first frontmatter line (after the opening `---` line). */\n start: number;\n /** Offset of the closing `---` line. */\n end: number;\n /** The YAML between the delimiter lines, including its last line break. */\n text: string;\n };\n body: {\n /** Offset of the body: right after the closing `---` line and its line break. */\n start: number;\n /** The Markdown after the closing `---` line, exactly as in the file. */\n text: string;\n /** 1-based line of the body's first line. */\n line: number;\n };\n /** The parsed frontmatter; node ranges are offsets into `frontmatter.text`. */\n document: Document.Parsed;\n lines: LineIndex;\n}\n\nconst DELIMITER = /^---[ \\t]*$/;\nconst CLOSING = /^(---|\\.\\.\\.)[ \\t]*$/;\n\n/** Result of splitting a file at its `---` delimiters, before the YAML is parsed. */\nexport interface SplitSource {\n eol: \"\\n\" | \"\\r\\n\";\n frontmatter: SpecSource[\"frontmatter\"];\n body: SpecSource[\"body\"];\n}\n\n/** Splits `text` at the `---` lines, or explains why it can't. */\nexport function splitFrontmatter(text: string): SplitSource | { error: string } {\n const bom = text.startsWith(\"\\uFEFF\") ? 1 : 0;\n const firstBreak = text.indexOf(\"\\n\", bom);\n const firstLine = text\n .slice(bom, firstBreak === -1 ? text.length : firstBreak)\n .replace(/\\r$/, \"\");\n if (!DELIMITER.test(firstLine)) {\n return { error: \"the file has no frontmatter: a spec must start with a '---' line\" };\n }\n if (firstBreak === -1) {\n return { error: \"the frontmatter is not closed: no '---' line after line 1\" };\n }\n const eol = text[firstBreak - 1] === \"\\r\" ? \"\\r\\n\" : \"\\n\";\n const start = firstBreak + 1;\n\n for (let lineStart = start; lineStart <= text.length;) {\n const lineBreak = text.indexOf(\"\\n\", lineStart);\n const lineEnd = lineBreak === -1 ? text.length : lineBreak;\n const line = text.slice(lineStart, lineEnd).replace(/\\r$/, \"\");\n if (CLOSING.test(line)) {\n const bodyStart = lineBreak === -1 ? text.length : lineBreak + 1;\n return {\n eol,\n frontmatter: { start, end: lineStart, text: text.slice(start, lineStart) },\n body: {\n start: bodyStart,\n text: text.slice(bodyStart),\n line: text.slice(0, bodyStart).split(\"\\n\").length,\n },\n };\n }\n if (lineBreak === -1) break;\n lineStart = lineBreak + 1;\n }\n return { error: \"the frontmatter is not closed: no '---' line after line 1\" };\n}\n\n/**\n * Parses a spec file. Returns the source when the file has a frontmatter block, even if the YAML\n * in it is invalid (those errors are in `diagnostics` as CS0101).\n */\nexport function parseSpecSource(\n text: string,\n file: string,\n): { source?: SpecSource; diagnostics: Diagnostic[] } {\n const lines = new LineIndex(text);\n const split = splitFrontmatter(text);\n if (\"error\" in split) {\n return {\n diagnostics: [\n createDiagnostic(\"CS0101\", {\n specLocation: { file, line: 1, column: 1 },\n message: `${file}: ${split.error}`,\n }),\n ],\n };\n }\n\n const document = parseDocument(split.frontmatter.text, { prettyErrors: false });\n const source: SpecSource = { file, text, ...split, document, lines };\n const diagnostics = document.errors.map((error) =>\n createDiagnostic(\"CS0101\", {\n specLocation: frontmatterLocation(source, error.pos[0], error.pos[1]),\n message: `invalid YAML: ${error.message.split(\"\\n\")[0]!.replace(/ at line \\d+.*$/, \"\")}`,\n }),\n );\n return { source, diagnostics };\n}\n\n/** File location of a range given as offsets into the frontmatter text. */\nexport function frontmatterLocation(source: SpecSource, start: number, end = start): Location {\n const from = source.lines.position(source.frontmatter.start + start);\n const to = source.lines.position(source.frontmatter.start + Math.max(start, end));\n return {\n file: source.file,\n line: from.line,\n column: from.column,\n endLine: to.line,\n endColumn: to.column,\n };\n}\n\n/** Reassembles a spec file from its parts with new frontmatter text; the rest is unchanged. */\nexport function withFrontmatter(source: SpecSource, frontmatterText: string): string {\n return (\n source.text.slice(0, source.frontmatter.start) +\n frontmatterText +\n source.text.slice(source.frontmatter.end)\n );\n}\n","/**\n * The Markdown body of a spec (plan §D5.4), PBI `body-parser`: references to rules and bindings,\n * the bullets under `Contracts` / `Invariants`, and the `Tasks` checklist. The body is otherwise\n * opaque and returned to agents as written.\n */\nimport type { Heading, List, ListItem, Nodes, RootContent } from \"mdast\";\nimport remarkParse from \"remark-parse\";\nimport { unified } from \"unified\";\n\nimport { LineIndex } from \"./util.js\";\n\nexport interface BodyReference {\n kind: \"rule\" | \"binding\";\n id: string;\n /** File position (1-based). */\n line: number;\n column: number;\n}\n\nexport interface ContractBullet {\n text: string;\n line: number;\n column: number;\n references: BodyReference[];\n}\n\nexport interface TaskItem {\n text: string;\n done: boolean;\n line: number;\n}\n\nexport interface SpecBody {\n /** Text of the first `#` heading. */\n title?: string;\n references: BodyReference[];\n /** Top-level bullets under a `Contracts` or `Invariants` heading. */\n contracts: ContractBullet[];\n /** Checklist items under a `Tasks` heading. */\n tasks: TaskItem[];\n /** `ADR-NNN` ids of the headings that start with one (the ADR log of an architecture spec). */\n adrIds: string[];\n}\n\nconst REFERENCE = /\\[(rule|binding):([^\\]\\s]+)\\]/g;\nconst CHECKBOX = /^\\[([ xX])\\](?:[ \\t]+|$)/;\nconst ADR_HEADING = /^(ADR-\\d+)\\b/;\n\n/** Parses a spec body. `firstLine` is the file line the body starts on. */\nexport function parseBody(markdown: string, firstLine: number): SpecBody {\n const tree = unified().use(remarkParse).parse(markdown);\n const toFileLine = (line: number): number => firstLine + line - 1;\n const body: SpecBody = { references: [], contracts: [], tasks: [], adrIds: [] };\n\n const lines = new LineIndex(markdown);\n const at = (offset: number): { line: number; column: number } => {\n const { line, column } = lines.position(offset);\n return { line: toFileLine(line), column };\n };\n\n const referencesIn = (node: Nodes): BodyReference[] => {\n const found: BodyReference[] = [];\n visit(node, (child) => {\n const start = child.position?.start.offset;\n if (start === undefined) return;\n if (child.type === \"text\") {\n // Positions come from the source, not from the decoded text (entities, indentation).\n const source = markdown.slice(start, child.position!.end.offset);\n let cursor = 0;\n for (const match of child.value.matchAll(REFERENCE)) {\n const index = source.indexOf(match[0], cursor);\n if (index !== -1) cursor = index + match[0].length;\n const kind = match[1] as \"rule\" | \"binding\";\n found.push({ kind, id: match[2]!, ...at(start + Math.max(index, 0)) });\n }\n } else if (child.type === \"linkReference\" || child.type === \"link\") {\n // `[rule:x][]` with a definition, or `[rule:x](#x)`.\n const label = child.type === \"linkReference\" ? (child.label ?? \"\") : plainText(child);\n const match = /^(rule|binding):(\\S+)$/.exec(label.trim());\n if (match)\n found.push({ kind: match[1] as \"rule\" | \"binding\", id: match[2]!, ...at(start) });\n }\n });\n return found;\n };\n\n body.references = referencesIn(tree);\n\n const headings: { name: string; depth: number }[] = [];\n const inSection = (...names: string[]): boolean =>\n headings.some((h) => names.includes(h.name.toLowerCase()));\n\n for (const node of tree.children) {\n if (node.type === \"heading\") {\n const name = plainText(node).trim();\n while (headings.length > 0 && headings[headings.length - 1]!.depth >= node.depth) {\n headings.pop();\n }\n headings.push({ name, depth: node.depth });\n if (node.depth === 1 && body.title === undefined) body.title = name;\n const adr = ADR_HEADING.exec(name);\n if (adr) body.adrIds.push(adr[1]!);\n continue;\n }\n if (node.type !== \"list\") continue;\n if (inSection(\"contracts\", \"invariants\")) {\n for (const item of node.children) {\n if (!item.position) continue;\n body.contracts.push({\n text: plainText(item).trim(),\n line: toFileLine(item.position.start.line),\n column: item.position.start.column,\n references: referencesIn(item),\n });\n }\n }\n if (inSection(\"tasks\")) collectTasks(node, body.tasks, toFileLine);\n }\n return body;\n}\n\nfunction collectTasks(list: List, tasks: TaskItem[], toFileLine: (line: number) => number): void {\n for (const item of list.children) {\n const text = itemText(item);\n const box = CHECKBOX.exec(text);\n if (box && item.position) {\n tasks.push({\n text: text.slice(box[0].length).trim(),\n done: box[1] !== \" \",\n line: toFileLine(item.position.start.line),\n });\n }\n for (const child of item.children) {\n if (child.type === \"list\") collectTasks(child, tasks, toFileLine);\n }\n }\n}\n\n/** Text of a list item's own first paragraph (not its nested lists). */\nfunction itemText(item: ListItem): string {\n const first = item.children[0];\n return first?.type === \"paragraph\" ? plainText(first) : \"\";\n}\n\nfunction plainText(node: Nodes | Heading | RootContent): string {\n if (\"value\" in node && typeof node.value === \"string\") return node.value;\n if (\"children\" in node) return (node.children as Nodes[]).map(plainText).join(\"\");\n return \"\";\n}\n\nfunction visit(node: Nodes, fn: (node: Nodes) => void): void {\n fn(node);\n if (\"children\" in node) for (const child of node.children as Nodes[]) visit(child, fn);\n}\n","/**\n * Binding resolution (plan §D11.5, ADR-005), PBI `binding-resolver`: finds the declaration a\n * binding points to. The `file` hint is tried first, then the files the binding resolved to last\n * time (its lock file, F5), then every source file, so a moved file still resolves. Not found →\n * CS0201 with did-you-mean; several candidates → CS0202; C# `partial` parts are merged.\n */\nimport { codeLocation, formatLocation, type SymbolEntry, type SymbolTable } from \"./codebase.js\";\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport type { FileFacts, SymbolFact } from \"./facts.js\";\nimport { BINDING_KINDS, type Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, globMatcher, listOf } from \"./util.js\";\n\nexport interface ResolvedBinding {\n binding: Binding;\n /** The declaration; for C# partial types, the parts merged into one. */\n symbol: SymbolFact;\n /** The file of the declaration (of its first part). */\n file: FileFacts;\n /** The files of every part. */\n files: string[];\n /** The declarations merged into `symbol`, each with its file; one unless C# `partial`. */\n parts: { symbol: SymbolFact; file: FileFacts }[];\n}\n\nexport interface BindingResolution {\n resolved?: ResolvedBinding;\n diagnostics: Diagnostic[];\n /**\n * True when neither the hint nor the locked files had the declaration, so every source file was\n * searched: a result that depends on the whole repository (`check --staged` reads it all then).\n */\n searched: boolean;\n}\n\nconst TYPE_KINDS = new Set<string>(BINDING_KINDS);\n\n/** `src/auth/service#AuthService.login` → module `src/auth/service`, name `AuthService.login`. */\nexport function splitSymbol(symbol: string): { module?: string; name: string } {\n const hash = symbol.lastIndexOf(\"#\");\n return hash === -1\n ? { name: symbol }\n : { module: symbol.slice(0, hash).replace(/^\\.\\//, \"\"), name: symbol.slice(hash + 1) };\n}\n\n/** True when `path` is the module `module`: with or without the extension, or ending with it. */\nexport const inModule = (path: string, module: string): boolean => {\n const bare = path.replace(/\\.[^./]+$/, \"\");\n const target = module.replace(/\\.[^./]+$/, \"\");\n return bare === target || bare.endsWith(`/${target}`);\n};\n\n/**\n * Resolves a binding in `table`. `locked` are the files the binding resolved to last time (from\n * its lock file), tried after the `file` hint.\n */\nexport function resolveBinding(\n spec: Spec,\n binding: Binding,\n table: SymbolTable,\n locked: readonly string[] = [],\n): BindingResolution {\n const { module, name } = splitSymbol(binding.symbol);\n const kindOk = (s: SymbolFact): boolean =>\n binding.kind ? s.kind === binding.kind : TYPE_KINDS.has(s.kind);\n const langOk = (f: FileFacts): boolean => !binding.lang || f.lang === binding.lang;\n const hinted = binding.file ? globMatcher(binding.file) : () => false;\n const inHint = (e: SymbolEntry): boolean =>\n binding.file !== undefined && (hinted(e.file.path) || binding.file.includes(e.file.path));\n\n const named = table\n .find(name)\n .filter((e) => langOk(e.file) && (!module || inModule(e.file.path, module)));\n const ofKind = named.filter((e) => kindOk(e.symbol));\n const inHinted = ofKind.filter(inHint);\n const inLocked = ofKind.filter((e) => locked.includes(e.file.path));\n const searched = inHinted.length === 0 && inLocked.length === 0;\n const groups = groupOverloads(\n inHinted.length > 0 ? inHinted : inLocked.length > 0 ? inLocked : ofKind,\n );\n\n const at = specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]);\n const base = {\n spec: spec.id,\n specLocation: at,\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n };\n const what = `${binding.kind ?? \"symbol\"} ${binding.symbol}`;\n\n if (groups.length === 0) {\n const otherKind = named[0];\n if (otherKind) {\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0201\", {\n ...base,\n codeLocation: codeLocation(otherKind.file.path, otherKind.symbol.nameRange),\n message:\n `binding \"${binding.id}\": no ${what}; found ${otherKind.symbol.kind} ` +\n `${otherKind.symbol.qualifiedName} at ${formatLocation(otherKind.file.path, otherKind.symbol.nameRange)}`,\n expected: what,\n actual: `${otherKind.symbol.kind} ${otherKind.symbol.qualifiedName}`,\n suggestions: [\n { message: `change the binding's kind to ${otherKind.symbol.kind}, or the code` },\n ],\n }),\n ],\n };\n }\n const close = closeNames(name, table, kindOk, langOk, inHint);\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0201\", {\n ...base,\n message:\n `binding \"${binding.id}\": ${what} not found` +\n (binding.file ? ` in ${listOf(binding.file)} or anywhere else` : \"\"),\n expected: what,\n actual: close.length > 0 ? close.map((c) => c.symbol.qualifiedName) : \"nothing\",\n suggestions:\n close.length > 0\n ? close.map((c) => ({\n message: `did you mean ${c.symbol.name}? (${formatLocation(c.file.path, c.symbol.nameRange)})`,\n }))\n : [{ message: \"fix the symbol or the file hint, or restore the code\" }],\n }),\n ],\n };\n }\n\n const parts = groups.map((g) => g[0]!);\n if (parts.length > 1 && !parts.every((p) => p.symbol.partial)) {\n const where = parts.map((p) => formatLocation(p.file.path, p.symbol.nameRange));\n return {\n searched,\n diagnostics: [\n createDiagnostic(\"CS0202\", {\n ...base,\n codeLocation: codeLocation(parts[0]!.file.path, parts[0]!.symbol.nameRange),\n message: `binding \"${binding.id}\": ${what} is ambiguous; ${parts.length} declarations match: ${listOf(where)}`,\n expected: what,\n actual: where,\n suggestions: [\n {\n message:\n \"qualify the symbol (Namespace.Type or path/to/module#Name) or add a file hint\",\n },\n ],\n }),\n ],\n };\n }\n\n return {\n resolved: {\n binding,\n symbol: parts.length === 1 ? parts[0]!.symbol : mergePartials(parts.map((p) => p.symbol)),\n file: parts[0]!.file,\n files: [...new Set(parts.map((p) => p.file.path))],\n parts: parts.map(({ symbol, file }) => ({ symbol, file })),\n },\n diagnostics: [],\n searched,\n };\n}\n\n/**\n * Overload signatures and their implementation are one declaration: entries with the same file,\n * qualified name and `static`-ness form a group, the implementation (plain id) first. C#\n * overloads all have bodies, so each is a declaration of its own. Every other declaration is its\n * own group, also when it shares an id (C# partial parts in one file).\n */\nexport function groupOverloads(entries: SymbolEntry[]): SymbolEntry[][] {\n const isImplementation = (e: SymbolEntry): boolean =>\n e.symbol.id === `${e.file.path}#${e.symbol.qualifiedName}`;\n const groups = new Map<string | SymbolEntry, SymbolEntry[]>();\n for (const entry of entries) {\n const { symbol, file } = entry;\n const callable = symbol.kind === \"function\" || symbol.kind === \"method\";\n const key = callable\n ? `${file.path}\\0${symbol.qualifiedName}\\0${symbol.modifiers.includes(\"static\")}`\n : entry;\n groups.set(key, [...(groups.get(key) ?? []), entry]);\n }\n return [...groups.values()].flatMap((group) =>\n group[0]!.file.lang !== \"csharp\"\n ? [[...group].sort((a, b) => Number(isImplementation(b)) - Number(isImplementation(a)))]\n : group.map((entry) => [entry]),\n );\n}\n\n/** C# partial parts as one type: members, bases, attributes and modifiers of every part. */\nexport function mergePartials(parts: SymbolFact[]): SymbolFact {\n const [first, ...rest] = parts as [SymbolFact, ...SymbolFact[]];\n const merged: SymbolFact = {\n ...first,\n members: [...first.members],\n bases: [...first.bases],\n attributes: [...first.attributes],\n modifiers: [...first.modifiers],\n };\n for (const part of rest) {\n merged.members.push(...part.members);\n for (const base of part.bases) {\n if (!merged.bases.some((b) => b.text === base.text)) merged.bases.push(base);\n }\n merged.attributes.push(...part.attributes);\n for (const modifier of part.modifiers) {\n if (!merged.modifiers.includes(modifier)) merged.modifiers.push(modifier);\n }\n if (part.exported) merged.exported = true;\n }\n return merged;\n}\n\n/**\n * Up to 3 declarations of the right kind whose names are close to `name` (Damerau-Levenshtein),\n * the hinted files first.\n */\nfunction closeNames(\n name: string,\n table: SymbolTable,\n kindOk: (s: SymbolFact) => boolean,\n langOk: (f: FileFacts) => boolean,\n inHint: (e: SymbolEntry) => boolean,\n): SymbolEntry[] {\n const last = name.slice(name.lastIndexOf(\".\") + 1);\n const candidates = table.entries.filter((e) => kindOk(e.symbol) && langOk(e.file));\n const firstByName = (entries: SymbolEntry[]): Map<string, SymbolEntry> => {\n const map = new Map<string, SymbolEntry>();\n for (const e of entries) if (!map.has(e.symbol.name)) map.set(e.symbol.name, e);\n return map;\n };\n const hinted = firstByName(candidates.filter(inHint));\n const all = firstByName(candidates);\n const names = [\n ...didYouMean(last, [...hinted.keys()].sort(compareStrings)),\n ...didYouMean(last, [...all.keys()].sort(compareStrings)),\n ];\n return [...new Set(names)].slice(0, 3).map((n) => hinted.get(n) ?? all.get(n)!);\n}\n","/**\n * The contract evaluator (plan §D5.3, §D11.5, analysis F-5), PBI `contract-evaluator`: checks a\n * resolved declaration against its binding: kind (in the resolver), export, base types,\n * attributes, constructor dependencies and members with their signatures. What syntax alone\n * can't decide is CS0220, never a failure (ADR-002). Every diagnostic names its contract item:\n * `binding:<id>` for the declaration, `binding:<id>.<member>` for each member.\n */\nimport { codeLocation, formatLocation, type SymbolTable } from \"./codebase.js\";\nimport { createDiagnostic, type Diagnostic, type DiagnosticCode } from \"./diagnostics.js\";\nimport type {\n AttributeFact,\n FileFacts,\n LanguageAdapter,\n ParamFact,\n SymbolFact,\n TypeRef,\n} from \"./facts.js\";\nimport { isSegmentSuffix, typeMatches } from \"./match.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Member, MemberKind } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, editDistance, listOf } from \"./util.js\";\n\nexport interface ContractContext {\n table: SymbolTable;\n adapter?: LanguageAdapter | undefined;\n /** `enforcement.unresolvable`: the severity of CS0220. */\n unresolvable: \"warn\" | \"error\";\n}\n\n/** Contract items of a binding: the declaration, then each member. */\nexport const bindingItems = (binding: { id: string; members: { name: string }[] }): string[] => [\n `binding:${binding.id}`,\n ...binding.members.map((m) => `binding:${binding.id}.${m.name}`),\n];\n\nconst VISIBILITY = new Set([\"public\", \"private\", \"protected\", \"internal\"]);\n\n/** Evaluates the contract of a resolved binding. */\nexport function evaluateContract(\n spec: Spec,\n resolved: ResolvedBinding,\n context: ContractContext,\n): Diagnostic[] {\n const { binding, symbol, file } = resolved;\n const diagnostics: Diagnostic[] = [];\n const where = codeLocation(file.path, symbol.nameRange);\n /** The file a member is declared in: the file of its part, for a C# partial type. */\n const pathOf = (member: SymbolFact): string =>\n resolved.parts.find((p) => p.symbol.members.includes(member))?.file.path ?? file.path;\n const subject = `${symbol.kind} ${symbol.qualifiedName}`;\n const normalize = (text: string): TypeRef =>\n context.adapter?.normalizeType(text) ?? plainType(text);\n const report = (\n code: DiagnosticCode,\n path: (string | number)[],\n item: string,\n message: string,\n extra: Partial<Diagnostic> = {},\n ): void => {\n diagnostics.push(\n createDiagnostic(code, {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, ...path]),\n codeLocation: where,\n bindingId: binding.id,\n item,\n message,\n ...(code === \"CS0220\" ? { severity: unresolvableSeverity(context) } : {}),\n ...extra,\n }),\n );\n };\n const item = `binding:${binding.id}`;\n\n // exported: TypeScript `export`, C# `public`.\n if (binding.exported !== undefined) {\n const exported = symbol.exported === true || symbol.modifiers.includes(\"public\");\n if (exported !== binding.exported) {\n report(\n \"CS0208\",\n [\"exported\"],\n item,\n `${subject} must ${binding.exported ? \"\" : \"not \"}be exported`,\n {\n expected: binding.exported ? \"exported\" : \"not exported\",\n actual: exported ? \"exported\" : \"not exported\",\n suggestions: [\n {\n message: binding.exported\n ? `export ${symbol.name} (TypeScript) or make it public (C#)`\n : `remove the export of ${symbol.name}, or set exported: true`,\n },\n ],\n },\n );\n }\n }\n\n // implements / extends: direct base types, by qualified-name suffix.\n const bases = symbol.bases.map((b) => ({\n base: b,\n variants: resolved.parts.flatMap((p) => baseVariants(b, p.file)),\n }));\n const foundBases = symbol.bases.length > 0 ? listOf(symbol.bases.map((b) => b.text)) : \"none\";\n const checkBase = (\n expectedText: string,\n path: (string | number)[],\n verb: string,\n candidates = bases,\n ): void => {\n const expected = normalize(expectedText);\n if (candidates.some(({ variants }) => variants.some((v) => typeMatches(expected, v)))) return;\n const unsure = candidates.filter(({ variants }) =>\n variants.some((v) => undecidableBase(v, context)),\n );\n if (unsure.length > 0) {\n report(\n \"CS0220\",\n path,\n item,\n `can't tell whether ${subject} ${verb} ${expected.text}: its base ${listOf(unsure.map((u) => u.base.text))} is a type alias or not a plain name`,\n {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [{ message: `name ${expected.text} directly in the declaration` }],\n },\n );\n return;\n }\n report(\"CS0204\", path, item, `${subject} does not ${verb} ${expected.text}`, {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [\n {\n message: `found base types: ${foundBases}; add ${expected.text} to the declaration of ${symbol.name}, or update the spec`,\n },\n ],\n });\n };\n binding.implements?.forEach((t, i) => checkBase(t, [\"implements\", i], \"implement\"));\n // C# doesn't mark the base class in a base list. A class or record has at most one, first in\n // the base list of the part that declares it, and a struct has none. An interface extends\n // every interface in its base list. Syntax can't tell a first base named like an interface\n // (`IFoo`, but also `IOException`) from a base class, so a match on one is CS0220.\n const csharpClass = file.lang === \"csharp\" && symbol.kind !== \"interface\";\n const extendable = !csharpClass\n ? bases\n : symbol.kind === \"struct\"\n ? []\n : bases.filter(({ base }) =>\n resolved.parts.some((p) => p.symbol.bases[0]?.text === base.text),\n );\n if (binding.extends !== undefined) {\n const expected = normalize(binding.extends);\n const interfaceLike = csharpClass\n ? extendable.find(\n ({ base, variants }) =>\n /^I[A-Z]/.test(base.name.at(-1) ?? \"\") &&\n variants.some((v) => typeMatches(expected, v)),\n )\n : undefined;\n if (interfaceLike) {\n report(\n \"CS0220\",\n [\"extends\"],\n item,\n `can't tell whether ${subject} extends ${expected.text}: ${interfaceLike.base.text} comes first in its base list but may be an interface`,\n {\n expected: expected.text,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [\n { message: `use implements: [${expected.text}] if it is an interface, or waive this` },\n ],\n },\n );\n } else {\n checkBase(binding.extends, [\"extends\"], \"extend\", extendable);\n }\n }\n\n // attributes / decorators.\n binding.attributes?.forEach((text, i) => {\n if (symbol.attributes.some((a) => attributeMatches(text, a))) return;\n report(\"CS0206\", [\"attributes\", i], item, `${subject} lacks attribute ${text}`, {\n expected: text,\n actual: symbol.attributes.map(attributeText),\n suggestions: [{ message: `add ${text} to ${symbol.name}` }],\n });\n });\n\n // constructor.requires: types a constructor must take (dependency injection).\n if (binding.constructorRequires && binding.constructorRequires.length > 0) {\n checkConstructor(binding.constructorRequires);\n }\n\n function checkConstructor(required: string[]): void {\n const path = [\"constructor\", \"requires\"];\n const ctors = symbol.members.filter((m) => m.kind === \"constructor\");\n if (ctors.length === 0) {\n if (symbol.bases.length > 0) {\n report(\n \"CS0220\",\n path,\n item,\n `can't tell whether ${subject} takes ${listOf(required)}: it has no constructor of its own and may inherit one from ${foundBases}`,\n {\n expected: required,\n suggestions: [{ message: `declare a constructor in ${symbol.name}` }],\n },\n );\n return;\n }\n required.forEach((type, i) =>\n report(\"CS0207\", [...path, i], item, `${subject} has no constructor taking ${type}`, {\n expected: type,\n actual: \"no constructor\",\n suggestions: [{ message: `add a constructor to ${symbol.name} that takes ${type}` }],\n }),\n );\n return;\n }\n const scored = ctors.map((ctor) => {\n const params = ctor.params ?? [];\n const status = required.map((type) => {\n const expected = normalize(type);\n if (params.some((p) => p.type && typeMatches(expected, p.type))) return \"ok\";\n return params.some((p) => !p.type) ? \"unsure\" : \"missing\";\n });\n return { ctor, status, ok: status.filter((s) => s === \"ok\").length };\n });\n if (scored.some((s) => s.ok === required.length)) return;\n const best = scored.reduce((a, b) => (b.ok > a.ok ? b : a));\n const found = `constructor(${(best.ctor.params ?? []).map(paramText).join(\", \")})`;\n best.status.forEach((status, i) => {\n if (status === \"ok\") return;\n const type = required[i]!;\n if (status === \"unsure\") {\n report(\n \"CS0220\",\n [...path, i],\n item,\n `can't tell whether ${subject} takes ${type}: ${found} has parameters without a type`,\n {\n expected: type,\n actual: found,\n suggestions: [{ message: \"add type annotations to the constructor parameters\" }],\n },\n );\n } else {\n report(\"CS0207\", [...path, i], item, `${subject}: constructor dependency ${type} missing`, {\n codeLocation: codeLocation(pathOf(best.ctor), best.ctor.nameRange),\n expected: type,\n actual: found,\n suggestions: [\n { message: `add a parameter of type ${type} to the constructor of ${symbol.name}` },\n ],\n });\n }\n });\n }\n\n // Members.\n const claimed = new Set(binding.members.map((m) => m.name));\n // Required members with no declaration of their name, by kind: the fallback suggestion below\n // is only safe when a single one of a kind is missing.\n const missingByKind = new Map<string | undefined, number>();\n for (const m of binding.members) {\n if (m.optional || m.kind === \"constructor\") continue;\n if (symbol.members.some((c) => c.name === m.name && c.kind !== \"constructor\")) continue;\n missingByKind.set(m.kind, (missingByKind.get(m.kind) ?? 0) + 1);\n }\n binding.members.forEach((member, i) => {\n const memberItem = `binding:${binding.id}.${member.name}`;\n const path = [\"members\", i];\n const candidates = symbol.members.filter((m) =>\n member.kind === \"constructor\"\n ? m.kind === \"constructor\"\n : m.name === member.name && m.kind !== \"constructor\",\n );\n if (candidates.length === 0) {\n if (member.optional) return;\n const close = closeMembers(member, symbol, claimed, missingByKind.get(member.kind) === 1);\n report(\n \"CS0203\",\n path,\n memberItem,\n `member ${member.name} missing in ${symbol.qualifiedName}`,\n {\n expected: memberText(member),\n actual: close.length > 0 ? close.map((c) => signatureText(c)) : \"nothing\",\n suggestions: [\n ...close.map((c) => ({\n message: `did you mean ${c.name}? (${formatLocation(pathOf(c), c.nameRange)})`,\n })),\n { message: `add ${member.name} to ${symbol.name}, or update the spec` },\n ],\n },\n );\n return;\n }\n const results = candidates.map((c) => ({\n candidate: c,\n ...compareMember(member, c, normalize, file),\n }));\n if (results.some((r) => r.mismatches.length === 0 && r.unsure.length === 0)) return;\n const best = results.reduce((a, b) =>\n b.mismatches.length + b.unsure.length < a.mismatches.length + a.unsure.length ? b : a,\n );\n const at = codeLocation(pathOf(best.candidate), best.candidate.nameRange);\n const found = signatureText(best.candidate);\n const visibility = best.mismatches.filter((m) => m.code === \"CS0208\");\n const signature = best.mismatches.filter((m) => m.code !== \"CS0208\");\n for (const group of [visibility, signature]) {\n if (group.length === 0) continue;\n const code = group[0]!.code;\n report(\n code,\n path,\n memberItem,\n `member ${member.name} ${code === \"CS0208\" ? \"visibility\" : code === \"CS0206\" ? \"attributes\" : \"signature\"} mismatch: ${group.map((m) => m.text).join(\"; \")}`,\n {\n codeLocation: at,\n expected: memberText(member),\n actual: found,\n suggestions: [\n { message: `change ${member.name} to ${memberText(member)}, or update the spec` },\n ],\n },\n );\n }\n if (best.mismatches.length === 0) {\n report(\n \"CS0220\",\n path,\n memberItem,\n `can't check member ${member.name} from syntax: ${best.unsure.join(\"; \")}`,\n {\n codeLocation: at,\n expected: memberText(member),\n actual: found,\n suggestions: [{ message: \"write the types explicitly in the code\" }],\n },\n );\n }\n });\n\n return diagnostics;\n}\n\ninterface Mismatch {\n code: DiagnosticCode;\n text: string;\n}\n\n/** Differences between a member entry and one declaration of that name. */\nfunction compareMember(\n member: Member,\n found: SymbolFact,\n normalize: (text: string) => TypeRef,\n file: FileFacts,\n): { mismatches: Mismatch[]; unsure: string[] } {\n const mismatches: Mismatch[] = [];\n const unsure: string[] = [];\n if (member.kind && !kindMatches(member.kind, found.kind, file.lang)) {\n mismatches.push({ code: \"CS0205\", text: `kind: expected ${member.kind}, found ${found.kind}` });\n }\n if (member.params) {\n const params = found.params;\n if (!params) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameters: expected (${member.params.join(\", \")}), found a ${found.kind}`,\n });\n } else if (params.length !== member.params.length) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameters: expected ${member.params.length}, found ${params.length}`,\n });\n } else {\n member.params.forEach((type, i) => {\n const param = params[i]!;\n if (type === \"*\") return;\n if (!param.type) {\n unsure.push(`parameter ${param.name} has no type`);\n return;\n }\n const expected = normalize(type);\n if (!typeMatches(expected, param.type)) {\n mismatches.push({\n code: \"CS0205\",\n text: `parameter ${i + 1} (${param.name}): expected ${expected.text}, found ${param.type.text}`,\n });\n }\n });\n }\n }\n if (member.returns !== undefined) {\n const expected = normalize(member.returns);\n if (!found.returns)\n unsure.push(\n `${found.name} has no declared ${found.kind === \"property\" ? \"type\" : \"return type\"}`,\n );\n else if (!typeMatches(expected, found.returns)) {\n mismatches.push({\n code: \"CS0205\",\n text: `returns: expected ${expected.text}, found ${found.returns.text}`,\n });\n }\n }\n for (const modifier of member.modifiers ?? []) {\n if (hasModifier(found, modifier, file.lang)) continue;\n mismatches.push({\n code: VISIBILITY.has(modifier) ? \"CS0208\" : \"CS0205\",\n text: `modifier ${modifier} missing`,\n });\n }\n for (const attribute of member.attributes ?? []) {\n if (found.attributes.some((a) => attributeMatches(attribute, a))) continue;\n mismatches.push({ code: \"CS0206\", text: `attribute ${attribute} missing` });\n }\n return { mismatches, unsure };\n}\n\n/** TypeScript has no fields apart from properties. */\nconst kindMatches = (expected: MemberKind, found: string, lang: string): boolean =>\n expected === found ||\n (lang === \"typescript\" &&\n (expected === \"field\" || expected === \"property\") &&\n found === \"property\");\n\n/** A modifier on a declaration; TypeScript class members without one are public. */\nfunction hasModifier(symbol: SymbolFact, modifier: string, lang: string): boolean {\n if (symbol.modifiers.includes(modifier)) return true;\n return (\n lang === \"typescript\" &&\n modifier === \"public\" &&\n !symbol.modifiers.some((m) => m === \"private\" || m === \"protected\")\n );\n}\n\n/**\n * Members of the declaration close to a missing member's name, of a compatible kind and not\n * required by another entry: by edit distance, else by a shared word (`checkToken` for\n * `validateToken`).\n */\nfunction closeMembers(\n member: Member,\n symbol: SymbolFact,\n claimed: Set<string>,\n onlyMissingOfKind: boolean,\n): SymbolFact[] {\n const candidates = symbol.members.filter(\n (m) =>\n m.kind !== \"constructor\" &&\n !claimed.has(m.name) &&\n (!member.kind ||\n m.kind === member.kind ||\n (member.kind !== \"method\" && m.kind === \"property\")),\n );\n const byName = new Map<string, SymbolFact>();\n for (const c of candidates) if (!byName.has(c.name)) byName.set(c.name, c);\n let names = didYouMean(member.name, byName.keys());\n if (names.length === 0) {\n const words = new Set(wordsOf(member.name));\n names = [...byName.keys()]\n .filter((name) => wordsOf(name).some((w) => words.has(w)))\n .sort(\n (a, b) =>\n editDistance(member.name.toLowerCase(), a.toLowerCase()) -\n editDistance(member.name.toLowerCase(), b.toLowerCase()),\n )\n .slice(0, 3);\n }\n // No similar name: when this is the only missing member of its kind and the declaration has a\n // single unclaimed member of that kind, that one is most likely meant (`login` written as\n // `signIn`).\n if (names.length === 0 && member.kind && onlyMissingOfKind) {\n const sameKind = [...byName.values()].filter((m) => m.kind === member.kind);\n if (sameKind.length === 1) names = [sameKind[0]!.name];\n }\n return names.map((n) => byName.get(n)!);\n}\n\n/** Lowercase words of an identifier of 3+ letters: `validateToken` → validate, token. */\nconst wordsOf = (name: string): string[] =>\n name\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[\\s_$-]+/)\n .map((w) => w.toLowerCase())\n .filter((w) => w.length >= 3);\n\n/**\n * A base type as written and as resolved through the file's imports: `Base` imported as\n * `import { IHandler as Base }` is also `IHandler`; `ns.IHandler` from `import * as ns` is also\n * `IHandler`.\n */\nfunction baseVariants(base: TypeRef, file: FileFacts): TypeRef[] {\n const variants = [base];\n const head = base.name[0];\n if (head === undefined) return variants;\n for (const imp of file.imports) {\n for (const imported of imp.names) {\n if ((imported.alias ?? imported.name) !== head) continue;\n if (imported.name === \"*\" && base.name.length > 1) {\n const name = base.name.slice(1);\n variants.push({ ...base, name, text: base.text.slice(head.length + 1) });\n } else if (imported.name !== \"*\" && imported.name !== \"default\" && imported.name !== head) {\n const name = [imported.name, ...base.name.slice(1)];\n variants.push({ ...base, name, text: imported.name + base.text.slice(head.length) });\n }\n }\n }\n return variants;\n}\n\n/** A base type syntax can't compare: not a plain name, or a type alias declared in the code. */\nfunction undecidableBase(base: TypeRef, context: ContractContext): boolean {\n if (base.name.length === 0) return true;\n const declared = context.table.find(base.name.join(\".\"));\n return declared.length > 0 && declared.every((e) => e.symbol.kind === \"type\");\n}\n\nconst unresolvableSeverity = (context: ContractContext): \"warning\" | \"error\" =>\n context.unresolvable === \"error\" ? \"error\" : \"warning\";\n\n/** A type reference from text without an adapter: only equal text matches. */\nconst plainType = (text: string): TypeRef => ({\n text: text.replace(/\\s+/g, \"\"),\n name: [],\n args: [],\n});\n\n/** `HttpGet(\"users\")` matches an attribute named `HttpGet`/`HttpGetAttribute` with that argument. */\nexport function attributeMatches(expected: string, found: AttributeFact): boolean {\n const match = /^\\s*([^(]+?)\\s*(?:\\((.*)\\))?\\s*$/s.exec(expected);\n if (!match) return false;\n const name = match[1]!.replace(/Attribute$/, \"\").split(\".\");\n const foundName = found.name.replace(/Attribute$/, \"\").split(\".\");\n if (!isSegmentSuffix(name, foundName)) return false;\n if (match[2] === undefined) return true;\n const args = splitArgs(match[2]).map(normalizeArg);\n const foundArgs = found.args.map(normalizeArg);\n return args.length === foundArgs.length && args.every((a, i) => a === foundArgs[i]);\n}\n\nconst normalizeArg = (arg: string): string => arg.replace(/\\s+/g, \"\").replace(/'/g, '\"');\n\n/** Splits arguments at top-level commas. */\nfunction splitArgs(text: string): string[] {\n if (text.trim() === \"\") return [];\n const args: string[] = [];\n let depth = 0;\n let quote: string | undefined;\n let current = \"\";\n for (const char of text) {\n if (quote) {\n if (char === quote) quote = undefined;\n } else if (char === '\"' || char === \"'\" || char === \"`\") quote = char;\n else if (\"([{<\".includes(char)) depth++;\n else if (\")]}>\".includes(char)) depth--;\n else if (char === \",\" && depth === 0) {\n args.push(current);\n current = \"\";\n continue;\n }\n current += char;\n }\n args.push(current);\n return args;\n}\n\nconst attributeText = (a: AttributeFact): string =>\n a.args.length > 0 ? `${a.name}(${a.args.join(\", \")})` : a.name;\n\nconst paramText = (p: ParamFact): string => (p.type ? `${p.name}: ${p.type.text}` : p.name);\n\n/** `login(string, number): Promise<boolean>`, as a spec writes it. */\nfunction memberText(member: Member): string {\n const params = member.params ? `(${member.params.join(\", \")})` : \"\";\n const returns = member.returns ? `: ${member.returns}` : \"\";\n const modifiers =\n member.modifiers && member.modifiers.length > 0 ? `${member.modifiers.join(\" \")} ` : \"\";\n return `${modifiers}${member.kind ? `${member.kind} ` : \"\"}${member.name}${params}${returns}`;\n}\n\n/** A declaration's signature: `method login(user: string): Promise<boolean>`. */\nexport function signatureText(symbol: SymbolFact): string {\n const modifiers = symbol.modifiers.length > 0 ? `${symbol.modifiers.join(\" \")} ` : \"\";\n const params = symbol.params ? `(${symbol.params.map(paramText).join(\", \")})` : \"\";\n const returns = symbol.returns ? `: ${symbol.returns.text}` : \"\";\n return `${modifiers}${symbol.kind} ${symbol.name}${params}${returns}`;\n}\n","/**\n * Rule evaluation (plan §D6), PBIs `structural-rules`, `query-and-test-rules` and\n * `architecture-rules`: the structural catalogue (§D6.2), raw Tree-sitter `query` rules (§D6.3)\n * through the adapter, and `test` rules. A rule's scope is its `within` binding or member, else\n * the spec's files (all sources for the architecture spec), narrowed by `paths`.\n */\nimport { builtinModules } from \"node:module\";\nimport { posix } from \"node:path\";\n\nimport {\n codeLocation,\n rangeContains,\n type Codebase,\n type SymbolEntry,\n type SymbolTable,\n} from \"./codebase.js\";\nimport { attributeMatches } from \"./contracts.js\";\nimport {\n createDiagnostic,\n type Diagnostic,\n type DiagnosticCode,\n type Location,\n} from \"./diagnostics.js\";\nimport type { CallFact, FileFacts, Range } from \"./facts.js\";\nimport { typePatternMatches, wildcard, qualifiedNameMatches } from \"./match.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Rule, StructuralRule } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/** The result of running the test command for one test. */\nexport interface TestRun {\n passed: boolean;\n /** The command line that ran. */\n command: string;\n /** The end of the command's output, for the report. */\n output: string;\n}\n\nexport interface RuleContext {\n codebase: Codebase;\n table: SymbolTable;\n /** The spec's resolved bindings, by id. */\n bindings: ReadonlyMap<string, ResolvedBinding>;\n /** The files the spec's rules apply to without `within`. */\n files: readonly FileFacts[];\n /** Runs a test rule's test (`check --run-tests`); undefined when tests aren't run. */\n runTest?: (symbol: string) => Promise<TestRun>;\n}\n\n/** The code a rule looks at: files, and inside them only `ranges` when `within` is set. */\ninterface Scope {\n files: FileFacts[];\n ranges?: Map<string, Range[]>;\n}\n\n/** Evaluates one rule of a spec. `manual` rules are never evaluated (ADR-007). */\nexport async function evaluateRule(\n spec: Spec,\n rule: Rule,\n context: RuleContext,\n): Promise<Diagnostic[]> {\n if (rule.class === \"manual\") return [];\n const scope = scopeOf(rule, context);\n if (!scope) return []; // `within` names a binding that didn't resolve; CS0201 says why.\n const diagnostics: Diagnostic[] = [];\n const report = (\n code: DiagnosticCode,\n message: string,\n extra: Partial<Diagnostic> & { codeLocation?: Location } = {},\n path: (string | number)[] = [],\n ): void => {\n diagnostics.push(\n createDiagnostic(code, {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, ...path]),\n ruleId: rule.id,\n item: `rule:${rule.id}`,\n message: rule.message ? `${rule.message} (${message})` : message,\n ...extra,\n }),\n );\n };\n const inScope = (path: string, range: Range): boolean => {\n const ranges = scope.ranges?.get(path);\n return !scope.ranges || (ranges ?? []).some((r) => rangeContains(r, range));\n };\n const adr = rule.adr ? `, ${rule.adr}` : \"\";\n\n if (rule.class === \"structural\") {\n evaluateStructural(rule, scope, context.table, inScope, report, adr);\n } else if (rule.class === \"query\") {\n const adapter = context.codebase.adapter(rule.lang);\n if (!adapter?.runQuery || adapter.checkQuery?.(rule.query) !== undefined) return []; // CS0130\n const hits: { path: string; range: Range }[] = [];\n for (const file of scope.files) {\n if (file.lang !== rule.lang || file.skipped !== undefined) continue;\n const source = await context.codebase.source(file.path);\n for (const range of adapter.runQuery(source, rule.query)) {\n if (inScope(file.path, range)) hits.push({ path: file.path, range });\n }\n }\n if (rule.expect === \"absent\") {\n for (const hit of hits) {\n report(\"CS0610\", `query rule \"${rule.id}\" matched; expected no match${adr}`, {\n codeLocation: codeLocation(hit.path, hit.range),\n expected: \"absent\",\n actual: \"match\",\n suggestions: [{ message: \"change the code so the query no longer matches\" }],\n });\n }\n } else if (hits.length === 0) {\n report(\"CS0610\", `query rule \"${rule.id}\" found no match; expected at least one${adr}`, {\n expected: \"present\",\n actual: \"no match\",\n suggestions: [{ message: \"add the code the query looks for\" }],\n });\n }\n } else {\n const { symbol, lang } = rule.test;\n const found = context.table.find(symbol).filter((e) => !lang || e.file.lang === lang);\n if (found.length === 0) {\n report(\n \"CS0620\",\n `test ${symbol} of rule \"${rule.id}\" not found`,\n {\n expected: symbol,\n actual: \"nothing\",\n suggestions: [{ message: `write the test ${symbol}, or fix the test symbol` }],\n },\n [\"test\", \"symbol\"],\n );\n } else if (context.runTest) {\n const run = await context.runTest(symbol);\n if (!run.passed) {\n report(\n \"CS0621\",\n `test ${symbol} of rule \"${rule.id}\" failed: ${run.command}`,\n {\n codeLocation: codeLocation(found[0]!.file.path, found[0]!.symbol.nameRange),\n expected: \"pass\",\n actual: run.output,\n suggestions: [{ message: `run ${run.command} and fix the test or the code` }],\n },\n [\"test\", \"symbol\"],\n );\n }\n }\n }\n return diagnostics;\n}\n\ntype Report = (\n code: DiagnosticCode,\n message: string,\n extra?: Partial<Diagnostic> & { codeLocation?: Location },\n path?: (string | number)[],\n) => void;\n\nfunction evaluateStructural(\n rule: StructuralRule,\n scope: Scope,\n table: SymbolTable,\n inScope: (path: string, range: Range) => boolean,\n report: Report,\n adr: string,\n): void {\n if (rule.forbid_call !== undefined || rule.require_call !== undefined) {\n const pattern = (rule.forbid_call ?? rule.require_call)!;\n const matches = wildcard(pattern);\n const calls: { file: FileFacts; call: CallFact; name: string }[] = [];\n for (const file of scope.files) {\n for (const call of file.calls) {\n const name = calleeNames(call.callee, file).find(matches);\n if (name !== undefined && inScope(file.path, call.range)) calls.push({ file, call, name });\n }\n }\n if (rule.forbid_call !== undefined) {\n for (const { file, call } of calls) {\n report(\n \"CS0601\",\n `call to ${call.callee} is forbidden by rule \"${rule.id}\" (${pattern}${adr})`,\n {\n codeLocation: codeLocation(file.path, call.range),\n expected: `no call matching ${pattern}`,\n actual: call.callee,\n suggestions: [\n { message: `remove the call to ${call.callee}, or add a waiver with a reason` },\n ],\n },\n [\"forbid_call\"],\n );\n }\n } else if (calls.length === 0) {\n report(\n \"CS0602\",\n `no call matching ${pattern} in the scope of rule \"${rule.id}\"${adr ? ` (${adr.slice(2)})` : \"\"}`,\n {\n expected: `a call matching ${pattern}`,\n actual: \"no such call\",\n suggestions: [{ message: `add a call matching ${pattern}` }],\n },\n [\"require_call\"],\n );\n }\n return;\n }\n\n const imports = rule.forbid_import ?? rule.allow_import_only;\n if (imports) {\n const from = globMatcher(imports.from);\n const to = globMatcher(imports.to);\n const forbid = rule.forbid_import !== undefined;\n const key = forbid ? \"forbid_import\" : \"allow_import_only\";\n for (const file of scope.files) {\n if (!from(file.path)) continue;\n for (const imp of file.imports) {\n if (!inScope(file.path, imp.range)) continue;\n const targets = importTargets(file.path, imp.module);\n const listed = targets.some(to);\n const violation = forbid ? listed : !listed && !isStdlib(imp.module, file.lang);\n if (!violation) continue;\n report(\n \"CS0603\",\n forbid\n ? `${file.path} imports ${imp.module}; rule \"${rule.id}\" forbids imports from ${listOf(imports.from)} to ${listOf(imports.to)}${adr}`\n : `${file.path} imports ${imp.module}; rule \"${rule.id}\" allows files in ${listOf(imports.from)} to import only ${listOf(imports.to)}${adr}`,\n {\n codeLocation: codeLocation(file.path, imp.range),\n expected: forbid\n ? `no import of ${listOf(imports.to)}`\n : `imports of ${listOf(imports.to)} only`,\n actual: imp.module,\n suggestions: [\n { message: `remove the import of ${imp.module} from ${file.path}, or move the code` },\n ],\n },\n [key],\n );\n }\n }\n return;\n }\n\n if (rule.naming) {\n const naming = rule.naming;\n const nameMatches = wildcard(naming.name);\n const inPath = naming.in_path ? globMatcher(naming.in_path) : undefined;\n for (const { symbol, file } of entriesIn(scope, table, inScope)) {\n if (naming.kind ? symbol.kind !== naming.kind : symbol.kind === \"constructor\") continue;\n if (!nameMatches(symbol.name)) continue;\n const problems: string[] = [];\n for (const type of naming.implements ?? []) {\n if (!symbol.bases.some((b) => typePatternMatches(type, b)))\n problems.push(`implement ${type}`);\n }\n if (\n naming.extends !== undefined &&\n !symbol.bases.some((b) => typePatternMatches(naming.extends!, b))\n ) {\n problems.push(`extend ${naming.extends}`);\n }\n for (const attribute of naming.attributes ?? []) {\n if (!symbol.attributes.some((a) => attributeMatches(attribute, a)))\n problems.push(`have attribute ${attribute}`);\n }\n if (inPath && !inPath(file.path)) problems.push(`live in ${listOf(naming.in_path!)}`);\n if (problems.length === 0) continue;\n report(\n \"CS0604\",\n `${symbol.kind} ${symbol.qualifiedName} must ${problems.join(\", \")} (rule \"${rule.id}\": ${naming.name}${adr})`,\n {\n codeLocation: codeLocation(file.path, symbol.nameRange),\n expected: problems,\n actual: symbol.bases.map((b) => b.text),\n suggestions: [{ message: `make ${symbol.name} ${problems.join(\", \")}, or rename it` }],\n },\n [\"naming\"],\n );\n }\n return;\n }\n\n if (rule.must_not_exist) {\n const { symbol: pattern, kind } = rule.must_not_exist;\n for (const { symbol, file } of entriesIn(scope, table, inScope)) {\n if (kind ? symbol.kind !== kind : symbol.kind === \"constructor\") continue;\n if (!qualifiedNameMatches(pattern, symbol.qualifiedName)) continue;\n report(\n \"CS0605\",\n `${symbol.kind} ${symbol.qualifiedName} must not exist (rule \"${rule.id}\"${adr})`,\n {\n codeLocation: codeLocation(file.path, symbol.nameRange),\n expected: `no ${kind ?? \"symbol\"} ${pattern}`,\n actual: symbol.qualifiedName,\n suggestions: [{ message: `remove or rename ${symbol.qualifiedName}` }],\n },\n [\"must_not_exist\"],\n );\n }\n }\n}\n\n/** The declarations in a scope. */\nfunction entriesIn(\n scope: Scope,\n table: SymbolTable,\n inScope: (path: string, range: Range) => boolean,\n): SymbolEntry[] {\n const files = new Set(scope.files.map((f) => f.path));\n return table.entries.filter(\n (e) => files.has(e.file.path) && inScope(e.file.path, e.symbol.range),\n );\n}\n\n/** The files and ranges a rule applies to; undefined when its `within` binding didn't resolve. */\nfunction scopeOf(rule: Rule, context: RuleContext): Scope | undefined {\n const paths = rule.paths ? globMatcher(rule.paths) : undefined;\n const narrow = (files: readonly FileFacts[]): FileFacts[] =>\n paths ? files.filter((f) => paths(f.path)) : [...files];\n const within = \"within\" in rule ? rule.within : undefined;\n if (within === undefined) return { files: narrow(context.files) };\n const bindingId = context.bindings.has(within)\n ? within\n : [...context.bindings.keys()]\n .filter((id) => within.startsWith(`${id}.`))\n .sort((a, b) => b.length - a.length)[0];\n const resolved = bindingId === undefined ? undefined : context.bindings.get(bindingId);\n if (!resolved) return undefined;\n const memberName =\n within.length > bindingId!.length ? within.slice(bindingId!.length + 1) : undefined;\n // Each part of a C# partial type is in its own file, with its own members.\n const ranges = new Map<string, Range[]>();\n for (const part of resolved.parts) {\n const targets = memberName\n ? part.symbol.members.filter((m) => m.name === memberName)\n : [part.symbol];\n if (targets.length === 0) continue;\n ranges.set(part.file.path, [\n ...(ranges.get(part.file.path) ?? []),\n ...targets.map((t) => t.range),\n ]);\n }\n if (ranges.size === 0) return undefined; // the missing member is CS0203\n const files = context.codebase.files.filter((f) => ranges.has(f.path));\n return { files: narrow(files), ranges };\n}\n\n/**\n * Names a call matches by: the callee as written, and with its first segment resolved through\n * the file's imports (`exec` imported from `node:child_process` is also `child_process.exec`).\n * An import of every name without an alias (C# `using System;`, `using static System.Console;`)\n * also prefixes the callee with the module. In C#, names starting with `System.` also match\n * without it, as types do.\n */\nexport function calleeNames(callee: string, file: FileFacts): string[] {\n const names = [callee];\n const [head, ...rest] = callee.split(\".\");\n for (const imp of file.imports) {\n const module = imp.module.replace(/^node:/, \"\");\n for (const imported of imp.names) {\n if (imported.name === \"*\" && imported.alias === undefined && imp.kind !== \"reexport\") {\n names.push(`${module}.${callee}`);\n continue;\n }\n if ((imported.alias ?? imported.name) !== head) continue;\n const name =\n imported.name === \"*\" || imported.name === \"default\"\n ? [module, ...rest]\n : [module, imported.name, ...rest];\n names.push(name.join(\".\"));\n }\n }\n if (file.lang === \"csharp\") {\n for (const name of [...names]) if (name.startsWith(\"System.\")) names.push(name.slice(7));\n }\n return names;\n}\n\nconst SOURCE_EXTENSIONS = [\".ts\", \".tsx\", \".mts\", \".cts\", \".d.ts\", \".js\", \".jsx\", \".mjs\", \".cjs\"];\n\n/**\n * What an import can be matched against: a relative specifier as a repository path (with and\n * without an extension, `./x.js` also as `x.ts`), a package specifier as written, without\n * `node:`, and as its package name.\n */\nexport function importTargets(fromFile: string, module: string): string[] {\n if (module.startsWith(\".\")) {\n const resolved = posix.normalize(posix.join(posix.dirname(fromFile), module));\n const bare = resolved.replace(/\\.(?:[mc]?[jt]sx?)$/, \"\");\n return [\n ...new Set([\n resolved,\n bare,\n ...SOURCE_EXTENSIONS.map((e) => bare + e),\n ...SOURCE_EXTENSIONS.map((e) => `${bare}/index${e}`),\n ]),\n ];\n }\n const name = module.replace(/^node:/, \"\");\n const segments = name.split(\"/\");\n const pkg = name.startsWith(\"@\") ? segments.slice(0, 2).join(\"/\") : segments[0]!;\n return [...new Set([module, name, pkg])];\n}\n\nconst BUILTINS = new Set(builtinModules);\n\n/** Node.js built-in modules (`fs`, `node:fs`); in C#, the `System` namespaces. */\nconst isStdlib = (module: string, lang: string): boolean =>\n lang === \"csharp\"\n ? module === \"System\" || module.startsWith(\"System.\")\n : module.startsWith(\"node:\") || BUILTINS.has(module.split(\"/\")[0]!);\n","/**\n * The check pipeline (plan §D11.3), PBIs `status-and-waivers` and `check-command`: resolves the\n * bindings of each spec, evaluates contracts and rules, applies the enforcement matrix by spec\n * status (§D8) and the waivers (§D6.5), and records every contract item's result. Architecture\n * rules apply to every source file unless the architecture spec is a draft (§D6.4).\n */\nimport { execFile } from \"node:child_process\";\n\nimport { SymbolTable, type Codebase } from \"./codebase.js\";\nimport { bindingItems, evaluateContract } from \"./contracts.js\";\nimport {\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n type DiagnosticCode,\n} from \"./diagnostics.js\";\nimport { parseErrorDiagnostics, type FileFacts, type LanguageAdapter } from \"./facts.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { applyLock, lockedFiles, type LockFile } from \"./lock.js\";\nimport { resolveBinding, type ResolvedBinding } from \"./resolve.js\";\nimport { evaluateRule, type TestRun } from \"./rules.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/**\n * `status`: enforcement by spec status (§D8): draft, ready and deprecated specs aren't checked,\n * failures of in-progress specs are warnings. `full`: every selected spec is checked as if it\n * were implemented (`check --spec`, `status … implemented`, `coverage`).\n */\nexport type CheckMode = \"status\" | \"full\";\n\nexport interface CheckOptions {\n /** Only these spec ids; repository-wide diagnostics are left out. */\n specs?: readonly string[];\n mode?: CheckMode;\n /** Today, for waiver expiry. */\n now?: Date;\n /** Runs a test rule's test (`--run-tests`). */\n runTest?: (symbol: string) => Promise<TestRun>;\n /**\n * Lock files by spec id (plan §D7), for the ratchet (CS0301), drift (CS0300) and the locked\n * files of bindings. Default: the lock files of the model.\n */\n locks?: ReadonlyMap<string, LockFile>;\n}\n\n/** The result of one contract item: a binding, a member or a rule. */\nexport interface ItemResult {\n spec: string;\n /** `binding:<id>`, `binding:<id>.<member>` or `rule:<id>`. */\n item: string;\n /** False for `manual` rules: nothing checks them (ADR-007). */\n enforceable: boolean;\n /** Checked and nothing failed (an active waiver counts as passing); false for manual rules. */\n passed: boolean;\n}\n\nexport interface CheckResult {\n /** The specs whose contracts were evaluated. */\n checked: Spec[];\n items: ItemResult[];\n /** Spec diagnostics (`--specs-only`) and code diagnostics, sorted. */\n diagnostics: Diagnostic[];\n /** Resolved bindings by spec id, then binding id. */\n resolved: Map<string, Map<string, ResolvedBinding>>;\n /**\n * True when a result depends on more than the files of the checked specs: a binding was looked\n * up in every source file, or a check consulted every declaration (ambiguity, type aliases,\n * test symbols). A check on part of the code (`check --staged`) is then repeated on all of it.\n */\n repositoryWide: boolean;\n}\n\n/** Codes whose result depends on every declaration of the repository, not only a spec's files. */\nconst REPOSITORY_WIDE_CODES = new Set<DiagnosticCode>([\"CS0202\", \"CS0204\", \"CS0220\", \"CS0620\"]);\n\n/** True when a spec's contracts are evaluated in `status` mode (§D6.4, §D8). */\nexport function isEnforced(spec: Spec): boolean {\n if (spec.type === \"architecture\") return spec.status !== \"draft\";\n return spec.status === \"in-progress\" || spec.status === \"implemented\";\n}\n\n/** CS0130: query rules whose query doesn't compile, checked when the specs load. */\nexport function queryDiagnostics(\n model: SpecModel,\n adapter: (lang: string) => LanguageAdapter | undefined,\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n for (const spec of model.specs.byFile.values()) {\n for (const rule of spec.rules) {\n if (rule.class !== \"query\") continue;\n const lang = adapter(rule.lang);\n const error = !lang\n ? `no language adapter for \"${rule.lang}\"`\n : !lang.checkQuery\n ? `the ${rule.lang} adapter doesn't support query rules`\n : lang.checkQuery(rule.query);\n if (error === undefined) continue;\n diagnostics.push(\n createDiagnostic(\"CS0130\", {\n spec: spec.id,\n ruleId: rule.id,\n item: `rule:${rule.id}`,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, \"query\"]),\n message: `rule \"${rule.id}\": invalid ${rule.lang} query: ${error}`,\n actual: rule.query,\n suggestions: [{ message: \"fix the query; check its parentheses and node types\" }],\n }),\n );\n }\n }\n return diagnostics;\n}\n\n/** Runs the check: spec diagnostics of `model` plus the evaluation of the code. */\nexport async function checkCode(\n model: SpecModel,\n codebase: Codebase,\n options: CheckOptions = {},\n): Promise<CheckResult> {\n const mode = options.mode ?? \"status\";\n const now = options.now ?? new Date();\n const locks = options.locks ?? model.locks;\n let repositoryWide = false;\n const table = new SymbolTable(codebase.files);\n const selected = options.specs ? new Set(options.specs) : undefined;\n const specs = model.specs\n .all()\n .filter((s) => (selected ? selected.has(s.id) : true))\n .filter(\n (s) =>\n s.valid &&\n (mode === \"full\" ? selected !== undefined || s.status !== \"deprecated\" : isEnforced(s)),\n );\n\n const specDiagnostics = [\n ...model.diagnostics,\n ...queryDiagnostics(model, (lang) => codebase.adapter(lang)),\n ].filter((d) => !selected || (d.spec !== undefined && selected.has(d.spec)));\n\n const diagnostics: Diagnostic[] = [];\n const items: ItemResult[] = [];\n const resolvedBySpec = new Map<string, Map<string, ResolvedBinding>>();\n const testRuns = new Map<string, Promise<TestRun>>();\n const runTest = options.runTest\n ? (symbol: string): Promise<TestRun> => {\n let run = testRuns.get(symbol);\n if (!run) testRuns.set(symbol, (run = options.runTest!(symbol)));\n return run;\n }\n : undefined;\n const failedSpecs = new Set(\n specDiagnostics.filter((d) => d.code === \"CS0130\").map((d) => `${d.spec}\\0${d.ruleId}`),\n );\n\n for (const spec of specs) {\n const raw: Diagnostic[] = [];\n const resolved = new Map<string, ResolvedBinding>();\n const lock = locks.get(spec.id);\n for (const binding of spec.bindings) {\n const resolution = resolveBinding(spec, binding, table, lockedFiles(lock, binding.id));\n raw.push(...resolution.diagnostics);\n if (resolution.searched) repositoryWide = true;\n if (!resolution.resolved) continue;\n resolved.set(binding.id, resolution.resolved);\n raw.push(\n ...evaluateContract(spec, resolution.resolved, {\n table,\n adapter: codebase.adapter(resolution.resolved.file.lang),\n unresolvable: model.config.enforcement.unresolvable,\n }),\n );\n }\n resolvedBySpec.set(spec.id, resolved);\n const files = specFiles(spec, resolved, codebase.files);\n for (const rule of spec.rules) {\n if (failedSpecs.has(`${spec.id}\\0${rule.id}`)) continue;\n raw.push(\n ...(await evaluateRule(spec, rule, {\n codebase,\n table,\n bindings: resolved,\n files,\n ...(runTest ? { runTest } : {}),\n })),\n );\n }\n\n if (raw.some((d) => REPOSITORY_WIDE_CODES.has(d.code))) repositoryWide = true;\n const enforced = enforce(spec, raw, mode, now);\n diagnostics.push(\n ...applyLock(spec, enforced, resolved, lock, {\n drift: model.config.enforcement.drift,\n asImplemented: mode === \"full\",\n }),\n );\n\n const unresolved = new Set(spec.bindings.filter((b) => !resolved.has(b.id)).map((b) => b.id));\n const failing = new Set(\n enforced.filter((d) => d.item && d.severity !== \"info\").map((d) => d.item!),\n );\n for (const binding of spec.bindings) {\n for (const item of bindingItems(binding)) {\n items.push({\n spec: spec.id,\n item,\n enforceable: true,\n passed: !unresolved.has(binding.id) && !failing.has(item),\n });\n }\n }\n for (const rule of spec.rules) {\n const item = `rule:${rule.id}`;\n const within = \"within\" in rule ? rule.within : undefined;\n const blocked =\n within !== undefined &&\n [...unresolved].some((id) => within === id || within.startsWith(`${id}.`));\n items.push({\n spec: spec.id,\n item,\n enforceable: rule.class !== \"manual\",\n passed:\n rule.class !== \"manual\" &&\n !blocked &&\n !failing.has(item) &&\n !failedSpecs.has(`${spec.id}\\0${rule.id}`),\n });\n }\n }\n\n // Syntax errors of the files the selected specs bind (all files without --spec).\n const boundFiles = new Set(\n [...resolvedBySpec.values()].flatMap((m) => [...m.values()].flatMap((r) => r.files)),\n );\n const parseErrors = codebase.files\n .filter((f) => !selected || boundFiles.has(f.path))\n .flatMap(parseErrorDiagnostics);\n\n return {\n checked: specs,\n items,\n diagnostics: sortDiagnostics([...specDiagnostics, ...diagnostics, ...parseErrors]),\n resolved: resolvedBySpec,\n repositoryWide,\n };\n}\n\n/** Files a spec's rules apply to by default: every source for the architecture spec, else the\n * files of its resolved bindings and its `scope` globs. */\nfunction specFiles(\n spec: Spec,\n resolved: ReadonlyMap<string, ResolvedBinding>,\n files: readonly FileFacts[],\n): FileFacts[] {\n if (spec.type === \"architecture\") return [...files];\n const bound = new Set([...resolved.values()].flatMap((r) => r.files));\n const inScope = spec.scope.length > 0 ? globMatcher(spec.scope) : () => false;\n return files.filter((f) => bound.has(f.path) || inScope(f.path));\n}\n\n/** Codes of contract failures, which the status matrix lowers for in-progress specs. */\nconst isContractFailure = (code: DiagnosticCode): boolean =>\n code.startsWith(\"CS02\") || code.startsWith(\"CS06\");\n\n/** Applies waivers (§D6.5) and the enforcement matrix (§D8) to a spec's raw diagnostics. */\nfunction enforce(spec: Spec, raw: Diagnostic[], mode: CheckMode, now: Date): Diagnostic[] {\n const today = isoDate(now);\n const out: Diagnostic[] = [];\n const active = spec.waivers.filter((w) => w.until === undefined || w.until >= today);\n for (const waiver of spec.waivers) {\n if (waiver.until === undefined || waiver.until >= today) continue;\n out.push(\n createDiagnostic(\"CS0401\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"waivers\", waiver.index, \"until\"]),\n ruleId: waiver.rule,\n message: `the waiver for rule \"${waiver.rule}\" expired on ${waiver.until} (${waiver.reason}); its violations are reported again`,\n expected: `until ≥ ${today}`,\n actual: waiver.until,\n suggestions: [\n { message: \"fix the violations and remove the waiver, or extend until with a reason\" },\n ],\n }),\n );\n }\n for (const d of raw) {\n const waiver = active.find(\n (w) =>\n d.ruleId === w.rule &&\n (!w.paths || (d.codeLocation !== undefined && globMatcher(w.paths)(d.codeLocation.file))),\n );\n if (waiver) {\n out.push({\n ...d,\n code: \"CS0400\",\n severity: \"info\",\n message: `waived${waiver.until ? ` until ${waiver.until}` : \"\"} (${waiver.reason}): ${d.code} ${d.message}`,\n actual: d.code,\n });\n continue;\n }\n const lowered =\n mode === \"status\" &&\n spec.type !== \"architecture\" &&\n spec.status === \"in-progress\" &&\n d.severity === \"error\" &&\n isContractFailure(d.code);\n out.push(lowered ? { ...d, severity: \"warning\" } : d);\n }\n return out;\n}\n\nconst isoDate = (date: Date): string =>\n `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}-${String(date.getDate()).padStart(2, \"0\")}`;\n\n/** `tests.command` as arguments: a string is split at whitespace. */\nexport const testCommandArgs = (command: string | readonly string[]): string[] =>\n typeof command === \"string\" ? command.trim().split(/\\s+/) : [...command];\n\n/**\n * Runs `tests.command` for one test, without a shell (ADR-009): `{test}` in an argument is\n * replaced with the test symbol. The test passes when the command exits with 0.\n */\nexport function runTestCommand(\n root: string,\n command: string | readonly string[],\n symbol: string,\n timeoutMs = 10 * 60_000,\n): Promise<TestRun> {\n const [file, ...args] = testCommandArgs(command).map((a) => a.replaceAll(\"{test}\", symbol));\n const line = [file, ...args].join(\" \");\n return new Promise((resolvePromise) => {\n execFile(\n file!,\n args,\n { cwd: root, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, windowsHide: true },\n (error, stdout, stderr) => {\n const output = `${stdout}${stderr}`.trim().split(/\\r?\\n/).slice(-20).join(\"\\n\");\n resolvePromise({\n passed: !error,\n command: line,\n output: error && !output ? error.message : output,\n });\n },\n );\n });\n}\n\n/** Specs a status change depends on, for `catspec status` (§D8). */\nexport interface StatusGate {\n allowed: boolean;\n diagnostics: Diagnostic[];\n}\n\n/**\n * Whether `spec` may move to `target` (§D8): `ready` needs every dependency to exist,\n * `in-progress` and `implemented` need them implemented and passing (CS0502; `force` skips this),\n * and `implemented` needs the spec's own contracts to pass (never forced).\n */\nexport async function statusGate(\n model: SpecModel,\n codebase: Codebase,\n spec: Spec,\n target: Spec[\"status\"],\n options: { force?: boolean; now?: Date } = {},\n): Promise<StatusGate> {\n const diagnostics: Diagnostic[] = [];\n const now = options.now ?? new Date();\n if (\n !options.force &&\n (target === \"ready\" || target === \"in-progress\" || target === \"implemented\")\n ) {\n const problems: string[] = [];\n for (const dep of spec.dependsOn) {\n const other = model.specs.get(dep);\n if (!other) {\n problems.push(`${dep} does not exist`);\n continue;\n }\n if (target === \"ready\") continue;\n if (other.status !== \"implemented\") {\n problems.push(`${dep} is ${other.status}, not implemented`);\n continue;\n }\n const result = await checkCode(model, codebase, { specs: [dep], mode: \"full\", now });\n if (result.diagnostics.some((d) => d.severity === \"error\")) {\n problems.push(\n `${dep} is implemented but its contracts fail (run \\`catspec check --spec ${dep}\\`)`,\n );\n }\n }\n if (problems.length > 0) {\n diagnostics.push(\n createDiagnostic(\"CS0502\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"depends_on\"]),\n message: `\"${spec.id}\" can't become ${target}: ${listOf(problems)}`,\n expected:\n target === \"ready\"\n ? \"every dependency exists\"\n : \"every dependency implemented and passing\",\n actual: problems,\n suggestions: [{ message: \"finish the dependencies first, or use --force\" }],\n }),\n );\n }\n }\n if (target === \"implemented\") {\n const result = await checkCode(model, codebase, { specs: [spec.id], mode: \"full\", now });\n diagnostics.push(...result.diagnostics.filter((d) => d.severity === \"error\"));\n }\n return {\n allowed: !diagnostics.some((d) => d.severity === \"error\"),\n diagnostics: sortDiagnostics(diagnostics),\n };\n}\n","/**\n * Lock files (plan §D7, ADR-004), PBIs `lock-files`, `ratchet` and `drift-and-accept`: the\n * observed state of a spec, generated next to it as `<spec-id>.lock.json` and committed.\n *\n * - `items`: a hash of each contract item as the spec declares it, so a change to one item resets\n * only that item (§D7.1).\n * - `satisfied`: items that passed once. A failure of one of them is a regression, CS0301, even\n * while the spec is in progress (ADR-006).\n * - `symbols`: where each binding resolved, and the shape of the declaration (bodies excluded)\n * with its fingerprint. A shape change of an implemented spec is drift, CS0300 (§D7.2), until\n * `catspec accept` records it.\n *\n * The writer is deterministic: keys are sorted and lists ordered, so the same state gives the same\n * bytes on every platform.\n */\nimport { createHash } from \"node:crypto\";\nimport { posix } from \"node:path\";\n\nimport type { ItemResult } from \"./check.js\";\nimport { bindingItems } from \"./contracts.js\";\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport type { ParamFact, SymbolFact } from \"./facts.js\";\nimport type { ResolvedBinding } from \"./resolve.js\";\nimport type { Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { listOf } from \"./util.js\";\n\n/** The shape of a declaration: what a caller depends on, without bodies (§D7.2). */\nexport interface Shape {\n kind: string;\n name: string;\n bases: string[];\n attributes: string[];\n modifiers: string[];\n /** Parameters and return type of a function binding: `(string,number):boolean`. */\n signature?: string;\n /** Member signatures, sorted: `public method login(string):Promise<boolean>`. */\n members: string[];\n}\n\nexport interface LockedSymbol {\n /** `path#QualifiedName` of the declaration (of its first part). */\n resolved: string;\n /** Every file of a C# partial type, when there is more than one. */\n files?: string[];\n fingerprint: string;\n shape: Shape;\n}\n\nexport interface LockFile {\n spec: string;\n /** Hash of the spec's bindings and rules. */\n specHash: string;\n /** Hash of each contract item as declared, by item. */\n items: Record<string, string>;\n /** Items that passed at least once, sorted. */\n satisfied: string[];\n /** Observed declarations, by binding id. */\n symbols: Record<string, LockedSymbol>;\n}\n\n/** The lock file of a spec: `<spec-id>.lock.json` in the spec's folder. */\nexport const lockPathOf = (spec: { id: string; file: string }): string =>\n posix.join(posix.dirname(spec.file), `${spec.id}.lock.json`);\n\n/** Specs that have lock files: every spec except the architecture spec. */\nexport const hasLockFile = (spec: Spec): boolean => spec.type !== \"architecture\";\n\nconst sha256 = (value: unknown): string =>\n `sha256:${createHash(\"sha256\").update(canonicalJson(value)).digest(\"hex\")}`;\n\n/** JSON with sorted object keys and no undefined values. */\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortKeys);\n if (value === null || typeof value !== \"object\") return value;\n return Object.fromEntries(\n Object.entries(value)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => compareStrings(a, b))\n .map(([k, v]) => [k, sortKeys(v)]),\n );\n}\n\n/** A frontmatter entry without its position in the list. */\nfunction declared<T extends { index: number }>(entry: T): Omit<T, \"index\"> {\n const copy: Partial<T> = { ...entry };\n delete copy.index;\n return copy as Omit<T, \"index\">;\n}\n\n/**\n * The declared contract of a binding item. `symbol` and `file` are locations, not contract\n * (ADR-008): `catspec sync` rewrites them without resetting the ratchet.\n */\nconst bindingContract = (binding: Binding): unknown => ({\n kind: binding.kind,\n lang: binding.lang,\n implements: binding.implements,\n extends: binding.extends,\n attributes: binding.attributes,\n constructorRequires: binding.constructorRequires,\n exported: binding.exported,\n});\n\n/** The hash of every contract item of a spec, by item (§D7.1). */\nexport function itemHashes(spec: Spec): Record<string, string> {\n const hashes: Record<string, string> = {};\n for (const binding of spec.bindings) {\n hashes[`binding:${binding.id}`] = sha256(bindingContract(binding));\n for (const member of binding.members) {\n hashes[`binding:${binding.id}.${member.name}`] = sha256(member);\n }\n }\n for (const rule of spec.rules) hashes[`rule:${rule.id}`] = sha256(declared(rule));\n return hashes;\n}\n\n/** Hash of the whole contract of a spec. */\nexport const specHash = (spec: Spec): string =>\n sha256({\n bindings: spec.bindings.map(declared),\n rules: spec.rules.map(declared),\n });\n\nconst paramType = (p: ParamFact): string =>\n `${p.rest ? \"...\" : \"\"}${p.type?.text ?? \"?\"}${p.optional ? \"?\" : \"\"}`;\n\nconst callSignature = (s: SymbolFact): string =>\n `(${(s.params ?? []).map(paramType).join(\",\")})${s.returns ? `:${s.returns.text}` : \"\"}`;\n\nconst sortedModifiers = (s: SymbolFact): string[] => [...s.modifiers].sort(compareStrings);\n\nconst attributeText = (a: { name: string; args: string[] }): string =>\n a.args.length > 0 ? `${a.name}(${a.args.join(\",\")})` : a.name;\n\n/** The shape of a declaration: kind, name, bases, attributes, modifiers and member signatures. */\nexport function shapeOf(symbol: SymbolFact): Shape {\n const member = (m: SymbolFact): string => {\n const modifiers = sortedModifiers(m);\n const head = [...modifiers, m.kind, m.name].join(\" \");\n return m.params !== undefined\n ? `${head}${callSignature(m)}`\n : `${head}${m.returns ? `:${m.returns.text}` : \"\"}`;\n };\n const shape: Shape = {\n kind: symbol.kind,\n name: symbol.qualifiedName,\n bases: symbol.bases.map((b) => b.text),\n attributes: symbol.attributes.map(attributeText).sort(compareStrings),\n modifiers: sortedModifiers(symbol),\n members: symbol.members.map(member).sort(compareStrings),\n };\n if (symbol.params !== undefined) shape.signature = callSignature(symbol);\n return shape;\n}\n\nexport const fingerprintOf = (shape: Shape): string => sha256(shape);\n\n/** The files a locked binding resolved to, for binding resolution (§D11.5 step 2). */\nexport function lockedFiles(lock: LockFile | undefined, bindingId: string): string[] {\n const entry = lock?.symbols[bindingId];\n if (!entry) return [];\n if (entry.files && entry.files.length > 0) return entry.files;\n const hash = entry.resolved.lastIndexOf(\"#\");\n return [hash === -1 ? entry.resolved : entry.resolved.slice(0, hash)];\n}\n\n/** Parses a lock file; undefined when it isn't a valid lock file (it is then rebuilt). */\nexport function parseLock(text: string): LockFile | undefined {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n return undefined;\n }\n if (value === null || typeof value !== \"object\") return undefined;\n const lock = value as Partial<LockFile>;\n const isRecord = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === \"object\" && !Array.isArray(v);\n if (\n typeof lock.spec !== \"string\" ||\n !Array.isArray(lock.satisfied) ||\n !lock.satisfied.every((s) => typeof s === \"string\") ||\n !isRecord(lock.items) ||\n !isRecord(lock.symbols) ||\n !Object.values(lock.symbols).every(\n (s) =>\n isRecord(s) &&\n typeof s.resolved === \"string\" &&\n typeof s.fingerprint === \"string\" &&\n isRecord(s.shape),\n )\n ) {\n return undefined;\n }\n return {\n spec: lock.spec,\n specHash: typeof lock.specHash === \"string\" ? lock.specHash : \"\",\n items: lock.items,\n satisfied: lock.satisfied,\n symbols: lock.symbols,\n };\n}\n\n/**\n * The lock file's text: the fields in the order of plan §D7, every map sorted by key, two-space\n * indent, `\\n` line endings and a final newline.\n */\nexport function serializeLock(lock: LockFile): string {\n const symbols = Object.fromEntries(\n Object.keys(lock.symbols)\n .sort(compareStrings)\n .map((id) => {\n const { resolved, files, fingerprint, shape } = lock.symbols[id]!;\n return [id, { resolved, files, fingerprint, shape: sortKeys(shape) }];\n }),\n );\n const ordered = {\n spec: lock.spec,\n specHash: lock.specHash,\n items: sortKeys(lock.items),\n satisfied: lock.satisfied,\n symbols,\n };\n return `${JSON.stringify(ordered, null, 2)}\\n`;\n}\n\n/** Items of the lock that still mean what the spec declares: same hash as when they passed. */\nfunction stillSatisfied(lock: LockFile | undefined, hashes: Record<string, string>): Set<string> {\n if (!lock) return new Set();\n return new Set(\n lock.satisfied.filter(\n (item) => hashes[item] !== undefined && lock.items[item] === hashes[item],\n ),\n );\n}\n\n/** True when a binding's declared contract (its item and every member item) is unchanged. */\nfunction bindingUnchanged(\n binding: Binding,\n lock: LockFile,\n hashes: Record<string, string>,\n): boolean {\n const items = bindingItems(binding);\n const locked = Object.keys(lock.items).filter(\n (item) => item === `binding:${binding.id}` || item.startsWith(`binding:${binding.id}.`),\n );\n return locked.length === items.length && items.every((item) => lock.items[item] === hashes[item]);\n}\n\nexport interface LockCheckOptions {\n /** Severity of drift for implemented specs (`enforcement.drift`). */\n drift: \"off\" | \"warn\" | \"strict\";\n /** `full`: the spec is checked as if implemented (`check --spec`). */\n asImplemented?: boolean;\n}\n\n/**\n * The ratchet and drift for one spec (§D7.1, §D7.2, §D8): a failure of an item that passed\n * before becomes CS0301 (an error, also in progress), and a shape change of a binding whose\n * contract didn't change is CS0300 (info in progress, `enforcement.drift` when implemented).\n */\nexport function applyLock(\n spec: Spec,\n diagnostics: Diagnostic[],\n resolved: ReadonlyMap<string, ResolvedBinding>,\n lock: LockFile | undefined,\n options: LockCheckOptions,\n): Diagnostic[] {\n if (!lock || spec.type === \"architecture\") return diagnostics;\n const hashes = itemHashes(spec);\n const satisfied = stillSatisfied(lock, hashes);\n const out = diagnostics.map((d) =>\n d.item !== undefined &&\n satisfied.has(d.item) &&\n d.severity !== \"info\" &&\n d.code !== \"CS0220\" &&\n d.code !== \"CS0401\"\n ? {\n ...d,\n code: \"CS0301\" as const,\n severity: \"error\" as const,\n message: `regression: ${d.item} passed before and now fails: ${d.code} ${d.message}`,\n }\n : d,\n );\n\n const implemented = options.asImplemented === true || spec.status === \"implemented\";\n const severity = implemented\n ? options.drift === \"off\"\n ? undefined\n : options.drift === \"strict\"\n ? (\"error\" as const)\n : (\"warning\" as const)\n : (\"info\" as const);\n if (severity === undefined) return out;\n for (const binding of spec.bindings) {\n const entry = lock.symbols[binding.id];\n const current = resolved.get(binding.id);\n if (!entry || !current || !bindingUnchanged(binding, lock, hashes)) continue;\n const shape = shapeOf(current.symbol);\n if (fingerprintOf(shape) === entry.fingerprint) continue;\n const changes = shapeChanges(entry.shape, shape);\n out.push(\n createDiagnostic(\"CS0300\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n codeLocation: {\n file: current.file.path,\n line: current.symbol.nameRange.start.line,\n column: current.symbol.nameRange.start.column,\n },\n bindingId: binding.id,\n severity,\n message: `binding \"${binding.id}\": the shape of ${current.symbol.qualifiedName} changed and the spec doesn't mention it: ${listOf(changes)}`,\n expected: entry.shape,\n actual: shape,\n suggestions: [\n { message: `run \\`catspec accept ${spec.id}\\` if the change is intended` },\n { message: \"or update the spec, or change the code back\" },\n ],\n }),\n );\n }\n return out;\n}\n\n/** Human-readable differences between two shapes. */\nfunction shapeChanges(before: Shape, after: Shape): string[] {\n const changes: string[] = [];\n if (before.kind !== after.kind) changes.push(`kind ${before.kind} → ${after.kind}`);\n if (before.name !== after.name) changes.push(`name ${before.name} → ${after.name}`);\n if ((before.signature ?? \"\") !== (after.signature ?? \"\")) {\n changes.push(`signature ${before.signature ?? \"none\"} → ${after.signature ?? \"none\"}`);\n }\n const lists: [string, keyof Shape][] = [\n [\"base\", \"bases\"],\n [\"attribute\", \"attributes\"],\n [\"modifier\", \"modifiers\"],\n [\"member\", \"members\"],\n ];\n for (const [label, key] of lists) {\n const a = (before[key] as string[] | undefined) ?? [];\n const b = (after[key] as string[] | undefined) ?? [];\n for (const removed of a.filter((x) => !b.includes(x))) changes.push(`- ${label} ${removed}`);\n for (const added of b.filter((x) => !a.includes(x))) changes.push(`+ ${label} ${added}`);\n }\n return changes.length > 0 ? changes : [\"the shape changed\"];\n}\n\nexport interface NextLockOptions {\n /**\n * `update` (the hook): keeps the ratchet history, and the accepted shapes of an implemented\n * spec until they are accepted. `accept`: records the current shapes. `rebuild`: from the\n * current code only, without history.\n */\n mode: \"update\" | \"accept\" | \"rebuild\";\n}\n\n/** The lock file after a check of `spec`. */\nexport function nextLock(\n spec: Spec,\n items: readonly ItemResult[],\n resolved: ReadonlyMap<string, ResolvedBinding>,\n previous: LockFile | undefined,\n options: NextLockOptions,\n): LockFile {\n const hashes = itemHashes(spec);\n const prev = options.mode === \"rebuild\" ? undefined : previous;\n const satisfied = stillSatisfied(prev, hashes);\n for (const item of items) {\n if (item.spec === spec.id && item.passed && hashes[item.item] !== undefined) {\n satisfied.add(item.item);\n }\n }\n const symbols: Record<string, LockedSymbol> = {};\n for (const binding of spec.bindings) {\n const current = resolved.get(binding.id);\n const old = prev?.symbols[binding.id];\n if (!current) {\n if (old) symbols[binding.id] = old;\n continue;\n }\n const shape = shapeOf(current.symbol);\n const location: Pick<LockedSymbol, \"resolved\" | \"files\"> = {\n resolved: `${current.file.path}#${current.symbol.qualifiedName}`,\n ...(current.files.length > 1 ? { files: [...current.files].sort(compareStrings) } : {}),\n };\n const keepAccepted =\n options.mode === \"update\" &&\n old !== undefined &&\n prev !== undefined &&\n spec.status === \"implemented\" &&\n bindingUnchanged(binding, prev, hashes);\n symbols[binding.id] = keepAccepted\n ? { ...location, fingerprint: old.fingerprint, shape: old.shape }\n : { ...location, fingerprint: fingerprintOf(shape), shape };\n }\n return {\n spec: spec.id,\n specHash: specHash(spec),\n items: hashes,\n satisfied: [...satisfied].sort(compareStrings),\n symbols,\n };\n}\n","/**\n * Git access (plan §D11.3, ADR-009), PBI `git-access`: git runs with `execFile` / `spawn` and an\n * argument list, never through a shell, so a file name is never interpreted as a command. Object\n * contents are read through one long-lived `git cat-file --batch` process. Every listing uses\n * `-z`, so names with spaces, quotes or newlines arrive unchanged.\n */\nimport { execFile, spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { resolve } from \"node:path\";\n\n/** Git isn't installed or isn't on PATH (CS0902). */\nexport class GitUnavailableError extends Error {\n constructor(cause?: unknown) {\n super(\"git is required but was not found on PATH\", { cause });\n this.name = \"GitUnavailableError\";\n }\n}\n\n/** A git command failed. */\nexport class GitError extends Error {\n constructor(\n readonly args: readonly string[],\n readonly exitCode: number | null,\n readonly stderr: string,\n ) {\n super(`git ${args[0] ?? \"\"} failed${stderr ? `: ${stderr.trim().split(\"\\n\")[0]}` : \"\"}`);\n this.name = \"GitError\";\n }\n}\n\n/** An entry of the index (`ls-files -s`) or of a tree (`ls-tree -r`). */\nexport interface TreeEntry {\n /** Octal file mode: `100644`, `100755`, `120000` (symbolic link), `160000` (submodule). */\n mode: string;\n blobSha: string;\n /** Merge stage: 0 normally, 1–3 for a conflicted file. Always 0 for a tree. */\n stage: number;\n /** Path relative to the folder git runs in, with forward slashes. */\n path: string;\n}\n\n/** A staged change (`diff --cached -M --name-status`). */\nexport interface StagedChange {\n /** `A` added, `M` modified, `D` deleted, `R` renamed, `C` copied, `T` type changed, … */\n status: string;\n path: string;\n /** The old path of a rename or copy. */\n from?: string;\n}\n\n/** A git object read by `cat-file --batch`. */\ninterface PendingRead {\n resolve: (content: Buffer | undefined) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * A long-lived `git cat-file --batch`: object ids go in on stdin, contents come back in order.\n * Requests are pipelined, so reading many files costs one process.\n */\nclass CatFileBatch {\n private readonly child: ChildProcessWithoutNullStreams;\n private readonly pending: PendingRead[] = [];\n private buffer: Buffer = Buffer.alloc(0);\n private failure?: Error;\n private readonly exited: Promise<void>;\n\n constructor(cwd: string, env: NodeJS.ProcessEnv | undefined) {\n this.child = spawn(\"git\", [\"cat-file\", \"--batch\"], {\n cwd,\n ...(env ? { env } : {}),\n windowsHide: true,\n });\n this.child.stdout.on(\"data\", (chunk: Buffer) => {\n this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);\n this.drain();\n });\n let stderr = \"\";\n this.child.stderr.on(\"data\", (chunk: Buffer) => (stderr += chunk.toString(\"utf8\")));\n this.child.on(\"error\", (error: NodeJS.ErrnoException) =>\n this.fail(error.code === \"ENOENT\" ? new GitUnavailableError(error) : error),\n );\n this.exited = new Promise((resolveExit) => {\n this.child.on(\"close\", (code) => {\n this.fail(new GitError([\"cat-file\", \"--batch\"], code, stderr || \"exited\"));\n resolveExit();\n });\n // A process that never started has nothing to wait for.\n this.child.on(\"error\", () => resolveExit());\n });\n // A closed pipe is reported through `close`; don't let it throw.\n this.child.stdin.on(\"error\", () => undefined);\n }\n\n /** True once the process has failed or exited; every later read would fail. */\n get failed(): boolean {\n return this.failure !== undefined;\n }\n\n /** The content of a blob, or undefined when the object doesn't exist. */\n read(sha: string): Promise<Buffer | undefined> {\n if (this.failure) return Promise.reject(this.failure);\n if (!/^[0-9a-f]{40,64}$/.test(sha)) {\n return Promise.reject(new Error(`not an object id: ${sha}`));\n }\n return new Promise((resolvePromise, reject) => {\n this.pending.push({ resolve: resolvePromise, reject });\n this.child.stdin.write(`${sha}\\n`);\n });\n }\n\n /** Ends the process and waits for it to exit (on Windows its folder stays locked until then). */\n close(): Promise<void> {\n this.child.stdin.end();\n return this.exited;\n }\n\n private drain(): void {\n for (;;) {\n const request = this.pending[0];\n if (!request) return;\n const newline = this.buffer.indexOf(0x0a);\n if (newline === -1) return;\n const header = this.buffer.subarray(0, newline).toString(\"utf8\");\n const parts = header.split(\" \");\n if (parts[1] === \"missing\" || parts[1] === \"ambiguous\") {\n this.buffer = this.buffer.subarray(newline + 1);\n this.pending.shift();\n request.resolve(undefined);\n continue;\n }\n const size = Number(parts[2]);\n if (parts.length !== 3 || !Number.isInteger(size)) {\n this.fail(new Error(`unexpected git cat-file output: ${header}`));\n return;\n }\n const end = newline + 1 + size;\n if (this.buffer.length < end + 1) return;\n const content = Buffer.from(this.buffer.subarray(newline + 1, end));\n this.buffer = this.buffer.subarray(end + 1);\n this.pending.shift();\n request.resolve(content);\n }\n }\n\n private fail(error: Error): void {\n this.failure ??= error;\n for (const request of this.pending.splice(0)) request.reject(this.failure);\n }\n}\n\n/** Git commands for one folder of a repository. Paths are relative to that folder. */\nexport class Git {\n private batch?: CatFileBatch;\n\n /**\n * @param cwd The folder git runs in; listings are relative to it.\n * @param env The environment of the git processes (default: this process's).\n */\n constructor(\n readonly cwd: string,\n readonly env?: NodeJS.ProcessEnv,\n ) {}\n\n /** Runs git with `args` (no shell) and returns its standard output. */\n run(args: readonly string[], options: { input?: string } = {}): Promise<Buffer> {\n return new Promise((resolvePromise, reject) => {\n const child = execFile(\n \"git\",\n [...args],\n {\n cwd: this.cwd,\n encoding: \"buffer\",\n maxBuffer: 256 * 1024 * 1024,\n windowsHide: true,\n ...(this.env ? { env: this.env } : {}),\n },\n (error, stdout, stderr) => {\n if (!error) {\n resolvePromise(stdout);\n return;\n }\n const code = (error as NodeJS.ErrnoException).code;\n reject(\n code === \"ENOENT\"\n ? new GitUnavailableError(error)\n : new GitError(\n args,\n typeof code === \"number\" ? code : null,\n stderr.toString(\"utf8\") || error.message,\n ),\n );\n },\n );\n if (options.input !== undefined) child.stdin?.end(options.input);\n });\n }\n\n /**\n * The repository's top-level folder and git common dir (shared by every worktree), as paths\n * from `cwd` (so they stay comparable with it where the temp folder is a symbolic link).\n */\n async repository(): Promise<{ topLevel: string; commonDir: string; prefix: string }> {\n const out = (await this.run([\"rev-parse\", \"--show-cdup\", \"--git-common-dir\", \"--show-prefix\"]))\n .toString(\"utf8\")\n .split(\"\\n\");\n return {\n topLevel: resolve(this.cwd, out[0]!),\n commonDir: resolve(this.cwd, out[1]!),\n prefix: out[2] ?? \"\",\n };\n }\n\n /** True when `cwd` is inside a git work tree. Throws `GitUnavailableError` without git. */\n async isRepository(): Promise<boolean> {\n try {\n return (await this.run([\"rev-parse\", \"--is-inside-work-tree\"])).toString().trim() === \"true\";\n } catch (error) {\n if (error instanceof GitError) return false;\n throw error;\n }\n }\n\n /** The index (`ls-files -s -z`): files under `cwd`, relative to it. */\n async lsFiles(): Promise<TreeEntry[]> {\n const out = await this.run([\"ls-files\", \"-s\", \"-z\"]);\n return records(out).map((record) => {\n const tab = record.indexOf(\"\\t\");\n const [mode, blobSha, stage] = record.slice(0, tab).split(\" \");\n return { mode: mode!, blobSha: blobSha!, stage: Number(stage), path: record.slice(tab + 1) };\n });\n }\n\n /** The files of a revision (`ls-tree -r -z`): files under `cwd`, relative to it. */\n async lsTree(revision: string): Promise<TreeEntry[]> {\n const out = await this.run([\"ls-tree\", \"-r\", \"-z\", revision, \"--\"]);\n return records(out).map((record) => {\n const tab = record.indexOf(\"\\t\");\n const [mode, , blobSha] = record.slice(0, tab).split(\" \");\n return { mode: mode!, blobSha: blobSha!, stage: 0, path: record.slice(tab + 1) };\n });\n }\n\n /**\n * The staged changes (`diff --cached -M --name-status -z --relative`): changes under `cwd`\n * against HEAD (an empty tree before the first commit), relative to `cwd`.\n */\n async stagedChanges(): Promise<StagedChange[]> {\n return nameStatus(\n await this.run([\n \"diff\",\n \"--cached\",\n \"-M\",\n \"--name-status\",\n \"-z\",\n \"--relative\",\n \"--no-ext-diff\",\n \"--no-color\",\n ]),\n );\n }\n\n /**\n * The changes from `revision` to the index (`cached`) or to the working tree\n * (`diff -M --name-status -z --relative <revision>`), relative to `cwd`. Files git doesn't track\n * yet aren't listed.\n */\n async changesSince(\n revision: string,\n options: { cached?: boolean } = {},\n ): Promise<StagedChange[]> {\n return nameStatus(\n await this.run([\n \"diff\",\n ...(options.cached ? [\"--cached\"] : []),\n \"-M\",\n \"--name-status\",\n \"-z\",\n \"--relative\",\n \"--no-ext-diff\",\n \"--no-color\",\n revision,\n \"--\",\n ]),\n );\n }\n\n /** The commit id `revision` names, or undefined when it names none (e.g. HEAD before the first commit). */\n async commitId(revision: string): Promise<string | undefined> {\n try {\n const out = await this.run([\"rev-parse\", \"--verify\", \"-q\", `${revision}^{commit}`]);\n return out.toString(\"utf8\").trim() || undefined;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** The current branch's short name, or undefined when HEAD is detached. */\n async currentBranch(): Promise<string | undefined> {\n try {\n const out = await this.run([\"symbolic-ref\", \"-q\", \"--short\", \"HEAD\"]);\n return out.toString(\"utf8\").trim() || undefined;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** The content of a blob through the long-lived `cat-file --batch`; undefined if missing. */\n readBlob(sha: string): Promise<Buffer | undefined> {\n // A batch that failed (its process exited or misbehaved) is replaced by a new one.\n if (this.batch?.failed) void this.batch.close();\n if (!this.batch || this.batch.failed) this.batch = new CatFileBatch(this.cwd, this.env);\n return this.batch.read(sha);\n }\n\n /**\n * The paths among `paths` whose working-tree content differs from the index, as git sees it\n * (`git diff`): line-ending conversion and clean filters applied, untracked files not listed.\n */\n async unstagedFiles(paths: readonly string[]): Promise<Set<string>> {\n if (paths.length === 0) return new Set();\n const out = await this.run([\n \"--literal-pathspecs\",\n \"diff\",\n \"--name-only\",\n \"-z\",\n \"--no-renames\",\n \"--\",\n ...paths,\n ]);\n return new Set(\n out\n .toString(\"utf8\")\n .split(\"\\0\")\n .filter((p) => p !== \"\"),\n );\n }\n\n /** Stages files (`git add`); paths are literal, never pathspec patterns. */\n async add(paths: readonly string[]): Promise<void> {\n if (paths.length === 0) return;\n await this.run([\"--literal-pathspecs\", \"add\", \"--\", ...paths]);\n }\n\n /** A config value, or undefined when it isn't set. */\n async config(key: string): Promise<string | undefined> {\n try {\n const value = (await this.run([\"config\", \"--get\", key])).toString(\"utf8\").trim();\n return value === \"\" ? undefined : value;\n } catch (error) {\n if (error instanceof GitError) return undefined;\n throw error;\n }\n }\n\n /** A path inside the git dir (`rev-parse --git-path`), e.g. `hooks`; honours core.hooksPath. */\n async gitPath(path: string): Promise<string> {\n const out = (await this.run([\"rev-parse\", \"--git-path\", path])).toString(\"utf8\").trim();\n return resolve(this.cwd, out);\n }\n\n /** Stops the `cat-file --batch` process and waits for it to exit. */\n async close(): Promise<void> {\n const batch = this.batch;\n delete this.batch;\n await batch?.close();\n }\n}\n\n/** Parses `diff --name-status -z` output. */\nfunction nameStatus(out: Buffer): StagedChange[] {\n const fields = records(out);\n const changes: StagedChange[] = [];\n for (let i = 0; i < fields.length;) {\n const status = fields[i++]!;\n if (status.startsWith(\"R\") || status.startsWith(\"C\")) {\n const from = fields[i++]!;\n changes.push({ status: status[0]!, from, path: fields[i++]! });\n } else {\n changes.push({ status: status[0]!, path: fields[i++]! });\n }\n }\n return changes;\n}\n\n/** NUL-separated records, without the trailing empty one. */\nfunction records(out: Buffer): string[] {\n const text = out.toString(\"utf8\");\n const fields = text.split(\"\\0\");\n if (fields.at(-1) === \"\") fields.pop();\n return fields;\n}\n","/**\n * Source providers (plan §D11.3, analysis F-9), PBI `source-providers`: one interface to read the\n * files of a repository from the working tree, the git index or a revision, so every check runs\n * the same way on each. Listings skip `node_modules`, dot-folders, symbolic links, submodules\n * and nested projects, like `listFiles`.\n */\nimport { readFile } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nimport { compareStrings } from \"../diagnostics.js\";\nimport { isListedPath, listFiles, withoutNestedProjects } from \"../util.js\";\nimport type { Git, TreeEntry } from \"./git.js\";\n\n// The callback API, promisified: `fs/promises` opens a FileHandle per file, which costs more per\n// file than the read itself in a cold run over thousands of files (plan §D11.7).\nconst readFileAsync = promisify(readFile);\n\n/** A file of a source: its root-relative POSIX path and, when known, its git blob SHA. */\nexport interface SourceEntry {\n path: string;\n /** Known for the index and revisions without reading the file, so caches can skip reading. */\n blobSha?: string;\n}\n\nexport interface SourceProvider {\n readonly kind: \"worktree\" | \"index\" | \"revision\";\n /** Every file, sorted by path. */\n list(): Promise<SourceEntry[]>;\n /** A file's content, or undefined when the source has no such file. */\n read(path: string): Promise<Buffer | undefined>;\n}\n\n/** The files on disk under `root`. */\nexport class WorkingTreeProvider implements SourceProvider {\n readonly kind = \"worktree\";\n\n constructor(readonly root: string) {}\n\n async list(): Promise<SourceEntry[]> {\n return (await listFiles(this.root)).map((path) => ({ path }));\n }\n\n read(path: string): Promise<Buffer | undefined> {\n return readFileAsync(join(this.root, path)).catch((error: NodeJS.ErrnoException) => {\n if (error.code === \"ENOENT\" || error.code === \"EISDIR\" || error.code === \"ENOTDIR\") {\n return undefined;\n }\n throw error;\n });\n }\n}\n\n/** Files of a git tree listing, read through `cat-file --batch`. */\nabstract class GitTreeProvider implements SourceProvider {\n abstract readonly kind: \"index\" | \"revision\";\n private listing?: Promise<Map<string, string>>;\n\n constructor(readonly git: Git) {}\n\n protected abstract entries(): Promise<TreeEntry[]>;\n\n async list(): Promise<SourceEntry[]> {\n const files = await this.files();\n return [...files].map(([path, blobSha]) => ({ path, blobSha }));\n }\n\n async read(path: string): Promise<Buffer | undefined> {\n const sha = (await this.files()).get(path);\n return sha === undefined ? undefined : this.git.readBlob(sha);\n }\n\n private files(): Promise<Map<string, string>> {\n this.listing ??= this.entries().then((entries) => {\n const regular = entries\n .filter((e) => e.stage === 0 && (e.mode === \"100644\" || e.mode === \"100755\"))\n .filter((e) => isListedPath(e.path))\n .sort((a, b) => compareStrings(a.path, b.path));\n const listed = new Set(withoutNestedProjects(regular.map((e) => e.path)));\n return new Map(regular.filter((e) => listed.has(e.path)).map((e) => [e.path, e.blobSha]));\n });\n return this.listing;\n }\n}\n\n/**\n * The git index: what the next commit will contain. Conflicted files (merge stages 1–3) have no\n * staged content yet and aren't listed.\n */\nexport class IndexProvider extends GitTreeProvider {\n readonly kind = \"index\";\n\n protected entries(): Promise<TreeEntry[]> {\n return this.git.lsFiles();\n }\n}\n\n/** The files of a revision, e.g. `HEAD`. */\nexport class RevisionProvider extends GitTreeProvider {\n readonly kind = \"revision\";\n\n constructor(\n git: Git,\n readonly revision: string,\n ) {\n super(git);\n }\n\n protected entries(): Promise<TreeEntry[]> {\n return this.git.lsTree(this.revision);\n }\n}\n","/**\n * The scope of `catspec check --staged` (plan §D11.3, §D11.7, §D13), PBI `staged-check`: the\n * commit being made, and only what it touches. A spec is checked when the commit changes its spec\n * file or lock file, a file its bindings resolved to (from the lock file), a file of its `file`\n * hints or `scope`, or declares a name one of its not-yet-located bindings looks for. The files\n * read are the changed files plus the files of those specs.\n */\nimport { SymbolTable } from \"./codebase.js\";\nimport { sortDiagnostics, type Diagnostic } from \"./diagnostics.js\";\nimport { parseErrorDiagnostics, type FileFacts } from \"./facts.js\";\nimport type { StagedChange } from \"./git/git.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { lockedFiles, lockPathOf } from \"./lock.js\";\nimport { splitSymbol } from \"./resolve.js\";\nimport { globMatcher } from \"./util.js\";\n\nexport interface StagedScope {\n /** Paths the commit adds, changes or deletes (both sides of a rename). */\n changed: Set<string>;\n /** Ids of the specs to check, the architecture spec included when its rules apply. */\n specs: string[];\n /** Source files to read; undefined means every file (the architecture spec changed). */\n files?: Set<string>;\n}\n\n/**\n * The specs and files a staged check needs. `changedFacts` are the facts of the changed source\n * files; `paths` every file of the index.\n */\nexport function stagedScope(\n model: SpecModel,\n changes: readonly StagedChange[],\n changedFacts: readonly FileFacts[],\n paths: readonly string[],\n): StagedScope {\n const changed = new Set(\n changes.flatMap((c) => (c.from === undefined ? [c.path] : [c.path, c.from])),\n );\n const changedList = [...changed];\n const declared = new SymbolTable(changedFacts);\n const touches = (globs: readonly string[]): boolean =>\n globs.length > 0 && changedList.some(globMatcher(globs));\n\n const specs: string[] = [];\n const files = new Set(changedList);\n for (const spec of model.specs.all()) {\n if (!spec.valid || spec.type === \"architecture\") continue;\n const lock = model.locks.get(spec.id);\n const located = spec.bindings.map((b) => ({ binding: b, files: lockedFiles(lock, b.id) }));\n const selected =\n changed.has(spec.file) ||\n changed.has(lockPathOf(spec)) ||\n located.some((l) => l.files.some((f) => changed.has(f))) ||\n spec.bindings.some((b) => b.file !== undefined && touches(b.file)) ||\n touches(spec.scope) ||\n located.some(\n (l) => l.files.length === 0 && declared.find(splitSymbol(l.binding.symbol).name).length > 0,\n );\n if (!selected) continue;\n specs.push(spec.id);\n for (const l of located) for (const f of l.files) files.add(f);\n const globs = [...spec.scope, ...spec.bindings.flatMap((b) => b.file ?? [])];\n if (globs.length > 0) {\n const match = globMatcher(globs);\n for (const path of paths) if (match(path)) files.add(path);\n }\n }\n\n const architecture = model.architecture?.valid ? model.architecture : undefined;\n const architectureChanged = architecture !== undefined && changed.has(architecture.file);\n if (architecture && (architectureChanged || changedFacts.length > 0)) specs.push(architecture.id);\n return { changed, specs, ...(architectureChanged ? {} : { files }) };\n}\n\n/**\n * The diagnostics a staged check reports: those of the checked specs, spec diagnostics of the\n * changed spec and lock files, syntax errors of the changed files, and architecture rule\n * violations in the changed files (in every file when the architecture spec itself changed).\n */\nexport function stagedDiagnostics(\n model: SpecModel,\n scope: StagedScope,\n checked: readonly Diagnostic[],\n changedFacts: readonly FileFacts[],\n): Diagnostic[] {\n const architecture = model.architecture?.id;\n const selected = new Set(scope.specs);\n const inChanged = (d: Diagnostic): boolean =>\n (d.codeLocation !== undefined && scope.changed.has(d.codeLocation.file)) ||\n (d.specLocation !== undefined && scope.changed.has(d.specLocation.file));\n const kept = checked.filter((d) => {\n if (d.spec === undefined || !selected.has(d.spec)) return inChanged(d);\n if (d.spec !== architecture || scope.files === undefined || d.code.startsWith(\"CS01\")) {\n return true;\n }\n return d.codeLocation !== undefined && scope.changed.has(d.codeLocation.file);\n });\n const extra = [\n ...model.diagnostics.filter(\n (d) => inChanged(d) || (d.spec === undefined && d.specLocation === undefined),\n ),\n ...changedFacts.flatMap(parseErrorDiagnostics),\n ];\n const seen = new Set(kept.map(key));\n for (const d of extra) {\n if (seen.has(key(d))) continue;\n seen.add(key(d));\n kept.push(d);\n }\n return sortDiagnostics(kept);\n}\n\nconst key = (d: Diagnostic): string =>\n JSON.stringify([d.code, d.spec, d.specLocation, d.codeLocation, d.message]);\n","/**\n * `catspec coverage` (analysis F-3, plan §D10), PBI `check-command`: how much of the specs is\n * met, how much of them is machine-checked, and how much of the code is bound by a spec.\n */\nimport type { Codebase } from \"./codebase.js\";\nimport { checkCode, type CheckOptions, type ItemResult } from \"./check.js\";\nimport type { SpecModel } from \"./load.js\";\n\nexport interface Ratio {\n count: number;\n total: number;\n /** `count / total` in percent, rounded to one decimal; 100 when `total` is 0. */\n percent: number;\n}\n\nexport interface SpecCoverage {\n spec: string;\n status: string;\n satisfaction: Ratio;\n enforceable: number;\n manual: number;\n unenforcedProse: number;\n}\n\nexport interface CoverageReport {\n /** Passing enforceable contract items out of all enforceable items. */\n satisfaction: Ratio;\n /** Enforceable items out of all contract statements: enforceable, manual and unenforced prose (CS0111). */\n enforcement: Ratio & { manual: number; unenforcedProse: number };\n /** Source files with a bound declaration out of all source files. */\n reverse: Ratio;\n specs: SpecCoverage[];\n items: ItemResult[];\n}\n\nconst ratio = (count: number, total: number): Ratio => ({\n count,\n total,\n percent: total === 0 ? 100 : Math.round((count / total) * 1000) / 10,\n});\n\n/**\n * Evaluates every spec except deprecated ones as if implemented, whatever its status, and\n * counts the results.\n */\nexport async function coverage(\n model: SpecModel,\n codebase: Codebase,\n options: Pick<CheckOptions, \"now\"> = {},\n): Promise<CoverageReport> {\n const result = await checkCode(model, codebase, { ...options, mode: \"full\" });\n const unenforced = (id: string): number =>\n model.config.enforcement.unenforced_prose === \"off\"\n ? 0\n : (model.specs.get(id)?.body.contracts.filter((c) => c.references.length === 0).length ?? 0);\n\n const specs = result.checked.map((spec): SpecCoverage => {\n const items = result.items.filter((i) => i.spec === spec.id);\n const enforceable = items.filter((i) => i.enforceable);\n return {\n spec: spec.id,\n status: spec.status,\n satisfaction: ratio(enforceable.filter((i) => i.passed).length, enforceable.length),\n enforceable: enforceable.length,\n manual: items.length - enforceable.length,\n unenforcedProse: unenforced(spec.id),\n };\n });\n const sum = (key: \"enforceable\" | \"manual\" | \"unenforcedProse\"): number =>\n specs.reduce((n, s) => n + s[key], 0);\n const enforceable = sum(\"enforceable\");\n const manual = sum(\"manual\");\n const unenforcedProse = sum(\"unenforcedProse\");\n const bound = new Set(\n [...result.resolved.values()].flatMap((bindings) =>\n [...bindings.values()].flatMap((r) => r.files),\n ),\n );\n return {\n satisfaction: ratio(result.items.filter((i) => i.enforceable && i.passed).length, enforceable),\n enforcement: {\n ...ratio(enforceable, enforceable + manual + unenforcedProse),\n manual,\n unenforcedProse,\n },\n reverse: ratio(codebase.files.filter((f) => bound.has(f.path)).length, codebase.files.length),\n specs,\n items: result.items,\n };\n}\n","/**\n * The dependency graph of specs (plan §D8, analysis F-11), PBI `dependency-graph`: `depends_on`\n * edges, unknown dependencies (CS0104), cycles with their full path (CS0105), a topological order\n * and which specs are ready to start.\n */\nimport { compareStrings, createDiagnostic, type Diagnostic } from \"./diagnostics.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean } from \"./util.js\";\n\nexport class DependencyGraph {\n /** Specs by id, sorted by id. */\n readonly specs: ReadonlyMap<string, Spec>;\n /** CS0104 and CS0105 diagnostics. */\n readonly diagnostics: Diagnostic[] = [];\n /** Each cycle as a path that ends where it starts: `[\"a\", \"b\", \"c\", \"a\"]`. */\n readonly cycles: string[][] = [];\n\n private readonly edges = new Map<string, string[]>();\n /** Strongly connected components (each sorted by id); a cycle is a component of 2+ specs. */\n private readonly components: string[][] = [];\n private readonly reverse = new Map<string, string[]>();\n\n constructor(specs: Iterable<Spec>) {\n const sorted = [...specs].sort((a, b) => compareStrings(a.id, b.id));\n this.specs = new Map(sorted.map((s) => [s.id, s]));\n\n for (const spec of sorted) {\n const deps: string[] = [];\n spec.dependsOn.forEach((dep, index) => {\n if (this.specs.has(dep)) {\n if (!deps.includes(dep)) deps.push(dep);\n return;\n }\n const close = didYouMean(dep, this.specs.keys());\n this.diagnostics.push(\n createDiagnostic(\"CS0104\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"depends_on\", index]),\n message: `\"${spec.id}\" depends on \"${dep}\", but there is no spec with that id`,\n actual: dep,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean \"${c}\"?` })) }\n : {}),\n }),\n );\n });\n deps.sort(compareStrings);\n this.edges.set(spec.id, deps);\n for (const dep of deps) {\n this.reverse.set(dep, [...(this.reverse.get(dep) ?? []), spec.id]);\n }\n }\n for (const list of this.reverse.values()) list.sort(compareStrings);\n this.findCycles();\n }\n\n /** Known specs `id` depends on, sorted. */\n dependencies(id: string): string[] {\n return this.edges.get(id) ?? [];\n }\n\n /** Specs that depend on `id`, sorted. */\n dependents(id: string): string[] {\n return this.reverse.get(id) ?? [];\n }\n\n /** Every edge as `{ spec, dependsOn }`, sorted. */\n edgeList(): { spec: string; dependsOn: string }[] {\n return [...this.edges].flatMap(([spec, deps]) =>\n deps.map((dependsOn) => ({ spec, dependsOn })),\n );\n }\n\n /**\n * True when every dependency exists and is satisfied. Until contracts are checked, a dependency\n * is satisfied when its status is `implemented`.\n */\n depsSatisfied(id: string): boolean {\n const spec = this.specs.get(id);\n if (!spec) return false;\n return spec.dependsOn.every((dep) => this.specs.get(dep)?.status === \"implemented\");\n }\n\n /** A spec is ready to start when its status is `ready` and its dependencies are satisfied. */\n isReady(id: string): boolean {\n return this.specs.get(id)?.status === \"ready\" && this.depsSatisfied(id);\n }\n\n /**\n * Specs in dependency order: every spec comes after the specs it depends on, the members of a\n * cycle together. Among the specs that can come next, the smallest id goes first.\n */\n topologicalOrder(): string[] {\n const componentOf = new Map<string, number>();\n this.components.forEach((members, index) => {\n for (const id of members) componentOf.set(id, index);\n });\n const waitingOn = this.components.map(() => new Set<number>());\n const neededBy = this.components.map(() => new Set<number>());\n for (const { spec, dependsOn } of this.edgeList()) {\n const from = componentOf.get(spec)!;\n const to = componentOf.get(dependsOn)!;\n if (from === to) continue;\n waitingOn[from]!.add(to);\n neededBy[to]!.add(from);\n }\n const order: string[] = [];\n const available = this.components.map((_, i) => i).filter((i) => waitingOn[i]!.size === 0);\n while (available.length > 0) {\n available.sort((a, b) => compareStrings(this.components[a]![0]!, this.components[b]![0]!));\n const next = available.shift()!;\n order.push(...this.components[next]!);\n for (const dependent of neededBy[next]!) {\n waitingOn[dependent]!.delete(next);\n if (waitingOn[dependent]!.size === 0) available.push(dependent);\n }\n }\n return order;\n }\n\n /** Tarjan's strongly connected components; reports one cycle per component. */\n private findCycles(): void {\n let counter = 0;\n const index = new Map<string, number>();\n const low = new Map<string, number>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const components = this.components;\n\n const connect = (id: string): void => {\n index.set(id, counter);\n low.set(id, counter);\n counter++;\n stack.push(id);\n onStack.add(id);\n for (const dep of this.dependencies(id)) {\n if (!index.has(dep)) {\n connect(dep);\n low.set(id, Math.min(low.get(id)!, low.get(dep)!));\n } else if (onStack.has(dep)) {\n low.set(id, Math.min(low.get(id)!, index.get(dep)!));\n }\n }\n if (low.get(id) === index.get(id)) {\n const component: string[] = [];\n let member: string;\n do {\n member = stack.pop()!;\n onStack.delete(member);\n component.push(member);\n } while (member !== id);\n components.push(component.sort(compareStrings));\n }\n };\n for (const id of this.edges.keys()) if (!index.has(id)) connect(id);\n\n for (const component of components) {\n const members = new Set(component);\n const start = [...members].sort(compareStrings)[0]!;\n if (members.size === 1 && !this.dependencies(start).includes(start)) continue;\n const cycle = this.shortestCycle(start, members);\n this.cycles.push(cycle);\n const spec = this.specs.get(start)!;\n const next = cycle[1]!;\n this.diagnostics.push(\n createDiagnostic(\"CS0105\", {\n spec: start,\n specLocation: specLocation(spec.source, [\"depends_on\", spec.dependsOn.indexOf(next)]),\n message: `dependency cycle: ${cycle.join(\" → \")}`,\n actual: cycle,\n suggestions: [{ message: \"remove one of the dependencies in the cycle\" }],\n }),\n );\n }\n this.cycles.sort((a, b) => compareStrings(a[0]!, b[0]!));\n }\n\n /** Shortest path from `start` back to itself inside one component (breadth-first). */\n private shortestCycle(start: string, members: Set<string>): string[] {\n const previous = new Map<string, string>();\n const queue = [start];\n for (let i = 0; i < queue.length; i++) {\n const id = queue[i]!;\n for (const dep of this.dependencies(id)) {\n if (!members.has(dep)) continue;\n if (dep === start) {\n const path = [start];\n for (let at = id; at !== start; at = previous.get(at)!) path.splice(1, 0, at);\n return [...path, start];\n }\n if (!previous.has(dep)) {\n previous.set(dep, id);\n queue.push(dep);\n }\n }\n }\n return [start, start];\n }\n}\n","/**\n * Finds and loads every spec of a repository (plan §D3, §D4, §D6.4), PBI `spec-loader`, and runs\n * the repository-level checks of `catspec check --specs-only`: unique ids (CS0103), the\n * feature-folder layout (CS0106), the architecture spec (CS0107), lock files without a spec\n * (CS0108) and ADR ids (CS0112). Specs and lock files are read from a source provider: the\n * working tree, or the git index for `check --staged` (F5).\n */\nimport { readFile } from \"node:fs/promises\";\nimport { join, posix } from \"node:path\";\n\nimport { workflowProfile, type CatspecConfig } from \"./config.js\";\nimport { featureFolderOf } from \"./workflow/schema.js\";\nimport {\n compareStrings,\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n} from \"./diagnostics.js\";\nimport { WorkingTreeProvider, type SourceProvider } from \"./git/providers.js\";\nimport { DependencyGraph } from \"./graph.js\";\nimport { hasLockFile, lockPathOf, parseLock, type LockFile } from \"./lock.js\";\nimport { splitFrontmatter } from \"./frontmatter.js\";\nimport { readSpec, specLocation, type Spec } from \"./spec.js\";\nimport { didYouMean, globMatcher, listFiles, listOf } from \"./util.js\";\n\n/** All specs of a repository, by id and by file. */\nexport class SpecSet {\n readonly byId = new Map<string, Spec>();\n readonly byFile = new Map<string, Spec>();\n\n /** Adds a spec; returns the spec that already has its id, if any (the new one isn't indexed by id). */\n add(spec: Spec): Spec | undefined {\n this.byFile.set(spec.file, spec);\n const existing = this.byId.get(spec.id);\n if (!existing) this.byId.set(spec.id, spec);\n return existing;\n }\n\n get(id: string): Spec | undefined {\n return this.byId.get(id);\n }\n\n /** Specs with a unique id, sorted by id. */\n all(): Spec[] {\n return [...this.byId.values()].sort((a, b) => compareStrings(a.id, b.id));\n }\n\n get size(): number {\n return this.byId.size;\n }\n}\n\nexport interface SpecModel {\n root: string;\n config: CatspecConfig;\n specs: SpecSet;\n graph: DependencyGraph;\n /** The architecture spec (`type: architecture` at `specs.architecture`), if exactly one exists:\n * it is optional (ADR-028). */\n architecture?: Spec;\n /** ADR ids of the architecture spec's log and of the plain ADR files at `specs.architecture`. */\n adrIds: string[];\n /** Every diagnostic of `catspec check --specs-only`, sorted. */\n diagnostics: Diagnostic[];\n /** Valid lock files (plan §D7) by spec id. */\n locks: Map<string, LockFile>;\n /** The text of each lock file read, by path, to write only what changed. */\n lockTexts: Map<string, string>;\n /** Where the specs were read from. */\n source: SourceProvider;\n}\n\nconst SPEC_FILE = /(^|\\/)[^/]+\\.spec\\.md$/;\n\n/**\n * Loads every spec under `root` with `config` and runs the spec checks (the pipeline of\n * `catspec check --specs-only`). Spec errors of `deprecated` specs are lowered to warnings (§D8).\n */\nexport async function loadSpecModel(\n root: string,\n config: CatspecConfig,\n source: SourceProvider = new WorkingTreeProvider(root),\n): Promise<SpecModel> {\n const files = (await source.list()).map((entry) => entry.path);\n const diagnostics: Diagnostic[] = [];\n const specs = new SpecSet();\n const options = { unenforcedProse: config.enforcement.unenforced_prose };\n\n const isIncluded = globMatcher(config.specs.include);\n const isArchitecture = architectureMatcher(config.specs.architecture);\n const architectureFiles = files.filter((f) => isArchitecture(f));\n const specFiles = files.filter((f) => isIncluded(f) && !architectureFiles.includes(f));\n\n /** The specs a diagnostic is about, when it is about more than the one in its file. */\n const involved = new Map<Diagnostic, Spec[]>();\n\n const read = async (file: string): Promise<Spec | undefined> => {\n const text = (await source.read(file))?.toString(\"utf8\") ?? \"\";\n const result = readSpec(text, file, options);\n diagnostics.push(...result.diagnostics);\n return result.spec;\n };\n\n // The architecture spec is optional (ADR-028). The files at `specs.architecture` are the\n // repository's ADRs: at most one of them is CatSpec's architecture spec (CatSpec frontmatter,\n // the repository-wide rules); the others are plain ADRs, read only for their ADR ids (CS0107).\n let architecture: Spec | undefined;\n const architectureTexts = new Map<string, string>();\n for (const file of architectureFiles) {\n architectureTexts.set(file, (await source.read(file))?.toString(\"utf8\") ?? \"\");\n }\n const rulesFiles = architectureFiles.filter((f) =>\n isArchitectureSpecText(architectureTexts.get(f)!),\n );\n // In the git index (`check --staged`), an architecture spec that exists on disk but isn't\n // staged yet, e.g. right after `catspec init --with-adr`, is a warning: the commit is checked\n // without its rules.\n const unstagedLog =\n rulesFiles.length === 0 && source.kind === \"index\"\n ? await findUnstagedArchitectureSpec(root, isArchitecture)\n : undefined;\n if (unstagedLog) {\n diagnostics.push(\n createDiagnostic(\"CS0107\", {\n severity: \"warning\",\n message: `the architecture spec ${unstagedLog} isn't staged, so this commit is checked without its rules`,\n suggestions: [{ message: `stage it: git add ${unstagedLog}` }],\n }),\n );\n } else if (rulesFiles.length > 1) {\n diagnostics.push(\n createDiagnostic(\"CS0107\", {\n specLocation: { file: rulesFiles[0]!, line: 1, column: 1 },\n message:\n `more than one architecture spec matches specs.architecture \"${config.specs.architecture}\": ` +\n listOf(rulesFiles),\n actual: rulesFiles,\n suggestions: [\n {\n message:\n \"keep the repository-wide rules in one file, or narrow specs.architecture in catspec.yaml\",\n },\n ],\n }),\n );\n } else if (rulesFiles.length === 1) {\n const spec = await read(rulesFiles[0]!);\n if (spec) {\n if (spec.type === \"architecture\") {\n architecture = spec;\n } else if (spec.valid) {\n diagnostics.push(\n createDiagnostic(\"CS0101\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"type\"]),\n message: `the architecture spec must have type \"architecture\", found \"${spec.type}\"`,\n expected: \"architecture\",\n actual: spec.type,\n }),\n );\n }\n addSpec(spec);\n }\n }\n\n // Read in parallel, index in file order (the first file keeps a duplicated id).\n for (const spec of await Promise.all(specFiles.map(read))) {\n if (spec) addSpec(spec);\n }\n\n function addSpec(spec: Spec): void {\n const existing = specs.add(spec);\n if (!existing) return;\n for (const [here, other] of [\n [existing, spec],\n [spec, existing],\n ] as const) {\n const duplicate = createDiagnostic(\"CS0103\", {\n spec: here.id,\n specLocation: specLocation(here.source, [\"id\"]),\n message: `duplicate spec id \"${here.id}\" in ${here.file} and ${other.file}`,\n actual: [existing.file, spec.file],\n });\n involved.set(duplicate, [existing, spec]);\n diagnostics.push(duplicate);\n }\n }\n\n // Layout (CS0106): machine specs live directly in a feature folder (`docs/spec/<feature>/`, or\n // the workflow's `feature_dir`), and the architecture spec at specs.architecture.\n if (config.layout === \"feature-folders\") {\n const profile = workflowProfile(config);\n const generic = profile.featureDir.replaceAll(\"{feature}\", \"<feature>\");\n for (const file of files) {\n if (!SPEC_FILE.test(file) || architectureFiles.includes(file)) continue;\n const name = file.split(\"/\").pop()!;\n const folder = featureFolderOf(profile.featureDirs, file);\n if (folder && file === `${folder.dir}/${name}`) continue;\n const deeper = folder?.dir;\n const target = deeper ? `${deeper}/${name}` : `${generic}/${name}`;\n const where = deeper\n ? deeper.slice(0, deeper.lastIndexOf(\"/\")) || \".\"\n : generic.replace(/\\/?<feature>.*$/, \"\") || \".\";\n diagnostics.push(\n createDiagnostic(\"CS0106\", {\n ...(specs.byFile.get(file) ? { spec: specs.byFile.get(file)!.id } : {}),\n specLocation: { file, line: 1, column: 1 },\n message: deeper\n ? `${file} is more than one folder deep in ${where}/; move it to ${target}`\n : `${file} is outside a feature folder; move it to ${target}`,\n expected: `${generic}/<id>.spec.md`,\n actual: file,\n suggestions: [{ message: `move it to ${target}, or set layout: free in catspec.yaml` }],\n }),\n );\n }\n for (const spec of specs.byFile.values()) {\n if (spec.type !== \"architecture\" || spec === architecture) continue;\n diagnostics.push(\n createDiagnostic(\"CS0106\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"type\"]),\n message:\n `${spec.file} is an architecture spec outside specs.architecture ` +\n `(\"${config.specs.architecture}\"); its rules belong in the ADR log`,\n actual: spec.file,\n }),\n );\n }\n }\n\n // ADR ids referenced by rules must exist in the ADR log (CS0112): the `## ADR-NNN` headings of\n // the architecture spec, and the ids of the plain ADR files next to it. Without any ADRs there\n // is nothing to check against.\n const adrIds = [...(architecture?.body.adrIds ?? [])];\n for (const file of architectureFiles) {\n if (rulesFiles.includes(file)) continue;\n for (const id of plainAdrIds(file, architectureTexts.get(file)!)) {\n if (!adrIds.some((known) => sameAdrId(known, id))) adrIds.push(id);\n }\n }\n const adrLog = architecture?.file ?? `specs.architecture \"${config.specs.architecture}\"`;\n if (adrIds.length > 0) {\n for (const spec of specs.byFile.values()) {\n for (const rule of spec.rules) {\n const ruleAdr = rule.adr;\n if (ruleAdr === undefined || adrIds.some((id) => sameAdrId(id, ruleAdr))) continue;\n const close = didYouMean(ruleAdr, adrIds);\n diagnostics.push(\n createDiagnostic(\"CS0112\", {\n spec: spec.id,\n ruleId: rule.id,\n specLocation: specLocation(spec.source, [\"rules\", rule.index, \"adr\"]),\n message: `rule \"${rule.id}\" enforces ${ruleAdr}, which is not in the ADR log ${adrLog}`,\n expected: adrIds,\n actual: ruleAdr,\n ...(close.length > 0\n ? { suggestions: close.map((c) => ({ message: `did you mean ${c}?` })) }\n : {}),\n }),\n );\n }\n }\n }\n\n // Lock files (CS0108): `<spec-id>.lock.json` next to a spec with that id.\n const locks = new Map<string, LockFile>();\n const lockTexts = new Map<string, string>();\n const listed = new Set(files);\n for (const spec of specs.all()) {\n if (!hasLockFile(spec)) continue;\n const path = lockPathOf(spec);\n if (!listed.has(path)) continue;\n const text = (await source.read(path))?.toString(\"utf8\");\n if (text === undefined) continue;\n lockTexts.set(path, text);\n const lock = parseLock(text);\n if (lock?.spec === spec.id) locks.set(spec.id, lock);\n }\n const lockOwners = new Set(\n [...specs.byFile.values()].filter(hasLockFile).map((spec) => lockPathOf(spec)),\n );\n for (const file of files) {\n if (!file.endsWith(\".lock.json\") || lockOwners.has(file)) continue;\n if (!isIncluded(file.replace(/\\.lock\\.json$/, \".spec.md\"))) continue;\n const id = posix.basename(file).replace(/\\.lock\\.json$/, \"\");\n diagnostics.push(\n createDiagnostic(\"CS0108\", {\n specLocation: { file, line: 1, column: 1 },\n message: `${file} has no spec with id \"${id}\" in ${posix.dirname(file)}/`,\n expected: `a spec with id \"${id}\" in ${posix.dirname(file)}/`,\n actual: file,\n suggestions: [\n {\n message:\n \"delete the lock file, or move it next to its spec (named <spec-id>.lock.json)\",\n },\n ],\n }),\n );\n }\n\n const graph = new DependencyGraph(specs.all());\n diagnostics.push(...graph.diagnostics);\n\n for (const d of graph.diagnostics) {\n if (d.code === \"CS0105\" && Array.isArray(d.actual)) {\n involved.set(\n d,\n (d.actual as string[]).flatMap((id) => specs.get(id) ?? []),\n );\n }\n }\n\n // Spec errors of deprecated specs are warnings (plan §D8), unless the error also involves a\n // spec that isn't deprecated (a cycle through an implemented spec, a duplicated id).\n const lowered = diagnostics.map((d) => {\n if (d.severity !== \"error\" || !d.code.startsWith(\"CS01\")) return d;\n const own = (d.specLocation && specs.byFile.get(d.specLocation.file)) ?? undefined;\n const about = involved.get(d) ?? (own ? [own] : []);\n const deprecated = about.length > 0 && about.every((s) => s.status === \"deprecated\");\n return deprecated ? { ...d, severity: \"warning\" as const } : d;\n });\n\n return {\n root,\n config,\n specs,\n graph,\n ...(architecture ? { architecture } : {}),\n adrIds,\n diagnostics: sortDiagnostics(lowered),\n locks,\n lockTexts,\n source,\n };\n}\n\n/**\n * Matches the files of `specs.architecture` (ADR-028): a glob or a file path as written, or a\n * folder (no glob characters and no `.md` ending) for every Markdown file in it.\n */\nexport function architectureMatcher(pattern: string): (path: string) => boolean {\n const clean = pattern.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n if (/[*?[\\]{}()!]/.test(clean) || /\\.md$/i.test(clean)) return globMatcher(clean);\n return globMatcher(`${clean}/**/*.md`);\n}\n\n/**\n * True when a file at `specs.architecture` is meant as CatSpec's architecture spec: its\n * frontmatter has a `catspec:` key or `type: architecture`. Other files (no frontmatter, or the\n * frontmatter of an ADR tool) are plain ADRs. A line match, so broken YAML is still reported.\n */\nexport function isArchitectureSpecText(text: string): boolean {\n const split = splitFrontmatter(text);\n if (\"error\" in split) return false;\n return /^(catspec\\s*:|type\\s*:\\s*[\"']?architecture[\"']?\\s*(#.*)?$)/m.test(split.frontmatter.text);\n}\n\n/** The ADR ids of a plain ADR file: its file name (`ADR-007-….md`, `0007-….md`) and its\n * `ADR-NNN` headings. */\nexport function plainAdrIds(file: string, text: string): string[] {\n const ids: string[] = [];\n const name = /^(?:adr-?)?(\\d+)(?=[-_. ])/i.exec(posix.basename(file));\n if (name) ids.push(`ADR-${name[1]}`);\n for (const match of text.matchAll(/^#{1,6}[ \\t]+\\[?(ADR-\\d+)\\b/gm)) {\n if (!ids.some((id) => sameAdrId(id, match[1]!))) ids.push(match[1]!);\n }\n return ids;\n}\n\n/** ADR ids compare by number: `ADR-7`, `ADR-007` and `ADR-0007` are the same decision. */\nexport const sameAdrId = (a: string, b: string): boolean =>\n Number(a.slice(4)) === Number(b.slice(4)) && /^ADR-\\d+$/.test(a) && /^ADR-\\d+$/.test(b);\n\n/** An architecture spec on disk that the git index doesn't have yet. */\nasync function findUnstagedArchitectureSpec(\n root: string,\n isArchitecture: (path: string) => boolean,\n): Promise<string | undefined> {\n for (const file of (await listFiles(root)).filter((f) => isArchitecture(f))) {\n const text = await readFile(join(root, file), \"utf8\").catch(() => \"\");\n if (isArchitectureSpecText(text)) return file;\n }\n return undefined;\n}\n","/**\n * Edits spec frontmatter without destroying its formatting (plan §D11.6, ADR-008), PBI\n * `spec-cst-editor`.\n *\n * Each operation is applied twice: with the `yaml` Document API (`setIn` / `deleteIn`), which\n * defines what the result must mean, and as a minimal splice of the source text at the node's\n * range, which keeps comments, key order, quoting and blank lines everywhere else. The spliced\n * text is parsed again and must equal the Document result; otherwise the edit is refused rather\n * than written. The Markdown body is never touched.\n */\nimport { isDeepStrictEqual } from \"node:util\";\n\nimport {\n Document,\n isCollection,\n isMap,\n isScalar,\n isSeq,\n parseDocument,\n Scalar,\n visit,\n type Node,\n type Pair,\n type ToStringOptions,\n type YAMLMap,\n type YAMLSeq,\n} from \"yaml\";\n\nimport type { PatchOp, PatchPath } from \"./diagnostics.js\";\nimport { withFrontmatter, type SpecSource } from \"./frontmatter.js\";\nimport { formatPath } from \"./schema-issues.js\";\n\n/**\n * `location` edits only say where the code is (`bindings[i].symbol`, `bindings[i].file`); auto-heal\n * and agents may apply them. Everything else changes the contract and needs a human (ADR-008).\n */\nexport type EditClass = \"location\" | \"contract\";\n\nexport function classifyOp(op: PatchOp, source: SpecSource): EditClass {\n const [list, index, key, item] = op.path;\n if (list !== \"bindings\" || typeof index !== \"number\") return \"contract\";\n // Only an existing binding can be moved; anything that adds a binding changes the contract.\n const binding = source.document.getIn([\"bindings\", index], true) as Node | undefined;\n if (!isMap(binding)) return \"contract\";\n const isText = (value: unknown): boolean => typeof value === \"string\" && value.length > 0;\n\n if (key === \"symbol\" && op.path.length === 3) {\n return op.op === \"set\" && isText(op.value) && binding.has(\"symbol\") ? \"location\" : \"contract\";\n }\n if (key === \"file\" && op.path.length === 3) {\n if (op.op === \"delete\") return \"location\";\n const list = Array.isArray(op.value) && op.value.length > 0 && op.value.every(isText);\n return isText(op.value) || list ? \"location\" : \"contract\";\n }\n if (key === \"file\" && op.path.length === 4 && typeof item === \"number\") {\n const files = binding.get(\"file\", true) as Node | undefined;\n if (!isSeq(files)) return \"contract\";\n if (op.op === \"delete\") return item < files.items.length ? \"location\" : \"contract\";\n return item <= files.items.length && isText(op.value) ? \"location\" : \"contract\";\n }\n return \"contract\";\n}\n\n/** A patch is a location edit only when every operation is one. */\nexport const classifyPatch = (ops: readonly PatchOp[], source: SpecSource): EditClass =>\n ops.every((op) => classifyOp(op, source) === \"location\") ? \"location\" : \"contract\";\n\n/** An edit that can't be applied without risking the file; nothing is written. */\nexport class SpecEditError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecEditError\";\n }\n}\n\n/** Applies `ops` to a spec and returns the new file text. The body stays byte-for-byte the same. */\nexport function applyPatch(source: SpecSource, ops: readonly PatchOp[]): string {\n if (ops.length === 0) return source.text;\n return withFrontmatter(source, editYaml(source.frontmatter.text, ops, source.eol));\n}\n\n/** Applies `ops` to a YAML document's text, keeping everything the operations don't change. */\nexport function editYaml(text: string, ops: readonly PatchOp[], eol: \"\\n\" | \"\\r\\n\" = \"\\n\"): string {\n let current = text;\n for (const op of ops) {\n try {\n current = applyOp(current, op, eol);\n } catch (error) {\n if (error instanceof SpecEditError) throw error;\n // e.g. \"Excessive alias count\" from the yaml library: refuse instead of crashing.\n const reason = error instanceof Error ? error.message : String(error);\n throw new SpecEditError(`can't edit ${formatPath(op.path)}: ${reason}`);\n }\n }\n return current;\n}\n\n/** The plain value at `path` of a YAML document's text, or undefined. Throws `SpecEditError`. */\nexport function readYaml(text: string, path: PatchPath): unknown {\n let value: unknown = parseYaml(text).toJS();\n for (const segment of path) {\n if (value === null || typeof value !== \"object\") return undefined;\n value = (value as Record<string | number, unknown>)[segment];\n }\n return value;\n}\n\nfunction applyOp(text: string, op: PatchOp, eol: string): string {\n const doc = parseYaml(text);\n if (op.path.length === 0) throw new SpecEditError(\"an edit needs a non-empty path\");\n\n const expected = doc.clone();\n const target = op.op === \"set\" ? normaliseSet(doc, op.path, op.value) : op;\n if (target.op === \"set\") expected.setIn(target.path, toNode(expected, target.value));\n else {\n if (!expected.hasIn(target.path)) {\n throw new SpecEditError(`nothing to delete at ${formatPath(target.path)}`);\n }\n expected.deleteIn(target.path);\n }\n\n // An edit that doesn't change the data doesn't change the text.\n if (isDeepStrictEqual(expected.toJS(), doc.toJS())) return text;\n\n const splice = new Splicer(text, doc, expected, eol);\n const next =\n target.op === \"set\" ? splice.set(target.path, target.value) : splice.delete(target.path);\n\n const check = parseDocument(next);\n if (check.errors.length > 0 || !isDeepStrictEqual(check.toJS(), expected.toJS())) {\n throw new SpecEditError(\n `refusing to edit ${formatPath(op.path)}: the result would not match the requested change; ` +\n \"edit the spec by hand\",\n );\n }\n return next;\n}\n\nfunction parseYaml(text: string): Document.Parsed {\n // Source tokens give the exact start of list items and keys (after anchors, tags, comments).\n const doc = parseDocument(text, { keepSourceTokens: true });\n if (doc.errors.length > 0) {\n throw new SpecEditError(\n `the frontmatter has YAML errors: ${doc.errors[0]!.message.split(\"\\n\")[0]}`,\n );\n }\n return doc;\n}\n\nconst toNode = (doc: Document, value: unknown): unknown =>\n value !== null && typeof value === \"object\" ? doc.createNode(value) : value;\n\n/**\n * Makes sure the parent of a `set` path exists: setting `links.pr` without `links`, or under\n * `links:` with no value, becomes setting `links` to `{ pr: … }`.\n */\nfunction normaliseSet(\n doc: Document,\n path: PatchPath,\n value: unknown,\n): { op: \"set\"; path: PatchPath; value: unknown } {\n for (let i = 0; i < path.length - 1; i++) {\n const prefix = path.slice(0, i + 1);\n const node = doc.getIn(prefix, true) as Node | null | undefined;\n if (node === undefined || node === null || (isScalar(node) && node.value === null)) {\n let nested = value;\n for (const segment of [...path.slice(i + 1)].reverse()) {\n if (typeof segment === \"number\") {\n if (segment !== 0) throw new SpecEditError(`no item ${segment} at ${formatPath(path)}`);\n nested = [nested];\n } else {\n nested = { [segment]: nested };\n }\n }\n return { op: \"set\", path: prefix, value: nested };\n }\n if (!isCollection(node)) {\n throw new SpecEditError(`${formatPath(prefix)} is a value, not a map or list`);\n }\n }\n const parent = path.length > 1 ? (doc.getIn(path.slice(0, -1), true) as Node) : doc.contents;\n const last = path[path.length - 1]!;\n if (isSeq(parent) && (typeof last !== \"number\" || last > parent.items.length || last < 0)) {\n throw new SpecEditError(`${formatPath(path)}: list index out of range`);\n }\n return { op: \"set\", path, value };\n}\n\n/** Text splices for one operation, driven by the node ranges of the parsed document. */\nclass Splicer {\n private readonly indentSeq: boolean;\n\n constructor(\n private readonly text: string,\n private readonly doc: Document.Parsed,\n private readonly expected: Document,\n private readonly eol: string,\n ) {\n this.indentSeq = detectIndentSeq(text, doc);\n }\n\n set(path: PatchPath, value: unknown): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n const key = path[path.length - 1]!;\n if (parent === null) return this.insertIntoEmptyRoot(key, value);\n if (!isMap(parent) && !isSeq(parent)) {\n throw new SpecEditError(`${formatPath(parentPath)} is not a map or list`);\n }\n\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n if (index < 0 || index >= parent.items.length) {\n return parent.flow\n ? this.flowAppend(parent, parentPath, key, value)\n : this.append(parent, key, value);\n }\n const node = isMap(parent)\n ? (parent.items[index]!.value as Node | null)\n : (parent.items[index] as Node | null);\n if (isScalar(node) && isScalarValue(value) && !isBlockScalar(node) && node.range) {\n return this.replaceScalar(node, value, parent.flow === true);\n }\n return parent.flow\n ? this.flowReplace(parent, index, key, value)\n : this.replaceItem(parent, index, key, value);\n }\n\n delete(path: PatchPath): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n const key = path[path.length - 1]!;\n if (!isMap(parent) && !isSeq(parent)) {\n throw new SpecEditError(`${formatPath(parentPath)} is not a map or list`);\n }\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n if (parent.flow) return this.flowDelete(parent, index);\n\n if (parent.items.length === 1) {\n // Removing the only item: rewrite the parent as an empty collection.\n if (parentPath.length === 0) throw new SpecEditError(\"can't remove the last frontmatter key\");\n return this.replaceInParent(parentPath);\n }\n\n const start = itemStart(this.text, parent, index);\n const end = itemEnd(this.text, parent, index);\n if (isLineStart(this.text, start)) {\n return this.text.slice(0, lineStart(this.text, start)) + this.text.slice(end);\n }\n // The item shares its line with the parent's indicator (`- key: value`): pull the next one up.\n const next = itemStart(this.text, parent, index + 1);\n return this.text.slice(0, start) + this.text.slice(next);\n }\n\n /** Rewrites the item at `path` (a key or list item of a block collection) with its expected value. */\n private replaceInParent(path: PatchPath): string {\n const parentPath = path.slice(0, -1);\n const parent = this.nodeAt(parentPath);\n if (!isMap(parent) && !isSeq(parent)) throw new SpecEditError(\"unexpected document shape\");\n const key = path[path.length - 1]!;\n const index = isMap(parent) ? findPair(parent, key) : (key as number);\n const value = this.expectedValue(path);\n return parent.flow\n ? this.flowReplace(parent, index, key, value)\n : this.replaceItem(parent, index, key, value);\n }\n\n /** Replaces a scalar's text, keeping its quoting style when the new value allows it. */\n private replaceScalar(node: Scalar, value: unknown, inFlow: boolean): string {\n const [start, end] = node.range!;\n let rendered = renderScalar(value, node.type, inFlow);\n if (start === end && this.text[start - 1] === \":\") rendered = ` ${rendered}`;\n return this.text.slice(0, start) + rendered + this.text.slice(end);\n }\n\n /** Replaces a whole pair or list item with a block rendering of its new value. */\n private replaceItem(\n parent: YAMLMap | YAMLSeq,\n index: number,\n key: string | number,\n value: unknown,\n ): string {\n const start = itemStart(this.text, parent, index);\n const end = itemEnd(this.text, parent, index);\n const column = start - lineStart(this.text, start);\n const lines = isMap(parent) ? this.render({ [String(key)]: value }) : this.render([value]);\n // A comment at the end of the item's first line (`key: [] # note`) stays on that line.\n const comment = trailingComment(this.text, start);\n if (comment && trailingComment(lines[0]!, 0) === undefined) lines[0] += comment;\n const endsWithBreak = this.text[end - 1] === \"\\n\";\n const replacement =\n lines.map((line, i) => (i === 0 ? line : \" \".repeat(column) + line)).join(this.eol) +\n (endsWithBreak ? this.eol : \"\");\n return this.text.slice(0, start) + replacement + this.text.slice(end);\n }\n\n /** Adds a new key at the end of a block map, or a new item at the end of a block list. */\n private append(parent: YAMLMap | YAMLSeq, key: string | number, value: unknown): string {\n const last = parent.items.length - 1;\n const first = itemStart(this.text, parent, 0);\n const column = first - lineStart(this.text, first);\n const at = itemEnd(this.text, parent, last);\n const lines = isMap(parent) ? this.render({ [String(key)]: value }) : this.render([value]);\n const prefix = at > 0 && this.text[at - 1] !== \"\\n\" ? this.eol : \"\";\n const block = lines.map((line) => \" \".repeat(column) + line).join(this.eol) + this.eol;\n return this.text.slice(0, at) + prefix + block + this.text.slice(at);\n }\n\n private insertIntoEmptyRoot(key: string | number, value: unknown): string {\n if (typeof key !== \"string\") throw new SpecEditError(\"the frontmatter must be a map\");\n const lines = this.render({ [key]: value });\n const prefix = this.text.length > 0 && !this.text.endsWith(\"\\n\") ? this.eol : \"\";\n return this.text + prefix + lines.join(this.eol) + this.eol;\n }\n\n /** Source range of item `index` of a flow collection, without the separating comma. */\n private flowRange(parent: YAMLMap | YAMLSeq, index: number): [number, number] {\n const item = parent.items[index];\n const first = (isMap(parent) ? (item as Pair).key : item) as Node | null;\n const last = (\n isMap(parent) ? ((item as Pair).value ?? (item as Pair).key) : item\n ) as Node | null;\n if (!first?.range || !last?.range)\n throw new SpecEditError(\"can't locate a flow collection item\");\n return [first.range[0], last.range[1]];\n }\n\n /** Text of one flow collection entry: `value`, or `key: value` in a map. */\n private flowEntry(parent: YAMLMap | YAMLSeq, key: string | number, value: unknown): string {\n const rendered = this.renderFlow(value);\n return isMap(parent)\n ? `${renderScalar(String(key), Scalar.PLAIN, true)}: ${rendered}`\n : rendered;\n }\n\n private flowReplace(\n parent: YAMLMap | YAMLSeq,\n index: number,\n key: string | number,\n value: unknown,\n ): string {\n const [start, end] = this.flowRange(parent, index);\n return this.text.slice(0, start) + this.flowEntry(parent, key, value) + this.text.slice(end);\n }\n\n private flowDelete(parent: YAMLMap | YAMLSeq, index: number): string {\n const count = parent.items.length;\n const [start, end] = this.flowRange(parent, index);\n if (count === 1) return this.text.slice(0, start) + this.text.slice(end);\n if (index < count - 1) {\n return this.text.slice(0, start) + this.text.slice(this.flowRange(parent, index + 1)[0]);\n }\n return this.text.slice(0, this.flowRange(parent, index - 1)[1]) + this.text.slice(end);\n }\n\n /**\n * Adds an entry at the end of a flow collection. An empty `[]` / `{}` under a block map or list\n * becomes a block collection instead, the way it would be written by hand.\n */\n private flowAppend(\n parent: YAMLMap | YAMLSeq,\n parentPath: PatchPath,\n key: string | number,\n value: unknown,\n ): string {\n const count = parent.items.length;\n const entry = this.flowEntry(parent, key, value);\n if (count > 0) {\n const end = this.flowRange(parent, count - 1)[1];\n return this.text.slice(0, end) + `, ${entry}` + this.text.slice(end);\n }\n if (parentPath.length > 0) {\n const grand = this.nodeAt(parentPath.slice(0, -1));\n if ((isMap(grand) || isSeq(grand)) && !grand.flow) return this.replaceInParent(parentPath);\n }\n const open = parent.range![0] + 1;\n return this.text.slice(0, open) + entry + this.text.slice(open);\n }\n\n /** One-line flow YAML for `value`. */\n private renderFlow(value: unknown): string {\n if (isScalarValue(value)) return renderScalar(value, Scalar.PLAIN, true);\n const doc = new Document(value);\n visit(doc, {\n Map: (_, node) => void (node.flow = true),\n Seq: (_, node) => void (node.flow = true),\n });\n const rendered = doc.toString(this.options()).trimEnd();\n if (rendered.includes(\"\\n\"))\n throw new SpecEditError(\"the value is too complex for a flow collection\");\n return rendered;\n }\n\n private expectedValue(path: PatchPath): unknown {\n const node = this.expected.getIn(path, true) as Node | undefined;\n return isScalar(node) ? node.value : (node?.toJSON() as unknown);\n }\n\n private nodeAt(path: PatchPath): Node | null {\n return path.length === 0\n ? this.doc.contents\n : ((this.doc.getIn(path, true) as Node | undefined) ?? null);\n }\n\n private options(): ToStringOptions {\n return { lineWidth: 0, flowCollectionPadding: false, indentSeq: this.indentSeq };\n }\n\n /** Block YAML for `value`, as lines without line breaks. */\n private render(value: unknown): string[] {\n return new Document(value).toString(this.options()).replace(/\\n$/, \"\").split(\"\\n\");\n }\n}\n\nconst isScalarValue = (value: unknown): boolean =>\n value === null || [\"string\", \"number\", \"boolean\"].includes(typeof value);\n\nconst isBlockScalar = (node: Scalar): boolean =>\n node.type === Scalar.BLOCK_LITERAL || node.type === Scalar.BLOCK_FOLDED;\n\n/** Renders a scalar in the style of the value it replaces, quoting only when needed. */\nfunction renderScalar(value: unknown, type: Scalar[\"type\"], inFlow: boolean): string {\n if (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n if (typeof value !== \"string\") return \"null\";\n if (value.includes(\"\\n\") || type === Scalar.QUOTE_DOUBLE) return JSON.stringify(value);\n if (type === Scalar.QUOTE_SINGLE) return `'${value.replace(/'/g, \"''\")}'`;\n const plain = new Document(value).toString({ lineWidth: 0 }).replace(/\\n$/, \"\");\n // Inside `[...]` or `{...}`, a plain scalar can't contain the flow indicators , [ ] { }.\n const unsafe = plain.includes(\"\\n\") || (inFlow && /[,[\\]{}]/.test(plain));\n return unsafe ? JSON.stringify(value) : plain;\n}\n\nfunction findPair(map: YAMLMap, key: string | number): number {\n return map.items.findIndex(\n (pair: Pair) => isScalar(pair.key) && String(pair.key.value) === String(key),\n );\n}\n\n/** Offset where item `index` starts: the key of a pair, or the `-` of a list item. */\nfunction itemStart(text: string, parent: YAMLMap | YAMLSeq, index: number): number {\n const token = parent.srcToken;\n if (token?.type === \"block-seq\") {\n // Every list item has a `-`; comment-only entries of the token list don't.\n const items = token.items.filter((it) => it.start.some((t) => t.type === \"seq-item-ind\"));\n const dash = items[index]?.start.find((t) => t.type === \"seq-item-ind\");\n if (dash) return dash.offset;\n } else if (token?.type === \"block-map\" && isMap(parent)) {\n const key = parent.items[index]?.key as Node | null | undefined;\n const item = token.items.find((it) => it.key && it.key === key?.srcToken);\n if (item?.key) {\n // An anchor, tag or `?` before the key belongs to the item.\n const prop = item.start.find((t) => ![\"space\", \"newline\", \"comment\"].includes(t.type));\n return prop?.offset ?? item.key.offset;\n }\n }\n if (isMap(parent)) {\n const key = parent.items[index]!.key as Node | null;\n if (!key?.range) throw new SpecEditError(\"can't locate a key in the frontmatter\");\n return key.range[0];\n }\n const item = parent.items[index] as Node | null;\n if (!item?.range) throw new SpecEditError(\"can't locate a list item in the frontmatter\");\n let at = item.range[0] - 1;\n while (at >= 0 && (text[at] === \" \" || text[at] === \"\\t\")) at--;\n if (text[at] !== \"-\")\n throw new SpecEditError(\"can't locate a list item's '-' in the frontmatter\");\n return at;\n}\n\n/** Offset right after the line break that ends item `index` (its trailing comment included). */\nfunction itemEnd(text: string, parent: YAMLMap | YAMLSeq, index: number): number {\n const item = parent.items[index];\n const node = (isMap(parent) ? ((item as Pair).value ?? (item as Pair).key) : item) as Node | null;\n const start = itemStart(text, parent, index);\n let end = node?.range?.[2] ?? start;\n while (end > start && /\\s/.test(text[end - 1]!)) end--;\n const lineBreak = text.indexOf(\"\\n\", end);\n return lineBreak === -1 ? text.length : lineBreak + 1;\n}\n\nconst lineStart = (text: string, offset: number): number => text.lastIndexOf(\"\\n\", offset - 1) + 1;\n\n/** The comment at the end of the line `offset` is on, with the spaces before it (`\" # note\"`). */\nfunction trailingComment(text: string, offset: number): string | undefined {\n const lineBreak = text.indexOf(\"\\n\", offset);\n const line = text.slice(offset, lineBreak === -1 ? text.length : lineBreak).replace(/\\r$/, \"\");\n let quote: string | undefined;\n for (let i = 0; i < line.length; i++) {\n const char = line[i]!;\n if (quote) {\n if (char === quote && !(quote === \"'\" && line[i + 1] === \"'\")) quote = undefined;\n else if (quote === \"'\" && char === \"'\") i++;\n else if (quote === '\"' && char === \"\\\\\") i++;\n } else if (char === \"'\" || char === '\"') {\n if (i === 0 || /[\\s[{,:-]/.test(line[i - 1]!)) quote = char;\n } else if (char === \"#\" && i > 0 && /[ \\t]/.test(line[i - 1]!)) {\n let from = i;\n while (from > 0 && /[ \\t]/.test(line[from - 1]!)) from--;\n return line.slice(from);\n }\n }\n return undefined;\n}\n\nconst isLineStart = (text: string, offset: number): boolean =>\n text.slice(lineStart(text, offset), offset).trim() === \"\";\n\n/** Whether block lists inside maps are indented under their key (`key:\\n - a`), as in most specs. */\nfunction detectIndentSeq(text: string, doc: Document.Parsed): boolean {\n let indented: boolean | undefined;\n visit(doc, {\n Pair: (_, pair) => {\n const key = pair.key as Node | null;\n const value = pair.value as Node | null;\n if (!isSeq(value) || value.flow || !key?.range || value.items.length === 0) return;\n let dash: number;\n try {\n dash = itemStart(text, value, 0);\n } catch {\n return undefined;\n }\n const keyColumn = key.range[0] - lineStart(text, key.range[0]);\n indented = dash - lineStart(text, dash) > keyColumn;\n return visit.BREAK;\n },\n });\n return indented ?? true;\n}\n","/**\n * Rename and move detection (plan §D11.4, §D11.8, analysis F-7, ADR-013), PBIs `rename-detection`\n * and `batch-rename-mapping`: works out where the declarations that bindings pointed to went.\n *\n * The input is a baseline: what each binding resolved to before the change (from the refactor\n * baseline, or from the lock file and `HEAD`). Every baseline declaration that no longer resolves\n * is matched to a declaration of the current code, using the strongest evidence first:\n *\n * 1. the rename map (`--map`): symbols, namespaces, paths;\n * 2. the same qualified name in another file (moved);\n * 3. a namespace or module prefix change shared by several declarations (`Identity.*` →\n * `Accounts.*`);\n * 4. a file rename from `git diff -M`, same name in the new file;\n * 5. an identical name-free fingerprint, unique on both sides;\n * 6. the similarity score `0.5·jaccard(member names) + 0.4·jaccard(body token 3-grams) +\n * 0.1·same file`.\n *\n * Rows 5 and 6 are a global one-to-one assignment: a new declaration is used at most once, and a\n * pair is taken only when both are each other's unique best match at or above `heal.threshold`.\n * Every declaration ends up mapped, ambiguous (CS0216) or lost (CS0217); nothing is guessed.\n */\nimport { createHash } from \"node:crypto\";\n\nimport type { SymbolEntry, SymbolTable } from \"./codebase.js\";\nimport { compareStrings } from \"./diagnostics.js\";\nimport type { FileFacts, Range, SourceFile, SymbolFact } from \"./facts.js\";\nimport { fingerprintOf, shapeOf, type LockedSymbol, type Shape } from \"./lock.js\";\nimport { nameMatches } from \"./match.js\";\nimport { groupOverloads, inModule, mergePartials, splitSymbol } from \"./resolve.js\";\nimport { escapeRegExp, LineIndex } from \"./util.js\";\n\n/** A declaration a binding resolved to before the change. */\nexport interface BaselineSymbol {\n /** Spec id. */\n spec: string;\n /** Binding id. */\n binding: string;\n /** `path#QualifiedName` of the declaration. */\n resolved: string;\n /** Every file of a C# partial type, when there is more than one. */\n files?: string[];\n fingerprint: string;\n /** Fingerprint of the shape without the declaration's own name and namespace. */\n nameFree: string;\n shape: Shape;\n /** Body tokens without the declaration's own name; empty when its source wasn't available. */\n tokens: string[];\n}\n\n/** The rename map of `catspec sync --map` (plan §D11.8). */\nexport interface RenameMap {\n /** Old qualified name (or `path#Name`) → new qualified name. */\n symbols?: Record<string, string>;\n /** Old namespace or name prefix → new one, segment-wise: `Identity` → `Accounts`. */\n namespaces?: Record<string, string>;\n /** Old path prefix → new one: `src/Identity/` → `src/Accounts/`. */\n paths?: Record<string, string>;\n}\n\n/** How a mapping was found, strongest first (the rows of plan §D11.8). */\nexport type Evidence = \"map\" | \"moved\" | \"prefix\" | \"file-rename\" | \"fingerprint\" | \"similarity\";\n\n/** A candidate with its similarity score. */\nexport interface ScoredCandidate {\n entry: SymbolEntry;\n score: number;\n}\n\n/** A baseline declaration mapped to a declaration of the current code. */\nexport interface Mapping {\n /** The bindings that pointed to the old declaration (one declaration can be bound twice). */\n bindings: BaselineSymbol[];\n target: SymbolEntry;\n /** Every file of the target when it is a C# partial type in several files. */\n files?: string[];\n evidence: Evidence;\n /** The similarity score, when computed. */\n score?: number;\n /** What the evidence was, e.g. `namespace Identity → Accounts`. */\n detail?: string;\n}\n\nexport interface Ambiguity {\n bindings: BaselineSymbol[];\n /** Best first. */\n candidates: ScoredCandidate[];\n detail?: string;\n}\n\nexport interface Lost {\n bindings: BaselineSymbol[];\n /** The closest candidate, below the threshold. */\n best?: ScoredCandidate;\n detail?: string;\n}\n\nexport interface RenameReport {\n mapped: Mapping[];\n ambiguous: Ambiguity[];\n lost: Lost[];\n}\n\nexport interface RenameInput {\n /** The bindings that no longer resolve, with what they resolved to before. */\n broken: readonly BaselineSymbol[];\n /** Every declaration of the current code. */\n table: SymbolTable;\n /** Current files that the baseline revision doesn't have, or has with other content. */\n changed: ReadonlySet<string>;\n /** Facts of the baseline versions of the files that changed or were deleted. */\n before: readonly FileFacts[];\n /** File renames from `git diff -M`: old path → new path. */\n renames?: ReadonlyMap<string, string>;\n map?: RenameMap;\n /** `heal.threshold`. */\n threshold: number;\n /** Body tokens of a current declaration (`bodyTokens`), computed only for scored candidates. */\n tokens: (entry: SymbolEntry) => Promise<string[]>;\n /** Ids (`path#id`) of current declarations that other bindings resolve to; never candidates. */\n taken?: ReadonlySet<string>;\n}\n\nconst sha256 = (value: unknown): string =>\n `sha256:${createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\")}`;\n\n/** The last segment of a qualified name. */\nconst simpleName = (qualifiedName: string): string =>\n qualifiedName.slice(qualifiedName.lastIndexOf(\".\") + 1);\n\n/** `path#QualifiedName` → path and qualified name. */\nexport function splitResolved(resolved: string): { file: string; qualifiedName: string } {\n const hash = resolved.lastIndexOf(\"#\");\n return hash === -1\n ? { file: resolved, qualifiedName: \"\" }\n : { file: resolved.slice(0, hash), qualifiedName: resolved.slice(hash + 1) };\n}\n\n/** Whole-word matches of any of `words`, tried in the order given; `extraBefore` also blocks. */\nexport const wordPattern = (words: string | readonly string[], extraBefore = \"\"): RegExp =>\n new RegExp(\n `(?<![\\\\p{L}\\\\p{N}_$${extraBefore}])(?:${(typeof words === \"string\" ? [words] : words)\n .map(escapeRegExp)\n .join(\"|\")})(?![\\\\p{L}\\\\p{N}_$])`,\n \"gu\",\n );\n\n/**\n * A shape without the declaration's own name: the qualified name is dropped and the simple name\n * is blanked where members repeat it (C# constructors), so a rename alone keeps the fingerprint.\n */\nexport function nameFreeFingerprint(shape: Shape): string {\n const name = simpleName(shape.name);\n const pattern = name ? wordPattern(name) : undefined;\n const blank = (text: string): string => (pattern ? text.replace(pattern, \"∅\") : text);\n return sha256([\n shape.kind,\n [...shape.bases].sort(compareStrings),\n [...shape.attributes].sort(compareStrings),\n [...shape.modifiers].sort(compareStrings),\n shape.signature === undefined ? null : blank(shape.signature),\n shape.members.map(blank).sort(compareStrings),\n ]);\n}\n\n/**\n * The member names of a shape (`public method login(string):boolean` → `login`). A member named\n * like the declaration itself (a C# constructor) is `∅`, so a rename alone keeps the names.\n */\nexport function memberNames(shape: Shape): string[] {\n const own = simpleName(shape.name);\n return shape.members.map((member) => {\n const head = member.split(/[(:]/)[0]!.trim();\n const name = head.slice(head.lastIndexOf(\" \") + 1);\n return name === own ? \"∅\" : name;\n });\n}\n\nconst TOKEN =\n /[\\p{L}_$][\\p{L}\\p{N}_$]*|\\d[\\p{L}\\p{N}_.]*|\"(?:[^\"\\\\\\n]|\\\\.)*\"|'(?:[^'\\\\\\n]|\\\\.)*'|`(?:[^`\\\\]|\\\\.)*`|\\S/gu;\n\n/**\n * The tokens of a declaration's source, without its own name: identifiers, numbers, strings and\n * punctuation. Language-independent, for the similarity score only (never written anywhere).\n */\nexport function bodyTokens(source: SourceFile, symbol: SymbolFact): string[] {\n const text = sliceRange(source, symbol.range);\n const tokens = text.match(TOKEN) ?? [];\n return tokens.filter((t) => t !== symbol.name);\n}\n\n/** Line indexes of the files tokenised, so the declarations of one file share one. */\nconst lineIndexes = new WeakMap<SourceFile, LineIndex>();\n\nfunction sliceRange(source: SourceFile, range: Range): string {\n const { text } = source;\n let lines = lineIndexes.get(source);\n if (!lines) lineIndexes.set(source, (lines = new LineIndex(text)));\n const offset = (p: Range[\"start\"]): number => lines.lineStart(p.line) + p.column - 1;\n return text.slice(offset(range.start), offset(range.end));\n}\n\n/** Jaccard index of two sets; two empty sets are equal. */\nexport function jaccard(a: ReadonlySet<string>, b: ReadonlySet<string>): number {\n if (a.size === 0 && b.size === 0) return 1;\n let common = 0;\n for (const x of a) if (b.has(x)) common++;\n return common / (a.size + b.size - common);\n}\n\nconst trigramSets = new WeakMap<readonly string[], Set<string>>();\n\n/** Token 3-grams (or the tokens themselves when there are fewer than three), cached per array. */\nconst trigrams = (tokens: readonly string[]): Set<string> => {\n let grams = trigramSets.get(tokens);\n if (grams) return grams;\n if (tokens.length < 3) grams = new Set(tokens);\n else {\n grams = new Set<string>();\n for (let i = 0; i + 2 < tokens.length; i++) {\n grams.add(`${tokens[i]}\\u0000${tokens[i + 1]}\\u0000${tokens[i + 2]}`);\n }\n }\n trigramSets.set(tokens, grams);\n return grams;\n};\n\n/** Similarity of two bodies: Jaccard over token 3-grams; 0 when either body is unknown. */\nexport function tokenSimilarity(a: readonly string[], b: readonly string[]): number {\n if (a.length === 0 || b.length === 0) return 0;\n return jaccard(trigrams(a), trigrams(b));\n}\n\n/**\n * The rename score of plan §D11.4: `0.5·jaccard(member names) + 0.4·tokenSimilarity(body) +\n * 0.1·sameFile`. Declarations without members (functions) compare their signatures instead.\n */\nexport function renameScore(\n before: { shape: Shape; tokens: readonly string[] },\n after: { shape: Shape; tokens: readonly string[] },\n sameFile: boolean,\n): number {\n const a = new Set(memberNames(before.shape));\n const b = new Set(memberNames(after.shape));\n const members =\n a.size === 0 && b.size === 0\n ? (before.shape.signature ?? \"\") === (after.shape.signature ?? \"\")\n ? 1\n : 0\n : jaccard(a, b);\n const score = 0.5 * members + 0.4 * tokenSimilarity(before.tokens, after.tokens);\n return Math.round((score + (sameFile ? 0.1 : 0)) * 1e6) / 1e6;\n}\n\n/** A baseline entry from a lock file's `symbols` entry and, when available, the old source. */\nexport function baselineFromLock(\n spec: string,\n binding: string,\n locked: LockedSymbol,\n tokens: string[] = [],\n): BaselineSymbol {\n return {\n spec,\n binding,\n resolved: locked.resolved,\n ...(locked.files ? { files: locked.files } : {}),\n fingerprint: locked.fingerprint,\n nameFree: nameFreeFingerprint(locked.shape),\n shape: locked.shape,\n tokens,\n };\n}\n\n/** A baseline entry from a declaration resolved in the baseline revision. */\nexport function baselineFromSymbol(\n spec: string,\n binding: string,\n resolved: { symbol: SymbolFact; file: { path: string }; files: string[] },\n source?: SourceFile,\n): BaselineSymbol {\n const shape = shapeOf(resolved.symbol);\n return {\n spec,\n binding,\n resolved: `${resolved.file.path}#${resolved.symbol.qualifiedName}`,\n ...(resolved.files.length > 1 ? { files: [...resolved.files].sort(compareStrings) } : {}),\n fingerprint: fingerprintOf(shape),\n nameFree: nameFreeFingerprint(shape),\n shape,\n tokens: source ? bodyTokens(source, resolved.symbol) : [],\n };\n}\n\n/** An old declaration and every binding that pointed to it. */\ninterface Group {\n key: string;\n file: string;\n qualifiedName: string;\n kind: string;\n bindings: BaselineSymbol[];\n /** The first binding's baseline entry (shape and tokens are the same for all). */\n first: BaselineSymbol;\n}\n\nconst entryKey = (e: SymbolEntry): string => `${e.file.path}#${e.symbol.id}`;\n\n/** True when a path segment prefix applies: `Identity` is a prefix of `Identity.Users.X`. */\nconst segmentPrefix = (prefix: string, name: string, sep: string): boolean =>\n prefix === \"\" || name === prefix || name.startsWith(prefix + sep);\n\n/** Replaces the longest matching prefix of `name` from `prefixes`; undefined when none applies. */\nfunction replacePrefix(\n name: string,\n prefixes: Record<string, string> | undefined,\n sep: string,\n): string | undefined {\n if (!prefixes) return undefined;\n const keys = Object.keys(prefixes)\n .filter((k) => k !== \"\" && (sep === \"/\" ? name.startsWith(k) : segmentPrefix(k, name, sep)))\n .sort((a, b) => b.length - a.length);\n const key = keys[0];\n return key === undefined ? undefined : prefixes[key]! + name.slice(key.length);\n}\n\n/** Maps every broken binding of `input` to its new declaration, or reports why it can't. */\nexport async function detectRenames(input: RenameInput): Promise<RenameReport> {\n const groups = groupBroken(input.broken);\n const report: RenameReport = { mapped: [], ambiguous: [], lost: [] };\n if (groups.length === 0) return report;\n\n const taken = input.taken ?? new Set<string>();\n const changedEntries = input.table.entries.filter(\n (e) => input.changed.has(e.file.path) && !taken.has(entryKey(e)),\n );\n // Declarations of the changed files that the baseline didn't have: rename candidates.\n const before = new Set<string>();\n const beforeAt = new Set<string>();\n const addBefore = (path: string, s: SymbolFact): void => {\n before.add(`${s.kind}\\u0000${s.qualifiedName}`);\n beforeAt.add(`${path}\\u0000${s.kind}\\u0000${s.qualifiedName}`);\n s.members.forEach((m) => addBefore(path, m));\n };\n for (const file of input.before) file.symbols.forEach((s) => addBefore(file.path, s));\n const fresh = changedEntries.filter(\n (e) => !before.has(`${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`),\n );\n /** A declaration its file didn't have before (a new file, or one it moved into). */\n const newHere = (e: SymbolEntry): boolean =>\n input.changed.has(e.file.path) &&\n !beforeAt.has(`${e.file.path}\\u0000${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`);\n\n // Body tokens of current declarations, computed once each.\n const tokenCache = new Map<SymbolEntry, Promise<string[]>>();\n const tokensOf = (e: SymbolEntry): Promise<string[]> => {\n let tokens = tokenCache.get(e);\n if (!tokens) tokenCache.set(e, (tokens = input.tokens(e)));\n return tokens;\n };\n\n /** A mapping by exact evidence, before the conflict check; or an outcome that ends the search. */\n type Exact =\n | { kind: \"mapped\"; target: SymbolEntry; evidence: Evidence; detail?: string }\n | { kind: \"ambiguous\"; candidates: SymbolEntry[]; detail: string }\n | { kind: \"lost\"; detail: string };\n const exact = new Map<Group, Exact>();\n const ofKind = (entries: readonly SymbolEntry[], g: Group): SymbolEntry[] =>\n entries.filter((e) => e.symbol.kind === g.kind && !taken.has(entryKey(e)));\n const decide = (\n g: Group,\n found: SymbolEntry[],\n evidence: Evidence,\n detail: string,\n ): Exact | undefined => {\n const unique = dedupe(found);\n if (unique.length === 1) return { kind: \"mapped\", target: unique[0]!, evidence, detail };\n if (unique.length > 1) return { kind: \"ambiguous\", candidates: unique, detail };\n return undefined;\n };\n\n // Rows 1 and 2: the rename map, then the same qualified name elsewhere.\n for (const g of groups) {\n const result = fromMap(g) ?? moved(g);\n if (result) exact.set(g, result);\n }\n\n function fromMap(g: Group): Exact | undefined {\n const map = input.map;\n if (!map) return undefined;\n for (const [from, to] of Object.entries(map.symbols ?? {})) {\n const { module, name } = splitSymbol(from);\n if (module !== undefined && !inModule(g.file, module)) continue;\n if (!nameMatches(name, g.qualifiedName)) continue;\n const target = splitSymbol(to);\n const found = ofKind(input.table.find(target.name), g).filter(\n (e) => target.module === undefined || inModule(e.file.path, target.module),\n );\n return (\n decide(g, found, \"map\", `rename map: ${from} → ${to}`) ?? {\n kind: \"lost\",\n detail: `the rename map names ${to}, which isn't in the code`,\n }\n );\n }\n const name = replacePrefix(g.qualifiedName, map.namespaces, \".\");\n const file = replacePrefix(g.file, map.paths, \"/\");\n if (name === undefined && file === undefined) return undefined;\n const qualifiedName = name ?? g.qualifiedName;\n const inFile = file ?? g.file;\n const exactly = ofKind(input.table.find(qualifiedName), g).filter(\n (e) => e.symbol.qualifiedName === qualifiedName,\n );\n const detail = [\n name !== undefined ? `namespace ${g.qualifiedName} → ${qualifiedName}` : undefined,\n file !== undefined ? `path ${g.file} → ${inFile}` : undefined,\n ]\n .filter(Boolean)\n .join(\", \");\n const there = exactly.filter((e) => e.file.path === inFile);\n return (\n decide(g, there.length > 0 ? there : exactly, \"map\", `rename map: ${detail}`) ??\n (file !== undefined && name === undefined\n ? decide(\n g,\n ofKind(input.table.entries, g).filter(\n (e) => e.file.path === inFile && e.symbol.name === simpleName(g.qualifiedName),\n ),\n \"map\",\n `rename map: ${detail}`,\n )\n : undefined)\n );\n }\n\n /**\n * The same qualified name in another file, only when it moved there: the declaration is gone\n * from its old file and new in the other one. An older, unrelated declaration of the same name\n * is not a move (TypeScript qualified names have no module part).\n */\n function moved(g: Group): Exact | undefined {\n const named = ofKind(input.table.find(g.qualifiedName), g).filter(\n (e) => e.symbol.qualifiedName === g.qualifiedName,\n );\n if (named.some((e) => e.file.path === g.file)) return undefined;\n return decide(g, named.filter(newHere), \"moved\", `moved from ${g.file}`);\n }\n\n // Row 3: a prefix change shared by several declarations (`Identity.*` → `Accounts.*`).\n const remaining = (): Group[] => groups.filter((g) => !exact.has(g));\n const prefixVotes = new Map<string, Set<Group>>();\n for (const g of remaining()) {\n const oldSegments = g.qualifiedName.split(\".\");\n for (const e of ofKind(fresh, g)) {\n if (e.symbol.name !== simpleName(g.qualifiedName)) continue;\n const newSegments = e.symbol.qualifiedName.split(\".\");\n let common = 0;\n while (\n common < oldSegments.length &&\n common < newSegments.length &&\n oldSegments[oldSegments.length - 1 - common] ===\n newSegments[newSegments.length - 1 - common]\n ) {\n common++;\n }\n const from = oldSegments.slice(0, oldSegments.length - common).join(\".\");\n const to = newSegments.slice(0, newSegments.length - common).join(\".\");\n if (from === to) continue;\n const key = `${from}\\u0000${to}`;\n prefixVotes.set(key, (prefixVotes.get(key) ?? new Set()).add(g));\n }\n }\n const prefixes = [...prefixVotes.entries()]\n .filter(([, voters]) => voters.size >= 2)\n .map(([key]) => key.split(\"\\u0000\") as [string, string])\n .sort((a, b) => b[0].length - a[0].length);\n for (const g of remaining()) {\n // Every rule that applies is tried: one namespace can be split into several.\n const hits: { found: SymbolEntry[]; detail: string }[] = [];\n for (const [from, to] of prefixes) {\n if (from === \"\" || !segmentPrefix(from, g.qualifiedName, \".\")) continue;\n const qualifiedName = to + g.qualifiedName.slice(from.length);\n const found = ofKind(fresh, g).filter((e) => e.symbol.qualifiedName === qualifiedName);\n if (found.length > 0) hits.push({ found, detail: `namespace ${from} → ${to}` });\n }\n if (hits.length === 0) continue;\n const result = decide(\n g,\n hits.flatMap((h) => h.found),\n \"prefix\",\n hits.length === 1\n ? hits[0]!.detail\n : `several prefix rules apply: ${hits.map((h) => h.detail).join(\"; \")}`,\n );\n if (result) exact.set(g, result);\n }\n\n // Row 4: the file was renamed; the same name in the new file.\n for (const g of remaining()) {\n const renamed = input.renames?.get(g.file);\n if (renamed === undefined) continue;\n const found = ofKind(changedEntries, g).filter(\n (e) => e.file.path === renamed && e.symbol.name === simpleName(g.qualifiedName),\n );\n const result = decide(g, found, \"file-rename\", `file renamed: ${g.file} → ${renamed}`);\n if (result) exact.set(g, result);\n }\n\n // Exact evidence must not use one declaration twice either.\n const claims = new Map<string, Group[]>();\n for (const [g, result] of exact) {\n if (result.kind !== \"mapped\") continue;\n const key = entryKey(result.target);\n claims.set(key, [...(claims.get(key) ?? []), g]);\n }\n const used = new Set<string>();\n for (const [g, result] of exact) {\n if (result.kind === \"lost\") {\n report.lost.push({ bindings: g.bindings, detail: result.detail });\n } else if (result.kind === \"ambiguous\") {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: result.candidates.map((entry) => ({ entry, score: 1 })),\n detail: result.detail,\n });\n } else if (claims.get(entryKey(result.target))!.length > 1) {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: [{ entry: result.target, score: 1 }],\n detail: `${result.target.symbol.qualifiedName} is also the target of ${listOfNames(\n claims.get(entryKey(result.target))!.filter((other) => other !== g),\n )}`,\n });\n used.add(entryKey(result.target));\n } else {\n const files = partialFiles.get(result.target.symbol);\n report.mapped.push({\n bindings: g.bindings,\n target: result.target,\n ...(files ? { files } : {}),\n evidence: result.evidence,\n ...(result.detail !== undefined ? { detail: result.detail } : {}),\n });\n used.add(entryKey(result.target));\n }\n }\n\n // Rows 5 and 6: global one-to-one assignment over the remaining declarations.\n const open = remaining();\n const pool = fresh.filter((e) => !used.has(entryKey(e)));\n const shapes = new Map<SymbolEntry, Shape>();\n const shapeFor = (e: SymbolEntry): Shape => {\n let shape = shapes.get(e);\n if (!shape) shapes.set(e, (shape = shapeOf(e.symbol)));\n return shape;\n };\n const nameFree = new Map<SymbolEntry, string>();\n const nameFreeFor = (e: SymbolEntry): string => {\n let fp = nameFree.get(e);\n if (fp === undefined) nameFree.set(e, (fp = nameFreeFingerprint(shapeFor(e))));\n return fp;\n };\n\n // Row 5: the name-free fingerprint is identical, and unique on both sides.\n const assigned = new Map<Group, Mapping>();\n const byPrint = new Map<string, { groups: Group[]; entries: SymbolEntry[] }>();\n for (const g of open) {\n const slot = byPrint.get(`${g.kind}\\u0000${g.first.nameFree}`) ?? { groups: [], entries: [] };\n slot.groups.push(g);\n byPrint.set(`${g.kind}\\u0000${g.first.nameFree}`, slot);\n }\n for (const e of pool) {\n const slot = byPrint.get(`${e.symbol.kind}\\u0000${nameFreeFor(e)}`);\n if (slot) slot.entries.push(e);\n }\n for (const { groups: gs, entries } of byPrint.values()) {\n if (gs.length !== 1 || entries.length !== 1) continue;\n const g = gs[0]!;\n const target = entries[0]!;\n const score = renameScore(\n g.first,\n { shape: shapeFor(target), tokens: await tokensOf(target) },\n sameFile(g, target),\n );\n // A shape without members is little more than a signature, which unrelated declarations\n // share: it maps by fingerprint only when the score reaches the threshold too.\n if (g.first.shape.members.length === 0 && score < input.threshold) continue;\n assigned.set(g, {\n bindings: g.bindings,\n target,\n evidence: \"fingerprint\",\n score,\n detail: \"only the name changed\",\n });\n }\n\n // Row 6: similarity, mutual unique best matches at or above the threshold.\n const unassigned = open.filter((g) => !assigned.has(g));\n const targets = new Set(pool.filter((e) => ![...assigned.values()].some((m) => m.target === e)));\n const scores = new Map<Group, ScoredCandidate[]>();\n for (const g of unassigned) {\n const scored: ScoredCandidate[] = [];\n for (const e of targets) {\n if (e.symbol.kind !== g.kind) continue;\n const score = renameScore(\n g.first,\n { shape: shapeFor(e), tokens: await tokensOf(e) },\n sameFile(g, e),\n );\n scored.push({ entry: e, score });\n }\n scored.sort(\n (a, b) => b.score - a.score || compareStrings(entryKey(a.entry), entryKey(b.entry)),\n );\n scores.set(g, scored);\n }\n const EPSILON = 1e-9;\n for (;;) {\n const free = unassigned.filter((g) => !assigned.has(g));\n const best = (g: Group): ScoredCandidate[] => {\n const live = scores.get(g)!.filter((c) => targets.has(c.entry) && c.score >= input.threshold);\n return live.filter((c) => c.score >= live[0]!.score - EPSILON);\n };\n const bestOld = new Map<SymbolEntry, { score: number; groups: Group[] }>();\n for (const g of free) {\n for (const c of scores.get(g)!) {\n if (!targets.has(c.entry) || c.score < input.threshold) continue;\n const slot = bestOld.get(c.entry);\n if (!slot || c.score > slot.score + EPSILON)\n bestOld.set(c.entry, { score: c.score, groups: [g] });\n else if (Math.abs(c.score - slot.score) <= EPSILON) slot.groups.push(g);\n }\n }\n let progress = false;\n for (const g of free) {\n const top = scores.get(g)!.length > 0 ? best(g) : [];\n if (top.length !== 1) continue;\n const candidate = top[0]!;\n const mutual = bestOld.get(candidate.entry);\n if (!mutual || mutual.groups.length !== 1 || mutual.groups[0] !== g) continue;\n assigned.set(g, {\n bindings: g.bindings,\n target: candidate.entry,\n evidence: \"similarity\",\n score: candidate.score,\n });\n targets.delete(candidate.entry);\n progress = true;\n }\n if (!progress) break;\n }\n\n for (const g of open) {\n const mapping = assigned.get(g);\n if (mapping) {\n report.mapped.push(mapping);\n continue;\n }\n // Candidates a closer match took are no longer candidates.\n const scored = (scores.get(g) ?? []).filter((c) => targets.has(c.entry));\n const above = scored.filter((c) => c.score >= input.threshold);\n if (above.length > 0) {\n report.ambiguous.push({\n bindings: g.bindings,\n candidates: above.slice(0, 5),\n detail: \"several candidates are equally close\",\n });\n } else {\n report.lost.push({\n bindings: g.bindings,\n ...(scored[0] && scored[0].score > 0 ? { best: scored[0] } : {}),\n });\n }\n }\n const order = (bindings: BaselineSymbol[]): string =>\n `${bindings[0]!.spec}\\u0000${bindings[0]!.binding}`;\n report.mapped.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n report.ambiguous.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n report.lost.sort((a, b) => compareStrings(order(a.bindings), order(b.bindings)));\n return report;\n\n function sameFile(g: Group, e: SymbolEntry): boolean {\n return e.file.path === g.file || input.renames?.get(g.file) === e.file.path;\n }\n}\n\nfunction groupBroken(broken: readonly BaselineSymbol[]): Group[] {\n const groups = new Map<string, Group>();\n for (const b of broken) {\n const group = groups.get(b.resolved);\n if (group) {\n group.bindings.push(b);\n continue;\n }\n const { file, qualifiedName } = splitResolved(b.resolved);\n groups.set(b.resolved, {\n key: b.resolved,\n file,\n qualifiedName: qualifiedName || b.shape.name,\n kind: b.shape.kind,\n bindings: [b],\n first: b,\n });\n }\n return [...groups.values()].sort((a, b) => compareStrings(a.key, b.key));\n}\n\n/** The files of the C# partial types `dedupe` merged, by merged declaration. */\nconst partialFiles = new WeakMap<SymbolFact, string[]>();\n\n/**\n * The distinct declarations among `entries`, grouped as binding resolution groups them: overload\n * signatures and their implementation are one, and the parts of a C# partial type are one\n * (merged, at the part in the first file).\n */\nfunction dedupe(entries: SymbolEntry[]): SymbolEntry[] {\n const out: SymbolEntry[] = [];\n const partials = new Map<string, SymbolEntry[]>();\n for (const group of groupOverloads(entries)) {\n const e = group[0]!;\n if (out.some((o) => o.file.path === e.file.path && o.symbol === e.symbol)) continue;\n if (!e.symbol.partial) out.push(e);\n else {\n const key = `${e.symbol.kind}\\u0000${e.symbol.qualifiedName}`;\n const parts = partials.get(key) ?? [];\n if (!parts.some((p) => p.symbol === e.symbol)) partials.set(key, [...parts, e]);\n }\n }\n for (const parts of partials.values()) {\n const sorted = [...parts].sort((a, b) => compareStrings(a.file.path, b.file.path));\n if (sorted.length === 1) {\n out.push(sorted[0]!);\n continue;\n }\n const symbol = mergePartials(sorted.map((p) => p.symbol));\n partialFiles.set(symbol, [...new Set(sorted.map((p) => p.file.path))]);\n out.push({ file: sorted[0]!.file, symbol });\n }\n return out;\n}\n\nconst listOfNames = (groups: Group[]): string => groups.map((g) => g.qualifiedName).join(\", \");\n","/**\n * `catspec sync` (plan §D10, §D11.4, §D11.6, §D11.8, ADR-008), PBIs `sync-command` and\n * `batch-rename-mapping`: turns a rename report into spec edits, lock-file moves and diagnostics.\n *\n * Edits are location-only `SpecPatch`es: a binding's `symbol` and `file` values, never a contract\n * field (every patch is checked with `classifyPatch`). Backticked mentions of old names in the\n * spec body are reported as info and rewritten only with `updateMentions`. Lock entries move to\n * the new declaration, so `satisfied` (the ratchet) survives; a shape that changed only by its\n * name is accepted, any other change stays drift (CS0300).\n */\nimport { posix } from \"node:path\";\n\nimport type { SymbolEntry } from \"./codebase.js\";\nimport { codeLocation, formatLocation } from \"./codebase.js\";\nimport {\n createDiagnostic,\n type Diagnostic,\n type PatchOp,\n type Severity,\n type SpecPatch,\n} from \"./diagnostics.js\";\nimport type { SpecModel } from \"./load.js\";\nimport { fingerprintOf, shapeOf, type LockedSymbol, type LockFile } from \"./lock.js\";\nimport {\n nameFreeFingerprint,\n splitResolved,\n type Ambiguity,\n type BaselineSymbol,\n type Lost,\n type Mapping,\n type RenameReport,\n wordPattern,\n} from \"./rename.js\";\nimport { inModule, splitSymbol } from \"./resolve.js\";\nimport { applyPatch, classifyPatch, readYaml, SpecEditError } from \"./spec-editor.js\";\nimport type { Binding } from \"./spec-schema.js\";\nimport { specLocation, type Spec } from \"./spec.js\";\nimport { globMatcher, listOf } from \"./util.js\";\n\n/** The edit of one spec file. */\nexport interface SpecEdit {\n spec: Spec;\n /** Frontmatter operations (location fields only). */\n ops: PatchOp[];\n /** The file text after the edit. */\n text: string;\n}\n\nexport interface SyncPlan {\n report: RenameReport;\n edits: SpecEdit[];\n /** Lock files with entries moved to the new declarations, by spec id (only specs with a lock). */\n locks: Map<string, LockFile>;\n /** CS0210 for each mapped binding, CS0216 ambiguous, CS0217 lost, CS0210 info for mentions. */\n diagnostics: Diagnostic[];\n}\n\nexport interface SyncOptions {\n /** Severity of the CS0210 of a mapped binding (default info: `sync` fixes it). */\n mappedSeverity?: Severity;\n /** Rewrite backticked mentions of old names in the spec bodies (`--update-mentions`). */\n updateMentions?: boolean;\n /** The `paths` of the rename map, to rewrite `file` globs. */\n paths?: Record<string, string>;\n /**\n * Bindings that still resolve, but outside their `file` hint (a moved file): their hint is\n * updated too. By spec id, then binding id.\n */\n movedHints?: ReadonlyMap<string, ReadonlyMap<string, SymbolEntry>>;\n}\n\nconst EVIDENCE: Record<Mapping[\"evidence\"], string> = {\n map: \"rename map\",\n moved: \"moved\",\n prefix: \"prefix rule\",\n \"file-rename\": \"file renamed\",\n fingerprint: \"same shape\",\n similarity: \"similarity\",\n};\n\n/** Plans the spec edits, lock moves and diagnostics of a rename report. */\nexport function planSync(\n model: SpecModel,\n report: RenameReport,\n options: SyncOptions = {},\n): SyncPlan {\n const diagnostics: Diagnostic[] = [];\n const ops = new Map<Spec, PatchOp[]>();\n const renamed = new Map<Spec, { from: string[]; to: string }[]>();\n const locks = new Map<string, LockFile>();\n const addOps = (spec: Spec, more: PatchOp[]): void => {\n if (more.length > 0) ops.set(spec, [...(ops.get(spec) ?? []), ...more]);\n };\n\n for (const mapping of report.mapped) {\n for (const old of mapping.bindings) {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) continue;\n const bindingOps = relocate(spec, binding, old, mapping.target, options.paths);\n addOps(spec, bindingOps);\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n renamed.set(spec, [\n ...(renamed.get(spec) ?? []),\n {\n from: [...new Set([oldName, splitSymbol(binding.symbol).name])],\n to: mapping.target.symbol.qualifiedName,\n },\n ]);\n moveLock(model, locks, old, mapping.target, mapping.files);\n const how =\n `${EVIDENCE[mapping.evidence]}${mapping.score !== undefined ? `, score ${mapping.score.toFixed(2)}` : \"\"}` +\n (mapping.detail ? `: ${mapping.detail}` : \"\");\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n codeLocation: codeLocation(mapping.target.file.path, mapping.target.symbol.nameRange),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n severity: options.mappedSeverity ?? \"info\",\n message: `binding \"${binding.id}\": ${oldName} is now ${mapping.target.symbol.qualifiedName} at ${formatLocation(mapping.target.file.path, mapping.target.symbol.nameRange)} (${how})`,\n expected: binding.symbol,\n actual: `${mapping.target.file.path}#${mapping.target.symbol.qualifiedName}`,\n suggestions: [\n {\n message: \"run `catspec sync --apply` to update the spec\",\n patch: { file: spec.file, ops: bindingOps },\n },\n ],\n }),\n );\n }\n }\n\n for (const [specId, hints] of options.movedHints ?? []) {\n const spec = model.specs.get(specId);\n if (!spec) continue;\n for (const [bindingId, entry] of hints) {\n const binding = spec.bindings.find((b) => b.id === bindingId);\n if (!binding) continue;\n const hintOps = rewriteHints(spec, binding, undefined, entry.file.path, options.paths);\n if (hintOps.length === 0) continue;\n addOps(spec, hintOps);\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"file\"]),\n codeLocation: codeLocation(entry.file.path, entry.symbol.nameRange),\n bindingId: binding.id,\n severity: \"info\",\n message: `binding \"${binding.id}\": ${binding.symbol} moved to ${entry.file.path}, outside its file hint (moved, score 1.00)`,\n suggestions: [\n {\n message: \"run `catspec sync --apply` to update the hint\",\n patch: { file: spec.file, ops: hintOps },\n },\n ],\n }),\n );\n }\n }\n\n for (const ambiguity of report.ambiguous) diagnostics.push(...ambiguous(model, ambiguity));\n for (const lost of report.lost) diagnostics.push(...lostDiagnostics(model, lost));\n\n const edits: SpecEdit[] = [];\n for (const spec of model.specs.byFile.values()) {\n const specOps = ops.get(spec) ?? [];\n const mentions = mentionsOf(spec, renamed.get(spec) ?? []);\n for (const m of mentions) {\n diagnostics.push(\n createDiagnostic(\"CS0210\", {\n spec: spec.id,\n specLocation: { file: spec.file, line: m.line, column: m.column },\n severity: \"info\",\n message: options.updateMentions\n ? `the body mentions \\`${m.text}\\`; rewritten to \\`${m.replacement}\\``\n : `the body mentions \\`${m.text}\\`, now \\`${m.replacement}\\`; \\`catspec sync --apply --update-mentions\\` rewrites it`,\n }),\n );\n }\n if (specOps.length === 0 && !(options.updateMentions && mentions.length > 0)) continue;\n if (specOps.length > 0 && classifyPatch(specOps, spec.source) !== \"location\") {\n throw new SpecEditError(`${spec.file}: a sync edit would change the contract (ADR-008)`);\n }\n let text = applyPatch(spec.source, specOps);\n if (options.updateMentions && mentions.length > 0) text = rewriteMentions(text, spec, mentions);\n edits.push({ spec, ops: specOps, text });\n }\n return { report, edits, locks, diagnostics };\n}\n\n/** The ops that point `binding` at `target`: its `symbol`, and its `file` hint if it has one. */\nfunction relocate(\n spec: Spec,\n binding: Binding,\n old: BaselineSymbol,\n target: SymbolEntry,\n paths: Record<string, string> | undefined,\n): PatchOp[] {\n const oldFile = splitResolved(old.resolved).file;\n const symbol = rewriteSymbol(binding.symbol, old, target);\n const out: PatchOp[] = [];\n if (symbol !== binding.symbol) {\n out.push({ op: \"set\", path: [\"bindings\", binding.index, \"symbol\"], value: symbol });\n }\n out.push(...rewriteHints(spec, binding, oldFile, target.file.path, paths));\n return out;\n}\n\n/**\n * The binding's `symbol` for the new declaration, written the way it was: as many name segments\n * as before (all of them when it was fully qualified), and the module path when it had one.\n */\nexport function rewriteSymbol(written: string, old: BaselineSymbol, target: SymbolEntry): string {\n const { module, name } = splitSymbol(written);\n const before = (splitResolved(old.resolved).qualifiedName || old.shape.name).split(\".\");\n const after = target.symbol.qualifiedName.split(\".\");\n const count = name.split(\".\").length;\n const newName = count >= before.length ? after.join(\".\") : after.slice(-count).join(\".\");\n if (module === undefined) return newName;\n const oldFile = splitResolved(old.resolved).file;\n const newModule = inModule(target.file.path, module)\n ? module\n : rewriteModule(module, oldFile, target.file.path);\n return `${written.startsWith(\"./\") ? \"./\" : \"\"}${newModule}#${newName}`;\n}\n\n/** A module path for `newFile` with as many segments as `module` had, and its extension style. */\nfunction rewriteModule(module: string, oldFile: string, newFile: string): string {\n const withoutExt = (p: string): string => p.replace(/\\.[^./]+$/, \"\");\n const hasExt = withoutExt(module) !== module && oldFile.endsWith(module);\n const target = hasExt ? newFile : withoutExt(newFile);\n const segments = module.split(\"/\").length;\n const all = target.split(\"/\");\n return segments >= all.length ? target : all.slice(-segments).join(\"/\");\n}\n\n/**\n * Ops that make the binding's `file` hint match `newFile`: an entry that named the old file is\n * replaced; a glob that matched it is moved with the rename map's `paths` or with the old file's\n * folder; an entry about other files (another partial part) is left alone.\n */\nfunction rewriteHints(\n spec: Spec,\n binding: Binding,\n oldFile: string | undefined,\n newFile: string,\n paths: Record<string, string> | undefined,\n): PatchOp[] {\n if (!binding.file) return [];\n const raw = readYaml(spec.source.frontmatter.text, [\"bindings\", binding.index, \"file\"]);\n const hints = typeof raw === \"string\" ? [raw] : Array.isArray(raw) ? (raw as unknown[]) : [];\n const matches = (hint: string, file: string): boolean => hint === file || globMatcher(hint)(file);\n if (hints.some((h) => typeof h === \"string\" && matches(h, newFile))) return [];\n const out: PatchOp[] = [];\n hints.forEach((hint, i) => {\n if (typeof hint !== \"string\") return;\n const matchedOld = oldFile !== undefined ? matches(hint, oldFile) : !matches(hint, newFile);\n if (!matchedOld) return;\n const next = moveHint(hint, oldFile, newFile, paths);\n if (next === hint) return;\n out.push({\n op: \"set\",\n path:\n typeof raw === \"string\"\n ? [\"bindings\", binding.index, \"file\"]\n : [\"bindings\", binding.index, \"file\", i],\n value: next,\n });\n });\n return out;\n}\n\nfunction moveHint(\n hint: string,\n oldFile: string | undefined,\n newFile: string,\n paths: Record<string, string> | undefined,\n): string {\n if (hint === oldFile || !/[*?[\\]{}!]/.test(hint)) return newFile;\n const mapped = Object.entries(paths ?? {})\n .filter(([from]) => from !== \"\" && hint.startsWith(from))\n .sort((a, b) => b[0].length - a[0].length)[0];\n if (mapped) {\n const moved = mapped[1] + hint.slice(mapped[0].length);\n if (globMatcher(moved)(newFile)) return moved;\n }\n if (oldFile !== undefined) {\n const from = `${posix.dirname(oldFile)}/`;\n const to = `${posix.dirname(newFile)}/`;\n if (hint.startsWith(from)) {\n const moved = to + hint.slice(from.length);\n if (globMatcher(moved)(newFile)) return moved;\n }\n }\n return newFile;\n}\n\n/**\n * The lock entry of a moved binding: the new location, and the new shape when it differs from the\n * accepted (locked) shape only by the name. Drift that was never accepted stays drift.\n */\nfunction moveLock(\n model: SpecModel,\n locks: Map<string, LockFile>,\n old: BaselineSymbol,\n target: SymbolEntry,\n files: string[] | undefined,\n): void {\n const lock = locks.get(old.spec) ?? model.locks.get(old.spec);\n if (!lock) return;\n const shape = shapeOf(target.symbol);\n const previous = lock.symbols[old.binding];\n const accepted = previous ? nameFreeFingerprint(previous.shape) : old.nameFree;\n const nameOnly = nameFreeFingerprint(shape) === accepted;\n const entry: LockedSymbol = {\n resolved: `${target.file.path}#${target.symbol.qualifiedName}`,\n ...(files ? { files } : {}),\n fingerprint: nameOnly ? fingerprintOf(shape) : (previous?.fingerprint ?? old.fingerprint),\n shape: nameOnly ? shape : (previous?.shape ?? old.shape),\n };\n locks.set(old.spec, { ...lock, symbols: { ...lock.symbols, [old.binding]: entry } });\n}\n\nfunction ambiguous(model: SpecModel, ambiguity: Ambiguity): Diagnostic[] {\n const names = ambiguity.candidates.map(\n (c) =>\n `${c.entry.symbol.qualifiedName} (${formatLocation(c.entry.file.path, c.entry.symbol.nameRange)}${c.score < 1 ? `, score ${c.score.toFixed(2)}` : \"\"})`,\n );\n return ambiguity.bindings.flatMap((old) => {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) return [];\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n return [\n createDiagnostic(\"CS0216\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n message: `binding \"${binding.id}\": can't tell where ${oldName} went${ambiguity.detail ? ` (${ambiguity.detail})` : \"\"}; candidates: ${listOf(names)}; the spec is not changed`,\n expected: oldName,\n actual: ambiguity.candidates.map(\n (c) => `${c.entry.file.path}#${c.entry.symbol.qualifiedName}`,\n ),\n suggestions: [\n {\n message: `name the rename in a map: { \"symbols\": { \"${oldName}\": \"<new name>\" } } and run \\`catspec sync --apply --map <file>\\``,\n },\n { message: \"or fix the binding's symbol by hand\" },\n ],\n }),\n ];\n });\n}\n\nfunction lostDiagnostics(model: SpecModel, lost: Lost): Diagnostic[] {\n return lost.bindings.flatMap((old) => {\n const spec = model.specs.get(old.spec);\n const binding = spec?.bindings.find((b) => b.id === old.binding);\n if (!spec || !binding) return [];\n const oldName = splitResolved(old.resolved).qualifiedName || old.shape.name;\n const best = lost.best\n ? `; the closest candidate, ${lost.best.entry.symbol.qualifiedName} (${formatLocation(lost.best.entry.file.path, lost.best.entry.symbol.nameRange)}), scores ${lost.best.score.toFixed(2)}, below heal.threshold`\n : \"\";\n return [\n createDiagnostic(\"CS0217\", {\n spec: spec.id,\n specLocation: specLocation(spec.source, [\"bindings\", binding.index, \"symbol\"]),\n bindingId: binding.id,\n item: `binding:${binding.id}`,\n message: `binding \"${binding.id}\": ${oldName} is gone and nothing replaces it${lost.detail ? ` (${lost.detail})` : \"\"}${best}`,\n expected: oldName,\n actual: \"nothing\",\n suggestions: [\n { message: \"restore the code, add the rename to a map (--map), or change the spec\" },\n ],\n }),\n ];\n });\n}\n\ninterface Mention {\n line: number;\n column: number;\n /** Offset of the code span's content in the file. */\n offset: number;\n text: string;\n replacement: string;\n}\n\n/** Backticked mentions of renamed names in the spec body, outside fenced code blocks. */\nfunction mentionsOf(spec: Spec, renames: { from: string[]; to: string }[]): Mention[] {\n if (renames.length === 0) return [];\n const { body } = spec.source;\n const mentions: Mention[] = [];\n let fenced = false;\n let offset = body.start;\n for (const [i, line] of body.text.split(\"\\n\").entries()) {\n if (/^\\s*(```|~~~)/.test(line)) fenced = !fenced;\n else if (!fenced) {\n for (const match of line.matchAll(/`([^`\\n]+)`/g)) {\n const text = match[1]!;\n const replacement = replaceNames(text, renames);\n if (replacement === text) continue;\n mentions.push({\n line: body.line + i,\n column: match.index + 2,\n offset: offset + match.index + 1,\n text,\n replacement,\n });\n }\n }\n offset += line.length + 1;\n }\n return mentions;\n}\n\n/**\n * `text` with every old name replaced, whole words only, in one pass (a replacement is never\n * replaced again); at each place the longest (qualified) form wins.\n */\nfunction replaceNames(text: string, renames: { from: string[]; to: string }[]): string {\n const replacements = new Map<string, string>();\n for (const r of renames) {\n for (const from of r.from) {\n const count = from.split(\".\").length;\n const to = r.to.split(\".\");\n const next = count >= to.length ? r.to : to.slice(-count).join(\".\");\n if (from !== next && !replacements.has(from)) replacements.set(from, next);\n }\n }\n if (replacements.size === 0) return text;\n const names = [...replacements.keys()].sort((a, b) => b.length - a.length);\n return text.replace(wordPattern(names, \".\"), (name) => replacements.get(name) ?? name);\n}\n\n/** Writes the mention replacements into the body of `text` (the edited file). */\nfunction rewriteMentions(text: string, spec: Spec, mentions: Mention[]): string {\n const shift = text.length - spec.source.text.length;\n let body = text.slice(spec.source.body.start + shift);\n for (const m of [...mentions].reverse()) {\n const at = m.offset - spec.source.body.start;\n body = body.slice(0, at) + m.replacement + body.slice(at + m.text.length);\n }\n const frontmatter = text.slice(0, spec.source.body.start + shift);\n return frontmatter + body;\n}\n\n/** A `SpecPatch` for one edit, for diagnostics and the MCP layer. */\nexport const editPatch = (edit: SpecEdit): SpecPatch => ({ file: edit.spec.file, ops: edit.ops });\n","/**\n * Workflow profiles at work (plan §D17.1, §D17.4, §D17.5), PBIs `stage-resolution`, `gate-runner`\n * and `workflow-cli`: which features exist, where each feature and work item is in the workflow,\n * the gates, and `stage start|finish`.\n *\n * The current stage is derived, never stored (ADR-004): it is the first stage whose finish gates\n * don't pass yet or whose status its specs haven't reached. Deriving never runs `command:` gates.\n * CatSpec never performs a stage itself; it describes it, checks it and sets the status.\n */\nimport { execFile } from \"node:child_process\";\nimport { appendFile, mkdir, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { checkCode, statusGate, testCommandArgs, type CheckResult } from \"../check.js\";\nimport type { Codebase } from \"../codebase.js\";\nimport { findGitCommonDir } from \"../config.js\";\nimport {\n compareStrings,\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n} from \"../diagnostics.js\";\nimport type { SpecModel } from \"../load.js\";\nimport { applyPatch } from \"../spec-editor.js\";\nimport type { SpecStatus } from \"../spec-schema.js\";\nimport type { Spec } from \"../spec.js\";\nimport { didYouMean, globMatcher, listOf } from \"../util.js\";\nimport {\n driverText,\n featureDirsText,\n featureFolderOf,\n gateName,\n type Driver,\n type Gate,\n type Stage,\n type Transition,\n type WorkflowProfile,\n} from \"./schema.js\";\nimport { findProgram, isBatchScript } from \"./doctor.js\";\n\n/** A workflow command that can't run: an unknown stage or target (a usage error). */\nexport class WorkflowError extends Error {}\n\nexport interface Feature {\n name: string;\n /** The feature folder, relative to the repository root. */\n dir: string;\n /** Its machine specs (valid, not the architecture spec), sorted by id. */\n specs: Spec[];\n}\n\n/** What a stage command is run for: a feature, or one spec (with its feature, if it has one). */\nexport interface Target {\n name: string;\n feature?: Feature;\n spec?: Spec;\n}\n\nexport type Phase = \"start\" | \"finish\";\n\nexport interface GateResult {\n gate: string;\n passed: boolean;\n /** A `command:` gate that wasn't run (`allow_commands` false): CS0706, doesn't block. */\n skipped?: boolean;\n /** Why it failed or was skipped, or what it checked. */\n detail: string;\n /** The diagnostics behind a failure (the underlying check). */\n diagnostics: Diagnostic[];\n}\n\n/** How a command gate runs; replaced in tests. */\nexport type CommandRunner = (\n root: string,\n args: string[],\n) => Promise<{ exitCode: number; output: string }>;\n\nexport interface WorkflowOptions {\n now?: Date;\n runCommand?: CommandRunner;\n}\n\nconst STATUS_RANK: Record<SpecStatus, number> = {\n draft: 0,\n ready: 1,\n \"in-progress\": 2,\n implemented: 3,\n deprecated: 4,\n};\n\n/** True when `status` is `target` or a later status. */\nexport const reached = (status: SpecStatus, target: SpecStatus): boolean =>\n STATUS_RANK[status] >= STATUS_RANK[target];\n\n/** The status a stage sets: at finish, else at start. */\nexport const stageStatus = (stage: Stage): SpecStatus | undefined =>\n stage.finish.status ?? stage.start.status;\n\n/**\n * A repository seen through its workflow profile: features, targets, gates and stage positions.\n * Check results are computed once per set of specs.\n */\nexport class Workflow {\n readonly features: Feature[];\n private readonly checks = new Map<string, Promise<CheckResult>>();\n\n constructor(\n readonly model: SpecModel,\n readonly codebase: Codebase,\n readonly profile: WorkflowProfile,\n /** Every file of the repository (root-relative POSIX paths). */\n readonly files: readonly string[],\n readonly options: WorkflowOptions = {},\n ) {\n const byName = new Map<string, Feature>();\n for (const file of files) {\n const folder = featureFolderOf(profile.featureDirs, file);\n if (!folder) continue;\n if (profile.notFeatures.includes(folder.name) || byName.has(folder.name)) continue;\n byName.set(folder.name, { ...folder, specs: [] });\n }\n for (const spec of this.specs()) {\n const feature = this.featureNameOf(spec);\n if (feature !== undefined) byName.get(feature)?.specs.push(spec);\n }\n this.features = [...byName.values()].sort((a, b) => compareStrings(a.name, b.name));\n }\n\n /** The work items: valid specs other than the architecture spec, sorted by id. */\n specs(): Spec[] {\n return this.model.specs.all().filter((s) => s.valid && s.type !== \"architecture\");\n }\n\n feature(name: string): Feature | undefined {\n return this.features.find((f) => f.name === name);\n }\n\n private featureNameOf(spec: Spec): string | undefined {\n const name = featureFolderOf(this.profile.featureDirs, spec.file)?.name;\n return name !== undefined && !this.profile.notFeatures.includes(name) ? name : undefined;\n }\n\n /** The feature a spec belongs to: the feature folder it is in. */\n featureOf(spec: Spec): Feature | undefined {\n const name = this.featureNameOf(spec);\n return name === undefined ? undefined : this.feature(name);\n }\n\n stage(id: string): Stage {\n const stage = this.profile.stages.find((s) => s.id === id);\n if (stage) return stage;\n const ids = this.profile.stages.map((s) => s.id);\n const close = didYouMean(id, ids);\n throw new WorkflowError(\n `no stage \"${id}\" in the workflow (${listOf(ids)})` +\n (close.length > 0 ? `; did you mean \"${close[0]}\"?` : \"\"),\n );\n }\n\n /** A feature name or a spec id; a feature wins when a name is both. */\n target(name: string): Target {\n const feature = this.feature(name);\n if (feature) return { name, feature };\n const spec = this.model.specs.get(name);\n if (spec && spec.type !== \"architecture\") {\n const owner = this.featureOf(spec);\n return { name, spec, ...(owner ? { feature: owner } : {}) };\n }\n const close = didYouMean(name, [\n ...this.features.map((f) => f.name),\n ...this.model.specs.byId.keys(),\n ]);\n throw new WorkflowError(\n `\"${name}\" is neither a feature (a folder ${featureDirsText(this.profile)}) nor a spec id` +\n (close.length > 0 ? `; did you mean ${close.map((c) => `\"${c}\"`).join(\", \")}?` : \"\"),\n );\n }\n\n /**\n * True for a per-spec stage before the one that sets `implemented`: aggregate specs (plan\n * §D17.1) have no work of their own, so they skip it and go straight to that stage.\n */\n skipsAggregates(stage: Stage): boolean {\n if (stage.per !== \"spec\") return false;\n const stages = this.profile.stages;\n const final = stages.findIndex(\n (s) => s.start.status === \"implemented\" || s.finish.status === \"implemented\",\n );\n return final >= 0 && stages.indexOf(stage) < final;\n }\n\n /** The specs a stage runs on for a target. */\n scope(stage: Stage, target: Target): { feature?: Feature; specs: Spec[] } {\n if (stage.per === \"spec\") {\n if (target.spec?.aggregate && this.skipsAggregates(stage)) {\n throw new WorkflowError(\n `\"${target.name}\" is an aggregate spec: it has no stage \"${stage.id}\" of its own; ` +\n \"it is closed once its dependencies are implemented\",\n );\n }\n const specs = target.spec ? [target.spec] : (target.feature?.specs ?? []);\n return {\n ...(target.feature ? { feature: target.feature } : {}),\n specs: specs.filter(\n (s) => s.status !== \"deprecated\" && !(s.aggregate && this.skipsAggregates(stage)),\n ),\n };\n }\n if (!target.feature) {\n throw new WorkflowError(\n `stage \"${stage.id}\" runs per feature, and spec \"${target.name}\" isn't in a feature folder (${featureDirsText(this.profile)})`,\n );\n }\n return {\n feature: target.feature,\n specs: target.feature.specs.filter((s) => s.status !== \"deprecated\"),\n };\n }\n\n /** The check of `ids` as if implemented, computed once. */\n check(ids: readonly string[]): Promise<CheckResult> {\n const key = [...ids].sort(compareStrings).join(\"\\0\");\n let result = this.checks.get(key);\n if (!result) {\n result = checkCode(this.model, this.codebase, {\n specs: ids,\n mode: \"full\",\n ...(this.options.now ? { now: this.options.now } : {}),\n });\n this.checks.set(key, result);\n }\n return result;\n }\n\n /** Path templates with the placeholders filled in; `{spec}` repeats for every spec. */\n expand(template: string, feature: Feature | undefined, specs: readonly Spec[]): string[] {\n const base = template\n .replaceAll(\"{feature_dir}\", feature?.dir ?? \"\")\n .replaceAll(\"{feature}\", feature?.name ?? \"\");\n return base.includes(\"{spec}\") ? specs.map((s) => base.replaceAll(\"{spec}\", s.id)) : [base];\n }\n\n /** The files a template names that exist: a plain path, or every match of a glob. */\n existing(path: string): string[] {\n if (!/[*?[\\]{}]/.test(path)) return this.files.includes(path) ? [path] : [];\n const matches = globMatcher(path);\n return this.files.filter((f) => matches(f));\n }\n\n // Gates -----------------------------------------------------------------------------------\n\n /**\n * Runs one gate for a stage over `specs` (of `feature`). `commands`: run `command:` gates\n * (with `allow_commands`), else report them skipped.\n */\n async gate(\n gate: Gate,\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult> {\n const ids = specs.map((s) => s.id);\n const name = gateName(gate);\n const result = (passed: boolean, detail: string, diagnostics: Diagnostic[] = []) => ({\n gate: name,\n passed,\n detail,\n diagnostics,\n });\n if (typeof gate !== \"string\") return this.commandGate(gate.command, feature, specs, commands);\n\n switch (gate) {\n case \"specs_valid\": {\n const inFeature = (file: string | undefined) =>\n feature !== undefined && file !== undefined && file.startsWith(`${feature.dir}/`);\n const errors = this.model.diagnostics.filter(\n (d) =>\n d.severity === \"error\" &&\n ((d.spec !== undefined && ids.includes(d.spec)) || inFeature(d.specLocation?.file)),\n );\n return errors.length === 0\n ? result(true, `${ids.length} spec(s) valid`)\n : result(\n false,\n `${errors.length} spec error(s); run \\`catspec check --specs-only\\``,\n errors,\n );\n }\n case \"artifacts\": {\n const missing: string[] = [];\n for (const template of stage.produces) {\n for (const path of this.expand(template, feature, specs)) {\n const found = [];\n for (const file of this.existing(path)) {\n const content = await this.model.source.read(file);\n if (content && content.toString(\"utf8\").trim().length > 0) found.push(file);\n }\n if (found.length === 0) missing.push(path);\n }\n }\n return missing.length === 0\n ? result(true, stage.produces.length > 0 ? \"every artifact exists\" : \"nothing to produce\")\n : result(false, `missing or empty: ${listOf(missing)}`);\n }\n case \"contracts_declared\": {\n if (specs.length === 0) return result(false, \"no machine spec (*.spec.md) yet\");\n const empty = specs.filter(\n (s) =>\n !s.aggregate && s.bindings.length === 0 && !s.rules.some((r) => r.class !== \"manual\"),\n );\n return empty.length === 0\n ? result(true, \"every spec declares a contract\")\n : result(false, `no binding or enforceable rule in ${listOf(empty.map((s) => s.id))}`);\n }\n case \"deps_known\": {\n const unknown = specs.flatMap((s) =>\n s.dependsOn.filter((d) => !this.model.specs.get(d)).map((d) => `${s.id} → ${d}`),\n );\n const errors = this.model.diagnostics.filter(\n (d) => d.code === \"CS0104\" && d.spec !== undefined && ids.includes(d.spec),\n );\n return unknown.length === 0\n ? result(true, \"every dependency exists\")\n : result(false, `unknown dependencies: ${listOf(unknown)}`, errors);\n }\n case \"deps_ready\": {\n // For a stage over a whole feature, dependencies inside the feature move together.\n const inScope = new Set(stage.per === \"feature\" ? ids : []);\n const problems: string[] = [];\n const diagnostics: Diagnostic[] = [];\n const deps = [...new Set(specs.flatMap((s) => s.dependsOn))]\n .filter((d) => !inScope.has(d))\n .sort(compareStrings);\n for (const dep of deps) {\n const other = this.model.specs.get(dep);\n if (!other) problems.push(`${dep} does not exist`);\n else if (other.status !== \"implemented\") {\n problems.push(`${dep} is ${other.status}, not implemented`);\n } else {\n const check = await this.check([dep]);\n const errors = check.diagnostics.filter((d) => d.severity === \"error\");\n if (errors.length > 0) {\n problems.push(`${dep} is implemented but its contracts fail`);\n diagnostics.push(...errors);\n }\n }\n }\n return problems.length === 0\n ? result(true, deps.length > 0 ? `${listOf(deps)} implemented` : \"no dependencies\")\n : result(false, listOf(problems), diagnostics);\n }\n case \"contracts_pass\": {\n if (ids.length === 0) return result(true, \"no spec to check\");\n const check = await this.check(ids);\n const errors = check.diagnostics.filter((d) => d.severity === \"error\");\n const waiting = specs.flatMap((s) =>\n s.aggregate\n ? s.dependsOn\n .filter((d) => this.model.specs.get(d)?.status !== \"implemented\")\n .map((d) => `${s.id} waits for ${d} to be implemented`)\n : [],\n );\n const failing = [...new Set(errors.flatMap((d) => (d.spec ? [d.spec] : [])))].sort(\n compareStrings,\n );\n if (errors.length === 0 && waiting.length === 0) {\n return result(true, `${listOf(ids)}: DONE`);\n }\n const parts = [\n ...(failing.length > 0\n ? [`contracts fail in ${listOf(failing)} (run \\`catspec check --spec <id>\\`)`]\n : errors.length > 0\n ? [`${errors.length} error(s)`]\n : []),\n ...waiting,\n ];\n return result(false, parts.join(\"; \"), errors);\n }\n case \"tasks_done\": {\n const open: string[] = [];\n if (stage.per === \"spec\") {\n for (const spec of specs) {\n const count = spec.body.tasks.filter((t) => !t.done).length;\n if (count > 0) open.push(`${spec.id}: ${count} open task(s) in ${spec.file}`);\n }\n } else if (feature) {\n const file = `${feature.dir}/tasks.md`;\n const text = (await this.model.source.read(file))?.toString(\"utf8\");\n const count = text === undefined ? 0 : openCheckboxes(text);\n if (count > 0) open.push(`${count} open task(s) in ${file}`);\n }\n return open.length === 0\n ? result(true, \"every task is ticked\")\n : result(false, listOf(open));\n }\n case \"no_drift\": {\n if (ids.length === 0) return result(true, \"no spec to check\");\n const check = await this.check(ids);\n const drift = check.diagnostics.filter((d) => d.code === \"CS0300\" && d.severity !== \"info\");\n return drift.length === 0\n ? result(true, \"no drift\")\n : result(\n false,\n `drift in ${listOf([...new Set(drift.map((d) => d.spec ?? \"?\"))])}; run \\`catspec accept <id>\\` for an intended change`,\n drift,\n );\n }\n case \"adr_valid\": {\n const architecture = this.model.architecture;\n const errors = this.model.diagnostics.filter(\n (d) =>\n d.severity === \"error\" &&\n (d.code === \"CS0107\" ||\n d.code === \"CS0112\" ||\n (architecture !== undefined &&\n (d.spec === architecture.id || d.specLocation?.file === architecture.file))),\n );\n return errors.length === 0 && architecture\n ? result(true, `${architecture.file} is valid`)\n : result(\n false,\n architecture ? `${errors.length} error(s) in the ADR log` : \"no ADR log\",\n errors,\n );\n }\n }\n }\n\n private async commandGate(\n command: string,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult> {\n const gate = `command: ${command}`;\n const args = testCommandArgs(command).flatMap((arg) =>\n arg.includes(\"{spec}\")\n ? specs.map((s) => this.expand(arg, feature, [s])[0]!)\n : this.expand(arg, feature, specs),\n );\n if (!commands) {\n return { gate, passed: true, skipped: true, detail: \"not run\", diagnostics: [] };\n }\n if (!this.profile.allowCommands) {\n return {\n gate,\n passed: true,\n skipped: true,\n detail: \"not run: workflow.allow_commands is false\",\n diagnostics: [\n createDiagnostic(\"CS0706\", {\n message: `the gate \\`${args.join(\" \")}\\` was not run: workflow.allow_commands is false`,\n actual: args,\n suggestions: [\n { message: \"run it yourself, or set workflow.allow_commands: true in catspec.yaml\" },\n ],\n }),\n ],\n };\n }\n const run = await (this.options.runCommand ?? runCommand)(this.model.root, args);\n return run.exitCode === 0\n ? { gate, passed: true, detail: `\\`${args.join(\" \")}\\` exited with 0`, diagnostics: [] }\n : {\n gate,\n passed: false,\n detail: `\\`${args.join(\" \")}\\` exited with ${run.exitCode}${run.output ? `:\\n${run.output}` : \"\"}`,\n diagnostics: [],\n };\n }\n\n /** Runs the gates of a transition. */\n async gates(\n transition: Transition,\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n commands: boolean,\n ): Promise<GateResult[]> {\n const results: GateResult[] = [];\n for (const gate of transition.gates) {\n results.push(await this.gate(gate, stage, feature, specs, commands));\n }\n return results;\n }\n\n // Stage resolution ------------------------------------------------------------------------\n\n /** True when a stage is done for these specs: finish gates pass and its status is reached. */\n async done(stage: Stage, feature: Feature | undefined, all: readonly Spec[]): Promise<boolean> {\n const specs = this.skipsAggregates(stage) ? all.filter((s) => !s.aggregate) : all;\n const status = stageStatus(stage);\n if (status !== undefined && !specs.every((s) => reached(s.status, status))) return false;\n if (stage.per === \"spec\" && specs.length === 0) return true;\n const results = await this.gates(stage.finish, stage, feature, specs, false);\n return results.every((r) => r.passed);\n }\n\n /** Where a feature is: its current stage, and each work item's stage. */\n async position(feature: Feature): Promise<FeaturePosition> {\n const stages = this.profile.stages;\n const specs = feature.specs.filter((s) => s.status !== \"deprecated\");\n for (const [index, stage] of stages.entries()) {\n if (stage.per === \"feature\") {\n if (await this.done(stage, feature, specs)) continue;\n return { feature: feature.name, dir: feature.dir, stage, items: [] };\n }\n // A run of per-spec stages: each work item is at its own stage.\n let end = index;\n while (end < stages.length && stages[end]!.per === \"spec\") end++;\n const run = stages.slice(index, end);\n const items: ItemPosition[] = [];\n for (const spec of specs) items.push(await this.item(spec, run));\n const first = run.find((s) => items.some((i) => i.stage === s.id));\n if (first) return { feature: feature.name, dir: feature.dir, stage: first, items };\n }\n return { feature: feature.name, dir: feature.dir, items: [] };\n }\n\n /** A work item's stage among a run of per-spec stages, and whether it can start. */\n async item(spec: Spec, run: readonly Stage[]): Promise<ItemPosition> {\n const feature = this.featureOf(spec);\n let current: Stage | undefined;\n for (const stage of run) {\n if (!(await this.done(stage, feature, [spec]))) {\n current = stage;\n break;\n }\n }\n const waitingOn = spec.dependsOn\n .filter((d) => this.model.specs.get(d)?.status !== \"implemented\")\n .sort(compareStrings);\n const state: ItemPosition[\"state\"] = !current\n ? \"done\"\n : spec.status === \"in-progress\"\n ? \"in-progress\"\n : waitingOn.length > 0\n ? \"waiting\"\n : \"ready\";\n return {\n spec: spec.id,\n status: spec.status,\n ...(current ? { stage: current.id } : {}),\n state,\n waitingOn: state === \"waiting\" ? waitingOn : [],\n };\n }\n\n /** The per-spec stages from a stage's run (the stages a work item goes through). */\n private specRun(stage: Stage): Stage[] {\n const stages = this.profile.stages;\n let start = stages.indexOf(stage);\n while (start > 0 && stages[start - 1]!.per === \"spec\") start--;\n let end = stages.indexOf(stage);\n while (end < stages.length && stages[end]!.per === \"spec\") end++;\n return stages.slice(start, end);\n }\n\n /** What to do next for a feature or a work item (`catspec next`, MCP `next_step`). */\n async next(name: string): Promise<NextStep> {\n const target = this.target(name);\n const spec = target.spec;\n if (!spec) {\n const feature = target.feature!;\n const position = await this.position(feature);\n return this.describeNext(name, feature, position.stage, position.items, feature.specs);\n }\n // One work item: the first stage not done for its feature (per-feature stages) or for it.\n const feature = target.feature;\n const all = feature?.specs.filter((s) => s.status !== \"deprecated\") ?? [];\n for (const stage of this.profile.stages) {\n if (stage.per === \"feature\") {\n if (!feature || (await this.done(stage, feature, all))) continue;\n return this.describeNext(name, feature, stage, [], [spec]);\n }\n if (await this.done(stage, feature, [spec])) continue;\n const item = await this.item(spec, this.specRun(stage));\n return this.describeNext(name, feature, stage, [item], [spec]);\n }\n const item = await this.item(spec, []);\n return this.describeNext(name, feature, undefined, [item], [spec]);\n }\n\n private describeNext(\n target: string,\n feature: Feature | undefined,\n stage: Stage | undefined,\n items: ItemPosition[],\n specs: readonly Spec[],\n ): NextStep {\n if (!stage) {\n return { target, ...(feature ? { feature: feature.name } : {}), done: true, items };\n }\n const index = this.profile.stages.indexOf(stage);\n const inputs = [\n ...this.profile.context.filter((f) => this.files.includes(f)),\n ...this.profile.stages\n .slice(0, index)\n .flatMap((s) => s.produces.flatMap((t) => this.expand(t, feature, specs)))\n .flatMap((p) => this.existing(p)),\n ...(stage.per === \"spec\" ? specs.map((s) => s.file) : []),\n ];\n return {\n target,\n ...(feature ? { feature: feature.name } : {}),\n done: false,\n stage: describeStage(stage),\n inputs: [...new Set(inputs)],\n produces: stage.produces.flatMap((t) => this.expand(t, feature, specs)),\n items,\n };\n }\n\n /**\n * The stages before `stage` that aren't done for the target (CS0705): earlier per-feature stages\n * for the feature, earlier per-spec stages for each spec.\n */\n private async outOfOrder(\n stage: Stage,\n feature: Feature | undefined,\n specs: readonly Spec[],\n ): Promise<string[]> {\n const pending: string[] = [];\n for (const earlier of this.profile.stages.slice(0, this.profile.stages.indexOf(stage))) {\n if (earlier.per === \"feature\") {\n if (!feature) continue;\n const all = feature.specs.filter((s) => s.status !== \"deprecated\");\n if (!(await this.done(earlier, feature, all))) pending.push(earlier.id);\n } else {\n const behind = [];\n for (const spec of specs) {\n if (!(await this.done(earlier, this.featureOf(spec), [spec]))) behind.push(spec.id);\n }\n if (behind.length > 0) pending.push(`${earlier.id} (${listOf(behind)})`);\n }\n }\n return pending;\n }\n\n /**\n * `catspec stage start|finish <stage> <target>`: checks the order (CS0705) and the gates\n * (CS0701, CS0702), then works out the status change. Nothing is written: `writeStage` does\n * that. With `force`, failures become warnings and the run is marked forced; `implemented` is\n * still never set while a spec's contracts fail.\n */\n async run(\n phase: Phase,\n stageId: string,\n targetName: string,\n options: { force?: boolean } = {},\n ): Promise<StageRun> {\n const stage = this.stage(stageId);\n const target = this.target(targetName);\n const { feature, specs } = this.scope(stage, target);\n const force = Boolean(options.force);\n const transition = stage[phase];\n const diagnostics: Diagnostic[] = [];\n const where = `${stage.id} ${targetName}`;\n const failCode = phase === \"start\" ? \"CS0701\" : \"CS0702\";\n\n const pending = await this.outOfOrder(stage, feature, specs);\n if (pending.length > 0) {\n diagnostics.push(\n createDiagnostic(\"CS0705\", {\n ...(force ? { severity: \"warning\" as const } : {}),\n message: `stage \"${stage.id}\" for \"${targetName}\" is out of order: ${listOf(pending)} not done yet`,\n expected: \"every earlier stage done\",\n actual: pending,\n suggestions: [\n {\n message: `run \\`catspec next ${feature?.name ?? targetName}\\` to see the current stage`,\n },\n ],\n }),\n );\n }\n\n const gates = await this.gates(transition, stage, feature, specs, true);\n for (const gate of gates) {\n diagnostics.push(...gate.diagnostics.filter((d) => d.code === \"CS0706\"));\n if (gate.passed) continue;\n diagnostics.push(\n createDiagnostic(failCode, {\n ...(force ? { severity: \"warning\" as const } : {}),\n message: `stage \"${stage.id}\" can't ${phase} for \"${targetName}\": gate ${gate.gate} failed: ${gate.detail}`,\n expected: gate.gate,\n actual: gate.detail,\n suggestions: [{ message: `fix it, then run \\`catspec stage ${phase} ${where}\\` again` }],\n }),\n ...gate.diagnostics,\n );\n }\n\n const blocked = diagnostics.some((d) => d.severity === \"error\");\n const changes: StatusChange[] = [];\n if (transition.status !== undefined && !blocked) {\n const status = transition.status;\n const inScope = new Set(specs.map((s) => s.id));\n for (const spec of specs) {\n if (reached(spec.status, status)) continue;\n // Dependencies inside a per-feature stage move together; statusGate checks the rest.\n const outside: Spec =\n stage.per === \"feature\"\n ? { ...spec, dependsOn: spec.dependsOn.filter((d) => !inScope.has(d)) }\n : spec;\n const gate = await statusGate(this.model, this.codebase, outside, status, {\n force,\n ...(this.options.now ? { now: this.options.now } : {}),\n });\n if (!gate.allowed) {\n diagnostics.push(...gate.diagnostics);\n continue;\n }\n changes.push({\n spec: spec.id,\n file: spec.file,\n from: spec.status,\n to: status,\n text: applyPatch(spec.source, [{ op: \"set\", path: [\"status\"], value: status }]),\n });\n }\n }\n\n const ok = !diagnostics.some((d) => d.severity === \"error\");\n return {\n phase,\n stage: describeStage(stage),\n target: targetName,\n ...(feature ? { feature: feature.name } : {}),\n specs: specs.map((s) => s.id),\n gates: gates.map(({ gate, passed, skipped, detail }) => ({\n gate,\n passed,\n ...(skipped ? { skipped } : {}),\n detail,\n })),\n produces: stage.produces.flatMap((t) => this.expand(t, feature, specs)),\n ok,\n forced:\n ok && force && diagnostics.some((d) => d.severity === \"warning\" && FORCED.has(d.code)),\n changes: ok ? changes : [],\n diagnostics: sortDiagnostics(diagnostics),\n };\n }\n}\n\nconst FORCED = new Set([\"CS0701\", \"CS0702\", \"CS0705\"]);\n\n/** Open checkboxes (`- [ ]`) in a Markdown file, outside code fences. */\nexport function openCheckboxes(markdown: string): number {\n let fenced = false;\n let count = 0;\n for (const line of markdown.split(/\\r?\\n/)) {\n if (/^\\s*(```|~~~)/.test(line)) fenced = !fenced;\n else if (!fenced && /^\\s*(?:[-*+]|\\d+[.)])\\s+\\[ \\]/.test(line)) count++;\n }\n return count;\n}\n\nexport interface StageInfo {\n id: string;\n per: Stage[\"per\"];\n driver: Driver;\n /** The driver in words: \"skill sdd-plan\", \"slash command /opsx:apply\". */\n driverText: string;\n start: { gates: string[]; status?: SpecStatus };\n finish: { gates: string[]; status?: SpecStatus };\n}\n\nexport const describeStage = (stage: Stage): StageInfo => ({\n id: stage.id,\n per: stage.per,\n driver: stage.driver,\n driverText: driverText(stage.driver),\n start: {\n gates: stage.start.gates.map(gateName),\n ...(stage.start.status ? { status: stage.start.status } : {}),\n },\n finish: {\n gates: stage.finish.gates.map(gateName),\n ...(stage.finish.status ? { status: stage.finish.status } : {}),\n },\n});\n\nexport interface ItemPosition {\n spec: string;\n status: SpecStatus;\n /** Its current stage; absent when it went through every stage. */\n stage?: string;\n /** ready: can start; waiting: on dependencies not implemented yet. */\n state: \"ready\" | \"waiting\" | \"in-progress\" | \"done\";\n waitingOn: string[];\n}\n\nexport interface FeaturePosition {\n feature: string;\n dir: string;\n /** The current stage; absent when the feature went through every stage. */\n stage?: Stage;\n /** Each work item's stage, while the current stage runs per spec. */\n items: ItemPosition[];\n}\n\nexport interface NextStep {\n target: string;\n feature?: string;\n /** Every stage is done. */\n done: boolean;\n stage?: StageInfo;\n /** Files to read first: the earlier stages' artifacts, the work items, extra context. */\n inputs?: string[];\n /** Files the stage must leave behind. */\n produces?: string[];\n items: ItemPosition[];\n}\n\nexport interface StatusChange {\n spec: string;\n file: string;\n from: SpecStatus;\n to: SpecStatus;\n /** The spec file with the new status. */\n text: string;\n}\n\nexport interface StageRun {\n phase: Phase;\n stage: StageInfo;\n target: string;\n feature?: string;\n specs: string[];\n gates: { gate: string; passed: boolean; skipped?: boolean; detail: string }[];\n produces: string[];\n /** No errors: the stage may start or finish. */\n ok: boolean;\n /** `--force` let failing gates or the order through. */\n forced: boolean;\n /** Status changes to write (none unless `ok`). */\n changes: StatusChange[];\n diagnostics: Diagnostic[];\n}\n\n/**\n * Writes a stage run's status changes, and logs a forced run in the runtime store\n * (`<git-common-dir>/catspec/workflow-overrides.log`, ADR-004).\n */\nexport async function writeStage(root: string, run: StageRun, now = new Date()): Promise<void> {\n for (const change of run.changes) await writeFile(join(root, change.file), change.text, \"utf8\");\n if (!run.forced) return;\n const common = findGitCommonDir(root);\n if (!common) return;\n const dir = join(common, \"catspec\");\n await mkdir(dir, { recursive: true });\n const entry = {\n at: now.toISOString(),\n phase: run.phase,\n stage: run.stage.id,\n target: run.target,\n overridden: run.diagnostics\n .filter((d) => FORCED.has(d.code))\n .map((d) => `${d.code} ${d.message}`),\n };\n await appendFile(join(dir, \"workflow-overrides.log\"), `${JSON.stringify(entry)}\\n`, \"utf8\");\n}\n\n/**\n * Runs a `command:` gate without a shell (ADR-009). On Windows the program is looked up with\n * PATHEXT; a batch script (`.cmd`, `.bat`, e.g. an npm shim) can't start without a shell, so the\n * gate fails with a message saying so.\n */\nexport function runCommand(\n root: string,\n args: string[],\n timeoutMs = 10 * 60_000,\n platform: NodeJS.Platform = process.platform,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<{ exitCode: number; output: string }> {\n const [file, ...rest] = args;\n const found = platform === \"win32\" ? findProgram(file!, root, env, platform) : undefined;\n if (found && isBatchScript(found)) {\n return Promise.resolve({\n exitCode: 1,\n output:\n `${file} is the batch script ${found}, which CatSpec can't start without a shell ` +\n \"(ADR-009); run the command yourself, or point the gate at the program it wraps\",\n });\n }\n return new Promise((resolve) => {\n execFile(\n found ?? file!,\n rest,\n { cwd: root, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024, windowsHide: true },\n (error, stdout, stderr) => {\n const output = `${stdout}${stderr}`.trim().split(/\\r?\\n/).slice(-20).join(\"\\n\");\n const code = error ? (typeof error.code === \"number\" ? error.code : 1) : 0;\n resolve({ exitCode: code, output: error && !output ? error.message : output });\n },\n );\n });\n}\n","/**\n * `catspec workflow doctor`, `workflow snippet` and preset detection (plan §D17.3, §D17.5), PBIs\n * `workflow-cli`, `workflow-presets` and `workflow-hook`: checks that the workflow fits the\n * repository, prints the lines to paste into a skill, finds an existing SDD workflow for\n * `catspec init`, and the final gates the pre-commit hook re-checks (CS0703).\n */\nimport { existsSync, readdirSync, statSync } from \"node:fs\";\nimport { delimiter, isAbsolute, join } from \"node:path\";\n\nimport { LineCounter, parseDocument } from \"yaml\";\n\nimport {\n createDiagnostic,\n sortDiagnostics,\n type Diagnostic,\n type Location,\n} from \"../diagnostics.js\";\nimport type { SpecModel } from \"../load.js\";\nimport { locate } from \"../schema-issues.js\";\nimport type { Spec } from \"../spec.js\";\nimport { testCommandArgs } from \"../check.js\";\nimport { listOf } from \"../util.js\";\nimport {\n gateName,\n SDD_SKILLS,\n type BuiltinGate,\n type PresetName,\n type Stage,\n type Transition,\n type WorkflowProfile,\n} from \"./schema.js\";\n\n/** Where a `workflow.stages[i]` key is in the config file, when the config lists the stages. */\nfunction configLocator(\n configFile: { path: string; text: string } | undefined,\n): (path: (string | number)[]) => Location | undefined {\n if (!configFile) return () => undefined;\n const lineCounter = new LineCounter();\n const doc = parseDocument(configFile.text, { lineCounter });\n return (path) => {\n if (!doc.hasIn([\"workflow\", ...path.slice(0, 2)])) return undefined;\n const range = locate(doc, [\"workflow\", ...path]);\n if (!range) return undefined;\n const { line, col } = lineCounter.linePos(range.start);\n return { file: configFile.path, line, column: col };\n };\n}\n\n/**\n * Where a program is: a path (relative to `root`), or the first match on PATH, with the PATHEXT\n * extensions on Windows. Undefined when it isn't found.\n */\nexport function findProgram(\n name: string,\n root: string,\n env: NodeJS.ProcessEnv = process.env,\n platform: NodeJS.Platform = process.platform,\n): string | undefined {\n if (name.includes(\"/\") || name.includes(\"\\\\\")) {\n const path = isAbsolute(name) ? name : join(root, name);\n return existsSync(path) ? path : undefined;\n }\n const extensions =\n platform === \"win32\"\n ? [\"\", ...(env.PATHEXT ?? \".EXE;.CMD;.BAT;.COM\").split(\";\").map((e) => e.toLowerCase())]\n : [\"\"];\n const dirs = (env.PATH ?? env.Path ?? \"\").split(delimiter).filter(Boolean);\n for (const dir of dirs) {\n for (const ext of extensions) {\n const file = join(dir, name + ext);\n try {\n if (statSync(file).isFile()) return file;\n } catch {\n // not here\n }\n }\n }\n return undefined;\n}\n\n/** True when `name` is a program on PATH (or a path to a file). */\nexport const onPath = (name: string, root: string, env: NodeJS.ProcessEnv = process.env): boolean =>\n findProgram(name, root, env) !== undefined;\n\n/**\n * A Windows batch script (`.cmd`, `.bat`, e.g. an npm shim): Node can't start one without a\n * shell, and CatSpec runs commands without one (ADR-009).\n */\nexport const isBatchScript = (path: string): boolean => /\\.(cmd|bat)$/i.test(path);\n\n/** Where agent skills usually live: Claude Code's folder, then the one shared by all agents. */\nexport const SKILL_DIRS = [\".claude/skills\", \".agents/skills\"] as const;\n\n/** The `sdd-*` skill folders of a skills folder, sorted. */\nconst sddSkillsIn = (root: string, skillsDir: string): string[] => {\n const dir = join(root, skillsDir);\n return existsSync(dir)\n ? readdirSync(dir)\n .filter((n) => n.startsWith(\"sdd-\"))\n .sort()\n : [];\n};\n\n/** The first of `SKILL_DIRS` with `sdd-*` skills, and those skills. */\nexport function findSddSkills(root: string): { skillsDir: string; skills: string[] } | undefined {\n for (const skillsDir of SKILL_DIRS) {\n const skills = sddSkillsIn(root, skillsDir);\n if (skills.length > 0) return { skillsDir, skills };\n }\n return undefined;\n}\n\n/**\n * The SDD workflow a repository already uses, by what is on disk (plan §D17.3). `sdd-*` skills\n * are looked for in `skillsDir`, or in each of `SKILL_DIRS` without it.\n */\nexport function detectPreset(root: string, skillsDir?: string): PresetName | undefined {\n if (existsSync(join(root, \"openspec\"))) return \"openspec\";\n if (existsSync(join(root, \".specify\"))) return \"spec-kit\";\n const found = skillsDir ? sddSkillsIn(root, skillsDir).length > 0 : findSddSkills(root);\n return found ? \"custom\" : undefined;\n}\n\n/** The skill file a `skill:` driver needs. */\nexport const skillFile = (profile: WorkflowProfile, name: string): string =>\n `${profile.skillsDir}/${name}/SKILL.md`;\n\n/**\n * `catspec workflow doctor`: every skill exists (CS0704), every command is on PATH (CS0704), and\n * the preset matches the repository (CS0700 warnings).\n */\nexport function workflowDoctor(\n root: string,\n profile: WorkflowProfile,\n options: { configFile?: { path: string; text: string }; env?: NodeJS.ProcessEnv } = {},\n): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const at = configLocator(options.configFile);\n const location = (path: (string | number)[]) => {\n const found = at(path);\n return found ? { specLocation: found } : {};\n };\n for (const [index, stage] of profile.stages.entries()) {\n const driver = stage.driver;\n if (driver.kind === \"skill\") {\n const file = skillFile(profile, driver.name);\n if (!existsSync(join(root, file))) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...location([\"stages\", index, \"driver\", \"skill\"]),\n message: `stage \"${stage.id}\": skill ${driver.name} not found; expected ${file}`,\n expected: file,\n actual: driver.name,\n suggestions: [\n {\n message: `create ${file}, fix the skill name, or set workflow.skills_dir in catspec.yaml`,\n },\n ],\n }),\n );\n }\n } else if (driver.kind === \"command\") {\n const program = testCommandArgs(driver.command)[0]!;\n if (!onPath(program, root, options.env)) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...location([\"stages\", index, \"driver\", \"command\"]),\n message: `stage \"${stage.id}\": command ${program} is not installed (not on PATH)`,\n actual: program,\n suggestions: [{ message: `install ${program}, or change the stage's driver` }],\n }),\n );\n }\n }\n for (const phase of [\"start\", \"finish\"] as const) {\n for (const [g, gate] of stage[phase].gates.entries()) {\n if (typeof gate === \"string\") continue;\n const program = testCommandArgs(gate.command)[0]!;\n const found = findProgram(program, root, options.env);\n if (found && process.platform === \"win32\" && isBatchScript(found)) {\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n severity: \"warning\",\n ...location([\"stages\", index, phase, \"gates\", g]),\n message: `stage \"${stage.id}\": the ${phase} gate \\`${gate.command}\\` would start ${found}, a batch script, which CatSpec can't run without a shell; run the command yourself`,\n actual: found,\n }),\n );\n continue;\n }\n if (found) continue;\n diagnostics.push(\n createDiagnostic(\"CS0704\", {\n ...(profile.allowCommands ? {} : { severity: \"warning\" as const }),\n ...location([\"stages\", index, phase, \"gates\", g]),\n message: `stage \"${stage.id}\": the ${phase} gate \\`${gate.command}\\` needs ${program}, which is not installed (not on PATH)`,\n actual: program,\n suggestions: [{ message: `install ${program}, or remove the gate` }],\n }),\n );\n }\n }\n }\n\n const detected = detectPreset(root, profile.skillsDir);\n const expected: Partial<Record<PresetName, string>> = {\n openspec: \"openspec/\",\n \"spec-kit\": \".specify/\",\n };\n const folder = expected[profile.preset];\n if (folder && !existsSync(join(root, folder))) {\n diagnostics.push(\n createDiagnostic(\"CS0700\", {\n severity: \"warning\",\n ...location([\"preset\"]),\n message: `workflow.preset is ${profile.preset}, but the repository has no ${folder} folder`,\n expected: folder,\n suggestions: [{ message: `set up ${profile.preset}, or change workflow.preset` }],\n }),\n );\n } else if (detected && detected !== profile.preset && profile.preset === \"catspec\") {\n diagnostics.push(\n createDiagnostic(\"CS0700\", {\n severity: \"warning\",\n ...location([\"preset\"]),\n message: `the repository looks like it uses ${detected === \"custom\" ? \"sdd-* skills\" : detected}, but workflow.preset is catspec`,\n actual: detected,\n suggestions: [{ message: `set workflow.preset: ${detected} in catspec.yaml` }],\n }),\n );\n }\n return sortDiagnostics(diagnostics);\n}\n\n/** `<feature>` or `<spec-id>`: what a stage command is run for. */\nconst targetWord = (stage: Stage): string => (stage.per === \"spec\" ? \"<spec-id>\" : \"<feature>\");\n\n/** True when a stage writes the machine specs (`*.spec.md`), so its agent writes the contract. */\nexport const writesSpecs = (stage: Stage): boolean =>\n stage.produces.some((p) => p.endsWith(\".spec.md\")) ||\n stage.finish.gates.includes(\"contracts_declared\");\n\n/**\n * How the agent of a stage that writes the machine specs writes them: CatSpec never calls an AI,\n * so the spec-writing skill or prompt says what goes into `<spec-id>.spec.md`.\n */\nexport const SPEC_WRITING_STEP =\n \"Next to the feature's spec, write `<spec-id>.spec.md`: in its YAML header, list as `bindings` \" +\n \"every class, interface and method this feature adds or changes, and under `rules` what must \" +\n \"stay true. `catspec guide spec-format` and `catspec guide rules` show the format; for a class \" +\n \"that already exists, `catspec bind <ClassName> --spec <spec-id>` writes its contract.\";\n\n/** `catspec workflow snippet <stage>`: the lines to paste into the stage's skill. */\nexport function stageSnippet(stage: Stage): string {\n const target = targetWord(stage);\n return [\n `First run \\`catspec stage start ${stage.id} ${target}\\`. If it fails, stop and report what it says.`,\n ...(writesSpecs(stage) ? [SPEC_WRITING_STEP] : []),\n `End with \\`catspec stage finish ${stage.id} ${target}\\` and fix everything it reports until it passes.`,\n ].join(\"\\n\");\n}\n\n/**\n * The steps of the `AGENTS.md` block (plan §D14.3) for this workflow: the stage that puts a work\n * item in progress, then the commands that finish it up to `implemented`.\n */\nexport function agentSteps(profile: WorkflowProfile): { begin: string; end: string[] } {\n const stages = profile.stages;\n const work = stages.findIndex(\n (s) => s.start.status === \"in-progress\" || s.finish.status === \"in-progress\",\n );\n if (work < 0) {\n return { begin: \"catspec status <id> in-progress\", end: [\"catspec status <id> implemented\"] };\n }\n const workStage = stages[work]!;\n const target = (s: Stage) => (s.per === \"spec\" ? \"<id>\" : \"<feature>\");\n const begin =\n workStage.start.status === \"in-progress\"\n ? `catspec stage start ${workStage.id} ${target(workStage)}`\n : `catspec stage finish ${workStage.id} ${target(workStage)}`;\n const end: string[] = [];\n for (const stage of stages.slice(work)) {\n if (stage !== workStage && (stage.start.gates.length > 0 || stage.start.status)) {\n end.push(`catspec stage start ${stage.id} ${target(stage)}`);\n }\n if (stage.finish.gates.length > 0 || stage.finish.status) {\n end.push(`catspec stage finish ${stage.id} ${target(stage)}`);\n }\n if (stageSetsImplemented(stage)) break;\n }\n return { begin, end };\n}\n\nconst stageSetsImplemented = (stage: Stage): boolean =>\n stage.start.status === \"implemented\" || stage.finish.status === \"implemented\";\n\n/**\n * The final gates (plan §D17.5): those of the transition that sets `implemented`, else the last\n * stage's finish gates.\n */\nexport function finalGates(\n profile: WorkflowProfile,\n): { stage: Stage; transition: Transition } | undefined {\n for (const stage of [...profile.stages].reverse()) {\n if (stage.finish.status === \"implemented\") return { stage, transition: stage.finish };\n if (stage.start.status === \"implemented\") return { stage, transition: stage.start };\n }\n const last = profile.stages.at(-1);\n return last ? { stage: last, transition: last.finish } : undefined;\n}\n\n/** Gates the hook can decide from a check it already ran (never `command:` or file lookups). */\nconst HOOK_GATES = new Set<BuiltinGate>([\n \"specs_valid\",\n \"contracts_pass\",\n \"tasks_done\",\n \"no_drift\",\n \"deps_known\",\n \"contracts_declared\",\n]);\n\n/**\n * CS0703 for the pre-commit hook (`workflow.enforce_in_hook`): `implemented` specs among `specs`\n * that no longer pass their final stage's built-in gates, decided from the diagnostics the staged\n * check computed. `command:` gates never run here.\n */\nexport function hookWorkflowDiagnostics(\n model: SpecModel,\n profile: WorkflowProfile,\n specs: readonly Spec[],\n diagnostics: readonly Diagnostic[],\n): Diagnostic[] {\n if (profile.enforceInHook === \"off\") return [];\n const final = finalGates(profile);\n if (!final) return [];\n const severity = profile.enforceInHook === \"error\" ? \"error\" : \"warning\";\n const out: Diagnostic[] = [];\n for (const spec of specs) {\n if (spec.status !== \"implemented\" || !spec.valid || spec.type === \"architecture\") continue;\n const own = diagnostics.filter((d) => d.spec === spec.id);\n const failed: string[] = [];\n for (const gate of final.transition.gates) {\n if (typeof gate !== \"string\" || !HOOK_GATES.has(gate)) continue;\n const passes = (() => {\n switch (gate) {\n case \"specs_valid\":\n return !model.diagnostics.some((d) => d.spec === spec.id && d.severity === \"error\");\n case \"contracts_pass\":\n return !own.some((d) => d.severity === \"error\");\n case \"tasks_done\":\n return spec.body.tasks.every((t) => t.done);\n case \"no_drift\":\n return !own.some((d) => d.code === \"CS0300\" && d.severity !== \"info\");\n case \"deps_known\":\n return spec.dependsOn.every((d) => model.specs.get(d));\n default:\n return (\n spec.aggregate ||\n spec.bindings.length > 0 ||\n spec.rules.some((r) => r.class !== \"manual\")\n );\n }\n })();\n if (!passes) failed.push(gateName(gate));\n }\n if (failed.length === 0) continue;\n out.push(\n createDiagnostic(\"CS0703\", {\n severity,\n spec: spec.id,\n specLocation: { file: spec.file, line: 1, column: 1 },\n message: `\"${spec.id}\" is implemented but no longer passes the ${final.stage.id} gates: ${listOf(failed)}`,\n expected: final.transition.gates.map(gateName),\n actual: failed,\n suggestions: [\n { message: \"fix the code or the spec, or move the spec back to in-progress\" },\n ],\n }),\n );\n }\n return out;\n}\n\n/**\n * The `feature_dir:` line `catspec init` writes, with a commented example of a list, for features\n * at several depths (domain folders). The example is a comment, so it never names a missing folder.\n */\nexport const featureDirYaml = (featureDir: string): string =>\n [\n \" # Where features live. A list for features at several depths, e.g.\",\n ` # feature_dir: [\"${featureDir.replace(\"{feature}\", \"billing/{feature}\")}\", \"${featureDir}\"]`,\n ` feature_dir: \"${featureDir}\"`,\n ].join(\"\\n\");\n\n/**\n * The `custom` preset's stages as YAML, for `catspec init` (plan §D17.2). Each stage uses the\n * repository's skill of its name (`sdd-task`, or the plural `sdd-tasks`) from `skills`; a stage\n * without one gets a manual driver, so the new config passes `catspec workflow doctor`.\n */\nexport const customWorkflowYaml = (\n skills: readonly string[] = SDD_SKILLS,\n skillsDir = \".claude/skills\",\n): string => {\n const driver = (name: string): string => {\n const skill = skills.find((s) => s === name || s === `${name}s`);\n return skill\n ? ` driver: { skill: ${skill} }`\n : ` driver: manual # no ${name} skill found; name your skill here: { skill: <name> }`;\n };\n return [\n \"workflow:\",\n \" preset: custom\",\n featureDirYaml(\"docs/spec/{feature}\"),\n ` skills_dir: \"${skillsDir}\" # where \\`skill:\\` drivers are found`,\n \" stages:\",\n \" - id: spec\",\n \" per: feature\",\n driver(SDD_SKILLS[0]),\n ' produces: [\"{feature_dir}/spec.md\", \"{feature_dir}/*.spec.md\"]',\n \" finish: { gates: [specs_valid, artifacts, contracts_declared] }\",\n \" - id: plan\",\n \" per: feature\",\n driver(SDD_SKILLS[1]),\n ' produces: [\"{feature_dir}/plan.md\"]',\n \" finish: { gates: [artifacts, deps_known], status: ready }\",\n \" - id: task\",\n \" per: spec\",\n driver(SDD_SKILLS[2]),\n \" start: { gates: [deps_ready], status: in-progress }\",\n \" finish: { gates: [contracts_pass] }\",\n \" - id: close\",\n \" per: spec\",\n driver(SDD_SKILLS[3]),\n \" finish: { gates: [contracts_pass, tasks_done, no_drift], status: implemented }\",\n \"\",\n ].join(\"\\n\");\n};\n","/**\n * Plain-text answers of the workflow commands (plan §D17.5), shared by the CLI and the MCP server\n * so both say the same thing: `catspec next` / `next_step` and `catspec stage` / `start_stage`,\n * `finish_stage`.\n */\nimport { listOf } from \"../util.js\";\nimport type { ItemPosition, NextStep, StageInfo, StageRun } from \"./engine.js\";\n\nconst gatesText = (gates: string[]): string => (gates.length > 0 ? listOf(gates) : \"none\");\n\n/** The stage's driver, gates and status changes, one per line. */\nexport function stageLines(stage: StageInfo): string[] {\n return [\n ` driver: ${stage.driverText}`,\n ` start gates: ${gatesText(stage.start.gates)}${stage.start.status ? ` → ${stage.start.status}` : \"\"}`,\n ` finish gates: ${gatesText(stage.finish.gates)}${stage.finish.status ? ` → ${stage.finish.status}` : \"\"}`,\n ];\n}\n\nconst itemLine = (item: ItemPosition): string => {\n switch (item.state) {\n case \"ready\":\n return ` ready: ${item.spec} → stage ${item.stage}`;\n case \"in-progress\":\n return ` in progress: ${item.spec} → stage ${item.stage}`;\n case \"waiting\":\n return ` waiting: ${item.spec} (on ${listOf(item.waitingOn)})`;\n case \"done\":\n return ` done: ${item.spec}`;\n }\n};\n\n/** `catspec next`: the current stage, how to run it, and each work item. */\nexport function formatNextStep(next: NextStep, driverFor?: (stage: string) => string): string {\n const lines: string[] = [];\n if (next.done || !next.stage) {\n lines.push(`${next.target}: every stage is done`);\n } else {\n const stage = next.stage;\n lines.push(`${next.target}: stage ${stage.id} (per ${stage.per}), use ${stage.driverText}`);\n lines.push(...stageLines(stage).slice(1));\n if (next.inputs && next.inputs.length > 0) lines.push(` read: ${listOf(next.inputs)}`);\n if (next.produces && next.produces.length > 0) {\n lines.push(` produce: ${listOf(next.produces)}`);\n }\n if (stage.per === \"feature\") {\n lines.push(\n ` run \\`catspec stage start ${stage.id} ${next.target}\\` first and ` +\n `\\`catspec stage finish ${stage.id} ${next.target}\\` at the end`,\n );\n }\n }\n if (next.items.length > 0) {\n lines.push(\"work items:\");\n for (const item of next.items) {\n const driver = item.stage && driverFor ? `, use ${driverFor(item.stage)}` : \"\";\n lines.push(\n itemLine(item) + (item.state === \"ready\" || item.state === \"in-progress\" ? driver : \"\"),\n );\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** `catspec stage start|finish`: the stage's context and each gate's result. */\nexport function formatStageRun(run: StageRun): string {\n const lines = [\n `stage ${run.stage.id} ${run.phase} for ${run.target}` +\n (run.specs.length > 0 ? ` (${listOf(run.specs)})` : \"\"),\n ` driver: ${run.stage.driverText}`,\n ];\n if (run.produces.length > 0) lines.push(` produce: ${listOf(run.produces)}`);\n for (const gate of run.gates) {\n const mark = gate.skipped ? \"-\" : gate.passed ? \"✔\" : \"✖\";\n lines.push(` ${mark} ${gate.gate}: ${gate.detail.split(\"\\n\").join(\"\\n \")}`);\n }\n if (run.gates.length === 0) lines.push(` no ${run.phase} gates`);\n for (const change of run.changes) lines.push(` ${change.spec}: ${change.from} → ${change.to}`);\n if (run.phase === \"start\" && run.ok) {\n const finish = run.stage.finish.gates;\n lines.push(\n ` when done run \\`catspec stage finish ${run.stage.id} ${run.target}\\`` +\n (finish.length > 0 ? ` (gates: ${listOf(finish)})` : \"\"),\n );\n }\n lines.push(\n run.ok\n ? run.forced\n ? `${run.phase === \"start\" ? \"started\" : \"finished\"} with --force (the override is logged)`\n : run.phase === \"start\"\n ? \"started\"\n : \"finished\"\n : `refused: the stage can't ${run.phase}`,\n );\n return `${lines.join(\"\\n\")}\\n`;\n}\n","/** Package name. */\nexport const packageName = \"@catspec/core\";\n\nexport * from \"./diagnostics.js\";\nexport * from \"./config.js\";\nexport * from \"./facts.js\";\nexport * from \"./match.js\";\nexport {\n codeLocation,\n formatLocation,\n SymbolTable,\n type Codebase,\n type SymbolEntry,\n} from \"./codebase.js\";\nexport {\n inModule,\n resolveBinding,\n splitSymbol,\n type BindingResolution,\n type ResolvedBinding,\n} from \"./resolve.js\";\nexport { attributeMatches, bindingItems, evaluateContract, signatureText } from \"./contracts.js\";\nexport { calleeNames, evaluateRule, importTargets, type TestRun } from \"./rules.js\";\nexport {\n checkCode,\n isEnforced,\n queryDiagnostics,\n runTestCommand,\n statusGate,\n testCommandArgs,\n type CheckMode,\n type CheckOptions,\n type CheckResult,\n type ItemResult,\n type StatusGate,\n} from \"./check.js\";\nexport {\n Git,\n GitError,\n GitUnavailableError,\n type StagedChange,\n type TreeEntry,\n} from \"./git/git.js\";\nexport {\n IndexProvider,\n RevisionProvider,\n WorkingTreeProvider,\n type SourceEntry,\n type SourceProvider,\n} from \"./git/providers.js\";\nexport {\n applyLock,\n fingerprintOf,\n hasLockFile,\n itemHashes,\n lockedFiles,\n lockPathOf,\n nextLock,\n parseLock,\n serializeLock,\n shapeOf,\n specHash,\n type LockCheckOptions,\n type LockedSymbol,\n type LockFile,\n type NextLockOptions,\n type Shape,\n} from \"./lock.js\";\nexport { stagedDiagnostics, stagedScope, type StagedScope } from \"./staged.js\";\nexport { coverage, type CoverageReport, type Ratio, type SpecCoverage } from \"./coverage.js\";\nexport {\n frontmatterLocation,\n parseSpecSource,\n splitFrontmatter,\n withFrontmatter,\n type SpecSource,\n type SplitSource,\n} from \"./frontmatter.js\";\nexport * from \"./spec-schema.js\";\nexport * from \"./spec-body.js\";\nexport { readSpec, specLocation, type ReadSpecOptions, type Spec } from \"./spec.js\";\nexport { DependencyGraph } from \"./graph.js\";\nexport {\n architectureMatcher,\n isArchitectureSpecText,\n loadSpecModel,\n plainAdrIds,\n sameAdrId,\n SpecSet,\n type SpecModel,\n} from \"./load.js\";\nexport {\n applyPatch,\n classifyOp,\n classifyPatch,\n editYaml,\n readYaml,\n SpecEditError,\n type EditClass,\n} from \"./spec-editor.js\";\nexport { formatPath } from \"./schema-issues.js\";\nexport {\n didYouMean,\n gitBlobSha,\n globMatcher,\n isListedPath,\n kebabCase,\n listFiles,\n LineIndex,\n relativePosix,\n toPosix,\n} from \"./util.js\";\nexport {\n baselineFromLock,\n baselineFromSymbol,\n bodyTokens,\n detectRenames,\n jaccard,\n memberNames,\n nameFreeFingerprint,\n renameScore,\n splitResolved,\n tokenSimilarity,\n type Ambiguity,\n type BaselineSymbol,\n type Evidence,\n type Lost,\n type Mapping,\n type RenameInput,\n type RenameMap,\n type RenameReport,\n type ScoredCandidate,\n} from \"./rename.js\";\nexport {\n editPatch,\n planSync,\n rewriteSymbol,\n type SpecEdit,\n type SyncOptions,\n type SyncPlan,\n} from \"./sync.js\";\nexport * from \"./workflow/schema.js\";\nexport * from \"./workflow/engine.js\";\nexport * from \"./workflow/doctor.js\";\nexport * from \"./workflow/format.js\";\n"],"mappings":"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","names":["key","join","z","text","_","key","z","key","text","stage","text","join","escapeRegExp","text","isMap","parseDocument","text","lineStart","parseDocument","text","text","extra","isMap","key","id","key","text","item","declared","key","nameMatches","files","createHash","posix","posix","createHash","attributeText","text","key","isoDate","execFile","resolve","record","stage","key","text","readFile","join","readFile","join","declared","enforceable","key","readFile","join","posix","specFiles","text","posix","readFile","join","isMap","isScalar","isSeq","parseDocument","visit","key","isMap","list","isSeq","text","parseDocument","isScalar","visit","item","createHash","sha256","createHash","text","sep","key","name","posix","specId","text","posix","execFile","join","existsSync","statSync","join","LineCounter","parseDocument","LineCounter","parseDocument","join","existsSync","statSync","stage","stage","key","template","unknown","text","transition","feature","item","join","resolve","execFile","stage"]}