@hawkeyexl/manni 1.1.0 → 2.0.0

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../package.json","../src/shared/collections.ts","../src/shared/globs.ts","../src/shared/errors.ts","../src/meta/types.ts","../src/meta/core/write-file.ts","../src/shared/program-name.ts","../src/meta/core/schema-cache.ts","../src/meta/core/integrity.ts","../src/meta/core/schema-registry.ts","../src/meta/core/json-text.ts","../src/meta/schemas/okf/0.1.json","../src/meta/schemas/diataxis/1.0.json","../src/meta/schemas/seven-action/1.0.json","../src/meta/schemas/tgdp/1.0.json","../src/meta/schemas/docusaurus-docs/3.10.json","../src/meta/schemas/docusaurus-blog/3.10.json","../src/meta/schemas/docusaurus-pages/3.10.json","../src/meta/schemas/starlight/0.41.json","../src/meta/schemas/antora/3.1.json","../src/meta/schemas/sphinx/9.1.json","../src/meta/schemas/myst/1.10.json","../src/meta/schemas/ogp/1.0.json","../src/meta/schemas/dcmi/1.1.json","../src/meta/schemas/microsoft-learn/1.0.json","../src/meta/schemas/dita/1.3.json","../src/meta/schemas/hugo/0.165.json","../src/meta/schemas/jekyll/4.4.json","../src/meta/schemas/vitepress/1.6.json","../src/meta/schemas/x-cards/1.0.json","../src/meta/schemas/agent-skills/1.0.json","../src/meta/schemas/claude-skill/2.1.json","../src/meta/schemas/mkdocs-material/9.7.json","../src/meta/schemas/claude-subagent/2.1.json","../src/meta/core/resolve-schema.ts","../src/meta/core/external-metadata-fetch.ts","../src/meta/extractors/frontmatter.ts","../src/meta/extractors/date-value.ts","../src/meta/extractors/pointer.ts","../src/meta/extractors/frontmatter-write.ts","../src/meta/extractors/patch-util.ts","../src/meta/extractors/markdown.ts","../src/meta/extractors/mdx.ts","../src/meta/extractors/asciidoc.ts","../src/meta/extractors/rst.ts","../src/meta/extractors/xml-read.ts","../src/meta/extractors/element-key.ts","../src/meta/extractors/dita.ts","../src/meta/extractors/xml-write.ts","../src/meta/extractors/xml-locate.ts","../src/meta/extractors/element-write.ts","../src/meta/extractors/dita-write.ts","../src/meta/extractors/xml.ts","../src/meta/extractors/html-read.ts","../src/meta/extractors/html-write.ts","../src/meta/extractors/html.ts","../src/meta/extractors/index.ts","../src/meta/core/external-metadata.ts","../src/meta/core/load-files.ts","../src/meta/core/gitignore.ts","../src/shared/git-root.ts","../src/meta/core/derive/types.ts","../src/meta/core/config.ts","../src/shared/config-file.ts","../src/shared/warn.ts","../src/meta/core/collections.ts","../src/meta/core/projection.ts","../src/meta/core/validator.ts","../src/meta/core/derive/cache.ts","../src/meta/core/derive/spawn.ts","../src/meta/core/derive/command.ts","../src/meta/core/derive/reviews.ts","../src/meta/core/derive/index.ts","../src/meta/core/derive/codeowners.ts","../src/meta/core/derive/git.ts","../src/meta/core/derive/config.ts","../src/meta/core/derive/table.ts","../src/meta/commands/validate.ts","../src/meta/core/baseline.ts","../src/meta/core/checks.ts","../src/meta/commands/get.ts","../src/meta/commands/schemas.ts","../src/meta/commands/query.ts","../src/meta/commands/fill.ts","../src/meta/commands/fill-prompt.ts","../src/meta/commands/derive.ts","../src/meta/reporters/sarif.ts","../src/meta/reporters/rule-id.ts","../src/meta/reporters/junit.ts","../src/shared/color.ts","../src/shared/github.ts","../src/meta/reporters/index.ts","../src/meta/reporters/fill.ts","../src/meta/reporters/derive.ts","../src/meta/reporters/get.ts","../src/meta/reporters/query.ts"],"sourcesContent":["{\n \"name\": \"@hawkeyexl/manni\",\n \"version\": \"1.1.0\",\n \"description\": \"One command line for documentation that is meant to be checked. `manni meta` validates the presence and format of document metadata (Markdown frontmatter and more) against JSON Schema, built for CI. Formerly docmeta.\",\n \"type\": \"module\",\n \"bin\": {\n \"manni\": \"dist/cli.js\",\n \"docmeta\": \"dist/docmeta.js\"\n },\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hawkeyexl/manni.git\"\n },\n \"homepage\": \"https://hawkeyexl.github.io/manni/\",\n \"bugs\": {\n \"url\": \"https://github.com/hawkeyexl/manni/issues\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"scripts\": {\n \"prebuild\": \"npm run check:deps\",\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"pretest\": \"npm run check:deps\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"pretypecheck\": \"npm run check:deps\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"check:deps\": \"node scripts/check-deps.mjs\",\n \"query:ui\": \"npm run build && node dist/cli.js meta query --db .manni/meta/query.db && node scripts/query-ui.mjs .manni/meta/query.db\",\n \"docs:check-cli\": \"node scripts/check-cli-reference.mjs\",\n \"docs:check-action\": \"node scripts/check-action-reference.mjs\",\n \"docs:check-api\": \"node scripts/check-api-reference.mjs\",\n \"docs:check-links\": \"node scripts/check-doc-links.mjs\",\n \"docs:check-tables\": \"node scripts/check-table-rows.mjs\",\n \"schemas:sync\": \"node scripts/sync-builtin-schemas.mjs\",\n \"schemas:check\": \"node scripts/check-builtin-schemas.mjs\",\n \"schemas:check-published\": \"node scripts/check-published-schemas.mjs\",\n \"commitlint\": \"commitlint --edit\",\n \"semantic-release\": \"semantic-release\",\n \"prepare\": \"node scripts/prepare.mjs\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"frontmatter\",\n \"metadata\",\n \"json-schema\",\n \"markdown\",\n \"validation\",\n \"cli\",\n \"ci\",\n \"okf\"\n ],\n \"license\": \"MIT\",\n \"overrides\": {\n \"esbuild\": \"^0.28.2\"\n },\n \"dependencies\": {\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@hawkeyexl/inference\": \"^0.3.1\",\n \"@xmldom/xmldom\": \"^0.9.12\",\n \"ajv\": \"^8.17.1\",\n \"ajv-draft-04\": \"^1.0.0\",\n \"ajv-formats\": \"^3.0.1\",\n \"commander\": \"^15.0.0\",\n \"fast-glob\": \"^3.3.2\",\n \"parse5\": \"^8.0.1\",\n \"picocolors\": \"^1.1.1\",\n \"picomatch\": \"^4.0.7\",\n \"playwright-core\": \"^1.63.0\",\n \"smol-toml\": \"^1.8.0\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^21.2.2\",\n \"@commitlint/config-conventional\": \"^21.2.2\",\n \"@eslint/js\": \"^10.0.1\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/commit-analyzer\": \"^13.0.1\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@semantic-release/github\": \"^12.0.8\",\n \"@semantic-release/npm\": \"^13.1.5\",\n \"@semantic-release/release-notes-generator\": \"^14.1.1\",\n \"@types/node\": \"^26.3.0\",\n \"@types/picomatch\": \"^4.0.3\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"eslint\": \"^10.9.1\",\n \"globals\": \"^17.11.0\",\n \"husky\": \"^9.1.7\",\n \"semantic-release\": \"^25.0.9\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.68.0\",\n \"vitest\": \"^4.1.11\"\n }\n}\n","/**\n * `collections:`, the family-level home for document sets (proposal 0041).\n *\n * A collection names a set of documents once, at the top level of\n * `manni.config.yaml`, and every tool reads the same declaration: the metadata\n * tool validates its members, `query` exposes it as a view, and `a11y check`\n * seeds from its `url`. Only the *declaration* is shared. Loading a manifest\n * and merging it into `ExtractedMetadata` stays with the metadata tool,\n * because that type is the metadata tool's.\n *\n * Every refusal in this parser is a shape that would otherwise read as\n * configured and do nothing, or do something nobody can see. The manifest\n * rules are 0037's, moved here unchanged in substance: an entry with no keys\n * owns nothing, one key under two manifests of a collection would need a\n * tiebreak (0020 refuses tiebreaks), and `$schema` from external metadata\n * would let a private file pick the schema a public document is judged by\n * (0015) with the provenance lost at the merge.\n */\nimport picomatch from \"picomatch\";\nimport { matchesFileGlob } from \"./globs.js\";\n\n/** One external-metadata manifest (proposals 0037, 0038, 0039) joined to a collection. */\nexport interface ExternalMetadataConfig {\n file: string;\n keys: string[];\n tokenEnv?: string;\n join?: string;\n}\n\n/** One named document set, as declared under the top-level `collections:` key. */\nexport interface CollectionConfig {\n name: string;\n paths: string[];\n exclude: string[];\n externalMetadata: ExternalMetadataConfig[];\n /** Where the collection is published; `manni a11y check` seeds from it. */\n url?: string;\n}\n\nconst COLLECTION_KEYS = [\n \"name\",\n \"paths\",\n \"exclude\",\n \"url\",\n \"externalMetadata\",\n] as const;\n\nconst EXTERNAL_METADATA_KEYS = [\"file\", \"keys\", \"tokenEnv\", \"join\"] as const;\n\n/**\n * The document-level schema key. The metadata tool spells it\n * `FILE_SCHEMA_KEY` in `src/meta/core/resolve-schema.ts`; the literal is\n * repeated here so the shared layer does not import a tool's module. Keep the\n * two in step.\n */\nconst SCHEMA_KEY = \"$schema\";\n\n/**\n * The label `load-files.ts` gives stdin (`STDIN_LABEL`). Repeated as a literal\n * for the same reason as `SCHEMA_KEY`: the shared layer does not depend on the\n * metadata tool. Stdin has no path, so it is a member of nothing.\n */\nconst STDIN = \"<stdin>\";\n\n/** Is this manifest reference a URL? The `url` branch of `classifyRef`. */\nfunction isUrlRef(ref: string): boolean {\n return /^https?:\\/\\//i.test(ref);\n}\n\n/**\n * Whether a URL may name an external-metadata manifest: `https://` anywhere,\n * or `http://` on a loopback host only, where plaintext leaks nothing.\n * Userinfo is refused because the URL is printed in every diagnostic and a\n * secret in it would print too. Returns the reason it may not, or `null`.\n */\nexport function externalMetadataUrlProblem(url: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"is not a valid URL\";\n }\n if (parsed.username !== \"\" || parsed.password !== \"\") {\n return 'carries a credential in the URL; put the token in an environment variable and name it with \"tokenEnv\"';\n }\n if (parsed.protocol === \"https:\") return null;\n if (parsed.protocol === \"http:\" && isLoopback(parsed.hostname)) return null;\n if (parsed.protocol === \"http:\") {\n return \"is plain http://; a bearer token over plaintext is a leak, and a public manifest is served over https too\";\n }\n return `has the unsupported scheme \"${parsed.protocol}\"`;\n}\n\nfunction isLoopback(host: string): boolean {\n return (\n host === \"localhost\" ||\n host === \"127.0.0.1\" ||\n host === \"[::1]\" ||\n host === \"::1\" ||\n host.startsWith(\"127.\")\n );\n}\n\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n toError: (message: string) => Error,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw toError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\n/**\n * Parse the top-level `collections:` value. Errors are built with `toError`,\n * so each tool reports a bad family file in its own error class.\n */\nexport function parseCollections(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n if (!Array.isArray(raw)) {\n throw toError(`${source}: \"collections\" must be a list.`);\n }\n if (raw.length === 0) {\n throw toError(\n `${source}: \"collections\" must name at least one collection; remove the key if there are none.`,\n );\n }\n // Names become SQL view names, and SQLite compares identifiers without\n // regard to case, so two names that differ only in case are one view.\n const taken = new Map<string, number>();\n return raw.map((entry, i) => {\n const where = `collections[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, COLLECTION_KEYS, where, source, toError);\n\n if (!isNonEmptyString(entry.name)) {\n throw toError(`${source}: ${where}.name must be a non-empty string.`);\n }\n const name = entry.name;\n const folded = name.toLowerCase();\n if (folded === \"docs\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the docs table every query reads. Pick another name, such as \"site\" or \"pages\".`,\n );\n }\n // The derived table (proposal 0040) is a view named `derived` over a\n // backing table named `_derived_rows`, built beside `docs` when a\n // statement asks for it, and `resolved` (proposal 0043) is the view over\n // `docs` and those rows. Any of the three would shadow it the same way.\n if (folded === \"derived\" || folded === \"_derived_rows\" || folded === \"resolved\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the derived table a query builds beside docs (the derived view, its _derived_rows table, and the resolved view over both). Pick another name.`,\n );\n }\n if (folded.startsWith(\"sqlite_\")) {\n throw toError(\n `${source}: ${where}.name \"${name}\" starts with \"sqlite_\", which SQLite reserves for its own objects. Pick another name.`,\n );\n }\n const owner = taken.get(folded);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.name \"${name}\" is already taken by collections[${owner}]; names are compared case-insensitively because they become SQL views.`,\n );\n }\n taken.set(folded, i);\n\n if (\n !Array.isArray(entry.paths) ||\n entry.paths.length === 0 ||\n entry.paths.some((p) => !isNonEmptyString(p))\n ) {\n throw toError(\n `${source}: ${where}.paths must be a non-empty list of files, directories or globs.`,\n );\n }\n const paths = entry.paths as string[];\n\n let exclude: string[] = [];\n if (entry.exclude !== undefined) {\n if (\n !Array.isArray(entry.exclude) ||\n entry.exclude.some((g) => !isNonEmptyString(g))\n ) {\n throw toError(`${source}: ${where}.exclude must be a list of globs.`);\n }\n exclude = entry.exclude as string[];\n }\n\n let url: string | undefined;\n if (entry.url !== undefined) {\n if (typeof entry.url !== \"string\" || !isHttpUrl(entry.url)) {\n throw toError(`${source}: ${where}.url must be an http(s) URL.`);\n }\n url = entry.url;\n }\n\n let externalMetadata: ExternalMetadataConfig[] = [];\n if (entry.externalMetadata !== undefined) {\n if (!Array.isArray(entry.externalMetadata)) {\n throw toError(`${source}: ${where}.externalMetadata must be a list.`);\n }\n externalMetadata = parseExternalMetadata(\n entry.externalMetadata,\n where,\n source,\n toError,\n );\n }\n\n return {\n name,\n paths,\n exclude,\n externalMetadata,\n ...(url === undefined ? {} : { url }),\n };\n });\n}\n\nfunction isHttpUrl(value: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return false;\n }\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n}\n\n/**\n * Parse one collection's `externalMetadata:`. 0037's rules, with the error\n * path rewritten and the noun changed: ownership is now disjoint within a\n * collection rather than across the whole config, because two collections may\n * each own the same key.\n */\nfunction parseExternalMetadata(\n raw: readonly unknown[],\n collectionWhere: string,\n source: string,\n toError: (message: string) => Error,\n): ExternalMetadataConfig[] {\n const owners = new Map<string, number>();\n return raw.map((entry, i) => {\n const where = `${collectionWhere}.externalMetadata[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, EXTERNAL_METADATA_KEYS, where, source, toError);\n if (!isNonEmptyString(entry.file)) {\n throw toError(\n `${source}: ${where}.file must be a non-empty string naming the manifest, relative to the config file.`,\n );\n }\n if (\n !Array.isArray(entry.keys) ||\n entry.keys.length === 0 ||\n entry.keys.some((k) => !isNonEmptyString(k))\n ) {\n throw toError(\n `${source}: ${where}.keys must be a non-empty list of key names.`,\n );\n }\n const isUrl = isUrlRef(entry.file);\n if (isUrl) {\n const problem = externalMetadataUrlProblem(entry.file);\n if (problem !== null) {\n throw toError(`${source}: ${where}.file ${problem}.`);\n }\n }\n if (entry.tokenEnv !== undefined) {\n if (!isNonEmptyString(entry.tokenEnv)) {\n throw toError(\n `${source}: ${where}.tokenEnv must be the name of an environment variable.`,\n );\n }\n if (!isUrl) {\n throw toError(\n `${source}: ${where}.tokenEnv is set, but \"file\" is a path, so no request is made and the token would go nowhere. Remove it, or make \"file\" a URL.`,\n );\n }\n }\n const keys = entry.keys as string[];\n if (entry.join !== undefined) {\n if (!isNonEmptyString(entry.join)) {\n throw toError(\n `${source}: ${where}.join must be \"path\" or the name of a top-level frontmatter field.`,\n );\n }\n if (entry.join === SCHEMA_KEY) {\n throw toError(`${source}: ${where}.join may not be \"${SCHEMA_KEY}\".`);\n }\n if (keys.includes(entry.join)) {\n throw toError(\n `${source}: ${where}.join names \"${entry.join}\", which the same entry owns — the value that selects an entry cannot come from the entry.`,\n );\n }\n }\n const seen = new Set<string>();\n for (const key of keys) {\n if (key === SCHEMA_KEY) {\n throw toError(\n `${source}: ${where}.keys may not include \"${SCHEMA_KEY}\" — a manifest never chooses the schema a document is judged by; use \"overrides\".`,\n );\n }\n if (seen.has(key)) {\n throw toError(`${source}: ${where}.keys lists \"${key}\" twice.`);\n }\n seen.add(key);\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.keys claims \"${key}\", which externalMetadata[${owner}] already owns — a key has exactly one manifest in a collection.`,\n );\n }\n owners.set(key, i);\n }\n return {\n file: entry.file,\n keys,\n ...(typeof entry.tokenEnv === \"string\" ? { tokenEnv: entry.tokenEnv } : {}),\n ...(typeof entry.join === \"string\" ? { join: entry.join } : {}),\n };\n });\n}\n\n/**\n * The collections a run covers: every one when `names` is undefined, else the\n * named ones in **declaration** order, however they were named on the command\n * line. Repeats collapse; an unknown name is an error, because a typo that\n * silently narrowed the run to nothing would read as a clean pass.\n */\nexport function selectCollections(\n collections: readonly CollectionConfig[],\n names: readonly string[] | undefined,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n // An empty list means the same as no list: every collection. Commander's\n // repeatable-option collector defaults to `[]`, so \"the user passed no\n // --collection\" reaches this function as an empty array at least as often as\n // it reaches it as `undefined`. Were `[]` to select nothing, a plain\n // `manni meta validate` would validate zero files and exit 0 the moment a\n // caller forwarded the raw commander value — the false green proposal 0014\n // exists to end, and invisible in the exit code. Nothing needs to express\n // \"select no collections\", so the ambiguity is resolved in the safe\n // direction. Do not tighten this back.\n if (names === undefined || names.length === 0) return [...collections];\n const wanted = new Set(names);\n for (const name of wanted) {\n if (!collections.some((c) => c.name === name)) {\n const configured =\n collections.length === 0\n ? \"(none)\"\n : collections.map((c) => c.name).join(\", \");\n // Names are unique case-insensitively (they become SQL views) but are\n // selected by their one spelling. When the miss is only a casing miss,\n // say so — \"Configured: guides\" beside \"Guides\" reads as a contradiction\n // to anyone who does not already know the rule.\n const nearMiss = collections.find(\n (c) => c.name.toLowerCase() === name.toLowerCase(),\n );\n const hint =\n nearMiss === undefined\n ? \"\"\n : ` Names are case-sensitive; did you mean \"${nearMiss.name}\"?`;\n throw toError(\n `no collection named \"${name}\" in ${source}. Configured: ${configured}.${hint}`,\n );\n }\n }\n return collections.filter((c) => wanted.has(c.name));\n}\n\n/**\n * Is this file a member of the collection? `relPath` is posix and already\n * relative to the config file's directory, so this is arithmetic on a string:\n * no `stat`, nothing that can fail, and nothing that costs per file. A path\n * that climbed out of the config directory, and stdin, are members of nothing.\n */\nexport function isMember(\n collection: CollectionConfig,\n relPath: string,\n): boolean {\n if (relPath === STDIN) return false;\n if (relPath.startsWith(\"../\")) return false;\n const matched = collection.paths.some((entry) => {\n const normalized = normalizeEntry(entry);\n if (normalized === \"\") return false;\n if (isGlob(normalized)) return matchesFileGlob(relPath, normalized);\n return relPath === normalized || relPath.startsWith(`${normalized}/`);\n });\n if (!matched) return false;\n // `exclude` is globs only, whatever `paths` was written as.\n return !collection.exclude.some((glob) => matchesFileGlob(relPath, glob));\n}\n\n/** A `paths` entry as a posix path with no `./` prefix and no trailing `/`. */\nfunction normalizeEntry(entry: string): string {\n const posix = entry.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n return posix.endsWith(\"/\") ? posix.slice(0, -1) : posix;\n}\n\n/**\n * Is this `paths` entry a glob, by picomatch's own definition, rather than a\n * bare file or directory to match by prefix?\n *\n * picomatch decides, not a character class of our own: an extended glob such\n * as `docs/!(drafts)/**` or `@(a|b)` has no `*`, `?`, `[` or `{` of its own\n * and a hand-rolled test read it as a literal path — matching nothing and\n * excluding nothing, silently. The one cost is that a literal directory whose\n * name carries parentheses, `docs/notes (old)`, is also read as a glob and so\n * matches itself only, not everything beneath it. Spell such a path as\n * `docs/notes (old)/**` to get the prefix behaviour back.\n */\nfunction isGlob(entry: string): boolean {\n return picomatch.scan(entry).isGlob;\n}\n","/**\n * Glob matching, shared by every tool.\n *\n * One matcher, so that the two questions that look alike really are alike: is\n * this file in a collection (proposal 0041), and does it match a schema\n * override's `files:` (0015). It lived in the metadata tool's schema resolver\n * until membership needed it too; a second copy is how the two would start\n * disagreeing about a dot file or a `\\`.\n */\nimport picomatch from \"picomatch\";\n\n/**\n * One compiled matcher per distinct glob, kept for the life of the process.\n * Never evicted, on purpose: the set of globs a run sees is the config's plus\n * a handful of flags, which is dozens at most, and a compile is the expensive\n * step. This module is shared across the family, so if it ever sits inside a\n * long-lived host that feeds it unbounded user globs, this is the line to\n * revisit — bound it, or key it per run. Until then an eviction policy would\n * be machinery for a case that does not exist.\n */\nconst matcherCache = new Map<string, (p: string) => boolean>();\n\n/**\n * Does this file path match the glob — or, for the list form, any of them — by\n * the shared rules (picomatch, dot files included, `\\` normalized to `/`)?\n */\nexport function matchesFileGlob(\n relPath: string,\n glob: string | readonly string[],\n): boolean {\n // picomatch takes a pattern array natively, so the list form needs no loop\n // here — but the cache does need a *string* key. Keyed on the array itself\n // this Map would compare by identity: a hit only for the very same object,\n // and an entry retained for every config ever parsed. JSON.stringify is the\n // key because it separates the two shapes on its own — a lone \"a/**\" and\n // [\"a/**\"] serialize differently — with no separator char to collide with\n // one inside a glob.\n const key = JSON.stringify(glob);\n let m = matcherCache.get(key);\n if (!m) {\n m = picomatch(glob as string | string[], { dot: true });\n matcherCache.set(key, m);\n }\n // Normalize Windows separators so globs written with `/` still match.\n return m(relPath.replace(/\\\\/g, \"/\"));\n}\n","/**\n * The error every tool under the umbrella throws for an operational failure.\n *\n * Each tool keeps its own subclass (`DocmetaError`, …) so its tests and\n * library callers can match on it. The base is what the shared bin runner\n * matches on: a `ToolError` is reported as one line and exit 2, anything else\n * is a bug and keeps its stack trace.\n */\nexport class ToolError extends Error {\n /** clig.dev: 2 is operational/usage; 1 is reserved for findings. */\n readonly exitCode: number = 2;\n\n constructor(message: string) {\n super(message);\n this.name = \"ToolError\";\n }\n}\n\n/**\n * The message a caught value carries, whatever was thrown.\n *\n * JavaScript can throw anything, so `(err as Error).message` is `undefined`\n * for a thrown string, number or `null`, and \"undefined\" is what the user\n * reads. An Error, or anything with a string `message`, gives that message.\n * A string is its own message. Anything else gives its JSON text, or its\n * `String()` form when it will not serialise.\n */\nexport function errorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n if (typeof err === \"string\") return err;\n if (\n typeof err === \"object\" &&\n err !== null &&\n \"message\" in err &&\n typeof err.message === \"string\"\n ) {\n return err.message;\n }\n try {\n // Typed as returning a string, but `undefined`, a function or a symbol\n // gives `undefined`.\n const json = JSON.stringify(err) as string | undefined;\n if (json !== undefined) return json;\n } catch {\n // A cycle, or a BigInt: fall through to the one form that always exists.\n }\n return String(err);\n}\n","/**\n * Shared types for docmeta.\n *\n * The pipeline is: load files -> extract metadata (format-specific) ->\n * resolve a schema set per file -> validate against each schema -> report.\n * Everything after extraction operates only on `ExtractedMetadata`, so new\n * input formats never touch validation, resolution, or reporting.\n */\nimport { ToolError } from \"../shared/errors.js\";\n\n/** Result of pulling a metadata block out of a single document. */\nexport interface ExtractedMetadata {\n /** Parsed metadata key/values. `{}` when a block is present but empty. */\n data: Record<string, unknown>;\n /** Whether a metadata block was found at all. */\n present: boolean;\n /**\n * Whether the metadata came from a removable fenced front matter block.\n * A per-extraction fact, deliberately not an extractor capability: RST and\n * AsciiDoc read a fenced block when one exists and fall back to native\n * docinfo/attribute parsing when not, so the same extractor yields both\n * answers. Absent (element-backed, native-header) means `DELETE FROM docs`\n * has no block whose removal would leave the document whole, and refuses.\n */\n fenced?: boolean;\n /** Name of the extractor/format that produced this (e.g. \"markdown\"). */\n format: string;\n /**\n * Map a JSON Pointer (Ajv `instancePath`, e.g. \"/tags/0\") or a bare top-level\n * key to its 1-based source line, for precise annotations. Returns undefined\n * when no position is known.\n */\n lineFor(this: void, pointer: string): number | undefined;\n /**\n * The column counterpart of {@link lineFor}, 1-based, resolving the same\n * pointer forms.\n *\n * **Optional on purpose.** `lineFor` is required and public, so widening it\n * to return a position pair would break every consumer that implements\n * `MetadataExtractor` outside this repository. A format that cannot cheaply\n * give a column simply omits this — today that is every frontmatter-based\n * extractor, whose `yaml` node offsets would need an offset -> line/col\n * conversion first. `html` and `xml` implement it.\n */\n colFor?(this: void, pointer: string): number | undefined;\n}\n\n/** Fenced front matter flavors, in fence order: `---`, `+++`, `;;;`. */\nexport type FrontmatterFlavor = \"yaml\" | \"toml\" | \"json\";\n\n/** Top-level metadata keys to set. Keys with `undefined` values are ignored. */\nexport type MetadataPatch = Record<string, unknown>;\n\nexport interface ApplyOptions {\n /** Flavor to use when creating a block from scratch. Default \"yaml\". */\n newBlockFlavor?: FrontmatterFlavor;\n /**\n * Top-level keys to remove entirely — deletion, where `patch` can only set\n * (`undefined` values there are ignored by contract). Removing a key that\n * is already absent is a no-op. Writers that cannot remove a key ignore\n * this option, so a caller that needs certainty must re-extract and check —\n * `runQuery`'s apply phase does exactly that and refuses the run on a\n * survivor.\n */\n deletions?: readonly string[];\n /**\n * The document's path, when the caller knows it. `extract` receives one and\n * `apply` did not, which left a writer unable to use the extension as a\n * signal — the XML writer needs it to tell a DITA topic from hand-rolled XML\n * that happens to have a `<task>` root.\n */\n filePath?: string;\n /**\n * The same `elements:` paths extraction was given.\n *\n * A writer re-reads the document to find where each key came from, and a read\n * without these paths would not produce a config-declared key at all — so the\n * writer would treat it as absent and create it somewhere else. That is the\n * asymmetry proposal 0018 calls a loop, arriving through the options object\n * rather than through the code.\n */\n elements?: readonly string[];\n}\n\n/** Per-run inputs to extraction, beyond the document itself. */\nexport interface ExtractOptions {\n /**\n * Extra element paths to lift, from `elements:` config. Slash-separated from\n * the document root, optionally ending in `@attribute`. These *extend* the\n * per-format convention: a path producing a key the convention already filled\n * is a no-op, so naming one cannot retype a key a content model typed exactly.\n */\n elements?: readonly string[];\n}\n\n/** A pluggable metadata extractor for one document format. */\nexport interface MetadataExtractor {\n /** Stable name, also used as `ExtractedMetadata.format`. */\n name: string;\n /** Lowercase file extensions this extractor handles, incl. dot (e.g. \".md\"). */\n extensions: string[];\n /**\n * Whether this extractor can *read* — false for a format that is registered\n * but not yet wired up. Every registered extractor sets it true today; it is\n * kept because it is a distinct capability from writability, which is the\n * presence of `apply`. A format can read without writing, and one being\n * added could be declared before it can do either.\n */\n implemented: boolean;\n /**\n * Extract metadata from raw file content.\n *\n * `this: void` — as on `apply` below, and on `ExtractedMetadata`'s\n * `lineFor`/`colFor`. Every implementation in this repo is a plain function\n * in an object literal and none of them reads `this`, so pulling one out\n * (`const apply = extractor.apply`) is the ordinary thing it looks like\n * rather than a binding hazard. Declaring that is what lets a reader — and\n * `unbound-method` — know it.\n *\n * Retyping these as properties holding functions would say the same thing,\n * and was tried first. It is the more expensive way: a property's parameters\n * are contravariant where a method's are bivariant, so on an *exported*\n * interface that swap silently narrows what an outside implementation may\n * be, which is a semver-visible change bought for a lint fix. `this: void`\n * leaves assignability exactly as it was.\n */\n extract(\n this: void,\n content: string,\n filePath: string,\n options?: ExtractOptions,\n ): ExtractedMetadata;\n /**\n * Return new content with every key in `patch` set at the top level. Pure:\n * no IO, no mutation, deterministic; returns `content` itself for a no-op.\n *\n * Absent means the format is read-only. Present but throwing `DocmetaError`\n * means this particular document cannot be rewritten safely.\n */\n apply?(\n this: void,\n content: string,\n patch: MetadataPatch,\n options?: ApplyOptions,\n ): string;\n}\n\n/** A single schema violation for one file, attributed to one schema. */\nexport interface FieldError {\n /** Schema id/ref that produced this error (e.g. \"google:okf:0.1\"). */\n schema: string;\n /** Ajv instancePath, e.g. \"/tags/0\" or \"\" for the root. */\n instancePath: string;\n /** Human-readable message. */\n message: string;\n /**\n * Ajv keyword that failed (e.g. \"required\", \"format\", \"pattern\"), or\n * \"parse\"/\"schema\" for the synthetic errors the command layer raises.\n *\n * This and `subject` are the machine-stable half of a violation's identity:\n * `message` is generated prose that an Ajv upgrade may reword, so nothing\n * durable — a baseline fingerprint, a SARIF `ruleId` — may be built from it.\n */\n keyword: string;\n /**\n * Discriminator within that keyword, when it is a stable identifier: the\n * missing property, the additional property, the format name, the expected\n * type. Deliberately unset for keywords whose parameter is a schema-authored\n * *value* (`pattern`'s regex, `enum`'s list, `minLength`'s number), which\n * changes whenever the schema is edited.\n */\n subject?: string;\n /** 1-based source line, when known. */\n line?: number;\n /** 1-based column, when known. */\n col?: number;\n /**\n * The file `line` and `col` refer to, when it is not the result's own file.\n *\n * Set only for a value a manifest supplied (proposal 0037), spelled\n * the way the run spells file labels. Absent means the document itself,\n * which is every violation that existed before external metadata. The finding's\n * subject file stays `ValidationResult.file`: that is its baseline identity\n * and its SARIF location, and this names where the *value* was written.\n */\n file?: string;\n}\n\n/** Validation outcome for a single file. */\nexport interface ValidationResult {\n /** Absolute or cwd-relative path of the file. */\n file: string;\n /** Extractor/format used. */\n format: string;\n /** Whether validation passed against every schema in the set. */\n ok: boolean;\n /** Schema ids/refs the file was validated against. */\n schemas: string[];\n /** All violations, across every schema in the set. */\n errors: FieldError[];\n /**\n * Findings a baseline suppressed for this file. Absent when no baseline\n * governed the run, or when it forgave nothing here.\n */\n baselined?: number;\n}\n\n/** How a baseline shaped the run. Present only when one governed it. */\nexport interface BaselineSummary {\n /** Baseline file path, spelled the way the user would type it. */\n path: string;\n /** Whether this run wrote the file (`--write-baseline`) or only read it. */\n written: boolean;\n /**\n * Fingerprints the baseline holds. On a read this counts only the files the\n * run checked, so validating one file does not report the rest as prunable.\n */\n recorded: number;\n /** Findings the baseline suppressed. */\n suppressed: number;\n /** Recorded fingerprints for checked files that no longer occur. */\n stale: number;\n /** Fingerprints this write added. Write only. */\n added?: number;\n /** Fingerprints this write dropped. Write only. */\n removed?: number;\n}\n\n/** Aggregate run summary. */\nexport interface RunSummary {\n files: number;\n passed: number;\n failed: number;\n /** Violations reported. Baselined ones are excluded — see `baseline`. */\n errors: number;\n /**\n * Candidate documents `.gitignore` removed from the walk. Omitted when it\n * removed none. Reported because silent removal is what makes the filter\n * dangerous — a counted removal is auditable.\n */\n gitignoreSkipped?: number;\n baseline?: BaselineSummary;\n}\n\n/** An operational/usage failure that should map to exit code 2. */\nexport class DocmetaError extends ToolError {\n constructor(message: string) {\n super(message);\n this.name = \"DocmetaError\";\n }\n}\n","/**\n * Atomic file writes.\n *\n * `fill` is the first command that modifies the user's sources, and it does so\n * in bulk over a glob, often while a dev server or editor is watching. A\n * truncated write from a crash or a full disk would be unrecoverable for them,\n * so every write lands via a temp file plus `rename` — the file either has its\n * old contents or its new ones, never half of each.\n *\n * The temp file must live in the *same directory* as the target: `rename` is\n * only atomic within a filesystem, and the OS temp dir is frequently a\n * different one.\n */\nimport { writeFile, rename, rm, stat, chmod } from \"node:fs/promises\";\nimport { dirname, join, basename } from \"node:path\";\nimport { programName } from \"../../shared/program-name.js\";\n\n/** Windows returns these when an editor or scanner holds the target open. */\nconst LOCKED = new Set([\"EPERM\", \"EBUSY\", \"EACCES\"]);\nconst RENAME_ATTEMPTS = 3;\n\nfunction errorCode(err: unknown): string | undefined {\n return typeof err === \"object\" && err !== null && \"code\" in err\n ? String(err.code)\n : undefined;\n}\n\nconst wait = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/**\n * Write `contents` to `path`, replacing it atomically. Falls back to a direct\n * write (with a warning on stderr) if the rename keeps failing because the\n * target is locked — on Windows that is a real and recoverable situation, and\n * refusing to write at all would be worse than a non-atomic write.\n */\nexport async function writeFileAtomic(\n path: string,\n /**\n * A `Uint8Array` writes byte-for-byte. `schemas vendor` needs that: the\n * integrity pin it records is taken over exactly what the server sent, and a\n * decode/re-encode round trip through a UTF-8 string would change the bytes\n * of a payload that is not valid UTF-8 — so the pin would be wrong the first\n * time anything checked it.\n */\n contents: string | Uint8Array,\n): Promise<void> {\n const tmp = join(\n dirname(path),\n `.${basename(path)}.manni-${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`,\n );\n\n try {\n // No encoding argument. Node ignores one when `contents` is a\n // `Uint8Array`, so passing `\"utf8\"` was harmless — but it reads as though a\n // decode happens, which is exactly what the byte-for-byte guarantee above\n // says must not. The two-argument overload defaults a string to UTF-8 and\n // writes bytes as they are, which is the behaviour both callers want.\n await writeFile(tmp, contents);\n\n // Carry the target's permissions over; a missing target just means we are\n // creating it, in which case the default mode is correct.\n try {\n const { mode } = await stat(path);\n await chmod(tmp, mode);\n } catch {\n // No existing file (or no permission to read its mode) — keep the default.\n }\n\n let lastError: unknown;\n for (let attempt = 1; attempt <= RENAME_ATTEMPTS; attempt++) {\n try {\n await rename(tmp, path);\n return;\n } catch (err) {\n lastError = err;\n const code = errorCode(err);\n if (code == null || !LOCKED.has(code)) throw err;\n if (attempt < RENAME_ATTEMPTS) await wait(attempt * 50);\n }\n }\n\n process.stderr.write(\n `${programName()}: ${path} is locked by another process; writing in place (not atomically).\\n`,\n );\n try {\n await writeFile(path, contents);\n } catch {\n throw lastError;\n }\n } finally {\n await rm(tmp, { force: true });\n }\n}\n","/**\n * The name the running bin was invoked as, for stderr prefixes.\n *\n * One package ships two bins: `manni`, and `docmeta` for the scripts written\n * before the rename. A diagnostic should name the command the user typed, so\n * the prefix is settled once by whichever entry point ran (`runProgram`) and\n * read by whoever writes to stderr. Library callers never set it, and get the\n * primary bin's name.\n */\nlet name = \"manni\";\n\nexport function programName(): string {\n return name;\n}\n\nexport function setProgramName(value: string): void {\n name = value;\n}\n","/**\n * The cross-run cache for schemas fetched over `http(s)`.\n *\n * The in-process `Map` in `schema-registry.ts` collapses N files into one\n * fetch and then dies with the process, so every `manni meta validate` in a\n * developer's edit loop re-fetches the same remote contract. This is the piece\n * that survives the run: one file per URL under `.manni/meta/schema-cache/`,\n * served while it is inside the TTL.\n *\n * **Its scope, stated honestly:** this is a local dev-loop and pre-commit win,\n * not a CI one. An ephemeral runner starts with an empty workspace, so the\n * cache is cold on every job and the remote host is still a single point of\n * failure for the org. Vendoring the schema into the consuming repo is what\n * fixes that; see `docs/proposals/0008-remote-schema-durability.md`.\n *\n * Written here rather than reusing `JsonCache` from `@hawkeyexl/inference`\n * (which `fill` keeps using for proposals) for three reasons the cache\n * semantics turn on: `JsonCache` has no TTL, no eviction, and writes with a\n * plain `writeFileSync`. Schema resolution is the most correctness-critical\n * path docmeta has, and a truncated entry there would be read back on the next\n * run — so writes go through `writeFileAtomic`.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdir, readFile, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { writeFileAtomic } from \"./write-file.js\";\n\n/**\n * Where the cache lives, relative to the project root.\n *\n * `.manni/` is already ignored wholesale, and `fill` writes its proposal\n * cache to `.manni/meta/cache` — a different directory, so the two never collide.\n */\nexport const SCHEMA_CACHE_DIR = \".manni/meta/schema-cache\";\n\n/** The only entry format this version understands. */\nexport const SCHEMA_CACHE_VERSION = 1;\n\n/** How long a cached schema is served before it is re-fetched. */\nexport const DEFAULT_TTL_HOURS = 24;\n\n/**\n * How far ahead of `Date.now()` an mtime may sit and still count as written\n * \"now\" rather than as a clock problem.\n *\n * A file's timestamp and `Date.now()` do not come from the same clock: on\n * Windows the system clock ticks in ~15.6ms steps while `Date.now()` is\n * interpolated, so a file written this instant can read as one or two\n * milliseconds in the future. Measured at ~1ms here; a network filesystem can\n * be worse. Without a tolerance, an entry the current run just wrote is stale\n * the moment it is read, which quietly turns the cache off.\n *\n * A minute is far above any of that and far below the shortest useful TTL, so\n * it separates jitter from the hours-to-years skew a restored archive carries.\n */\nconst FUTURE_MTIME_TOLERANCE_MS = 60_000;\n\n/** The cache directory for a project rooted at `root`. */\nexport function schemaCacheDir(root: string): string {\n return join(root, SCHEMA_CACHE_DIR);\n}\n\n/** What one cache file holds. */\nexport interface SchemaCacheEntry {\n version: number;\n /** The URL this entry was fetched from; re-checked on read. */\n url: string;\n /**\n * When it was fetched, ISO-8601. **Diagnostic only** — freshness is measured\n * on the file's mtime, which a restored cache or a clock change cannot make\n * disagree with the filesystem the way an embedded timestamp can.\n */\n fetchedAt: string;\n schema: Record<string, unknown>;\n}\n\nexport interface ReadOptions {\n /**\n * Serve an entry regardless of age. What `--offline` needs: there is no\n * re-fetch available, so a stale copy beats failing the run outright.\n */\n ignoreTtl?: boolean;\n}\n\nexport class SchemaCache {\n constructor(\n private readonly dir: string,\n private readonly ttlHours: number = DEFAULT_TTL_HOURS,\n ) {}\n\n /** A TTL of 0 disables the cache in both directions. */\n get enabled(): boolean {\n return this.ttlHours > 0;\n }\n\n /**\n * The file an entry lives in.\n *\n * Keyed on a hex digest of the URL, never on the URL itself: a URL carries\n * `/`, `..`, `:`, and a query string, so `join(dir, url + \".json\")` lets the\n * *server's* address decide where the write lands. A digest cannot escape the\n * directory.\n */\n entryPath(url: string): string {\n const key = createHash(\"sha256\").update(url).digest(\"hex\");\n return join(this.dir, `${key}.json`);\n }\n\n /**\n * The cached schema for `url`, or null.\n *\n * Every malformation — an unreadable file, unparseable JSON, an unknown\n * version, an envelope naming a different URL, a payload that is not an\n * object — degrades to a **miss**. A cache is an optimization, and a corrupt\n * entry must cost one fetch, never a failed run that no `docmeta` command\n * explains how to fix.\n */\n async read(\n url: string,\n options: ReadOptions = {},\n ): Promise<Record<string, unknown> | null> {\n if (!this.enabled) return null;\n const file = this.entryPath(url);\n\n if (options.ignoreTtl !== true) {\n let mtimeMs: number;\n try {\n ({ mtimeMs } = await stat(file));\n } catch {\n return null;\n }\n const age = Date.now() - mtimeMs;\n // An age below `-FUTURE_MTIME_TOLERANCE_MS` is an entry stamped in the\n // future by more than clock jitter explains, and it would satisfy the TTL\n // check for as long as the clock took to catch up — hours of intended\n // lifetime turned into years. An archive keeps the mtimes it was packed\n // with, and a machine whose clock ran fast leaves every entry it wrote\n // ahead of now, so this outlives the clock that caused it.\n //\n // Treated as a miss rather than clamped: the miss costs one fetch, and\n // the write that follows re-stamps the file, so the entry heals instead\n // of staying suspect. `ignoreTtl` still serves it — `--offline` has no\n // fetch to fall back on, and there a stale contract beats no contract.\n if (\n age < -FUTURE_MTIME_TOLERANCE_MS ||\n age >= this.ttlHours * 3_600_000\n ) {\n return null;\n }\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(await readFile(file, \"utf8\"));\n } catch {\n return null;\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n return null;\n }\n const entry = raw as Record<string, unknown>;\n if (entry.version !== SCHEMA_CACHE_VERSION) return null;\n // A digest collision cannot realistically produce this, but a hand-edited\n // or half-copied cache directory can, and validating against the wrong\n // contract is a silent wrong answer rather than an error.\n if (entry.url !== url) return null;\n const schema = entry.schema;\n if (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n return null;\n }\n return schema as Record<string, unknown>;\n }\n\n /**\n * Record a freshly fetched schema.\n *\n * A failure to write is swallowed. A read-only checkout, a full disk, or a\n * sandbox with no write access must cost the *next* run one fetch, not this\n * run its result.\n *\n * Returns whether the entry actually landed on disk, which is a different\n * question from whether the run should continue.\n */\n async write(url: string, schema: Record<string, unknown>): Promise<boolean> {\n if (!this.enabled) return false;\n const entry: SchemaCacheEntry = {\n version: SCHEMA_CACHE_VERSION,\n url,\n fetchedAt: new Date().toISOString(),\n schema,\n };\n try {\n await mkdir(this.dir, { recursive: true });\n await writeFileAtomic(\n this.entryPath(url),\n `${JSON.stringify(entry, null, 2)}\\n`,\n );\n return true;\n } catch {\n // Intentionally silent: see the doc comment. The boolean is how a caller\n // learns the entry is not on disk without the failure becoming fatal —\n // `schema-registry` needs exactly that to know an offline call cannot\n // legally be served from the in-process memo.\n return false;\n }\n }\n}\n","/**\n * Integrity pins for vendored schemas.\n *\n * A vendored schema is a file in the consuming repository's own history, so the\n * question an integrity pin answers is narrow: are the bytes on disk still the\n * bytes that were downloaded? That makes an edited, truncated, or\n * merge-mangled copy a loud failure instead of a contract that quietly changed\n * meaning.\n *\n * One algorithm and one encoding, deliberately. Every additional accepted form\n * is another state the mismatch message has to be right about, and there is no\n * interoperability argument here — docmeta writes these strings itself.\n */\nimport { createHash } from \"node:crypto\";\n\n/** The only digest algorithm `integrity:` accepts. */\nexport const INTEGRITY_ALGORITHM = \"sha256\";\n\n/** What a well-formed pin looks like, for error messages. */\nexport const INTEGRITY_SHAPE = `${INTEGRITY_ALGORITHM}-<64 hex characters>`;\n\nconst INTEGRITY_RE = new RegExp(`^${INTEGRITY_ALGORITHM}-([0-9a-f]{64})$`);\n\n/**\n * The pin for a byte sequence.\n *\n * Hashes the **bytes**, never a string: decoding to UTF-8 and re-encoding is\n * lossy for a payload that is not valid UTF-8, which would make the pin wrong\n * in exactly the case an integrity check exists to catch.\n */\nexport function integrityOf(bytes: Uint8Array): string {\n return `${INTEGRITY_ALGORITHM}-${createHash(INTEGRITY_ALGORITHM).update(bytes).digest(\"hex\")}`;\n}\n\n/** Whether `value` is a pin this version can verify. */\nexport function isIntegrity(value: string): boolean {\n return INTEGRITY_RE.test(value);\n}\n\n/**\n * How two byte sequences differ, for the mismatch message.\n *\n * `line-endings` is not a nicety. A vendored schema is committed, and a\n * repository with `core.autocrlf=true` (or a `*.json text` attribute) hands a\n * Windows checkout CRLF bytes that hash differently from the LF bytes that were\n * downloaded — a mismatch on a file nobody touched. Naming that case is the\n * difference between a five-minute fix and a user deleting the pin.\n */\nexport type IntegrityDiff = \"line-endings\" | \"content\";\n\n/** Bytes with every CRLF collapsed to LF. */\nfunction toLf(bytes: Uint8Array): Uint8Array {\n const out = new Uint8Array(bytes.length);\n let n = 0;\n for (let i = 0; i < bytes.length; i++) {\n const byte = bytes[i];\n if (byte === undefined) continue;\n // 0x0d CR followed by 0x0a LF: drop the CR, keep the LF.\n if (byte === 0x0d && bytes[i + 1] === 0x0a) continue;\n out[n++] = byte;\n }\n return out.subarray(0, n);\n}\n\n/** Bytes with every bare LF expanded to CRLF. */\nfunction toCrlf(bytes: Uint8Array): Uint8Array {\n const lf = toLf(bytes);\n const out = new Uint8Array(lf.length * 2);\n let n = 0;\n for (let i = 0; i < lf.length; i++) {\n const byte = lf[i];\n if (byte === undefined) continue;\n if (byte === 0x0a) out[n++] = 0x0d;\n out[n++] = byte;\n }\n return out.subarray(0, n);\n}\n\n/**\n * Why `bytes` does not match `expected`.\n *\n * Only ever called once a mismatch is established, so \"they are identical\" is\n * not among the answers.\n *\n * Both conversions are tried because only the *pin* survives, not the bytes it\n * was taken from, so there is no way to normalize both sides. A CRLF working\n * copy of an LF download is caught by the first; an LF checkout of a CRLF\n * download by the second.\n */\nexport function diagnoseIntegrity(\n bytes: Uint8Array,\n expected: string,\n): IntegrityDiff {\n if (integrityOf(toLf(bytes)) === expected) return \"line-endings\";\n if (integrityOf(toCrlf(bytes)) === expected) return \"line-endings\";\n return \"content\";\n}\n","/**\n * Source of truth for schemas. Holds the built-in schemas (addressed by\n * `vendor:name:version` ids) and knows how to load any schema reference —\n * a built-in id, a local `.json` path, or an `http(s)` URL.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { Buffer } from \"node:buffer\";\nimport { DocmetaError } from \"../types.js\";\nimport { stripBom } from \"./json-text.js\";\nimport {\n DEFAULT_TTL_HOURS,\n SchemaCache,\n schemaCacheDir,\n} from \"./schema-cache.js\";\nimport {\n INTEGRITY_SHAPE,\n diagnoseIntegrity,\n integrityOf,\n isIntegrity,\n} from \"./integrity.js\";\n\nimport okf01 from \"../schemas/okf/0.1.json\" with { type: \"json\" };\nimport diataxis10 from \"../schemas/diataxis/1.0.json\" with { type: \"json\" };\nimport sevenAction10 from \"../schemas/seven-action/1.0.json\" with { type: \"json\" };\nimport tgdp10 from \"../schemas/tgdp/1.0.json\" with { type: \"json\" };\nimport docusaurusDocs310 from \"../schemas/docusaurus-docs/3.10.json\" with { type: \"json\" };\nimport docusaurusBlog310 from \"../schemas/docusaurus-blog/3.10.json\" with { type: \"json\" };\nimport docusaurusPages310 from \"../schemas/docusaurus-pages/3.10.json\" with { type: \"json\" };\nimport starlight041 from \"../schemas/starlight/0.41.json\" with { type: \"json\" };\nimport antora31 from \"../schemas/antora/3.1.json\" with { type: \"json\" };\nimport sphinx91 from \"../schemas/sphinx/9.1.json\" with { type: \"json\" };\nimport myst110 from \"../schemas/myst/1.10.json\" with { type: \"json\" };\nimport ogp10 from \"../schemas/ogp/1.0.json\" with { type: \"json\" };\nimport dcmi11 from \"../schemas/dcmi/1.1.json\" with { type: \"json\" };\nimport microsoftLearn10 from \"../schemas/microsoft-learn/1.0.json\" with { type: \"json\" };\nimport ditaMetadata13 from \"../schemas/dita/1.3.json\" with { type: \"json\" };\nimport hugoPage0165 from \"../schemas/hugo/0.165.json\" with { type: \"json\" };\nimport jekyllPage44 from \"../schemas/jekyll/4.4.json\" with { type: \"json\" };\nimport vitepressPage16 from \"../schemas/vitepress/1.6.json\" with { type: \"json\" };\nimport xCards10 from \"../schemas/x-cards/1.0.json\" with { type: \"json\" };\nimport agentSkills10 from \"../schemas/agent-skills/1.0.json\" with { type: \"json\" };\nimport claudeSkill21 from \"../schemas/claude-skill/2.1.json\" with { type: \"json\" };\nimport mkdocsMaterial97 from \"../schemas/mkdocs-material/9.7.json\" with { type: \"json\" };\nimport claudeSubagent21 from \"../schemas/claude-subagent/2.1.json\" with { type: \"json\" };\nimport { errorMessage } from \"../../shared/errors.js\";\n\nexport interface BuiltinInfo {\n id: string;\n title: string;\n description: string;\n}\n\n/** Built-in schemas keyed by `vendor:name:version` id. */\nconst BUILTINS = new Map<string, Record<string, unknown>>([\n [\"google:okf:0.1\", okf01],\n [\"diataxis:diataxis:1.0\", diataxis10],\n [\"passo-uno:seven-action:1.0\", sevenAction10],\n [\"tgdp:templates:1.0\", tgdp10],\n [\"docusaurus:docs:3.10\", docusaurusDocs310],\n [\"docusaurus:blog:3.10\", docusaurusBlog310],\n [\"docusaurus:pages:3.10\", docusaurusPages310],\n [\"astro:starlight:0.41\", starlight041],\n [\"antora:page:3.1\", antora31],\n [\"sphinx:docinfo:9.1\", sphinx91],\n [\"myst:frontmatter:1.10\", myst110],\n [\"ogp:article:1.0\", ogp10],\n [\"dcmi:elements:1.1\", dcmi11],\n [\"microsoft:learn:1.0\", microsoftLearn10],\n [\"oasis:dita-metadata:1.3\", ditaMetadata13],\n [\"hugo:page:0.165\", hugoPage0165],\n [\"jekyll:page:4.4\", jekyllPage44],\n [\"vitepress:page:1.6\", vitepressPage16],\n [\"x:cards:1.0\", xCards10],\n [\"agentskills:skill:1.0\", agentSkills10],\n [\"anthropic:claude-skill:2.1\", claudeSkill21],\n [\"mkdocs:material:9.7\", mkdocsMaterial97],\n [\"anthropic:claude-subagent:2.1\", claudeSubagent21],\n]);\n\n/**\n * Refuse a built-in id whose first segment is `check`.\n *\n * `check:<name>` is a corpus check's identity inside baseline fingerprints and\n * rule ids (proposal 0026), and it deliberately matches `BUILTIN_ID` so\n * `classifyRef` passes it through untouched. That makes the first segment a\n * shared namespace: a real built-in published as `check:…` could collide with\n * a check's identity while both are legal. Reserved from this side so the\n * collision can never ship — the registry throws at load if the table gains\n * one.\n */\nexport function assertPublishableBuiltinId(id: string): void {\n const first = id.split(\":\")[0];\n if (first === \"check\") {\n throw new Error(\n `Built-in id \"${id}\" is not publishable: the \"check\" first segment is reserved for corpus check identities (check:<name>, proposal 0026).`,\n );\n }\n // `external:owned` is the identity of a document carrying a key a manifest\n // owns (proposal 0037), reserved for the same reason.\n if (first === \"external\") {\n throw new Error(\n `Built-in id \"${id}\" is not publishable: the \"external\" first segment is reserved for external-metadata finding identities (external:owned, external:duplicate, proposal 0037).`,\n );\n }\n // `derived:stale` is the identity of a managed field whose asserted value\n // differs from what git, CODEOWNERS or the review record says, reserved likewise.\n if (first === \"derived\") {\n throw new Error(\n `Built-in id \"${id}\" is not publishable: the \"derived\" first segment is reserved for derived finding identities (derived:stale).`,\n );\n }\n}\n\nfor (const id of BUILTINS.keys()) assertPublishableBuiltinId(id);\n\nexport function listBuiltins(): BuiltinInfo[] {\n return [...BUILTINS.entries()].map(([id, schema]) => ({\n id,\n title: typeof schema.title === \"string\" ? schema.title : id,\n description:\n typeof schema.description === \"string\" ? schema.description : \"\",\n }));\n}\n\n/**\n * Where the docs site serves byte-identical copies of the built-ins (0009).\n *\n * The site's `site` is `https://hawkeyexl.github.io` and its `base` is\n * `/manni`, and Astro serves `docs/public/**` at the site root — so\n * `docs/public/schemas/okf/0.1.json` is reachable at\n * `<PUBLISHED_BASE>okf/0.1.json`.\n */\nexport const PUBLISHED_BASE = \"https://hawkeyexl.github.io/manni/schemas/\";\n\n/**\n * Where the same bytes were served before the rename. Proposal 0009 promised\n * those URLs stay byte-stable, and the old repository's Pages keeps serving\n * them, so a `$schema` written against one keeps resolving to the bundle\n * rather than becoming a network fetch of a stranger's copy.\n */\nexport const LEGACY_PUBLISHED_BASE =\n \"https://hawkeyexl.github.io/docmeta/schemas/\";\n\n/**\n * Published URL → built-in id.\n *\n * Written out rather than derived, because the two sides do **not** correspond\n * mechanically: `passo-uno:seven-action:1.0` lives at `seven-action/1.0.json`,\n * `tgdp:templates:1.0` at `tgdp/1.0.json`, and `docusaurus:docs:3.10` at\n * `docusaurus-docs/3.10.json`. Any rule that reproduced one of those would get\n * the other two wrong, and getting it wrong means fetching a built-in over the\n * network — the regression stress test 1 of proposal 0009 exists to prevent.\n *\n * Matched as an exact string. A prefix or host rule would also swallow\n * `.../schemas/okf/9.9.json`, which does not exist and must stay an ordinary\n * remote ref that fails with a 404 rather than resolving to something else.\n */\nconst PUBLISHED_PATHS: readonly (readonly [string, string])[] = [\n [\"okf/0.1.json\", \"google:okf:0.1\"],\n [\"diataxis/1.0.json\", \"diataxis:diataxis:1.0\"],\n [\"seven-action/1.0.json\", \"passo-uno:seven-action:1.0\"],\n [\"tgdp/1.0.json\", \"tgdp:templates:1.0\"],\n [\"docusaurus-docs/3.10.json\", \"docusaurus:docs:3.10\"],\n [\"docusaurus-blog/3.10.json\", \"docusaurus:blog:3.10\"],\n [\"docusaurus-pages/3.10.json\", \"docusaurus:pages:3.10\"],\n [\"starlight/0.41.json\", \"astro:starlight:0.41\"],\n [\"antora/3.1.json\", \"antora:page:3.1\"],\n [\"sphinx/9.1.json\", \"sphinx:docinfo:9.1\"],\n [\"myst/1.10.json\", \"myst:frontmatter:1.10\"],\n [\"ogp/1.0.json\", \"ogp:article:1.0\"],\n [\"dcmi/1.1.json\", \"dcmi:elements:1.1\"],\n [\"microsoft-learn/1.0.json\", \"microsoft:learn:1.0\"],\n [\"dita/1.3.json\", \"oasis:dita-metadata:1.3\"],\n [\"hugo/0.165.json\", \"hugo:page:0.165\"],\n [\"jekyll/4.4.json\", \"jekyll:page:4.4\"],\n [\"vitepress/1.6.json\", \"vitepress:page:1.6\"],\n [\"x-cards/1.0.json\", \"x:cards:1.0\"],\n [\"agent-skills/1.0.json\", \"agentskills:skill:1.0\"],\n [\"claude-skill/2.1.json\", \"anthropic:claude-skill:2.1\"],\n [\"mkdocs-material/9.7.json\", \"mkdocs:material:9.7\"],\n [\"claude-subagent/2.1.json\", \"anthropic:claude-subagent:2.1\"],\n];\n\n/** Published URL → built-in id, under the current base. */\nconst PUBLISHED_ALIAS: ReadonlyMap<string, string> = new Map(\n PUBLISHED_PATHS.map(([path, id]) => [`${PUBLISHED_BASE}${path}`, id]),\n);\n\n/**\n * The same table under the pre-rename base. Consulted for resolution only;\n * `publishedBuiltins()` lists each built-in once, under the current URL.\n */\nconst LEGACY_PUBLISHED_ALIAS: ReadonlyMap<string, string> = new Map(\n PUBLISHED_PATHS.map(([path, id]) => [`${LEGACY_PUBLISHED_BASE}${path}`, id]),\n);\n\n/**\n * The bundled object a published URL names, or `undefined`.\n *\n * **Both** tables have to answer, not just `PUBLISHED_ALIAS`. A URL mapped to\n * an id that is not in `BUILTINS` — a typo in one of the two literals — is not\n * a published built-in at all: `loadSchema` would fall through to the network\n * for it. If membership alone decided, the trust boundary would exempt a URL\n * that then got fetched from a third party, which is the one combination\n * neither check may produce. One resolution, so the two cannot disagree.\n *\n * Unreachable in practice: a test asserts the table covers exactly\n * {@link listBuiltins}, so a mismatch fails the suite rather than shipping.\n * The point of resolving through both is that a future edit cannot quietly\n * turn a typo into a trust hole.\n */\nfunction publishedBuiltinSchema(\n ref: string,\n): Record<string, unknown> | undefined {\n const id = PUBLISHED_ALIAS.get(ref) ?? LEGACY_PUBLISHED_ALIAS.get(ref);\n return id === undefined ? undefined : BUILTINS.get(id);\n}\n\n/**\n * Does this reference name a built-in that docmeta happens to publish?\n *\n * A published URL resolves to a **bundled object**: no request is made, no\n * third party can answer for it, and the bytes are the ones in this package. So\n * every place that reasons about what a `url` ref can reach has to treat it as\n * the built-in it is — see `assertDocumentRefAllowed` in `resolve-schema.ts`,\n * which shares this predicate rather than repeating the table.\n */\nexport function isPublishedBuiltinUrl(ref: string): boolean {\n return publishedBuiltinSchema(ref) !== undefined;\n}\n\n/** One built-in, in both of its spellings, with the object they both name. */\nexport interface PublishedBuiltin {\n /** The `vendor:name:version` id, which is also the schema's own `$id`. */\n id: string;\n /** The docs-site URL serving byte-identical content. */\n url: string;\n /** The same content under the pre-rename base, still served and still honored. */\n legacyUrl: string;\n /** The bundled object — the same reference `loadSchema(id)` returns. */\n schema: Record<string, unknown>;\n}\n\n/**\n * Every built-in with its published URL, for callers that need both spellings.\n *\n * `validator.ts` registers these with each Ajv instance so a user's schema can\n * `$ref` a built-in by either name, and the tests assert this covers exactly\n * {@link listBuiltins} — adding a built-in without a URL fails there.\n */\nexport function publishedBuiltins(): PublishedBuiltin[] {\n const out: PublishedBuiltin[] = [];\n for (const [path, id] of PUBLISHED_PATHS) {\n const url = `${PUBLISHED_BASE}${path}`;\n const legacyUrl = `${LEGACY_PUBLISHED_BASE}${path}`;\n const schema = publishedBuiltinSchema(url);\n // A URL whose id is not in `BUILTINS` is skipped rather than registered as\n // `undefined`. Unreachable while both tables are literals here, and the\n // coverage test is what keeps it that way: it compares this list against\n // `listBuiltins()`, so a typo shows up as a missing entry — which is\n // exactly what skipping produces.\n if (schema) out.push({ id, url, legacyUrl, schema });\n }\n return out;\n}\n\nexport type RefKind = \"builtin\" | \"file\" | \"url\";\n\n/**\n * A built-in id looks like `seg(:seg)+` using only [a-z0-9._-] segments, with\n * no path separators and not ending in `.json`. This deliberately excludes\n * Windows paths (`C:\\...`), URLs, and `.json` files so a typo'd built-in is\n * reported as an unknown id rather than silently treated as a missing file.\n */\nconst BUILTIN_ID = /^[a-z0-9][a-z0-9._-]*(?::[a-z0-9][a-z0-9._-]*)+$/i;\n\nexport function classifyRef(ref: string): { kind: RefKind; ref: string } {\n if (/^https?:\\/\\//i.test(ref)) return { kind: \"url\", ref };\n if (\n !ref.includes(\"/\") &&\n !ref.includes(\"\\\\\") &&\n !ref.toLowerCase().endsWith(\".json\") &&\n BUILTIN_ID.test(ref)\n ) {\n return { kind: \"builtin\", ref };\n }\n return { kind: \"file\", ref };\n}\n\nconst urlCache = new Map<string, Record<string, unknown>>();\n\n/**\n * Refs whose `urlCache` entry came off the **network** in this process.\n *\n * `urlCache` is a memo, so an entry warmed by an earlier online call would\n * satisfy a later `offline` one — the guard never runs, because the short\n * circuit happens before it. For the CLI that is unreachable (each invocation\n * is a fresh process), but `loadSchema` is public API, and a long-lived\n * consumer doing `loadSchema(url)` then `loadSchema(url, { offline: true })`\n * would see offline \"work\" and then fail in an air-gapped process. Worse, it\n * holds even with no disk cache configured at all, so the run has nothing\n * legal to serve.\n *\n * Tracking provenance keeps the memo for entries an offline run may legally\n * use — anything read from the disk cache — while sending network-sourced refs\n * back through `resolveRemote`, which applies the guard.\n */\nconst urlFromNetwork = new Set<string>();\n\n/**\n * In-flight fetches, keyed on the *promise* rather than the resolved schema.\n *\n * `urlCache` only populates once the response has been read, so it collapses\n * repeat loads but not concurrent ones — and `fill` calls `loadSchema`\n * directly, once per file, inside a worker pool. Every worker therefore missed\n * the cache while the first fetch was still pending, and N files sharing one\n * remote ref fired N concurrent requests at the same host.\n *\n * Mirrors `Validator.compile`, including its two disciplines: the entry is\n * stored before the first await, and a rejection evicts it through a detached\n * `.catch()`. See the comments at the `set` below for why each matters.\n *\n * Keyed on `offline` as well as the ref, via {@link inflightKey}. Sharing one\n * entry across both modes let an offline caller join an online caller's open\n * fetch and receive the network result — the very thing `urlFromNetwork`\n * refuses one step earlier, undone by arriving a moment sooner.\n */\nconst urlInflight = new Map<string, Promise<Record<string, unknown>>>();\n\n/**\n * The `urlInflight` key for one call.\n *\n * Offline and online resolves of the same URL are different requests with\n * different answers, so they must not share an entry — in *either* direction.\n * An offline caller joining an online fetch is served over the network. An\n * online caller joining an offline resolve inherits its rejection when nothing\n * is cached, failing a run that had a working network the whole time.\n *\n * The cost is one extra resolve when a single process runs both modes against\n * one URL concurrently, which no CLI invocation does — every run has one\n * `offline` setting.\n *\n * `false` and `undefined` deliberately collapse to the same key: only `true`\n * means offline, and an absent flag is an online call, so the two must share an\n * entry or an ordinary run would dedup against nothing.\n */\nfunction inflightKey(ref: string, offline: boolean | undefined): string {\n return `${offline === true ? \"offline\" : \"online\"}:${ref}`;\n}\n\n/** Default network timeout for fetching a remote (`http(s)`) schema. */\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/**\n * Default cap on a fetched schema's body, in bytes.\n *\n * `AbortSignal.timeout` covers a *slow* body but not a *fast, huge* one, so\n * without a cap a hostile or misconfigured endpoint can stream until the\n * process runs out of memory. The largest schema docmeta itself ships is the\n * 112 KB SARIF meta-schema, so 5 MB is roughly two orders of magnitude of\n * headroom over anything a real document contract needs.\n */\nconst DEFAULT_MAX_BYTES = 5 * 1024 * 1024;\n\n/**\n * Keys that make a JSON object a *contract* — something that can reject a\n * document. An object carrying none of them constrains nothing, so every\n * document passes it, and it is far likelier to be an error envelope served\n * with HTTP 200 (an API gateway, a proxy, a misconfigured bucket) than a\n * schema.\n *\n * This is deliberately **not** meta-schema validation. docmeta compiles four\n * dialects, and schema quality is the author's business: a sparse but real\n * schema must keep working. The guard targets one specific failure — a\n * non-schema served as one — and nothing else.\n *\n * The list is therefore deliberately **generous**, covering the standard\n * validation and applicator vocabularies across draft-04 through 2020-12. The\n * two failure directions are not symmetric: letting an odd payload through\n * means it fails at compile time or behaves as the permissive schema it\n * literally is, while rejecting a real schema breaks a working setup outright.\n * A schema whose only root keyword is `if`/`then` or `patternProperties` is\n * perfectly ordinary, and an error envelope carries none of these.\n */\nconst SCHEMA_KEYS = [\n // Core identity and reference\n \"$schema\",\n \"$id\",\n \"$ref\",\n \"$defs\",\n \"definitions\",\n // Applicators\n \"allOf\",\n \"anyOf\",\n \"oneOf\",\n \"not\",\n \"if\",\n \"then\",\n \"else\",\n \"dependentSchemas\",\n \"dependencies\",\n // Object shape\n \"type\",\n \"properties\",\n \"required\",\n \"additionalProperties\",\n \"patternProperties\",\n \"propertyNames\",\n \"unevaluatedProperties\",\n \"dependentRequired\",\n \"minProperties\",\n \"maxProperties\",\n // Array shape\n \"items\",\n \"prefixItems\",\n \"contains\",\n \"unevaluatedItems\",\n \"minItems\",\n \"maxItems\",\n \"uniqueItems\",\n \"minContains\",\n \"maxContains\",\n // Scalar constraints\n \"enum\",\n \"const\",\n \"format\",\n \"pattern\",\n \"minLength\",\n \"maxLength\",\n \"minimum\",\n \"maximum\",\n \"exclusiveMinimum\",\n \"exclusiveMaximum\",\n \"multipleOf\",\n] as const;\n\n/**\n * Backoff before the single retry.\n *\n * One attempt, not three: the timeout already means a hung host costs\n * `timeoutMs`, and three retries would make that three times over per URL. One\n * removes the most common flake at a bounded cost.\n */\nconst RETRY_DELAY_MS = 500;\n\n/**\n * Not `unref`'d, deliberately. During the backoff this timer is frequently the\n * only thing left on the event loop — an unref'd one lets node exit **0 with no\n * output at all**, turning a failed fetch into a silent green run.\n */\nconst wait = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/**\n * What a config recorded about one reference beyond the reference itself.\n *\n * Kept out of the ref string deliberately: the ref appears in every report,\n * every baseline fingerprint, and `Validator`'s compile cache key, so it has to\n * stay exactly the string the user wrote.\n */\nexport interface SchemaPin {\n /** Where the reference was vendored from — a URL, or a local path. */\n source?: string;\n /** `sha256-<64 hex>` the file's bytes must hash to. */\n integrity?: string;\n}\n\nexport interface LoadSchemaOptions {\n /**\n * Directory a **relative local-file** ref is resolved against.\n *\n * Omitted means `process.cwd()`, which is what the CLI wants and what this\n * always did. A library caller passing `cwd` to a command core needs the\n * ref measured from *that* directory instead: `rebaseConfigSchemaRefs`\n * deliberately leaves refs untouched when the config already sits in the\n * run's `cwd`, so `./schema/house.json` arrives here exactly as written and\n * was then read against the wrong directory.\n *\n * Resolved at read time rather than by rewriting the ref, and that choice is\n * load-bearing: the ref string is what reports name, what `Validator` keys\n * its compile cache on, and what every baseline fingerprint is taken over.\n * Rewriting it to an absolute path would silently move every recorded\n * baseline. `canonicalSchemaRef` in `baseline.ts` already measures a relative\n * ref from the run's `cwd`, so this makes loading agree with fingerprinting\n * rather than introducing a new convention.\n */\n fileBase?: string;\n /** Abort a remote fetch after this many ms (default 10_000). */\n timeoutMs?: number;\n /** Reject a remote schema whose body exceeds this many bytes (default 5 MB). */\n maxBytes?: number;\n /**\n * Directory for the cross-run schema cache. Omitted means **no disk cache**:\n * the registry never guesses a project root, so a library caller gets the\n * in-process behavior until it opts in. The command cores pass\n * `schemaCacheDir(configDir ?? cwd)`.\n */\n cacheDir?: string;\n /** Hours a cached entry stays fresh; `0` disables the cache (default 24). */\n ttlHours?: number;\n /**\n * Never touch the network. A URL ref resolves from the disk cache — ignoring\n * the TTL, since there is no re-fetch to fall back on — and an uncached one\n * fails naming the URL. Built-ins and local files are unaffected.\n *\n * This is a *durability* control, not a trust boundary, and it never was:\n * whether a document may name a URL at all is decided upstream by\n * `schemaTrust` in `resolveSchemaSet`, which is the last place that still\n * knows a ref came from a document rather than from an operator (proposal\n * 0015). `offline` used to block that case by accident and was the only thing\n * standing there; it is now free to mean only what it says.\n */\n offline?: boolean;\n /**\n * Provenance and integrity pins, keyed on the reference exactly as it is\n * passed to `loadSchema`. Built by `collectSchemaPins` from the **rebased**\n * config, so both sides spell a local path the same way; a config with no\n * mapping-form `schemas:` entries produces an empty map and none of this\n * runs.\n */\n pins?: ReadonlyMap<string, SchemaPin>;\n}\n\n/**\n * A fetch failure a second attempt might not hit: a network-level error, or a\n * 5xx. Never a 4xx — a 404 will not heal, and retrying it only doubles the\n * cost of a misconfiguration.\n *\n * Extends `DocmetaError` so that if the retry also fails, the error escaping\n * this module is already the operational error the CLI knows how to report.\n */\nclass RetryableFetchError extends DocmetaError {}\n\n/** An abort — ours are only ever raised by the request's timeout signal. */\nfunction isAbort(err: unknown): boolean {\n const name = (err as { name?: unknown } | null)?.name;\n return name === \"TimeoutError\" || name === \"AbortError\";\n}\n\n/**\n * The `JSON.parse` messages that splice a prefix of the parsed text into\n * themselves: `Unexpected token 'r', \"root:x:0:0\"... is not valid JSON`, with\n * an optional leading `...` when the failure is mid-document.\n *\n * The other family — `Expected ':' after property name in JSON at position 4\n * (line 1 column 5)` — quotes nothing back and is left exactly as V8 wrote it.\n */\nconst JSON_PARSE_EXCERPT =\n /^Unexpected token '[\\s\\S]', (?:\\.\\.\\.)?\"([\\s\\S]*)\"(?:\\.\\.\\.)? is not valid JSON$/;\n\n/** 1-based position of `index` in `text`, for an error message. */\nfunction lineColumn(text: string, index: number): string {\n let line = 1;\n let column = 1;\n const stop = Math.min(index, text.length);\n for (let i = 0; i < stop; i++) {\n if (text.charCodeAt(i) === 10) {\n line += 1;\n column = 1;\n } else {\n column += 1;\n }\n }\n return `line ${line} column ${column}`;\n}\n\n/**\n * A parse failure for a **file** ref, with the file's own bytes taken out.\n *\n * The excerpt V8 embeds is content off the operator's disk, and this message\n * reaches stderr *and* the `json`/`sarif` reports the formats workflow uploads\n * to code scanning — so before proposal 0015 it was readable by whoever opened\n * the pull request, roughly ten bytes per run and repeatable with a different\n * path each time.\n *\n * Position is what the operator actually needs, and it survives: the excerpt is\n * located in the text we just tried to parse, and its line and column are\n * reported instead of the excerpt itself. \"Where\", without the \"what\".\n *\n * Deliberately **not** applied to the remote-response excerpt above. `73c625f`\n * put that in front of the operator on purpose, and a response body from a URL\n * the operator configured is a different thing from bytes off their disk.\n */\nfunction withoutFileExcerpt(message: string, text: string): string {\n const match = JSON_PARSE_EXCERPT.exec(message);\n if (!match) return message;\n const quoted = match[1];\n const at = quoted === undefined || quoted === \"\" ? -1 : text.indexOf(quoted);\n return at < 0 ? \"unexpected token\" : `unexpected token at ${lineColumn(text, at)}`;\n}\n\n/** A short, single-line sample of a response body, for an error message. */\nfunction excerpt(raw: string, limit = 200): string {\n const flat = raw.replace(/\\s+/g, \" \").trim();\n return flat.length > limit ? `${flat.slice(0, limit)}…` : flat;\n}\n\n/**\n * Read a response body, aborting once it exceeds `maxBytes`.\n *\n * Counts the bytes actually received. `content-length` is advisory — it may be\n * absent on a chunked response and it may simply be a lie — so it is never\n * consulted; trusting it is what leaves the cap bypassable.\n */\nasync function readCappedBody(\n ref: string,\n res: Response,\n maxBytes: number,\n): Promise<Buffer> {\n const body = res.body;\n if (!body) return Buffer.alloc(0);\n // `@types/node` types `Response.body` as `ReadableStream<any>`, so every\n // chunk would arrive as `any` and the size accounting below would be done in\n // `any` arithmetic — which is how a cap silently stops being a cap. Name the\n // chunk type once, here, at the boundary where the `any` enters.\n const reader = body.getReader() as ReadableStreamDefaultReader<Uint8Array>;\n const chunks: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n // Annotated `value?:` rather than taking `ReadableStreamReadResult`'s\n // word for it. That type is the more precise of the two — a discriminated\n // union promising a value whenever `done` is false — and it is deliberately\n // not used here: the promise is the *stream implementation's* to keep, not\n // something the reader enforces, and the guard below is only meaningful\n // while the type admits the case it guards.\n const { done, value }: { done: boolean; value?: Uint8Array } =\n await reader.read();\n if (done) break;\n // `Uint8Array` is always truthy, even at length 0, so this only ever\n // means \"no chunk this turn\" — not \"skip an empty chunk\".\n if (value === undefined) continue;\n total += value.byteLength;\n if (total > maxBytes) {\n throw new DocmetaError(\n `Schema \"${ref}\" is too large: the response exceeds the ${maxBytes}-byte limit.`,\n );\n }\n chunks.push(value);\n }\n } finally {\n // Drop the rest of the response when we bailed out early; a no-op once the\n // stream has already completed.\n void reader.cancel().catch(() => {});\n }\n // Concatenate rather than decoding per chunk: a multi-byte character can\n // straddle a chunk boundary. `total` is already exact, so passing it spares\n // `concat` a second pass to re-derive the same length.\n //\n // Returned as **bytes**. `schemas vendor` hashes and writes exactly what the\n // server sent, and a decode/re-encode round trip through a UTF-8 string is\n // lossy for a payload that is not valid UTF-8 — which would make an integrity\n // pin wrong in precisely the case it exists to catch.\n return Buffer.concat(chunks, total);\n}\n\n/**\n * Reject a fetched payload that is not a schema.\n *\n * Only remote refs are guarded. A local file or a built-in is something the\n * user chose deliberately and can inspect, and a no-op contract there is their\n * call; a URL is a live third party that can answer with anything.\n */\nfunction assertFetchedSchema(\n ref: string,\n value: unknown,\n raw: string,\n): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n // A bare `true` is a legal JSON Schema meaning \"everything passes\" — the\n // same false green as an envelope, and never what a published document\n // contract means.\n return failNotASchema(\n ref,\n raw,\n `expected a JSON object, got ${Array.isArray(value) ? \"an array\" : `a ${typeof value}`}`,\n );\n }\n const schema = value as Record<string, unknown>;\n if (!SCHEMA_KEYS.some((key) => key in schema)) {\n return failNotASchema(\n ref,\n raw,\n // Diagnosis only. Naming all ~47 accepted keywords here pushed several\n // hundred characters between the operator and the response excerpt below,\n // which is the part that actually identifies the culprit. The full list\n // is reference material and lives in the schema-resolution docs.\n \"it carries no JSON Schema keyword, so it constrains nothing and every \" +\n \"document would pass it\",\n );\n }\n return schema;\n}\n\nfunction failNotASchema(ref: string, raw: string, reason: string): never {\n throw new DocmetaError(\n `Schema \"${ref}\" does not look like a JSON Schema: ${reason}. ` +\n `The server returned: ${excerpt(raw)}`,\n );\n}\n\n/**\n * One request, returning an OK response.\n *\n * A network error and a 5xx are raised as `RetryableFetchError`; a 4xx and a\n * timeout are not. The timeout is deliberate: it is already the budget for a\n * host that is not answering, so retrying it buys no new information and\n * doubles the ceiling per URL.\n */\nasync function requestSchema(\n ref: string,\n timeoutMs: number,\n timedOut: DocmetaError,\n): Promise<Response> {\n let res: Response;\n try {\n res = await fetch(ref, { signal: AbortSignal.timeout(timeoutMs) });\n } catch (err) {\n if (isAbort(err)) throw timedOut;\n throw new RetryableFetchError(\n `Failed to fetch schema \"${ref}\": ${errorMessage(err)}`,\n );\n }\n if (!res.ok) {\n // Discard the body: nothing reads it, and leaving it undrained can hold the\n // socket open — which matters now that a second request may follow.\n void res.body?.cancel().catch(() => {});\n const message = `Failed to fetch schema \"${ref}\": HTTP ${res.status}.`;\n throw res.status >= 500\n ? new RetryableFetchError(message)\n : new DocmetaError(message);\n }\n return res;\n}\n\n/** A fetched schema, with the bytes it arrived as. */\nexport interface FetchedSchema {\n /** Exactly what the server sent, undecoded. */\n bytes: Buffer;\n /** The same payload, parsed and guarded. */\n schema: Record<string, unknown>;\n}\n\n/**\n * Fetch, size-cap, parse, and guard a remote schema. At most two requests.\n *\n * Exported for `schemas vendor`, which needs the raw bytes to write and to\n * hash. Sharing this path rather than fetching separately is what keeps\n * vendoring subject to the same size cap, retry policy, and payload guard as\n * validation — a vendored error envelope would otherwise be committed to the\n * repository and pass every document from then on.\n *\n * Deliberately **not** routed through the disk cache or `offline`: vendoring is\n * an explicit request to download, and the cache stores a parsed schema rather\n * than the bytes a pin has to be taken over.\n */\nexport async function fetchSchemaBytes(\n ref: string,\n options: LoadSchemaOptions = {},\n): Promise<FetchedSchema> {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;\n const timedOut = new DocmetaError(\n `Failed to fetch schema \"${ref}\": timed out after ${timeoutMs}ms.`,\n );\n\n let res: Response;\n try {\n res = await requestSchema(ref, timeoutMs, timedOut);\n } catch (err) {\n if (!(err instanceof RetryableFetchError)) throw err;\n await wait(RETRY_DELAY_MS);\n // The second attempt is the last one. If it fails the same way, the error\n // is already a `DocmetaError` and propagates as the operational failure it\n // is.\n res = await requestSchema(ref, timeoutMs, timedOut);\n }\n\n let bytes: Buffer;\n try {\n bytes = await readCappedBody(ref, res, maxBytes);\n } catch (err) {\n if (err instanceof DocmetaError) throw err;\n // The headers arrive first, so a timeout during the body lands here rather\n // than on the `fetch` above. Reporting it as a parse failure — which is\n // what reading the body as JSON in one step did — points the operator at\n // the schema author instead of at the network.\n if (isAbort(err)) throw timedOut;\n throw new DocmetaError(\n `Failed to fetch schema \"${ref}\": ${errorMessage(err)}`,\n );\n }\n\n // `bytes` is returned untouched below — `schemas vendor` hashes it and writes\n // it, so the vendored copy is what the server actually sent. Only the string\n // we parse loses the BOM. See `stripBom`.\n const raw = stripBom(bytes.toString(\"utf8\"));\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new DocmetaError(\n `Schema \"${ref}\" did not return valid JSON: ${errorMessage(err)}`,\n );\n }\n\n return { bytes, schema: assertFetchedSchema(ref, parsed, raw) };\n}\n\n/**\n * Resolve one remote ref: disk cache, then the network.\n *\n * Runs **inside** the in-flight promise the url branch stores, not beside it.\n * Hoisting the cache read out would put an `await` between the miss and the\n * `set`, which is the check-then-act race `urlInflight` exists to close — and\n * it would also let `fill`'s worker pool race N writes onto one cache file.\n */\nasync function resolveRemote(\n ref: string,\n options: LoadSchemaOptions,\n): Promise<Record<string, unknown>> {\n // Hoisted rather than read twice: `cache` is derived from it, so branching on\n // `cacheDir` first is what lets the compiler see that a working cache implies\n // a directory worth naming in the remedy below.\n const cacheDir = options.cacheDir;\n const cache = cacheDir\n ? new SchemaCache(cacheDir, options.ttlHours ?? DEFAULT_TTL_HOURS)\n : null;\n\n if (cache) {\n // Offline ignores the TTL: expiry exists to trigger a re-fetch, and there\n // is none available, so a stale contract beats no contract at all.\n const hit = await cache.read(ref, { ignoreTtl: options.offline === true });\n if (hit) {\n urlCache.set(ref, hit);\n // Served from disk, so an offline call may use this memo from now on.\n urlFromNetwork.delete(ref);\n return hit;\n }\n }\n\n if (options.offline === true) {\n // The remedy depends on the configuration, and the old wording named a\n // hard-coded directory while advising a re-run that could never help. With\n // no cache configured, or with the TTL set to 0, running online populates\n // nothing — so saying \"run once online\" there sends the operator in a\n // circle.\n // Branch on whether the cache *works*, not on whether the object exists.\n // `cacheDir` is always supplied by the CLI, so `cache` is non-null even\n // when `ttlHours: 0` has disabled reads and writes alike — and telling that\n // user to \"run once without --offline to populate the cache\" is advice that\n // can never work, which is the circular remedy this message was rewritten\n // to remove.\n // Three cases, not two, because \"no cache\" and \"cache switched off\" have\n // different remedies and naming the wrong one is what made the earlier\n // versions of this message send people in circles.\n // Same three cases, ordered so `cacheDir` is narrowed to a string by the\n // time the first branch interpolates it.\n const remedy =\n cacheDir === undefined\n ? \"No schema cache is configured for this run, so there is nothing for --offline to read. Pass a `cacheDir`, or point the reference at a local file or a built-in id.\"\n : cache?.enabled\n ? `Run once without --offline to populate ${cacheDir}, or point the reference at a local file.`\n : \"The schema cache is switched off (`schemaCache.ttlHours: 0`), so there is nothing for --offline to read. Set a non-zero `schemaCache.ttlHours`, or point the reference at a local file or a built-in id.\";\n throw new DocmetaError(\n `Cannot resolve schema \"${ref}\": --offline is set and it could not be served from cache. ${remedy}`,\n );\n }\n\n const { schema } = await fetchSchemaBytes(ref, options);\n urlCache.set(ref, schema);\n urlFromNetwork.add(ref);\n if (cache && (await cache.write(ref, schema))) {\n // Only once the entry really landed. `write` swallows its failures by\n // design — a read-only checkout must not fail the run — so clearing the\n // mark unconditionally would tell a later offline call it may use the memo\n // for a schema that never reached disk: the same false pass, one step\n // narrower.\n urlFromNetwork.delete(ref);\n }\n return schema;\n}\n\n/**\n * Settle the remote-schema options for one run, from the config and the flag.\n *\n * Lives here rather than in a command core because all three commands need the\n * same answer, and because \"where does the cache live\" is a property of schema\n * loading, not of `validate`. `root` is the config's directory when a config\n * governs the run, so a developer running from `docs/` shares the cache with\n * CI running from the repo root instead of quietly keeping a second one.\n */\nexport function schemaLoadOptions(args: {\n root: string;\n /**\n * Where a relative local-file schema ref is measured from — the run's `cwd`,\n * not `root`. The two differ when a config was discovered in an ancestor, and\n * a `--schema ./x.json` typed on the command line belongs to the directory\n * the user was standing in, not to the config's.\n */\n fileBase?: string;\n /** Config `schemaCache.ttlHours`. */\n ttlHours?: number;\n /** `--offline`, else config `offline:`. */\n offline?: boolean;\n /** From `collectSchemaPins(config)`; omitted when the config pins nothing. */\n pins?: ReadonlyMap<string, SchemaPin>;\n}): LoadSchemaOptions {\n return {\n cacheDir: schemaCacheDir(args.root),\n ...(args.fileBase !== undefined ? { fileBase: args.fileBase } : {}),\n ...(args.ttlHours !== undefined ? { ttlHours: args.ttlHours } : {}),\n ...(args.offline !== undefined ? { offline: args.offline } : {}),\n // An empty map is dropped so a config with no mapping-form entries produces\n // exactly the options object it produced before 0008.\n ...(args.pins !== undefined && args.pins.size > 0\n ? { pins: args.pins }\n : {}),\n };\n}\n\n/**\n * How to get the bytes of a pinned reference back, for an error message.\n *\n * Two states, and they lead different places: the config recorded where the\n * schema came from, or it did not. Advising a re-vendor without a `source` to\n * re-vendor *from* is the kind of remedy that sends an operator in a circle.\n */\nfunction repinAdvice(ref: string, pin: SchemaPin): string {\n return pin.source !== undefined\n ? `Re-download it with \\`manni meta schemas vendor ${pin.source}\\`, or update the recorded integrity if the change was intended.`\n : `Restore the file from version control, or record the new bytes by re-running \\`manni meta schemas vendor\\` with the URL this copy came from. (No \\`source:\\` is recorded for \"${ref}\", so manni cannot say where that is.)`;\n}\n\n/**\n * Check a local schema file against its recorded pin.\n *\n * Three outcomes, all of them enumerated rather than defaulted: the pin is not\n * one this version can verify, the bytes match, or they do not — and in the\n * last case the *reason* is narrowed further, because a CRLF checkout of an LF\n * download is a mismatch on a file nobody edited and reads as corruption unless\n * it is named.\n */\nfunction assertIntegrity(\n ref: string,\n bytes: Buffer,\n pin: SchemaPin,\n integrity: string,\n): void {\n // Reachable only from a library caller building pins by hand; the config\n // parser rejects a malformed pin at its source, where the line number is.\n if (!isIntegrity(integrity)) {\n throw new DocmetaError(\n `Schema \"${ref}\" has an integrity pin manni cannot verify: \"${integrity}\". Expected \"${INTEGRITY_SHAPE}\".`,\n );\n }\n const found = integrityOf(bytes);\n if (found === integrity) return;\n\n const because =\n diagnoseIntegrity(bytes, integrity) === \"line-endings\"\n ? `The contents differ only in line endings, so this is almost certainly a checkout converting them rather than an edit — keep the file byte-exact with a \\`.gitattributes\\` rule such as \\`${ref.split(/[\\\\/]/).pop() ?? \"*.json\"} -text\\`.`\n : \"The file's contents have changed since it was vendored.\";\n\n throw new DocmetaError(\n `Schema \"${ref}\" does not match its recorded integrity.\\n` +\n ` expected ${integrity}\\n` +\n ` found ${found}\\n` +\n `${because} ${repinAdvice(ref, pin)}`,\n );\n}\n\n/** Load and return the JSON Schema object for a reference. */\nexport async function loadSchema(\n ref: string,\n options: LoadSchemaOptions = {},\n): Promise<Record<string, unknown>> {\n const { kind } = classifyRef(ref);\n const pin = options.pins?.get(ref);\n\n // A pin on anything but a local file cannot be checked: a built-in has no\n // bytes on disk, and a URL may legitimately be served from the schema cache,\n // which stores the parsed schema rather than what the server sent. Silently\n // skipping it would leave a config that reads as pinned and is not, so this\n // fails loudly instead. The config parser rejects the same thing earlier and\n // with a better message; this catches a library caller.\n if (pin?.integrity !== undefined && kind !== \"file\") {\n throw new DocmetaError(\n `Schema \"${ref}\" carries an integrity pin, but a pin can only be verified against a local file (this is a ${kind === \"url\" ? \"URL\" : \"built-in id\"}). Vendor it with \\`manni meta schemas vendor\\`, or drop the pin.`,\n );\n }\n\n if (kind === \"builtin\") {\n const schema = BUILTINS.get(ref);\n if (!schema) {\n const available = [...BUILTINS.keys()].join(\", \");\n throw new DocmetaError(\n `Unknown built-in schema \"${ref}\". Available: ${available || \"(none)\"}.`,\n );\n }\n return schema;\n }\n\n if (kind === \"url\") {\n // First, ahead of every cache and every request: a URL docmeta publishes is\n // one of its own built-ins, and resolving it over the network would be\n // slower, subject to the timeout, broken offline, and broken air-gapped —\n // for a file that is already in this package. Returning the bundled object\n // itself (not a copy) also keeps the two spellings sharing one Ajv\n // registration, since `Validator.compileUncached` dedupes on `$id`.\n //\n // Placed inside the url branch rather than before it deliberately: an\n // integrity pin on a non-file ref is refused above, and that stays true for\n // a published URL. The pin would have nothing to verify — no bytes are\n // fetched — and a pin that silently checked nothing reads as protection\n // that is not there. Vendor the file if you want a pinned copy.\n // The same resolution `isPublishedBuiltinUrl` uses, so a URL the trust\n // boundary treated as a built-in cannot arrive here and be fetched.\n const published = publishedBuiltinSchema(ref);\n if (published) return published;\n\n const cached = urlCache.get(ref);\n // An offline call must not be satisfied by something this process pulled\n // over the network; it goes back through `resolveRemote` so the disk cache\n // and the guard both apply, exactly as they would in a fresh process.\n if (cached && !(options.offline === true && urlFromNetwork.has(ref))) {\n return cached;\n }\n const key = inflightKey(ref, options.offline);\n const inflight = urlInflight.get(key);\n // A caller joining an in-flight fetch inherits the first caller's\n // `timeoutMs`/`maxBytes` — there is one request, so there is one set of\n // limits. Every production call site uses the defaults, so this is only\n // reachable from a library consumer passing custom options for a URL\n // another call is already fetching.\n if (inflight) return inflight;\n // Synchronous by design: the `set` has to happen in the same tick as the\n // miss, or a second caller slips in before the entry exists and fetches\n // again.\n const pending = resolveRemote(ref, options);\n urlInflight.set(key, pending);\n // Evict once settled, either way. This map exists only to collapse\n // *concurrent* callers onto one request; `urlCache` is the actual cache and\n // is consulted first, so a resolved entry left here is a duplicate handle\n // that would accumulate one per distinct URL for the life of the process.\n // Eviction is safe at this point because `fetchSchema` populates `urlCache`\n // before it resolves, so a caller arriving after the delete finds the\n // schema rather than re-fetching.\n //\n // A failed fetch is likewise not retained, so a transient failure stays\n // retryable rather than poisoning the ref. The `catch` before `finally`\n // keeps this chain off the returned promise: without it, a rejection would\n // surface here as an unhandled one, and the caller's own rejection must\n // remain theirs to handle.\n void pending\n .catch(() => {})\n .finally(() => {\n if (urlInflight.get(key) === pending) urlInflight.delete(key);\n });\n return pending;\n }\n\n // file\n //\n // `resolve` is a no-op on an already-absolute ref, which is the shape\n // `rebaseConfigSchemaRefs` produces when the config lives somewhere other\n // than the run's `cwd`. So both paths land here correctly: an absolute ref\n // passes through, and a relative one is measured from the run's directory.\n // The pin is checked against that same resolved file, so a vendored schema\n // verifies from a library caller's `cwd` as well as from the CLI's.\n // A local file ref. `resolveSchemaSet` has already refused this one if a\n // *document* named it and it pointed outside the repository (proposal 0015);\n // by here the ref is just a string and that provenance is gone.\n const file = resolvePath(options.fileBase ?? process.cwd(), ref);\n let bytes: Buffer;\n try {\n // Bytes, not a decoded string: the pin below is taken over what is actually\n // on disk, and a UTF-8 round trip would silently repair a payload that is\n // not valid UTF-8 into one that hashes differently from the vendored copy.\n bytes = await readFile(file);\n } catch {\n // A vendored schema that is missing is a different problem from a mistyped\n // path — the file is supposed to be committed, so it is either not checked\n // in or the checkout is partial. Say where it came from when the config\n // recorded that.\n //\n // Either way it names the ref as written rather than the resolved path:\n // that is the string the user put in their config, and the one every other\n // message uses for it.\n throw new DocmetaError(\n pin?.source !== undefined\n ? `Schema file not found: \"${ref}\". It was vendored from ${pin.source}; commit the file, or re-download it with \\`manni meta schemas vendor ${pin.source}\\`.`\n : `Schema file not found: \"${ref}\".`,\n );\n }\n if (pin?.integrity !== undefined) {\n assertIntegrity(ref, bytes, pin, pin.integrity);\n }\n // After `assertIntegrity`, deliberately: the pin covers the bytes on disk,\n // BOM and all. See `stripBom`.\n const text = stripBom(bytes.toString(\"utf8\"));\n try {\n return JSON.parse(text) as Record<string, unknown>;\n } catch (err) {\n throw new DocmetaError(\n `Schema file \"${ref}\" is not valid JSON: ${withoutFileExcerpt(errorMessage(err), text)}`,\n );\n }\n}\n","/**\n * Concessions that belong to **JSON as text**, and to nothing else: reading it\n * into a value, and writing a value back out.\n *\n * Its own module so each rule below has one statement rather than several, and\n * so the constraint that makes it subtle is written down once, next to the code\n * it constrains.\n */\n\n/**\n * Drop a leading byte-order mark.\n *\n * `EF BB BF` at the head of a UTF-8 file decodes to U+FEFF, and Node's\n * `JSON.parse` rejects it — while almost every other tool accepts it. Windows\n * editors write it routinely: PowerShell 5.1's `Set-Content -Encoding utf8`,\n * Notepad, older VS Code configurations. The result was a schema file that\n * every other JSON tool read happily failing as\n * `is not valid JSON: unexpected token at line 1 column 1`, which reads as an\n * empty or corrupt file and points the operator nowhere near the cause.\n *\n * **Apply this to the decoded string that is about to be parsed, never to the\n * bytes.** An integrity pin is taken over exactly what is on disk or exactly\n * what a server sent, BOM included, and `schemas vendor` writes those same\n * bytes to the vendored copy. Stripping anywhere upstream of the hash would\n * make every pinned BOM'd schema fail its own pin, and would make the vendored\n * file differ from the source it claims to be a copy of. Parsing is the only\n * step that cares.\n *\n * Only U+FEFF, and only leading: a BOM anywhere else is real content, and\n * UTF-16/UTF-32 marks are a different problem — those files are not valid UTF-8\n * at all, and reporting them as bad JSON is honest.\n */\nexport function stripBom(text: string): string {\n return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n}\n\n/**\n * The indent an object-per-line JSON file uses, read off its first indented\n * line. The known blind spot is shared by every caller on purpose: a\n * single-line or minified file yields the two-space fallback and gets\n * re-emitted pretty-printed — acceptable for files whose edits are meant to be\n * read in a diff, and better stated once here than diverging per copy.\n */\nexport function detectJsonIndent(text: string): string {\n return /^\\{\\s*\\n([ \\t]+)/.exec(text)?.[1] ?? \" \";\n}\n\n/**\n * `JSON.stringify`, with the return type it actually has.\n *\n * `lib.es5.d.ts` declares the common overload as returning `string`, and that\n * is a lie the language ships with: `undefined`, a function and a symbol each\n * stringify to `undefined`, as does any value whose `toJSON` returns one. Four\n * places in this repo already handle that with `?? fallback` — and against the\n * declared type every one of those fallbacks reads as dead code, which is\n * exactly how a live guard eventually gets tidied away.\n *\n * The fallback stays the caller's decision, because it differs: `infer` samples\n * want an empty cell, `fill`'s canonical form wants the values kept *distinct*\n * from each other. This only makes the possibility visible.\n */\nexport function toJsonText(value: unknown): string | undefined {\n return JSON.stringify(value);\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"google:okf:0.1\",\n \"title\": \"Open Knowledge Format (OKF) v0.1\",\n \"description\": \"Frontmatter schema for OKF v0.1 concept files. OKF requires only `type`; all other fields are recommended, and unknown keys are explicitly tolerated. See https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md\",\n \"type\": \"object\",\n \"required\": [\"type\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"A short string identifying the kind of concept. Used for routing, filtering, and presentation.\"\n },\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Human-readable display name. If omitted, consumers MAY derive a title from the filename.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Single-sentence summary used for indexing and previews.\"\n },\n \"resource\": {\n \"type\": \"string\",\n \"format\": \"uri\",\n \"description\": \"A URI uniquely identifying the underlying asset. Absent for abstract concepts.\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"Short strings for categorization.\"\n },\n \"timestamp\": {\n \"type\": \"string\",\n \"format\": \"date-time\",\n \"description\": \"ISO 8601 datetime of last meaningful change.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"diataxis:diataxis:1.0\",\n \"title\": \"Diataxis documentation types v1.0\",\n \"description\": \"Requires `type` and constrains it to the four Diataxis forms. Adopting Diataxis is a statement that every page is one of the four, so an untyped page is a gap rather than an abstention. Like tgdp:templates:1.0 it classifies what a page *is*, so both claim the same key: stacking them narrows `type` to the intersection of the two vocabularies, so pick one. It composes freely with a schema keyed on a different field, such as passo-uno:seven-action:1.0. See https://diataxis.fr/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"required\": [\"type\"],\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"tutorial\", \"how-to\", \"reference\", \"explanation\"],\n \"description\": \"Which of the four Diataxis forms this page is. `tutorial` is learning-oriented, `how-to` is task-oriented, `reference` is information-oriented, and `explanation` is understanding-oriented.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"passo-uno:seven-action:1.0\",\n \"title\": \"Seven-Action Documentation Model v1.0\",\n \"description\": \"Constrains `action` to the seven reader actions of the Seven-Action Documentation Model (upstream model version 2025-01-09). `action` names what the reader is doing, which is independent of what the page is, so this schema composes with a content-type schema keyed on `type`. Vocabulary only: `action` is not required. See https://passo.uno/seven-action-model/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"action\": {\n \"type\": \"string\",\n \"enum\": [\n \"appraise\",\n \"understand\",\n \"explore\",\n \"practice\",\n \"remember\",\n \"develop\",\n \"troubleshoot\"\n ],\n \"description\": \"What the reader is trying to do on this page: `appraise` (discern whether something fits), `understand` (learn a concept), `explore` (discover what exists), `practice` (train a skill), `remember` (recall a detail), `develop` (integrate it into their own work), or `troubleshoot` (solve a problem).\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"tgdp:templates:1.0\",\n \"title\": \"The Good Docs Project template types v1.0\",\n \"description\": \"Requires `type` and constrains it to the 25 template slugs published by The Good Docs Project (upstream templates repo, main as of 2026-08-09). Unlike passo-uno:seven-action:1.0, which checks a value only if one is present, this schema also demands the key: adopting it is a statement that every page is one of the templates, so an untyped page is a gap. Like Diataxis it classifies what a page *is*, so both claim the same key: stacking them is not an error, but it narrows `type` to the intersection of the two vocabularies, so pick one. It composes freely with a schema keyed on a different field, such as passo-uno:seven-action:1.0. See https://www.thegooddocsproject.dev/template\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"required\": [\"type\"],\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\n \"api-getting-started\",\n \"api-reference\",\n \"bug-report\",\n \"changelog\",\n \"code-of-conduct\",\n \"code-of-conduct-incident-record\",\n \"code-of-conduct-remediation-record\",\n \"code-of-conduct-response-plan\",\n \"concept\",\n \"contact-support\",\n \"contributing-guide\",\n \"glossary\",\n \"how-to\",\n \"installation-guide\",\n \"our-team\",\n \"quickstart\",\n \"readme\",\n \"reference\",\n \"release-notes\",\n \"sdk-overview\",\n \"style-guide\",\n \"terminology-system\",\n \"troubleshooting\",\n \"tutorial\",\n \"user-personas\"\n ],\n \"description\": \"Which Good Docs Project template this page follows, as the template's slug. The Core pack is `concept`, `how-to`, `readme`, `reference`, `release-notes`, `troubleshooting`, and `tutorial`; the rest come from the Community and Misc packs.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"docusaurus:docs:3.10\",\n \"title\": \"Docusaurus docs front matter v3.10\",\n \"description\": \"Front matter accepted by @docusaurus/plugin-content-docs as of Docusaurus 3.10. Docusaurus marks no field as required, so this is a format check, not a presence check: it constrains the shape of every field the plugin documents and requires none of them. Unknown keys are tolerated, matching Docusaurus, which allows theme and plugin front matter. It claims neither `type` nor `action`, so it composes with diataxis:diataxis:1.0, tgdp:templates:1.0, or passo-uno:seven-action:1.0. Stacking it with google:okf:0.1 is the one exception: both define `tags`, and OKF allows string tags only, so a Docusaurus tag object fails against OKF. Pair it with docusaurus:blog:3.10 and docusaurus:pages:3.10 via per-directory config overrides. See https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs#markdown-front-matter\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"description\": \"Unique document id. Defaults to the file path without the extension.\"\n },\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Text title used for page metadata. Defaults to the Markdown title, then the id. May be empty.\"\n },\n \"pagination_label\": {\n \"type\": \"string\",\n \"description\": \"Text shown in the next/previous buttons for this document. Defaults to `sidebar_label`, then `title`.\"\n },\n \"sidebar_label\": {\n \"type\": \"string\",\n \"description\": \"Text shown for this document in the sidebar. Defaults to `title`.\"\n },\n \"sidebar_position\": {\n \"type\": \"number\",\n \"description\": \"Position of this document in an autogenerated sidebar. A number, so quoting it makes it a string and Docusaurus rejects it.\"\n },\n \"sidebar_class_name\": {\n \"type\": \"string\",\n \"description\": \"Class name applied to this document's sidebar label.\"\n },\n \"sidebar_key\": {\n \"type\": \"string\",\n \"description\": \"Stable identifier for the sidebar item, used mainly for i18n.\"\n },\n \"sidebar_custom_props\": {\n \"type\": \"object\",\n \"description\": \"Arbitrary custom properties attached to this document's sidebar item.\"\n },\n \"displayed_sidebar\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Name of the sidebar to display when viewing this document, overriding the one it belongs to.\"\n },\n \"hide_title\": {\n \"type\": \"boolean\",\n \"description\": \"Hide the front matter title at the top of the page. Does not hide a Markdown `#` title.\"\n },\n \"hide_table_of_contents\": {\n \"type\": \"boolean\",\n \"description\": \"Hide the right-hand table of contents.\"\n },\n \"toc_min_heading_level\": {\n \"type\": \"number\",\n \"minimum\": 2,\n \"maximum\": 6,\n \"description\": \"Shallowest heading level shown in the table of contents. Between 2 and 6, and no deeper than `toc_max_heading_level`. Typed `number` rather than `integer` because upstream is `Joi.number().min(2).max(6)` with no `.integer()`; being stricter here would fail a page Docusaurus builds.\"\n },\n \"toc_max_heading_level\": {\n \"type\": \"number\",\n \"minimum\": 2,\n \"maximum\": 6,\n \"description\": \"Deepest heading level shown in the table of contents. Between 2 and 6. Typed `number` rather than `integer` to match upstream, as with `toc_min_heading_level`.\"\n },\n \"pagination_next\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Id of the document the \\\"Next\\\" link points to. `null` removes the link.\"\n },\n \"pagination_prev\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"Id of the document the \\\"Previous\\\" link points to. `null` removes the link.\"\n },\n \"parse_number_prefixes\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the number-prefix parser applies to this document, overriding the plugin's `numberPrefixParser` option.\"\n },\n \"custom_edit_url\": {\n \"type\": [\"string\", \"null\"],\n \"format\": \"uri-reference\",\n \"description\": \"URL of this document's edit page. `null` removes the edit link; a relative path is legal.\"\n },\n \"keywords\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"Keywords meta tag for search engines.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Meta description for search engines. Defaults to the first line of Markdown content. May be empty.\"\n },\n \"image\": {\n \"type\": \"string\",\n \"format\": \"uri-reference\",\n \"description\": \"Cover image used in social link previews. A site-root path such as `/img/card.png` is legal.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Custom URL for this document. Defaults to the file path.\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": [\"string\", \"object\"],\n \"required\": [\"label\", \"permalink\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"label\": { \"type\": \"string\" },\n \"permalink\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" }\n }\n },\n \"description\": \"Tags for this document: either a string, or an object carrying both a `label` and a `permalink`. `required` and `properties` bind only to the object form, so a plain string tag passes and a half-written object reports the key it is missing.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"A draft document is available in development only. Cannot be combined with `unlisted`.\"\n },\n \"unlisted\": {\n \"type\": \"boolean\",\n \"description\": \"An unlisted document is published but hidden from navigation, search, and sitemaps. Cannot be combined with `draft`.\"\n },\n \"last_update\": {\n \"type\": \"object\",\n \"minProperties\": 1,\n \"additionalProperties\": false,\n \"properties\": {\n \"author\": {\n \"type\": \"string\",\n \"description\": \"Overrides the last-update author.\"\n },\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Overrides the last-update date.\"\n }\n },\n \"description\": \"Overrides the computed last-update information. Takes `author`, `date`, or both, and at least one of them.\"\n }\n },\n \"if\": {\n \"required\": [\"draft\"],\n \"properties\": { \"draft\": { \"const\": true } }\n },\n \"then\": {\n \"properties\": { \"unlisted\": { \"const\": false } }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"docusaurus:blog:3.10\",\n \"title\": \"Docusaurus blog front matter v3.10\",\n \"description\": \"Front matter accepted by @docusaurus/plugin-content-blog as of Docusaurus 3.10. Docusaurus marks no field as required, so this is a format check, not a presence check. Unknown keys are tolerated, matching Docusaurus. `authors` is deliberately loose — a key, an inline author object, or a list of either — because Docusaurus resolves author entries against `authors.yml` rather than validating them strictly. The single-author `author*` keys are the deprecated spelling that `authors` replaces. It claims neither `type` nor `action`, so it composes with the taxonomy vocabularies; stacking it with google:okf:0.1 is the one exception, since both define `tags` and OKF allows string tags only. See https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-blog#markdown-front-matter\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"authors\": {\n \"description\": \"One author or several: a key from `authors.yml`, an inline author object, or a list mixing the two. The `$ref` types the inline-object form and `items` the list form, so each shape is checked without an anyOf that would report every alternative as a separate failure.\",\n \"type\": [\"string\", \"object\", \"array\"],\n \"$ref\": \"#/$defs/authorFields\",\n \"items\": { \"$ref\": \"#/$defs/author\" }\n },\n \"author\": {\n \"type\": \"string\",\n \"description\": \"Deprecated in favor of `authors`. The post author's name.\"\n },\n \"author_url\": {\n \"type\": \"string\",\n \"format\": \"uri-reference\",\n \"description\": \"Deprecated in favor of `authors`. URL of the author's profile page.\"\n },\n \"author_image_url\": {\n \"type\": \"string\",\n \"format\": \"uri-reference\",\n \"description\": \"Deprecated in favor of `authors`. URL of the author's thumbnail image.\"\n },\n \"author_title\": {\n \"type\": \"string\",\n \"description\": \"Deprecated in favor of `authors`. A description of the author.\"\n },\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Blog post title. Defaults to the Markdown title.\"\n },\n \"title_meta\": {\n \"type\": \"string\",\n \"description\": \"SEO title used for `<title>` and `og:title`. Defaults to `title`.\"\n },\n \"sidebar_label\": {\n \"type\": \"string\",\n \"description\": \"Text shown for this post in the blog sidebar. Defaults to `title`.\"\n },\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Post creation date. Defaults to a date parsed from the file name, then the file's creation time.\"\n },\n \"tags\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": [\"string\", \"object\"],\n \"required\": [\"label\", \"permalink\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"label\": { \"type\": \"string\" },\n \"permalink\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" }\n }\n },\n \"description\": \"Tags for this post: either a string, or an object carrying both a `label` and a `permalink`. `required` and `properties` bind only to the object form, so a plain string tag passes and a half-written object reports the key it is missing.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"A draft post is available in development only. Cannot be combined with `unlisted`.\"\n },\n \"unlisted\": {\n \"type\": \"boolean\",\n \"description\": \"An unlisted post is published but hidden from listings, search, and sitemaps. Cannot be combined with `draft`.\"\n },\n \"hide_table_of_contents\": {\n \"type\": \"boolean\",\n \"description\": \"Hide the right-hand table of contents.\"\n },\n \"toc_min_heading_level\": {\n \"type\": \"number\",\n \"minimum\": 2,\n \"maximum\": 6,\n \"description\": \"Shallowest heading level shown in the table of contents. Between 2 and 6, and no deeper than `toc_max_heading_level`. Typed `number` rather than `integer` because upstream is `Joi.number().min(2).max(6)` with no `.integer()`; being stricter here would fail a page Docusaurus builds.\"\n },\n \"toc_max_heading_level\": {\n \"type\": \"number\",\n \"minimum\": 2,\n \"maximum\": 6,\n \"description\": \"Deepest heading level shown in the table of contents. Between 2 and 6. Typed `number` rather than `integer` to match upstream, as with `toc_min_heading_level`.\"\n },\n \"keywords\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"Keywords meta tag for search engines.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Meta description for search engines. Defaults to the first line of Markdown content. May be empty.\"\n },\n \"image\": {\n \"type\": \"string\",\n \"format\": \"uri-reference\",\n \"description\": \"Cover image used in social link previews. A site-root path such as `/img/card.png` is legal.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Custom URL for this post. Defaults to the file path.\"\n },\n \"last_update\": {\n \"type\": \"object\",\n \"minProperties\": 1,\n \"additionalProperties\": false,\n \"properties\": {\n \"author\": {\n \"type\": \"string\",\n \"description\": \"Overrides the last-update author.\"\n },\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Overrides the last-update date.\"\n }\n },\n \"description\": \"Overrides the computed last-update information. Takes `author`, `date`, or both, and at least one of them.\"\n }\n },\n \"if\": {\n \"required\": [\"draft\"],\n \"properties\": { \"draft\": { \"const\": true } }\n },\n \"then\": {\n \"properties\": { \"unlisted\": { \"const\": false } }\n },\n \"$defs\": {\n \"authorFields\": {\n \"description\": \"The inline author fields, defined once and shared by the single-author and list forms so the two cannot drift apart. It declares no `type`, because `properties` is ignored for non-objects — that is what lets the single-author form apply it without excluding the string and array spellings.\",\n \"properties\": {\n \"key\": { \"type\": \"string\" },\n \"name\": { \"type\": \"string\" },\n \"title\": { \"type\": \"string\" },\n \"url\": { \"type\": \"string\", \"format\": \"uri-reference\" },\n \"imageURL\": { \"type\": \"string\", \"format\": \"uri-reference\" },\n \"email\": { \"type\": \"string\" },\n \"socials\": { \"type\": \"object\" },\n \"page\": { \"type\": [\"boolean\", \"object\"] }\n }\n },\n \"author\": {\n \"description\": \"One entry in an `authors` list: a key from `authors.yml`, or an inline author object.\",\n \"type\": [\"string\", \"object\"],\n \"$ref\": \"#/$defs/authorFields\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"docusaurus:pages:3.10\",\n \"title\": \"Docusaurus pages front matter v3.10\",\n \"description\": \"Front matter accepted by @docusaurus/plugin-content-pages as of Docusaurus 3.10. Docusaurus marks no field as required, so this is a format check, not a presence check. Unknown keys are tolerated, matching Docusaurus. The field set is the smallest of the three: standalone pages carry no sidebar, pagination, or tag metadata. See https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-pages#markdown-front-matter\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Page title. Defaults to the Markdown title. May be empty.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Meta description for search engines. Defaults to the first line of Markdown content. May be empty.\"\n },\n \"keywords\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"Keywords meta tag for search engines.\"\n },\n \"image\": {\n \"type\": \"string\",\n \"format\": \"uri-reference\",\n \"description\": \"Cover image used in social link previews. A site-root path such as `/img/card.png` is legal.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Custom URL for this page. Defaults to the file path; `/` makes it the site root.\"\n },\n \"wrapperClassName\": {\n \"type\": \"string\",\n \"description\": \"Class name added to the page wrapper, for targeting this page in CSS.\"\n },\n \"hide_table_of_contents\": {\n \"type\": \"boolean\",\n \"description\": \"Hide the right-hand table of contents.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"A draft page is available in development only. Cannot be combined with `unlisted`.\"\n },\n \"unlisted\": {\n \"type\": \"boolean\",\n \"description\": \"An unlisted page is published but hidden from search and sitemaps. Cannot be combined with `draft`.\"\n }\n },\n \"if\": {\n \"required\": [\"draft\"],\n \"properties\": { \"draft\": { \"const\": true } }\n },\n \"then\": {\n \"properties\": { \"unlisted\": { \"const\": false } }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"astro:starlight:0.41\",\n \"title\": \"Astro Starlight front matter v0.41\",\n \"description\": \"Front matter accepted by Astro Starlight as of 0.41. Unlike the Docusaurus built-ins, this one requires `title`: Starlight refuses to build a page without it, so its absence is an error rather than a default. Every other field is optional and checked only when present. Unknown keys are tolerated, matching Starlight's own schema extension mechanism. See https://starlight.astro.build/reference/frontmatter/\",\n \"type\": \"object\",\n \"required\": [\"title\"],\n \"additionalProperties\": true,\n \"$defs\": {\n \"linkRef\": {\n \"description\": \"A pagination link: `false` to hide it, `true` for the default, a string to relabel it, or an object to set both target and text. Branched with `if`/`then` rather than `anyOf` so a fault inside the object form is reported once, against the key that is wrong.\",\n \"if\": { \"type\": \"object\" },\n \"then\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"link\": { \"type\": \"string\" },\n \"label\": { \"type\": \"string\" }\n }\n },\n \"else\": { \"type\": [\"boolean\", \"string\"] }\n },\n \"headingLevel\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"maximum\": 6\n }\n },\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Shown at the top of the page, in the browser tab, and in page metadata. The only field Starlight requires.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Used for page metadata and search engine optimization.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Overrides the URL slug derived from the file path.\"\n },\n \"editUrl\": {\n \"type\": [\"string\", \"boolean\"],\n \"format\": \"uri-reference\",\n \"description\": \"Customizes the edit-page link, or disables it with `false`. The format constrains the string branch only.\"\n },\n \"head\": {\n \"type\": \"array\",\n \"description\": \"Additional tags injected into this page's `<head>`.\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"tag\"],\n \"properties\": {\n \"tag\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The tag name, such as `meta` or `script`.\"\n },\n \"attrs\": {\n \"type\": \"object\",\n \"description\": \"Attributes set on the tag.\"\n },\n \"content\": {\n \"type\": \"string\",\n \"description\": \"Text content placed inside the tag.\"\n }\n }\n }\n },\n \"tableOfContents\": {\n \"description\": \"Controls which headings the on-page table of contents lists, or `false` to hide it entirely. Written as `if`/`then` rather than `anyOf` so that a bad heading level is reported against `/tableOfContents/maxHeadingLevel` — an `anyOf` collapses every branch failure onto the parent, which is the wrong caret.\",\n \"if\": { \"type\": \"object\" },\n \"then\": {\n \"additionalProperties\": false,\n \"properties\": {\n \"minHeadingLevel\": { \"$ref\": \"#/$defs/headingLevel\" },\n \"maxHeadingLevel\": { \"$ref\": \"#/$defs/headingLevel\" }\n }\n },\n \"else\": { \"type\": \"boolean\", \"const\": false }\n },\n \"template\": {\n \"type\": \"string\",\n \"enum\": [\"doc\", \"splash\"],\n \"description\": \"Layout template. `doc` is the default; `splash` is the wider landing-page layout that pairs with `hero`.\"\n },\n \"hero\": {\n \"type\": \"object\",\n \"description\": \"Hero block shown at the top of the page, normally with `template: splash`.\",\n \"properties\": {\n \"title\": { \"type\": \"string\" },\n \"tagline\": { \"type\": \"string\" },\n \"image\": {\n \"type\": \"object\",\n \"description\": \"One image, a light/dark pair, or raw HTML.\"\n },\n \"actions\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"text\", \"link\"],\n \"properties\": {\n \"text\": { \"type\": \"string\" },\n \"link\": { \"type\": \"string\" },\n \"variant\": {\n \"type\": \"string\",\n \"enum\": [\"primary\", \"secondary\", \"minimal\"]\n },\n \"icon\": { \"type\": \"string\" },\n \"attrs\": { \"type\": \"object\" }\n }\n }\n }\n }\n },\n \"banner\": {\n \"type\": \"object\",\n \"required\": [\"content\"],\n \"description\": \"Announcement banner shown at the top of the page.\",\n \"properties\": {\n \"content\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Banner text. Inline HTML is allowed.\"\n }\n }\n },\n \"lastUpdated\": {\n \"type\": [\"string\", \"boolean\"],\n \"pattern\": \"^[0-9]{4}-[0-9]{2}-[0-9]{2}\",\n \"description\": \"A YAML date overriding the git-derived last-updated stamp, or a boolean turning the stamp on or off for this page. The pattern constrains the string branch only, and accepts a plain date or a full timestamp.\"\n },\n \"prev\": { \"$ref\": \"#/$defs/linkRef\" },\n \"next\": { \"$ref\": \"#/$defs/linkRef\" },\n \"pagefind\": {\n \"type\": \"boolean\",\n \"description\": \"Whether this page is included in the site search index. Defaults to true.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"A draft page is excluded from production builds. Defaults to false.\"\n },\n \"sidebar\": {\n \"type\": \"object\",\n \"description\": \"How this page appears in an autogenerated sidebar group.\",\n \"properties\": {\n \"label\": {\n \"type\": \"string\",\n \"description\": \"Sidebar link text. Defaults to the page title.\"\n },\n \"order\": {\n \"type\": \"number\",\n \"description\": \"Sort weight within the group; lower sorts higher.\"\n },\n \"hidden\": {\n \"type\": \"boolean\",\n \"description\": \"Omit this page from the autogenerated group. Defaults to false.\"\n },\n \"badge\": {\n \"description\": \"A badge beside the sidebar link: a string, or an object naming its variant.\",\n \"if\": { \"type\": \"object\" },\n \"then\": {\n \"required\": [\"text\"],\n \"properties\": {\n \"text\": { \"type\": \"string\" },\n \"variant\": {\n \"type\": \"string\",\n \"enum\": [\"note\", \"tip\", \"caution\", \"danger\", \"success\", \"default\"]\n }\n }\n },\n \"else\": { \"type\": \"string\" }\n },\n \"attrs\": {\n \"type\": \"object\",\n \"description\": \"HTML attributes set on the sidebar link.\"\n }\n }\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"antora:page:3.1\",\n \"title\": \"Antora page header attributes v3.1\",\n \"description\": \"The AsciiDoc document header attributes Antora 3.1 reads from a page, plus the two AsciiDoc built-ins (`description`, `keywords`) it carries into page metadata. `title` is required because the page title is the only mandatory header element in Antora. Values are the *typed* results of AsciiDoc attribute entries: a bare `:page-partial:` is `true`, an unset `:!page-partial:` is `false`, and `:page-toclevels: 3` is the number 3. Custom `page-*` attributes are yours to define and are tolerated. See https://docs.antora.org/antora/latest/page/page-attributes/\",\n \"type\": \"object\",\n \"required\": [\"title\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The page title, written as the `= Title` line. The only required header element.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"AsciiDoc built-in. Stored in an HTML meta tag on the published page.\"\n },\n \"keywords\": {\n \"type\": \"string\",\n \"description\": \"AsciiDoc built-in. A comma-separated list *as a single string* — AsciiDoc attribute values are text, so this is never a YAML array.\"\n },\n \"navtitle\": {\n \"type\": \"string\",\n \"description\": \"Link text used when the navigation references this page. Defaults to the page reftext.\"\n },\n \"page-aliases\": {\n \"type\": \"string\",\n \"description\": \"Comma-separated alternate resource IDs that should redirect to this page.\"\n },\n \"page-layout\": {\n \"type\": \"string\",\n \"description\": \"Which UI template renders this page. Defaults to the `default` layout.\"\n },\n \"page-partial\": {\n \"type\": \"boolean\",\n \"description\": \"Marks the page as a partial, kept unconverted for inclusion elsewhere. Set with a bare `:page-partial:` and cleared with `:!page-partial:`.\"\n },\n \"page-role\": {\n \"type\": \"string\",\n \"description\": \"Space-separated classes added to the page body. The default UI reserves `-toc`, which hides the table-of-contents sidebar.\"\n },\n \"page-toclevels\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"maximum\": 5,\n \"description\": \"How many heading levels the sidebar table of contents shows. The default UI shows 2.\"\n },\n \"page-tags\": {\n \"type\": \"string\",\n \"description\": \"Comma-separated tags as a single string, following the same attribute-entry typing as `keywords`.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"sphinx:docinfo:9.1\",\n \"title\": \"Sphinx file-wide metadata v9.1\",\n \"description\": \"The file-wide metadata fields Sphinx reads from a document's leading field list (docinfo), as of Sphinx 9.1. Sphinx requires none of them. The set is deliberately small because docinfo values are always parsed as strings by Sphinx itself — a field list cannot carry a list or a mapping — so anything richer belongs in front matter, not here. Flag fields are written bare (`:orphan:`), which reaches the validator as `true`. See https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"properties\": {\n \"tocdepth\": {\n \"type\": \"integer\",\n \"description\": \"Maximum depth of the table of contents for this file. Affects the local toctree only, not the global sidebar.\"\n },\n \"orphan\": {\n \"type\": \"boolean\",\n \"description\": \"Suppresses the warning raised when this file is in no toctree. Written bare as `:orphan:`.\"\n },\n \"nocomments\": {\n \"type\": \"boolean\",\n \"description\": \"Suppresses the comment form on the generated page. Written bare as `:nocomments:`.\"\n },\n \"no-search\": {\n \"type\": \"boolean\",\n \"description\": \"Excludes this document from full-text search. Object search still applies. Written bare as `:no-search:`.\"\n },\n \"nosearch\": {\n \"type\": \"boolean\",\n \"deprecated\": true,\n \"description\": \"The pre-7.3 spelling of `no-search`. Sphinx renamed it in 7.3 and still accepts this form, so it is annotated rather than rejected — a schema that failed the build on a spelling the tool accepts would assert something untrue about the tool. Prefer `no-search`.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"myst:frontmatter:1.10\",\n \"title\": \"MyST page frontmatter v1.10\",\n \"description\": \"The page-level MyST frontmatter fields, as of mystmd 1.10. MyST requires nothing: a page with no `title` takes one from its first heading. What this schema does carry is MyST's documented length caps — 500 characters on `title`, `subtitle`, `description` and `label`, 40 on `short_title` and `subject` — which are the constraints a long title silently violates. Project-level keys that belong in `myst.yml` (`bibliography`, `references`, `requirements`, `social`) are not described here; they are tolerated like any unknown key. Controlled vocabularies MyST defines but this schema does not reproduce — the 14 CRediT contributor roles above all — are checked for shape only, never against a transcribed list. See https://mystmd.org/guide/frontmatter\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"person\": {\n \"description\": \"An author, editor or reviewer: an object, or a string referencing one declared elsewhere by id.\",\n \"if\": { \"type\": \"object\" },\n \"then\": {\n \"properties\": {\n \"name\": {\n \"type\": [\"string\", \"object\"],\n \"description\": \"Full name, or a CSL-JSON object of parsed name parts.\"\n },\n \"id\": { \"type\": \"string\" },\n \"orcid\": { \"type\": \"string\" },\n \"email\": { \"type\": \"string\", \"format\": \"email\" },\n \"corresponding\": {\n \"type\": \"boolean\",\n \"description\": \"Marks the corresponding author. MyST requires an `email` alongside it.\"\n },\n \"roles\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" },\n \"description\": \"CRediT contributor roles. Checked as strings only — the 14-term vocabulary and its aliases are not transcribed here, so a guessed enum cannot reject a valid role.\"\n },\n \"affiliations\": {\n \"type\": [\"string\", \"array\"],\n \"items\": { \"type\": [\"string\", \"object\"] }\n },\n \"equal_contributor\": { \"type\": \"boolean\" },\n \"deceased\": { \"type\": \"boolean\" },\n \"note\": { \"type\": \"string\" },\n \"url\": { \"type\": \"string\" }\n }\n },\n \"else\": { \"type\": \"string\" }\n },\n \"people\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"$ref\": \"#/$defs/person\" } },\n \"else\": { \"$ref\": \"#/$defs/person\" }\n },\n \"stringList\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"string\" } },\n \"else\": { \"type\": \"string\" }\n }\n },\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"maxLength\": 500,\n \"description\": \"Page title. When absent, MyST lifts it from the first heading and removes that heading from the content.\"\n },\n \"subtitle\": {\n \"type\": \"string\",\n \"maxLength\": 500,\n \"description\": \"Complementary title text shown beneath the title.\"\n },\n \"short_title\": {\n \"type\": \"string\",\n \"maxLength\": 40,\n \"description\": \"Abbreviated title for running headers and navigation. Capped at 40 characters.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"maxLength\": 500,\n \"description\": \"Summary of the page, used for previews and indexing.\"\n },\n \"label\": {\n \"type\": \"string\",\n \"maxLength\": 500,\n \"description\": \"Identifier this page can be cross-referenced by.\"\n },\n \"subject\": {\n \"type\": \"string\",\n \"maxLength\": 40,\n \"description\": \"Short subject categorization. Capped at 40 characters.\"\n },\n \"date\": {\n \"type\": \"string\",\n \"description\": \"Publication date. MyST accepts ISO 8601 (`2026-08-23`) and RFC 2822 variants (`23 Aug 2026`), so this is not constrained to one format.\"\n },\n \"keywords\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Key concepts described by the page.\"\n },\n \"tags\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Categorization tags.\"\n },\n \"authors\": { \"$ref\": \"#/$defs/people\" },\n \"editors\": { \"$ref\": \"#/$defs/people\" },\n \"reviewers\": { \"$ref\": \"#/$defs/people\" },\n \"affiliations\": {\n \"type\": [\"object\", \"array\"],\n \"items\": { \"type\": [\"string\", \"object\"] },\n \"description\": \"Institutions referenced by `authors`, declared inline or by id.\"\n },\n \"license\": {\n \"type\": [\"string\", \"object\"],\n \"description\": \"An SPDX identifier such as `CC-BY-4.0`, or an object describing content and code licenses separately.\"\n },\n \"copyright\": { \"type\": \"string\" },\n \"open_access\": { \"type\": \"boolean\" },\n \"doi\": { \"type\": \"string\", \"description\": \"A DOI, bare or as a URL.\" },\n \"arxiv\": { \"type\": \"string\" },\n \"pmid\": { \"type\": \"integer\" },\n \"pmcid\": {\n \"type\": \"string\",\n \"pattern\": \"^PMC[0-9]+$\",\n \"description\": \"A PubMed Central id: the literal `PMC` followed by digits.\"\n },\n \"github\": {\n \"type\": \"string\",\n \"description\": \"A repository URL, or `owner/name`.\"\n },\n \"edit_url\": { \"type\": \"string\", \"format\": \"uri-reference\" },\n \"source_url\": { \"type\": \"string\", \"format\": \"uri-reference\" },\n \"binder\": { \"type\": \"string\", \"format\": \"uri-reference\" },\n \"thumbnail\": { \"type\": \"string\" },\n \"banner\": { \"type\": \"string\" },\n \"first_page\": { \"type\": [\"string\", \"number\"] },\n \"last_page\": { \"type\": [\"string\", \"number\"] },\n \"venue\": { \"type\": [\"string\", \"object\"] },\n \"volume\": { \"type\": [\"string\", \"number\", \"object\"] },\n \"issue\": { \"type\": [\"string\", \"number\", \"object\"] },\n \"funding\": { \"type\": [\"object\", \"array\"] },\n \"kernelspec\": {\n \"type\": \"object\",\n \"description\": \"Jupyter kernel this page executes against.\"\n },\n \"execute\": { \"type\": \"object\" },\n \"math\": {\n \"type\": \"object\",\n \"description\": \"Macro dictionary applied to math on this page.\"\n },\n \"abbreviations\": { \"type\": \"object\" },\n \"numbering\": { \"type\": \"object\" },\n \"parts\": {\n \"type\": \"object\",\n \"description\": \"Named parts such as `abstract` or `data_availability`.\"\n },\n \"exports\": { \"type\": [\"object\", \"array\"] },\n \"downloads\": { \"type\": [\"object\", \"array\"] },\n \"options\": { \"type\": \"object\" }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"ogp:article:1.0\",\n \"title\": \"Open Graph protocol, article profile\",\n \"description\": \"The Open Graph protocol's basic metadata plus the `article` object type. Unusually among the built-ins, this one enforces genuine requirements: the protocol names `og:title`, `og:type`, `og:url` and `og:image` as required for every page, and a page missing one has no valid Open Graph object at all. It is also the built-in that checks something no build tool checks — nothing fails when `og:image` is absent, the page just renders badly everywhere it is shared. In HTML these live on `<meta property=\\\"…\\\">`, which docmeta reads alongside `name=`; in front matter they are ordinary quoted keys. See https://ogp.me/\",\n \"type\": \"object\",\n \"required\": [\"og:title\", \"og:type\", \"og:url\", \"og:image\"],\n \"additionalProperties\": true,\n \"$defs\": {\n \"url\": { \"type\": \"string\", \"format\": \"uri\" },\n \"urlList\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"$ref\": \"#/$defs/url\" } },\n \"else\": { \"$ref\": \"#/$defs/url\" }\n },\n \"textList\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"string\" } },\n \"else\": { \"type\": \"string\" }\n },\n \"timestamp\": {\n \"type\": \"string\",\n \"format\": \"date-time\",\n \"description\": \"An ISO 8601 datetime.\"\n }\n },\n \"properties\": {\n \"og:title\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The object's title, as it should appear in the graph. Required.\"\n },\n \"og:type\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The object type, such as `article` or `website`. Required. Not enumerated: the protocol allows namespaced and vendor types beyond the published list.\"\n },\n \"og:url\": {\n \"$ref\": \"#/$defs/url\",\n \"description\": \"The canonical URL, used as the object's permanent id. Required, and absolute — a site-root path is not a canonical URL.\"\n },\n \"og:image\": {\n \"$ref\": \"#/$defs/urlList\",\n \"description\": \"URL of the image representing the object. Required.\"\n },\n \"og:description\": {\n \"type\": \"string\",\n \"description\": \"A one- or two-sentence description of the object.\"\n },\n \"og:site_name\": {\n \"type\": \"string\",\n \"description\": \"The name of the overall site this object belongs to.\"\n },\n \"og:determiner\": {\n \"type\": \"string\",\n \"enum\": [\"a\", \"an\", \"the\", \"\", \"auto\"],\n \"description\": \"The word preceding the title in a sentence. The protocol lists exactly these five, the empty string among them.\"\n },\n \"og:locale\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-z]{2,3}(_[A-Z]{2})?$\",\n \"description\": \"Locale in `language_TERRITORY` form, such as `en_US`. Defaults to `en_US`. The hyphenated BCP 47 spelling `en-US` is not what the protocol specifies and is rejected here.\"\n },\n \"og:locale:alternate\": {\n \"if\": { \"type\": \"array\" },\n \"then\": {\n \"items\": { \"type\": \"string\", \"pattern\": \"^[a-z]{2,3}(_[A-Z]{2})?$\" }\n },\n \"else\": { \"type\": \"string\", \"pattern\": \"^[a-z]{2,3}(_[A-Z]{2})?$\" },\n \"description\": \"Other locales this page is available in.\"\n },\n \"og:audio\": {\n \"$ref\": \"#/$defs/urlList\",\n \"description\": \"URL of audio accompanying the object.\"\n },\n \"og:video\": {\n \"$ref\": \"#/$defs/urlList\",\n \"description\": \"URL of video accompanying the object.\"\n },\n \"article:published_time\": {\n \"$ref\": \"#/$defs/timestamp\",\n \"description\": \"When the article was first published.\"\n },\n \"article:modified_time\": {\n \"$ref\": \"#/$defs/timestamp\",\n \"description\": \"When the article was last changed.\"\n },\n \"article:expiration_time\": {\n \"$ref\": \"#/$defs/timestamp\",\n \"description\": \"When the article stops being current.\"\n },\n \"article:author\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Author profile URLs, or names. Repeated `<meta>` tags collapse to the last one on extraction, so a single string is the usual shape.\"\n },\n \"article:section\": {\n \"type\": \"string\",\n \"description\": \"The high-level section the article belongs to.\"\n },\n \"article:tag\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Tags describing the article.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"dcmi:elements:1.1\",\n \"title\": \"Dublin Core Metadata Element Set v1.1\",\n \"description\": \"The fifteen elements of the Dublin Core Metadata Element Set, as published in the DCMI Recommendation of 2020-01-20. DCMI marks no element mandatory, so this requires nothing and checks shape only. Every element is repeatable in Dublin Core, so each accepts a single value or a list of them. `type` is deliberately *not* enumerated: DCMI recommends a controlled vocabulary such as the DCMI Type Vocabulary rather than mandating one, and enumerating it here would reject conforming documents that use a different vocabulary. Element names are the unprefixed terms the Recommendation defines; documents using the DCMI-HTML `DC.title` spelling in `<meta name>` need a schema of their own. See https://www.dublincore.org/specifications/dublin-core/dcmi-terms/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"text\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"string\" } },\n \"else\": { \"type\": \"string\" }\n },\n \"w3cdtf\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}(-[0-9]{2}(-[0-9]{2}(T[0-9]{2}:[0-9]{2}(:[0-9]{2}(\\\\.[0-9]+)?)?(Z|[+-][0-9]{2}:[0-9]{2}))?)?)?$\"\n }\n },\n \"properties\": {\n \"title\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"A name given to the resource.\"\n },\n \"creator\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"An entity primarily responsible for making the resource.\"\n },\n \"contributor\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"An entity responsible for making contributions to the resource.\"\n },\n \"publisher\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"An entity responsible for making the resource available.\"\n },\n \"subject\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"The topic of the resource.\"\n },\n \"description\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"An account of the resource.\"\n },\n \"date\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"$ref\": \"#/$defs/w3cdtf\" } },\n \"else\": { \"$ref\": \"#/$defs/w3cdtf\" },\n \"description\": \"A point or period of time associated with an event in the lifecycle of the resource. Encoded as W3CDTF, which permits reduced precision — `2026`, `2026-08` and `2026-08-23` are all legal, and a full datetime carries a timezone.\"\n },\n \"type\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"The nature or genre of the resource. Recommended best practice is a controlled vocabulary such as the DCMI Type Vocabulary (Collection, Dataset, Event, Image, InteractiveResource, MovingImage, PhysicalObject, Service, Software, Sound, StillImage, Text), but DCMI does not require one, so no enum is imposed.\"\n },\n \"format\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"The file format, physical medium, or dimensions of the resource. Recommended best practice is a MIME type.\"\n },\n \"identifier\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"An unambiguous reference to the resource within a given context.\"\n },\n \"source\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"A related resource from which the described resource is derived.\"\n },\n \"language\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"A language of the resource. Recommended best practice is an IETF BCP 47 tag.\"\n },\n \"relation\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"A related resource.\"\n },\n \"coverage\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"The spatial or temporal topic of the resource, its spatial applicability, or the jurisdiction under which it is relevant.\"\n },\n \"rights\": {\n \"$ref\": \"#/$defs/text\",\n \"description\": \"Information about rights held in and over the resource.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"microsoft:learn:1.0\",\n \"title\": \"Microsoft Learn article metadata\",\n \"description\": \"The YAML front matter Microsoft Learn requires and recommends on a documentation article. Five attributes are required — omitting any of them fails the Learn build — and two of them carry format rules that catch mistakes no generic date or length check would: `ms.date` is `MM/DD/YYYY`, not ISO 8601, and `description` has a documented 75-300 character range. `ms.topic` is a string rather than an enum on purpose: the authoritative list is an internal Microsoft taxonomy, the published docfx-era set and the values Azure repositories actually use disagree, and an invented enum would fail correct articles. Attribute names are case-sensitive. See https://learn.microsoft.com/en-us/contribute/content/metadata\",\n \"type\": \"object\",\n \"required\": [\"title\", \"description\", \"author\", \"ms.author\", \"ms.date\"],\n \"additionalProperties\": true,\n \"$defs\": {\n \"textList\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"string\" } },\n \"else\": { \"type\": \"string\" }\n }\n },\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The page title shown on the browser tab. Required, and the single most important attribute for search.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"minLength\": 75,\n \"maxLength\": 300,\n \"description\": \"A summary of the article, used in site search. Required. Microsoft documents the hard range as 75-300 characters and recommends 115-145; only the hard range is enforced here.\"\n },\n \"author\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The author's GitHub account ID — not a display name. Required.\"\n },\n \"ms.author\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"^[^@\\\\s]+$\",\n \"description\": \"The owner's Microsoft alias, without `@microsoft.com`. Required. The pattern rejects a full email address, which is the usual way this one is written wrong.\"\n },\n \"ms.date\": {\n \"type\": \"string\",\n \"pattern\": \"^(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])/[0-9]{4}$\",\n \"description\": \"The date of the last substantial edit, in `MM/DD/YYYY`. Required. Note that this is *not* ISO 8601: `2026-08-23` is rejected, `08/23/2026` is correct.\"\n },\n \"ms.topic\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The kind of article, such as `how-to`, `conceptual`, `quickstart`, `tutorial` or `overview`. Not enumerated — see this schema's description for why.\"\n },\n \"ms.service\": {\n \"type\": \"string\",\n \"description\": \"The service the article documents.\"\n },\n \"ms.subservice\": {\n \"type\": \"string\",\n \"description\": \"A component within `ms.service`.\"\n },\n \"ms.custom\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Free-form tags used for reporting and campaign tracking.\"\n },\n \"ms.collection\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Collections this article belongs to.\"\n },\n \"ms.reviewer\": {\n \"type\": \"string\",\n \"description\": \"Microsoft alias of the technical reviewer.\"\n },\n \"ms.devlang\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Programming languages the article covers.\"\n },\n \"ms.prod\": {\n \"type\": \"string\",\n \"description\": \"The product, for repositories that use `ms.prod` instead of `ms.service`.\"\n },\n \"ms.technology\": {\n \"type\": \"string\",\n \"description\": \"A technology within `ms.prod`.\"\n },\n \"keywords\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Search keywords for the article.\"\n },\n \"zone_pivot_groups\": {\n \"type\": \"string\",\n \"description\": \"The pivot group enabling tabbed variants of the article.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"oasis:dita-metadata:1.3\",\n \"title\": \"DITA 1.3 document metadata\",\n \"description\": \"The typed metadata elements OASIS defines for a DITA topic or map, as docmeta reads them. Named `dita-metadata` rather than `dita-prolog` because it constrains `topicmeta.*` too, and a name saying prolog would be wrong for every map. Keys follow docmeta's element rule — the containing element is the namespace — so a topic's `<prolog><metadata><audience>` is `metadata.audience` while a map's `<topicmeta><audience>` is `topicmeta.audience`. That is not a quirk: the OASIS content model makes them peers under `<topicmeta>` and nests them under `<prolog>` in a topic, and each key names where the value actually is. Cardinality is taken from the content model, so `author*` is a list and `source?` is a scalar. Requires nothing: DITA marks no metadata element mandatory. The `<othermeta name= content=>` channel keeps its flat keys and is not described here — a document may carry both, and both are validated. See https://docs.oasis-open.org/dita/dita/v1.3/os/part1-base/langRef/containers/prolog-elements.html\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"textList\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"scalarList\": {\n \"type\": \"array\",\n \"items\": { \"type\": [\"string\", \"number\"] },\n \"description\": \"Attribute values are parsed as YAML scalars, as they are in every format docmeta reads, so `year=\\\"2026\\\"` arrives as the number 2026 while `version=\\\"2.1.0\\\"` stays a string. Both are accepted rather than the reader special-casing these attributes, which would be a surprise nothing else in the tool prepares you for.\"\n },\n \"ditaDate\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}-[0-9]{2}-[0-9]{2}$\",\n \"description\": \"A `YYYY-MM-DD` date. DITA types these attributes as CDATA, so the DTD itself imposes no format — this is the convention DITA-OT and every toolchain around it assume, checked here because a date nothing validates is a date that drifts.\"\n }\n },\n \"properties\": {\n \"prolog.author\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Topic authors, from `<prolog><author>`. A list: the content model is `author*`.\"\n },\n \"prolog.source\": {\n \"type\": \"string\",\n \"description\": \"The resource this topic derives from, from `<prolog><source>`. Scalar: `source?`.\"\n },\n \"prolog.publisher\": {\n \"type\": \"string\",\n \"description\": \"Who makes the topic available, from `<prolog><publisher>`. Scalar: `publisher?`.\"\n },\n \"prolog.permissions\": {\n \"type\": \"string\",\n \"description\": \"Entitlement required to view the topic, from `<permissions @entitlement>`. Not enumerated — DITA suggests values without fixing them.\"\n },\n \"prolog.resourceid\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Application-specific identifiers, from `<resourceid @id>`. A list: `resourceid*`.\"\n },\n \"topicmeta.author\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Map authors, from `<topicmeta><author>`. The map spelling of `prolog.author`.\"\n },\n \"topicmeta.source\": {\n \"type\": \"string\",\n \"description\": \"The map spelling of `prolog.source`.\"\n },\n \"topicmeta.publisher\": {\n \"type\": \"string\",\n \"description\": \"The map spelling of `prolog.publisher`.\"\n },\n \"topicmeta.permissions\": {\n \"type\": \"string\",\n \"description\": \"The map spelling of `prolog.permissions`.\"\n },\n \"topicmeta.resourceid\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"The map spelling of `prolog.resourceid`.\"\n },\n \"topicmeta.audience\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Intended audiences, from `<topicmeta><audience @type>`. A map holds these directly; a topic nests them, where they are `metadata.audience`.\"\n },\n \"topicmeta.category\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Categories, from `<topicmeta><category>`. The map spelling of `metadata.category`.\"\n },\n \"critdates.created\": {\n \"$ref\": \"#/$defs/ditaDate\",\n \"description\": \"Creation date, from `<critdates><created @date>`. Scalar: `created?`. Identical in topics and maps, because the containing element is the same in both.\"\n },\n \"critdates.revised\": {\n \"type\": \"array\",\n \"items\": { \"$ref\": \"#/$defs/ditaDate\" },\n \"description\": \"Revision dates, from `<critdates><revised @modified>`. A list: `revised*`.\"\n },\n \"metadata.audience\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Intended audiences in a topic, from `<prolog><metadata><audience @type>`. A list: `audience*`. Not enumerated — the values are a project's own vocabulary.\"\n },\n \"metadata.category\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Categories in a topic, from `<prolog><metadata><category>`. A list: `category*`.\"\n },\n \"prodinfo.prodname\": {\n \"type\": \"string\",\n \"description\": \"Product name, from `<prodinfo><prodname>`. Scalar: `prodname?`.\"\n },\n \"prodinfo.brand\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Manufacturer or brand, from `<prodinfo><brand>`.\"\n },\n \"prodinfo.component\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Product component, from `<prodinfo><component>`.\"\n },\n \"prodinfo.featnum\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Feature number, from `<prodinfo><featnum>`.\"\n },\n \"prodinfo.platform\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Operating system or hardware, from `<prodinfo><platform>`.\"\n },\n \"prodinfo.prognum\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Program or order number, from `<prodinfo><prognum>`.\"\n },\n \"prodinfo.series\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Product series, from `<prodinfo><series>`. These six are a repeatable *choice* group in the content model, so they may interleave in any order.\"\n },\n \"vrm.version\": {\n \"$ref\": \"#/$defs/scalarList\",\n \"description\": \"Product version, from `<vrmlist><vrm @version>`. Keyed for the element rather than its container because `<vrm>` is EMPTY and carries three separate facts — keying it `vrmlist.vrm` would have to pick one and discard two. For an attribute the containing thing is the element, so the naming rule applies one level down rather than changing.\"\n },\n \"vrm.release\": {\n \"$ref\": \"#/$defs/scalarList\",\n \"description\": \"Product release, from `<vrmlist><vrm @release>`. A `<vrm>` carrying no `@release` contributes nothing here, and is dropped from the element list with it, so a write still lands on the element its value came from.\"\n },\n \"vrm.modification\": {\n \"$ref\": \"#/$defs/scalarList\",\n \"description\": \"Modification level, from `<vrmlist><vrm @modification>`.\"\n },\n \"copyright.copyryear\": {\n \"$ref\": \"#/$defs/scalarList\",\n \"description\": \"Copyright years, from `<copyright><copyryear @year>`. A list: the content model is `copyryear+`.\"\n },\n \"copyright.copyrholder\": {\n \"type\": \"string\",\n \"description\": \"Copyright holder, from `<copyright><copyrholder>`.\"\n },\n \"keywords.keyword\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Search keywords, from `<keywords><keyword>`. Reached through the children rather than the container: `<keywords>` holds `(indexterm | keyword)*` and has no text of its own.\"\n },\n \"keywords.indexterm\": {\n \"$ref\": \"#/$defs/textList\",\n \"description\": \"Index terms, from `<keywords><indexterm>`. A *nested* `<indexterm>` makes its parent a container rather than a value, so only flat terms are lifted.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"hugo:page:0.165\",\n \"title\": \"Hugo front matter v0.165\",\n \"description\": \"The front matter fields Hugo itself defines, as of 0.165. Hugo requires nothing — a page with no front matter at all builds — so this schema can only ever fail a page on the shape of a value it already carries. That is most of the value: `weight` must be an integer and `draft` a boolean, and the usual way a Hugo page goes quietly wrong is a quoted number or a `draft: \\\"false\\\"` that is true. Custom keys and taxonomy terms such as `tags` and `categories` are user-configured rather than defined by Hugo, so they are tolerated rather than described here. Dates are plain strings on purpose: Hugo parses several layouts, including bare years and Unix timestamps, so a `format` here would reject input Hugo accepts. Hugo's default fence is TOML, whose native dates docmeta normalizes to the string they were written as. See https://gohugo.io/content-management/front-matter/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"date\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"A date string. Hugo accepts several layouts, so only the type is checked.\"\n },\n \"stringList\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n },\n \"listFlag\": {\n \"description\": \"How the page is listed: a boolean, or one of the three names `build.list` accepts. Kept separate from `renderFlag` because the two options do not share a vocabulary — `local` is meaningful only here, and merging the sets would accept `link` on the wrong one.\",\n \"if\": { \"type\": \"string\" },\n \"then\": { \"enum\": [\"always\", \"never\", \"local\"] },\n \"else\": { \"type\": \"boolean\" }\n },\n \"renderFlag\": {\n \"description\": \"How the page is rendered: a boolean, or one of the three names `build.render` accepts. `link` is meaningful only here — see `listFlag`.\",\n \"if\": { \"type\": \"string\" },\n \"then\": { \"enum\": [\"always\", \"never\", \"link\"] },\n \"else\": { \"type\": \"boolean\" }\n }\n },\n \"properties\": {\n \"aliases\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Page-relative or site-relative paths that redirect to this page.\"\n },\n \"build\": {\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"description\": \"Per-page build options.\",\n \"properties\": {\n \"list\": { \"$ref\": \"#/$defs/listFlag\" },\n \"render\": { \"$ref\": \"#/$defs/renderFlag\" },\n \"publishResources\": { \"type\": \"boolean\" }\n }\n },\n \"cascade\": {\n \"description\": \"Values passed down to descendant pages unless overwritten. A map, or an array of maps each carrying a `_target` filter.\",\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"object\" } },\n \"else\": { \"type\": \"object\" }\n },\n \"date\": {\n \"$ref\": \"#/$defs/date\",\n \"description\": \"The date associated with the page, typically its creation date.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Rendered into a meta element for search engines.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"A draft is not rendered unless `--buildDrafts` is passed. A quoted `\\\"false\\\"` is a string, and every string is truthy — this is the check that catches it.\"\n },\n \"expiryDate\": {\n \"$ref\": \"#/$defs/date\",\n \"description\": \"After this date the page is no longer rendered.\"\n },\n \"headless\": {\n \"type\": \"boolean\",\n \"description\": \"Makes a leaf bundle headless: its resources stay available but it publishes no page.\"\n },\n \"isCJKLanguage\": {\n \"type\": \"boolean\",\n \"description\": \"Counts words the CJK way, which changes summaries and reading time.\"\n },\n \"keywords\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Keywords, typically rendered into a meta element.\"\n },\n \"lastmod\": {\n \"$ref\": \"#/$defs/date\",\n \"description\": \"The date the page was last modified.\"\n },\n \"layout\": {\n \"type\": \"string\",\n \"description\": \"A template name overriding the default lookup order.\"\n },\n \"linkTitle\": {\n \"type\": \"string\",\n \"description\": \"A shorter title for lists and navigation.\"\n },\n \"markup\": {\n \"type\": \"string\",\n \"description\": \"The content format identifier, such as `md` or `html`.\"\n },\n \"menus\": {\n \"description\": \"Menus this page joins: one name, several names, or a map giving each entry its own options.\",\n \"if\": { \"type\": \"object\" },\n \"then\": { \"type\": \"object\" },\n \"else\": {\n \"if\": { \"type\": \"array\" },\n \"then\": { \"$ref\": \"#/$defs/stringList\" },\n \"else\": { \"type\": \"string\" }\n }\n },\n \"outputs\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Output formats to render this page in, such as `html` and `json`.\"\n },\n \"params\": {\n \"type\": \"object\",\n \"description\": \"Custom page parameters, reached as `.Params` in templates.\"\n },\n \"publishDate\": {\n \"$ref\": \"#/$defs/date\",\n \"description\": \"Before this date the page is not rendered.\"\n },\n \"resources\": {\n \"type\": \"array\",\n \"description\": \"Metadata attached to the page's resources. Each entry needs the `src` glob it applies to.\",\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"src\"],\n \"additionalProperties\": true,\n \"properties\": {\n \"src\": { \"type\": \"string\", \"minLength\": 1 },\n \"name\": { \"type\": \"string\" },\n \"title\": { \"type\": \"string\" },\n \"params\": { \"type\": \"object\" }\n }\n }\n },\n \"sitemap\": {\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"description\": \"Per-page sitemap options.\",\n \"properties\": {\n \"changefreq\": {\n \"type\": \"string\",\n \"enum\": [\n \"always\",\n \"hourly\",\n \"daily\",\n \"weekly\",\n \"monthly\",\n \"yearly\",\n \"never\"\n ],\n \"description\": \"One of the seven values the sitemap protocol defines. Anything else is ignored by consumers.\"\n },\n \"priority\": { \"type\": \"number\", \"minimum\": 0, \"maximum\": 1 },\n \"disable\": { \"type\": \"boolean\" }\n }\n },\n \"sites\": {\n \"type\": \"object\",\n \"description\": \"The sites matrix and its complements.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Overrides the final segment of the URL path.\"\n },\n \"summary\": {\n \"type\": \"string\",\n \"description\": \"An explicit summary, used instead of the one Hugo derives.\"\n },\n \"title\": {\n \"type\": \"string\",\n \"description\": \"The page title. Not required: Hugo falls back to a title derived from the file name.\"\n },\n \"translationKey\": {\n \"type\": \"string\",\n \"description\": \"Relates translations of one page across languages.\"\n },\n \"type\": {\n \"type\": \"string\",\n \"description\": \"The content type, overriding the one derived from the section.\"\n },\n \"url\": {\n \"type\": \"string\",\n \"description\": \"Overrides the entire URL path, ignoring the file's position in the section tree.\"\n },\n \"weight\": {\n \"type\": \"integer\",\n \"description\": \"Sort weight within a collection; lower sorts first. An integer — a quoted number sorts as a string, which is the classic way a Hugo menu comes out in the wrong order.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"jekyll:page:4.4\",\n \"title\": \"Jekyll front matter v4.4\",\n \"description\": \"The predefined front matter variables Jekyll itself defines, as of 4.4. The list is deliberately short because Jekyll's is: three global variables and four more for posts. Everything else you see in a Jekyll site — `nav_order`, `parent`, `has_children`, `redirect_from` — comes from a theme or a plugin, not from Jekyll, so it is tolerated rather than described here. Nothing is required: an empty `---` block is valid, and it is the block's *presence*, not its contents, that marks a file for processing. The check that earns its keep is `published`, which must be a boolean — `published: \\\"false\\\"` is a non-empty string, every string is truthy, and the post publishes anyway. See https://jekyllrb.com/docs/front-matter/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"termList\": {\n \"description\": \"One term, or several. Jekyll accepts a YAML list or a space-separated string.\",\n \"if\": { \"type\": \"array\" },\n \"then\": { \"items\": { \"type\": \"string\" } },\n \"else\": { \"type\": \"string\" }\n }\n },\n \"properties\": {\n \"layout\": {\n \"type\": [\"string\", \"null\"],\n \"description\": \"The layout file to wrap this document in, without its extension. `null` or `none` suppresses the layout entirely, which is why the null type is allowed.\"\n },\n \"permalink\": {\n \"type\": \"string\",\n \"description\": \"Overrides the built URL for this document.\"\n },\n \"published\": {\n \"type\": \"boolean\",\n \"description\": \"`false` keeps the document out of the generated site. Must be a real boolean: a quoted `\\\"false\\\"` is truthy and publishes.\"\n },\n \"date\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Overrides the date taken from the post's file name, and so its ordering and permalink. A string — Jekyll accepts a date with an optional time and offset, so no single format applies.\"\n },\n \"category\": {\n \"$ref\": \"#/$defs/termList\",\n \"description\": \"The post's category. The singular and plural keys both work and are additive, which is how a post ends up filed twice.\"\n },\n \"categories\": {\n \"$ref\": \"#/$defs/termList\",\n \"description\": \"One or more categories the post belongs to.\"\n },\n \"tags\": {\n \"$ref\": \"#/$defs/termList\",\n \"description\": \"One or more tags on the post.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"vitepress:page:1.6\",\n \"title\": \"VitePress front matter v1.6\",\n \"description\": \"Front matter accepted by VitePress 1.6 — the four options every theme honours, plus the default theme's page-level toggles. Nothing is required: each option has a default, so a page with no front matter renders. Pinned to 1.6 because that is the stable line; 2.0 was still in alpha when this was written and is deliberately not described here. The fields worth having checked are the union-typed ones, `outline` above all: it takes a heading level, a pair of levels, `deep`, or `false`, and anything else is silently ignored rather than reported. See https://vitepress.dev/reference/frontmatter-config\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"headingLevel\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"maximum\": 6\n }\n },\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Overrides the site-level title for this page.\"\n },\n \"titleTemplate\": {\n \"type\": [\"string\", \"boolean\"],\n \"description\": \"The suffix appended to the title, or `false` to drop it.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Overrides the site-level description for this page.\"\n },\n \"head\": {\n \"type\": \"array\",\n \"description\": \"Extra tags injected into this page's `<head>`. Each entry is a `[tag, attrs]` pair, optionally followed by inner content.\",\n \"items\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"prefixItems\": [{ \"type\": \"string\", \"minLength\": 1 }]\n }\n },\n \"layout\": {\n \"type\": \"string\",\n \"enum\": [\"doc\", \"home\", \"page\"],\n \"description\": \"`doc` is the default and applies the documentation styling; `home` renders the hero and features; `page` is a blank slate.\"\n },\n \"hero\": {\n \"type\": \"object\",\n \"description\": \"The home layout's hero block: `name`, `text`, `tagline`, `image`, `actions`. Left unconstrained beyond its type — the shape varies with the theme.\"\n },\n \"features\": {\n \"type\": \"array\",\n \"description\": \"The home layout's feature cards.\",\n \"items\": { \"type\": \"object\" }\n },\n \"navbar\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the navbar shows on this page. Defaults to true.\"\n },\n \"sidebar\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the sidebar shows on this page. Defaults to true. This is the page-level toggle only — the sidebar's *contents* are configured in the site config, not here.\"\n },\n \"aside\": {\n \"description\": \"Where the aside sits, or `false` to hide it. `true` is the default (right); `left` moves it.\",\n \"if\": { \"type\": \"string\" },\n \"then\": { \"const\": \"left\" },\n \"else\": { \"type\": \"boolean\" }\n },\n \"outline\": {\n \"description\": \"Which heading levels the on-page outline lists: one level, a `[from, to]` pair, `deep` for every level, or `false` to hide it. Branched on array-ness with `if`/`then` rather than `anyOf`, so a bad level inside the pair is reported against the pair; an `anyOf` collapses every branch failure onto the parent and puts the caret on the wrong line. The scalar branch is one `enum` rather than a second nesting of `if`/`then`, so a wrong value produces a single error naming every value that would have worked.\",\n \"if\": { \"type\": \"array\" },\n \"then\": {\n \"type\": \"array\",\n \"minItems\": 2,\n \"maxItems\": 2,\n \"items\": { \"$ref\": \"#/$defs/headingLevel\" }\n },\n \"else\": { \"enum\": [1, 2, 3, 4, 5, 6, \"deep\", false] }\n },\n \"lastUpdated\": {\n \"type\": [\"boolean\", \"string\"],\n \"description\": \"Whether to show the last-updated stamp, or a date overriding it. The string branch is a date, which is how a YAML date arrives once parsed.\"\n },\n \"editLink\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the edit-this-page link shows. Defaults to true.\"\n },\n \"footer\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the footer shows. Defaults to true.\"\n },\n \"pageClass\": {\n \"type\": \"string\",\n \"description\": \"An extra CSS class set on the page root, for per-page styling.\"\n },\n \"isHome\": {\n \"type\": \"boolean\",\n \"description\": \"Forces home-page styling on a page whose layout is not `home`.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"x:cards:1.0\",\n \"title\": \"X (Twitter) Cards markup\",\n \"description\": \"The `twitter:*` meta tags that turn a shared link into a card on X. The companion to `ogp:article:1.0`: same `<meta>` channel, and the pair is normally shipped together, which is why a site with Open Graph tags and no card tags is the usual half-done state. Only `twitter:card` is required. `twitter:title`, `twitter:description` and `twitter:image` fall back to their `og:` equivalents, so requiring them here would fail pages that are correct — but `twitter:card` has no fallback, and without it X picks no card type at all. Like Open Graph, this checks something no build tool checks: nothing fails when the tags are wrong, the link just renders badly everywhere it is shared. In HTML these sit on `<meta name=\\\"…\\\">`; in front matter they are ordinary quoted keys. See https://developer.x.com/en/docs/x-for-websites/cards/overview/markup\",\n \"type\": \"object\",\n \"required\": [\"twitter:card\"],\n \"additionalProperties\": true,\n \"$defs\": {\n \"handle\": {\n \"type\": \"string\",\n \"pattern\": \"^@?[A-Za-z0-9_]{1,15}$\",\n \"description\": \"An X handle, with or without the leading `@`. Fifteen characters at most, letters, digits and underscores only — the pattern rejects an email address or a profile URL, which is how this field is usually written wrong.\"\n },\n \"accountId\": {\n \"type\": [\"string\", \"integer\"],\n \"pattern\": \"^[0-9]+$\",\n \"description\": \"A numeric account id. Typed for both channels: from HTML every attribute is a string, while front matter can carry a real number.\"\n },\n \"httpsUrl\": {\n \"type\": \"string\",\n \"format\": \"uri\",\n \"pattern\": \"^https://\",\n \"description\": \"An absolute HTTPS URL. X does not load card media over plain HTTP.\"\n },\n \"pixels\": {\n \"type\": [\"string\", \"integer\"],\n \"pattern\": \"^(?!0+$)[0-9]+$\",\n \"minimum\": 1,\n \"description\": \"A pixel count, at least 1. Typed for both channels: an HTML `content=` attribute is always a string, while front matter can carry a real number. Both branches enforce the same floor — `pattern` is ignored on a number and `minimum` on a string, so each needs its own spelling of \\\"not zero\\\", or the string form silently accepts a `0` the number form rejects.\"\n }\n },\n \"properties\": {\n \"twitter:card\": {\n \"type\": \"string\",\n \"enum\": [\"summary\", \"summary_large_image\", \"app\", \"player\"],\n \"description\": \"The card type. Required, and the one tag with no `og:` fallback — omit it and no card renders at all. Enumerated because X defines exactly these four and ignores anything else.\"\n },\n \"twitter:site\": {\n \"$ref\": \"#/$defs/handle\",\n \"description\": \"The handle of the site the card belongs to.\"\n },\n \"twitter:site:id\": {\n \"$ref\": \"#/$defs/accountId\",\n \"description\": \"The numeric id of the site's account, an alternative to `twitter:site`.\"\n },\n \"twitter:creator\": {\n \"$ref\": \"#/$defs/handle\",\n \"description\": \"The handle of the content's author.\"\n },\n \"twitter:creator:id\": {\n \"$ref\": \"#/$defs/accountId\",\n \"description\": \"The numeric id of the author's account.\"\n },\n \"twitter:title\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 70,\n \"description\": \"The card's title. Truncated past 70 characters, so the length is a real limit rather than a style rule. Falls back to `og:title`.\"\n },\n \"twitter:description\": {\n \"type\": \"string\",\n \"maxLength\": 200,\n \"description\": \"The card's description. Truncated past 200 characters. Falls back to `og:description`.\"\n },\n \"twitter:image\": {\n \"$ref\": \"#/$defs/httpsUrl\",\n \"description\": \"The card's image. Must be HTTPS — an HTTP image is dropped and the card renders without it. Falls back to `og:image`.\"\n },\n \"twitter:image:alt\": {\n \"type\": \"string\",\n \"maxLength\": 420,\n \"description\": \"Alternative text for the image, for people using a screen reader. 420 characters at most.\"\n },\n \"twitter:player\": {\n \"$ref\": \"#/$defs/httpsUrl\",\n \"description\": \"The HTTPS URL of the iframe player. Player cards only.\"\n },\n \"twitter:player:width\": {\n \"$ref\": \"#/$defs/pixels\",\n \"description\": \"The player's width in pixels.\"\n },\n \"twitter:player:height\": {\n \"$ref\": \"#/$defs/pixels\",\n \"description\": \"The player's height in pixels.\"\n },\n \"twitter:player:stream\": {\n \"$ref\": \"#/$defs/httpsUrl\",\n \"description\": \"The URL of a raw video stream, as an alternative to an iframe player.\"\n },\n \"twitter:app:country\": {\n \"type\": \"string\",\n \"pattern\": \"^[A-Z]{2}$\",\n \"description\": \"The two-letter ISO 3166-1 alpha-2 country code for the app store to use. Uppercase.\"\n },\n \"twitter:app:name:iphone\": { \"type\": \"string\", \"minLength\": 1 },\n \"twitter:app:id:iphone\": { \"$ref\": \"#/$defs/accountId\" },\n \"twitter:app:url:iphone\": { \"type\": \"string\", \"format\": \"uri\" },\n \"twitter:app:name:ipad\": { \"type\": \"string\", \"minLength\": 1 },\n \"twitter:app:id:ipad\": { \"$ref\": \"#/$defs/accountId\" },\n \"twitter:app:url:ipad\": { \"type\": \"string\", \"format\": \"uri\" },\n \"twitter:app:name:googleplay\": { \"type\": \"string\", \"minLength\": 1 },\n \"twitter:app:id:googleplay\": { \"type\": \"string\", \"minLength\": 1 },\n \"twitter:app:url:googleplay\": { \"type\": \"string\", \"format\": \"uri\" }\n },\n \"if\": {\n \"properties\": { \"twitter:card\": { \"const\": \"player\" } },\n \"required\": [\"twitter:card\"]\n },\n \"then\": {\n \"required\": [\n \"twitter:title\",\n \"twitter:image\",\n \"twitter:player\",\n \"twitter:player:width\",\n \"twitter:player:height\"\n ],\n \"description\": \"A player card is the one type with its own required set: without the player URL and its dimensions there is nothing to embed, and X falls back to no card rather than to a summary.\"\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"agentskills:skill:1.0\",\n \"title\": \"Agent Skills SKILL.md frontmatter\",\n \"description\": \"Frontmatter for the Agent Skills open standard — the portable `SKILL.md` format published at agentskills.io and read by Claude, Codex, Gemini CLI, Copilot, Cursor and others. Six fields, two of them required. This is the one built-in that sets `additionalProperties: false`, and the reason is not strictness for its own sake: the tooling on the distribution path — `package_skill.py`, claude.ai skill uploads, the Skills API — fails with `Unexpected key(s) in SKILL.md frontmatter` rather than ignoring a field it does not know. A schema that tolerated unknown keys would pass exactly the file that cannot be shipped. Validate a skill you intend to distribute against this; validate a Claude Code-only skill against `anthropic:claude-skill:2.1`, which is the superset. One spec rule is out of reach here: `name` must also match the skill's parent directory name, which is a fact about the path rather than the front matter. The spec carries no version number of its own; `1.0` labels the format as published at https://agentskills.io/specification\",\n \"type\": \"object\",\n \"required\": [\"name\", \"description\"],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 64,\n \"pattern\": \"^[a-z0-9]+(?:-[a-z0-9]+)*$\",\n \"description\": \"The skill's identifier, 1-64 characters. Lowercase letters, digits and hyphens only, with no leading, trailing or consecutive hyphen. Must also equal the name of the directory holding this `SKILL.md`, which no front matter check can see.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 1024,\n \"description\": \"What the skill does *and* when to use it, in at most 1024 characters. Agents load this at startup for every installed skill and decide from it alone whether to open the body, so keywords that name the triggering task belong here.\"\n },\n \"license\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"The license covering the skill: a license name such as `Apache-2.0`, or a pointer to a bundled file such as `Proprietary. LICENSE.txt has complete terms`.\"\n },\n \"compatibility\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 500,\n \"description\": \"Environment requirements, in at most 500 characters — intended product, required system packages, network access. Most skills do not need this field.\"\n },\n \"metadata\": {\n \"type\": \"object\",\n \"additionalProperties\": { \"type\": \"string\" },\n \"description\": \"Client-defined properties the spec does not cover. A map from string keys to **string** values: the spec's own example quotes `version: \\\"1.0\\\"` because unquoted it is a YAML float and this map takes strings. Claude Code's `metadata` is free-form by comparison, so a nested or numeric value passes there and fails here.\"\n },\n \"allowed-tools\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Space-separated tools pre-approved to run, such as `Bash(git:*) Bash(jq:*) Read`. Marked experimental in the spec: support varies between agents, and the list form Claude Code also accepts is not part of the standard.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"anthropic:claude-skill:2.1\",\n \"title\": \"Claude Code SKILL.md frontmatter v2.1\",\n \"description\": \"Frontmatter accepted by Claude Code 2.1 in a `SKILL.md` file: the six fields of the Agent Skills standard plus the fourteen Claude Code adds for invocation control, subagent execution, tool grants and activation scope. It requires nothing, because Claude Code marks every field optional — a skill with no front matter at all loads, taking its description from the first paragraph of the body. Unknown keys are tolerated for the same reason: Claude Code ignores a field it does not recognise. That tolerance is exactly what makes this schema the wrong one to check a skill you intend to publish. The distribution path — claude.ai uploads, the Skills API, `package_skill.py` — accepts only the standard's six fields and hard-errors on the rest, so validate against `agentskills:skill:1.0` as well when the skill has to travel. Boolean fields take `yes`, `no`, `on`, `off`, `1` and `0` in any letter case as well as `true` and `false`; a YAML 1.2 parser hands most of those through as a string or an integer, so the schema accepts all three types rather than `boolean` alone. See https://code.claude.com/docs/en/skills\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"flag\": {\n \"description\": \"A Claude Code boolean. `true`/`false` reach the validator as booleans, `1`/`0` as integers, and `yes`/`no`/`on`/`off` — plus any mixed-case spelling such as `TrUe` — as strings, because YAML 1.2 resolves only the core spellings. Written as three type-scoped keywords rather than a branch: `pattern` constrains only the string form and `minimum`/`maximum` only the integer one, so a wrong value is reported once, against the key, instead of once per failed branch plus a summary.\",\n \"type\": [\"boolean\", \"string\", \"integer\"],\n \"pattern\": \"^(?:[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|[Yy][Ee][Ss]|[Nn][Oo]|[Oo][Nn]|[Oo][Ff][Ff]|[01])$\",\n \"minimum\": 0,\n \"maximum\": 1\n },\n \"wordsOrList\": {\n \"description\": \"A field Claude Code accepts either as one delimited string or as a YAML list of entries. `items` applies only to the array form, so no branch is needed and a bad entry is reported once, against the item that is wrong.\",\n \"type\": [\"string\", \"array\"],\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n }\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Display name shown in skill listings, defaulting to the directory name. Deliberately unconstrained here: in a personal or project skill this is only a label, and Claude Code accepts spaces and capitals that the Agent Skills `name` rules forbid. Validate against `agentskills:skill:1.0` to hold it to the portable form. In a plugin skill it also sets the last segment of the command.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"What the skill does and when to use it, which is how Claude decides whether to load it. Falls back to the first paragraph of the body when absent. The listing truncates `description` and `when_to_use` together at 1,536 characters, so the key use case goes first; that cap is a truncation rather than an error, and is not enforced here.\"\n },\n \"when_to_use\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Extra triggering context — phrases or example requests — appended to `description` in the skill listing, and counted against the same 1,536-character cap. Claude Code only; not part of the Agent Skills standard.\"\n },\n \"argument-hint\": {\n \"type\": \"string\",\n \"description\": \"Autocomplete hint for the arguments the skill expects, such as `[issue-number]` or `[filename] [format]`.\"\n },\n \"arguments\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Named positional arguments for `$name` substitution in the body, as a space-separated string or a YAML list. Names map to argument positions in order.\"\n },\n \"disable-model-invocation\": {\n \"$ref\": \"#/$defs/flag\",\n \"description\": \"`true` keeps Claude from loading the skill on its own, leaving `/name` as the only way in. For workflows whose timing you want to own — commit, deploy, send. Also keeps the skill out of subagent preloads and scheduled-task prompts. Default: `false`.\"\n },\n \"user-invocable\": {\n \"$ref\": \"#/$defs/flag\",\n \"description\": \"`false` hides the skill from the `/` menu so only Claude can invoke it, for background knowledge nobody should trigger by hand. Default: `true`.\"\n },\n \"allowed-tools\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Tools pre-approved for the turn that invokes this skill, as a space- or comma-separated string or a YAML list. The grant clears with your next message and does not restrict anything: tools left off the list stay callable under your normal permission settings. A project skill's grant applies even in an untrusted folder, which is why one checked into a repository is worth reading before you run it.\"\n },\n \"disallowed-tools\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Tools removed from Claude's pool while the skill is active — an autonomous loop dropping `AskUserQuestion`, say. Clears with your next message. Cannot remove `EndConversation` while any other tool remains. Claude Code only.\"\n },\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Model to use while the skill is active, taking the same values as `/model` plus `inherit`. Deliberately not enumerated: the accepted set moves with the product and with an organisation's `availableModels` allowlist, so a list assembled here would reject working skills. With `context: fork` it sets the forked subagent's model instead.\"\n },\n \"effort\": {\n \"enum\": [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"],\n \"description\": \"Reasoning effort while the skill is active, overriding the session level. Which levels are actually available depends on the model. Claude Code only.\"\n },\n \"context\": {\n \"const\": \"fork\",\n \"description\": \"`fork` runs the skill in its own subagent context, with the rendered body as the prompt and no access to the conversation history. The only value Claude Code defines.\"\n },\n \"agent\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Which subagent type runs the skill. Applies only with `context: fork`. Not enumerated, because the set includes whatever agents the project, its plugins and the user define.\"\n },\n \"background\": {\n \"$ref\": \"#/$defs/flag\",\n \"description\": \"Applies only with `context: fork`. `false` waits for the forked subagent's result inside the invoking turn instead of letting it run in the background. Default: `true`; needs Claude Code 2.1.218 or later.\"\n },\n \"hooks\": {\n \"type\": \"object\",\n \"description\": \"Hooks registered when the skill is invoked, which then run for the rest of the session. Keyed by hook event, in the same shape as the hooks configuration, including the `once` option. The inner shape is left unconstrained here: it is the hooks contract rather than the skill contract, and it is versioned separately.\"\n },\n \"paths\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Glob patterns that scope automatic activation, as a comma-separated string or a YAML list. With these set, Claude loads the skill on its own only while working on matching files. Same format as path-specific memory rules. Ignored in a `.claude/commands/` file.\"\n },\n \"shell\": {\n \"enum\": [\"bash\", \"powershell\"],\n \"description\": \"Which shell runs the skill's inline `` !`command` `` injections. Defaults to `bash`, which fails the invocation outright on Windows without Git Bash; `powershell` routes them through the PowerShell tool instead.\"\n },\n \"metadata\": {\n \"type\": \"object\",\n \"description\": \"Free-form map for your own tooling — entitlement or catalogue fields Claude Code reads but never acts on, dropping a value that is not a map. Looser than the standard's `metadata`, which takes string values only, so a nested or numeric entry here will not survive packaging for distribution. Do not reuse front matter field names such as `paths` as keys.\"\n },\n \"license\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"License covering the skill, from the Agent Skills standard. Claude Code accepts the field and does not act on it.\"\n },\n \"compatibility\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 500,\n \"description\": \"Environment requirements, from the Agent Skills standard, in at most 500 characters. Claude Code accepts the field and does not act on it.\"\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"mkdocs:material:9.7\",\n \"title\": \"MkDocs Material front matter v9.7\",\n \"description\": \"Front matter read by MkDocs 1.6 and Material for MkDocs 9.7 — the two keys MkDocs itself defines (`title`, `template`), the six Material's own templates read, the three its bundled plugins read, and the eight the blog plugin reads on a post. Nothing is required: MkDocs takes a page title from the `nav`, the first H1 or the file name in turn, so a page with no front matter at all builds and renders. That makes it a pure shape check, and the shapes worth checking are the ones the build accepts and then acts on wrongly — a `hide` entry no template tests for, a `tags` string the search plugin skips, a `date` mapping with no `created`. Pinned to Material 9.7 because 9.7.0 is the last feature release of the line. See https://www.mkdocs.org/user-guide/writing-your-docs/#meta-data and https://squidfunk.github.io/mkdocs-material/reference/\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"$defs\": {\n \"stringList\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n },\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"description\": \"Overrides the page title. MkDocs checks the `nav` entry, then this, then the first H1, then the file name, and stops at the first that answers — so nothing breaks without it.\"\n },\n \"template\": {\n \"type\": \"string\",\n \"description\": \"The theme template rendering this page, instead of `main.html`. Resolved against the theme's template directory, so a name the theme does not carry fails the build.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Becomes the page's `<meta name=\\\"description\\\">`, and the description on its social card.\"\n },\n \"author\": {\n \"type\": \"string\",\n \"description\": \"Becomes the page's `<meta name=\\\"author\\\">`. One name, not a list — Material renders the value straight into the attribute. The blog plugin's `authors` is a different key.\"\n },\n \"icon\": {\n \"type\": \"string\",\n \"description\": \"An icon shortcode, resolved as `.icons/<value>.svg` — so `material/cached`, not `material/cached.svg`. Shown beside the page in the navigation.\"\n },\n \"status\": {\n \"type\": \"string\",\n \"description\": \"A status marker shown in the navigation. `new` and `deprecated` ship with the theme; any other value has to be declared in `theme.extra.status`, so the set is site-configured and not enumerated here.\"\n },\n \"subtitle\": {\n \"type\": \"string\",\n \"description\": \"Rendered under the page's navigation entry. Added in Material 9.6.\"\n },\n \"hide\": {\n \"type\": \"array\",\n \"description\": \"Page elements to hide. Material tests membership of this list in its templates and reports nothing for an entry it does not know, so a value outside these six hides nothing and says nothing.\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\"navigation\", \"toc\", \"path\", \"tags\", \"footer\", \"feedback\"]\n }\n },\n \"tags\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"Tags for this page, read by the tags plugin and added to the search index. A list, never a bare string: the search plugin skips a `tags` that is not a list without a word.\"\n },\n \"search\": {\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"description\": \"Per-page search options.\",\n \"properties\": {\n \"exclude\": {\n \"type\": \"boolean\",\n \"description\": \"Keeps the page out of the search index entirely.\"\n },\n \"boost\": {\n \"type\": \"number\",\n \"description\": \"Multiplies the page's search ranking. Copied into the index as written, so a quoted number arrives as a string and ranks nothing.\"\n }\n }\n },\n \"social\": {\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"description\": \"Per-page overrides of the social cards plugin's site-level settings.\",\n \"properties\": {\n \"cards\": {\n \"type\": \"boolean\",\n \"description\": \"`false` skips card generation for this page.\"\n },\n \"cards_layout\": {\n \"type\": \"string\",\n \"description\": \"The layout to render this page's card with, resolved under `cards_layout_dir`.\"\n },\n \"cards_layout_options\": {\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"description\": \"Layout options merged over the site-level ones — `title`, `description`, `background_color`, `background_image`, `color`, `font_family`. Left unconstrained beyond its type, because the keys a layout reads are the layout's own.\"\n }\n }\n },\n \"date\": {\n \"description\": \"A blog post's date: the date itself, or a mapping carrying `created` plus any other date you want the templates to have. The blog plugin errors on a post with no `date` at all, and on a mapping with no `created`. Typed but not format-checked: MkDocs parses front matter with PyYAML, which resolves several timestamp spellings, so pinning one format here would fail input the plugin accepts.\",\n \"if\": { \"type\": \"object\" },\n \"then\": {\n \"type\": \"object\",\n \"required\": [\"created\"],\n \"additionalProperties\": { \"type\": \"string\" },\n \"properties\": {\n \"created\": { \"type\": \"string\" },\n \"updated\": { \"type\": \"string\" }\n }\n },\n \"else\": { \"type\": \"string\" }\n },\n \"authors\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"A blog post's authors, as identifiers defined in `.authors.yml`. Duplicates are dropped silently, so they are not an error here.\"\n },\n \"categories\": {\n \"$ref\": \"#/$defs/stringList\",\n \"description\": \"A blog post's categories. Deduplicated the same way as `authors`.\"\n },\n \"draft\": {\n \"type\": \"boolean\",\n \"description\": \"Holds a post back from the built site. A quoted `\\\"false\\\"` is a string, which the post configuration refuses outright.\"\n },\n \"pin\": {\n \"type\": \"boolean\",\n \"description\": \"Pins a post to the top of the blog views. Defaults to false.\"\n },\n \"readtime\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"description\": \"Overrides the computed reading time, in minutes.\"\n },\n \"slug\": {\n \"type\": \"string\",\n \"description\": \"Overrides the URL segment a post is built at, otherwise derived from its title.\"\n },\n \"links\": {\n \"type\": \"array\",\n \"description\": \"Links shown in a post's sidebar, written in the same shape as `nav`: a path, or a mapping of label to path.\",\n \"items\": { \"type\": [\"string\", \"object\"] }\n }\n }\n}\n","{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"anthropic:claude-subagent:2.1\",\n \"title\": \"Claude Code subagent definition front matter v2.1\",\n \"description\": \"Front matter accepted by Claude Code 2.1 in an agent definition — a markdown file under `.claude/agents/`, `~/.claude/agents/`, or a plugin's `agents/` directory, whose body is the subagent's system prompt. Eighteen fields, of which `name` and `description` are required: a file with no `name` is skipped as documentation and one with no `description` is refused with an error, so neither is optional the way a `SKILL.md` field is. Unknown keys are tolerated, because Claude Code records an unrecognised agent key as telemetry and loads the file anyway. The enumerated sets here are the ones the loader checks rather than the ones the documentation lists — `isolation` takes `remote` as well as `worktree`, and `permissionMode` takes `manual` as an alias for `default`. Three fields carry a plugin caveat: `permissionMode`, `hooks` and `mcpServers` are read for a project or user agent and ignored for a plugin one. Do not reach for this schema to check a `SKILL.md`. The two contracts look alike and are not, starting with tool grants spelled `tools` and `disallowedTools` here and `allowed-tools` and `disallowed-tools` there — see `anthropic:claude-skill:2.1`. See https://code.claude.com/docs/en/sub-agents\",\n \"type\": \"object\",\n \"additionalProperties\": true,\n \"required\": [\"name\", \"description\"],\n \"$defs\": {\n \"wordsOrList\": {\n \"description\": \"A field Claude Code accepts either as one delimited string or as a YAML list of entries. The string form is split on commas and spaces falling outside parentheses, so a parenthesised rule such as `Bash(npm run test:*)` survives as a single entry. `items` applies only to the array form, so no branch is needed and a bad entry is reported once, against the item that is wrong.\",\n \"type\": [\"string\", \"array\"],\n \"items\": { \"type\": \"string\", \"minLength\": 1 }\n }\n },\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"^[^-]\",\n \"description\": \"The agent's identity: how the Agent tool, the `--agent` flag and an `Agent(...)` tool grant address it, and what a hook sees as `agent_type`. Required — a file without one is skipped silently as documentation rather than reported. Independent of the filename, which is only where the agent was found, and of the directory it sits in. Constrained here to the one rule the loader enforces, that a name may not begin with `-`. The documented lowercase-and-hyphens convention is not enforced, and agent types with capitals in them ship today, so a schema holding this to `^[a-z-]+$` would fail agents that work. Avoid `:` all the same: it is the separator in a plugin-scoped identifier such as `my-plugin:reviewer`.\"\n },\n \"description\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"When to delegate to this agent, which is how Claude decides whether to call it and what the Agent tool listing shows. Required — an agent file without one is refused with `missing required 'description' in frontmatter`. Saying \\\"use proactively\\\" encourages automatic delegation. The descriptions of all custom agents share one budget, so keep this short; that budget is a truncation rather than an error, and is not enforced here.\"\n },\n \"model\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"description\": \"Model the agent runs on, taking the same values as `/model` plus `inherit`, which matches the spawning conversation and is also what omitting the field does. Deliberately not enumerated: the accepted set moves with the product and is narrowed further by an organisation's `availableModels` allowlist, so a list assembled here would reject working agents.\"\n },\n \"tools\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Allowlist of tools the agent may call, replacing the default inherited set. Entries are exact tool names, scoped rules such as `Bash(npm run test:*)`, `Agent(worker, researcher)` to bound which agents it may spawn, or an `mcp__<server>` pattern. A list containing `*` imposes no restriction at all, which is what omitting the field already does.\"\n },\n \"disallowedTools\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Denylist of tools removed from whatever pool the agent ends up with, in the same entry format as `tools`. Useful for narrowing the inherited set without enumerating everything kept — an agent that may run commands but must not edit files.\"\n },\n \"color\": {\n \"enum\": [\n \"red\",\n \"blue\",\n \"green\",\n \"yellow\",\n \"purple\",\n \"orange\",\n \"pink\",\n \"cyan\"\n ],\n \"description\": \"Display colour for the agent in the task list and transcript. A closed, published set of eight. Worth checking even though it is cosmetic: a colour outside the set is dropped without a warning, so the only symptom is an agent that never takes the colour you gave it.\"\n },\n \"effort\": {\n \"type\": [\"string\", \"integer\"],\n \"pattern\": \"^(?:low|medium|high|xhigh|max|-?[0-9]+)$\",\n \"description\": \"Reasoning effort while the agent runs, overriding the session level. Either one of the five published levels or an integer, which is why this is typed as two: `pattern` constrains only the string form and leaves the integer one alone, so a wrong value is reported once, against the key. Which levels a model actually offers varies. The loader additionally folds case and resolves two internal aliases; neither is part of the published contract, and both are left out here so the accepted set matches `anthropic:claude-skill:2.1`. The integer form carries **no lower bound**, deliberately, and that asymmetry with `maxTurns` is a fact about the loader rather than an oversight: `maxTurns` is checked for a positive integer and warns otherwise, while `effort` is checked with a bare integer test, so `0` and `-3` are both taken and neither is reported. A `minimum` here would fail an agent that runs. The integer may also be written quoted, which is why the pattern carries a digit branch as well as the five names — the loader reaches the numeric form through `parseInt` on the string, so `\\\"8\\\"` and `8` are the same value to it, exactly as they are for `maxTurns`.\"\n },\n \"permissionMode\": {\n \"enum\": [\n \"acceptEdits\",\n \"auto\",\n \"bypassPermissions\",\n \"default\",\n \"dontAsk\",\n \"manual\",\n \"plan\"\n ],\n \"description\": \"Permission mode the agent runs in, defaulting to the spawning conversation's. `manual` is accepted as an alias for `default` and normalised to it before the mode is checked, so both spellings are legal. Read for a project or user agent; ignored for a plugin agent, which is warned about rather than failed.\"\n },\n \"maxTurns\": {\n \"type\": [\"integer\", \"string\"],\n \"minimum\": 1,\n \"pattern\": \"^[1-9][0-9]*$\",\n \"description\": \"Cap on agentic turns before the agent stops; its output is then marked partial and it can be resumed. A positive integer, written either as a YAML number or as a quoted string — typed as both, with `minimum` constraining only the number and `pattern` only the string, so a wrong value is reported once. `null` is rejected on purpose: the loader treats it as an invalid value rather than as an absent one.\"\n },\n \"skills\": {\n \"$ref\": \"#/$defs/wordsOrList\",\n \"description\": \"Skills preloaded into the agent's context when it starts, by name. The full skill content is injected, so this is a budget as well as a convenience; the agent can still reach an unlisted skill through the Skill tool.\"\n },\n \"mcpServers\": {\n \"type\": \"array\",\n \"description\": \"MCP servers available to the agent. Each entry is either the name of a server the parent session already runs, reused by reference, or a one-key map defining a server inline and scoped to this agent alone. The inner shape of an inline definition is left unconstrained here: it is the MCP server contract rather than the agent contract, and it is versioned separately. Read for a project or user agent; ignored for a plugin agent.\",\n \"items\": { \"type\": [\"string\", \"object\"] }\n },\n \"hooks\": {\n \"type\": \"object\",\n \"description\": \"Hooks registered for the lifetime of this agent, keyed by hook event, in the same shape as the hooks configuration. `Stop` is registered as `SubagentStop`. The inner shape is left unconstrained here for the same reason as `mcpServers`: it is the hooks contract, versioned separately. Read for a project or user agent; ignored for a plugin agent, and it needs a trusted workspace.\"\n },\n \"memory\": {\n \"enum\": [\"user\", \"project\", \"local\"],\n \"description\": \"Scope of the agent's persistent memory directory: `user` for `~/.claude/agent-memory/<name>/`, `project` for `.claude/agent-memory/<name>/` — version-controlled and shared — and `local` for `.claude/agent-memory-local/<name>/`. Needs auto memory enabled. Setting this also forces the memory tools into the agent's tool set, even when `tools` did not list them.\"\n },\n \"background\": {\n \"type\": [\"boolean\", \"string\"],\n \"pattern\": \"^(?:true|false)$\",\n \"description\": \"`true` keeps the agent in the background even when Claude asks for its result in the foreground. Accepts a YAML boolean, or the exact lowercase strings `true` and `false`. The two branches are not the same set and the difference is invisible in the file: YAML 1.2 resolves `true`, `True` and `TRUE` to booleans, so all three reach the validator on the boolean branch and pass, while a *quoted* `\\\"True\\\"` stays a string and fails, because the loader compares the string form against `'true'` and `'false'` exactly. This is the trap in moving between the two Claude Code contracts: a `SKILL.md` flag takes `yes`, `no`, `on`, `off`, `1` and `0` as well, while the agent loader answers every one of those with `Must be 'true', 'false', or omitted.` Written as two type-scoped keywords rather than a branch, so a wrong value is reported once, against the key.\"\n },\n \"isolation\": {\n \"enum\": [\"worktree\", \"remote\"],\n \"description\": \"Where the agent's file changes land. `worktree` runs it in a temporary git worktree cut from the repository's default branch, cleaned up automatically when nothing changed; `remote` is the loader's other accepted value. The published documentation names only `worktree`, and the schema follows the loader, which warns on anything outside these two.\"\n },\n \"initialPrompt\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\",\n \"description\": \"First user turn, submitted automatically when this definition runs as the *main* session — through `--agent` or the `agent` setting — and prepended to any prompt the user supplies. Commands and skills in it are expanded. Not read when the definition is spawned as a subagent, which is the usual case, so an agent that only ever gets delegated to has no use for it. A value that is only whitespace is discarded silently by the loader, so the pattern requires one non-space character rather than leaving `minLength` to pass it.\"\n },\n \"observer\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\",\n \"description\": \"Agent type spawned automatically as a background observer whenever this agent runs, to watch how it works rather than to do the work. Names an agent type, so it is not enumerated: the set includes whatever the project, its plugins and the user define. Blank or whitespace-only is dropped silently, which is why the pattern demands a non-space character instead of letting `minLength` wave a run of spaces through.\"\n },\n \"observerMessage\": {\n \"type\": \"string\",\n \"minLength\": 1,\n \"pattern\": \"\\\\S\",\n \"description\": \"Extra instruction appended, after the harness-owned default, to each activity digest sent to the `observer`. Only meaningful alongside `observer`; that pairing is a cross-field rule the schema does not express. Whitespace alone is discarded silently, so the pattern reports it.\"\n }\n }\n}\n","/**\n * Resolve the schema *set* for a single file by precedence:\n * 1. CLI --schema overrides (apply to all files)\n * 2. $schema in the file's metadata (string or list)\n * 3. first matching config override (by glob)\n * 4. config default schemas\n * 5. the built-in default set (DEFAULT_SCHEMAS)\n */\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type {\n DocmetaConfig,\n DocumentRefTrust,\n SchemaEntry,\n SchemaOverride,\n SchemaTrustRoot,\n} from \"./config.js\";\nimport {\n classifyRef,\n isPublishedBuiltinUrl,\n type SchemaPin,\n} from \"./schema-registry.js\";\nimport { DocmetaError } from \"../types.js\";\nimport { matchesFileGlob } from \"../../shared/globs.js\";\n\n/**\n * Applied when nothing else resolves. Seven-Action is safe to include here\n * because it constrains `action` — a key documents don't otherwise carry — and\n * does not require it, so adding it fails nothing that passed before.\n * Diataxis is deliberately absent: it both requires and constrains `type`, so\n * defaulting it would fail every repo not already on Diataxis.\n */\nexport const DEFAULT_SCHEMAS: readonly string[] = Object.freeze([\n \"google:okf:0.1\",\n \"passo-uno:seven-action:1.0\",\n]);\nexport const FILE_SCHEMA_KEY = \"$schema\";\n\n/**\n * The reference a `schemas:` entry loads, in either form.\n *\n * The ref *string* is what `resolveSchemaSet` returns and therefore what every\n * report names, what every baseline fingerprint is taken over, and what keys\n * `Validator`'s compile cache. Widening those to carry a mapping would have\n * changed all three; the `{source, integrity}` pair travels separately, in\n * the pin map below.\n */\nexport function schemaEntryRef(entry: SchemaEntry): string {\n return typeof entry === \"string\" ? entry : entry.ref;\n}\n\n/**\n * The ref → pin map for a config, for `loadSchema` to consult.\n *\n * Only entries that actually carry `source` or `integrity` are recorded, so a\n * config written entirely in the string form produces an empty map and nothing\n * about how it loads changes.\n *\n * Keyed on the ref exactly as `resolveSchemaSet` will hand it to `loadSchema`,\n * which means this must be built from the **rebased** config — the same\n * absolute spelling on both sides, or the pin silently fails to apply.\n */\nexport function collectSchemaPins(\n config: DocmetaConfig | null | undefined,\n): Map<string, SchemaPin> {\n const pins = new Map<string, SchemaPin>();\n for (const entry of config?.schemas ?? []) {\n if (typeof entry === \"string\") continue;\n if (entry.source === undefined && entry.integrity === undefined) continue;\n pins.set(entry.ref, {\n ...(entry.source !== undefined ? { source: entry.source } : {}),\n ...(entry.integrity !== undefined ? { integrity: entry.integrity } : {}),\n });\n }\n return pins;\n}\n\n/**\n * Re-point a config's **local file** schema refs at the config's own directory.\n *\n * `schemas: [\"./house.schema.json\"]` means the file next to the config; that is\n * what the person editing the config can see. But `loadSchema` reads a file ref\n * relative to the process's working directory, so once the config lives\n * somewhere other than where the command was invoked — via `-c ../x.yaml`, or\n * via discovery finding an ancestor — the same ref points at nothing.\n *\n * Only refs the *config* supplied are rebased. A document's own `$schema` and a\n * `--schema` on the command line were both written by someone standing in the\n * working directory, so they keep resolving from there. Built-in ids and URLs\n * have no base to speak of and pass through untouched.\n *\n * When the config's directory *is* the working directory — every setup that\n * works today — the config object is returned unchanged, so nothing about an\n * existing run moves, right down to the ref strings that appear in reports.\n * The rebased form is absolute rather than relative on purpose: relative would\n * only be correct while `process.cwd()` matched `cwd`, which is true of the CLI\n * but not of `runValidate` called as a library.\n */\nexport function rebaseConfigSchemaRefs(\n config: DocmetaConfig,\n configDir: string,\n cwd: string,\n): DocmetaConfig {\n // Exact string comparison, deliberately. `path.resolve` preserves input\n // casing rather than canonicalizing it, so two differently-cased spellings of\n // the same directory on a case-insensitive filesystem would compare unequal\n // and refs would be rebased to absolute paths needlessly — cosmetic, not\n // incorrect. Lowercasing instead would be wrong on a case-sensitive\n // filesystem, where two casings really are two directories. In practice both\n // values reach here from the same `resolve(cwd)` call site.\n if (resolve(configDir) === resolve(cwd)) return config;\n\n const rebase = (ref: string): string =>\n classifyRef(ref).kind === \"file\" && !isAbsolute(ref)\n ? resolve(configDir, ref)\n : ref;\n\n /**\n * The mapping form rebases its `ref` for the same reason a string does, and\n * its `source` too when that is itself a local path — a schema vendored from\n * a checkout elsewhere on disk names a file the config's author could see,\n * not one the caller's working directory can.\n *\n * A `source` that is a URL passes through `rebase` untouched, so no branch is\n * needed here for it.\n */\n const rebaseEntry = (entry: SchemaEntry): SchemaEntry =>\n typeof entry === \"string\"\n ? rebase(entry)\n : {\n ...entry,\n ref: rebase(entry.ref),\n ...(entry.source !== undefined\n ? { source: rebase(entry.source) }\n : {}),\n };\n\n return {\n ...config,\n ...(config.schemas ? { schemas: config.schemas.map(rebaseEntry) } : {}),\n ...(config.overrides\n ? {\n overrides: config.overrides.map((o) => ({\n ...o,\n schemas: o.schemas.map(rebase),\n })),\n }\n : {}),\n };\n}\n\nexport interface ResolveParams {\n /** File path (relative is fine) used for override glob matching. */\n filePath: string;\n /** `$schema` value pulled from the file's metadata. */\n fileSchema?: unknown;\n /** Repeatable `--schema` values; non-empty means override. */\n cliSchemas?: string[];\n /** Loaded config, if any. */\n config?: DocmetaConfig | null;\n /**\n * Directory a **relative document-supplied** file ref is measured from — the\n * run's `cwd`, matching `LoadSchemaOptions.fileBase`. Only the containment\n * check below reads it; the ref string itself is never rewritten.\n */\n fileBase?: string;\n /**\n * The repository a document-supplied local path may not escape. Supplied by\n * the command cores via `schemaTrustRoot`.\n *\n * **Omitting it skips containment.** The resolver is synchronous and pure,\n * and finding a git root is a filesystem walk — so the root is settled once\n * per run by the caller rather than rediscovered per file. `runValidate` and\n * `runFill` both pass it, and `test/commands.test.ts` proves they do end to\n * end; a library caller that resolves refs itself opts in the same way.\n */\n trustRoot?: SchemaTrustRoot;\n /**\n * Diagnostics for the user. Used by `documentRefs: none`, which must say\n * which document's `$schema` it dropped — discarding input in silence is the\n * failure mode this key exists to remove.\n */\n onNotice?: (message: string) => void;\n /**\n * The collections this file belongs to (proposal 0041), from `memberOf`.\n *\n * What an `overrides[].collection` entry is matched against, in place of the\n * glob match a `files:` entry gets. Absent means the caller decided\n * membership does not apply — a library caller with no config file, or a\n * command that has not resolved it — and a `collection:` override then\n * matches nothing, rather than everything.\n */\n memberOf?: readonly string[];\n}\n\n/**\n * The shared glob matcher, re-exported for the callers that reached it here\n * while it lived in this module. Membership (0041) and override resolution\n * ask the same question, so they share one matcher in `src/shared/globs.ts`.\n */\nexport { matchesFileGlob };\n\n/**\n * An override's `files:` as a list, whatever shape it was written in.\n *\n * The single place the string and list forms collapse. Exported because the\n * two places that *display* a group's globs — the collections exclusion notice\n * and `query`'s split-corpus remedy — need the same list, and a second\n * spelling of \"is it an array?\" scattered across them is how the two forms\n * start disagreeing.\n */\nexport function overrideGlobs(\n files: string | readonly string[] | undefined,\n): readonly string[] {\n if (files === undefined) return [];\n return typeof files === \"string\" ? [files] : files;\n}\n\n/**\n * Does this override govern this file?\n *\n * The one place the two spellings of \"which files\" collapse (0041 rule 8): an\n * entry carries exactly one of `files:` (globs, matched by the shared matcher)\n * or `collection:` (a name, matched against the file's membership). Resolution\n * itself is unchanged — first match wins, in config order — so the two forms\n * are interchangeable at the point of decision and nowhere else.\n */\nexport function overrideMatches(\n override: SchemaOverride,\n filePath: string,\n memberOf: readonly string[],\n): boolean {\n if (override.collection !== undefined) {\n return memberOf.includes(override.collection);\n }\n return (\n override.files !== undefined && matchesFileGlob(filePath, override.files)\n );\n}\n\nfunction coerceFileSchema(value: unknown): string[] | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"string\") return [value];\n if (Array.isArray(value) && value.every((v) => typeof v === \"string\")) {\n return value;\n }\n throw new Error(\n `Invalid \"${FILE_SCHEMA_KEY}\": must be a string or a list of strings.`,\n );\n}\n\nfunction dedupe(refs: string[]): string[] {\n return [...new Set(refs)];\n}\n\n/**\n * Does a document-supplied URL name a host the config listed?\n *\n * Both `hostname` (`schemas.example.com`) and `host` (`127.0.0.1:8080`) are\n * compared, so an entry may carry a port or not. Case-insensitive, because DNS\n * is: an allowlist that `Schemas.Example.com` slipped past would be a footgun,\n * not a feature.\n */\nfunction hostAllowed(url: URL, hosts: readonly string[]): boolean {\n const hostname = url.hostname.toLowerCase();\n const host = url.host.toLowerCase();\n return hosts.some((h) => {\n const want = h.trim().toLowerCase();\n return want === hostname || want === host;\n });\n}\n\n/**\n * Refuse a ref this document is not trusted to name.\n *\n * Called **only** from the `fileSchema` branch below, which is the last place\n * that still knows where a ref came from — by the time `loadSchema` sees one it\n * is just a string. Config- and CLI-supplied refs never reach here, in any\n * mode, and that is deliberate: an operator wrote those.\n *\n * Throws `DocmetaError` per ref. `runValidate` and `runFill` both catch it and\n * file it as a per-file `keyword: \"schema\"` finding, so a refusal is **one\n * failing file** (exit 1) annotated on the offending document rather than an\n * aborted run.\n */\nfunction assertDocumentRefAllowed(\n ref: string,\n mode: Exclude<DocumentRefTrust, \"none\">,\n params: ResolveParams,\n): void {\n const { kind } = classifyRef(ref);\n\n // A built-in is bundled with docmeta: it names no host and reads no file, so\n // there is nothing for a document to reach with it. Allowed in every mode —\n // `test/fixtures/schema-ref.md` and the documented \"self-describing document\"\n // pattern both depend on that.\n //\n // A **published** built-in URL (proposal 0009) is the same object under a\n // second name: `loadSchema` aliases it back to the bundled copy before any\n // cache or request, so it too reaches nothing. It is exempted here, above the\n // `kind === \"url\"` block, rather than inside it — because there are two\n // refusals to clear, not one. `documentRefs: \"local\"` rejects any URL outright\n // and never consults `hosts`; `documentRefs: \"any\"` with a non-empty `hosts`\n // rejects a host the operator did not list. An exemption placed inside the url\n // block would clear the second and leave the first, which would make the\n // spelling docmeta itself advertises unusable in the stricter mode.\n //\n // Deliberately narrow: this is an exact-match table lookup, not a host or\n // prefix rule, so any other URL on the same host stays subject to both checks.\n if (kind === \"builtin\" || isPublishedBuiltinUrl(ref)) return;\n\n if (kind === \"url\") {\n if (mode === \"local\") {\n throw new DocmetaError(\n `Refusing the \"${FILE_SCHEMA_KEY}\" URL \"${ref}\": schemaTrust.documentRefs is \"local\", so a document may name a built-in id or a schema file inside the repository, but not a URL. Vendor it with \\`manni meta schemas vendor ${ref}\\` and reference the local copy, or put the URL in \\`schemas:\\` where an operator controls it.`,\n );\n }\n const hosts = params.config?.schemaTrust?.hosts;\n if (!hosts || hosts.length === 0) return; // `any` with no list: as before\n let url: URL;\n try {\n url = new URL(ref);\n } catch {\n throw new DocmetaError(\n `Refusing the \"${FILE_SCHEMA_KEY}\" URL \"${ref}\": it cannot be parsed as a URL, so it cannot be checked against schemaTrust.hosts.`,\n );\n }\n if (!hostAllowed(url, hosts)) {\n throw new DocmetaError(\n `Refusing the \"${FILE_SCHEMA_KEY}\" URL \"${ref}\": host \"${url.host}\" is not in schemaTrust.hosts (${hosts.join(\", \")}). Add the host there, or reference a schema the config already names.`,\n );\n }\n return;\n }\n\n // A local path. \"A schema in this project\" is what a document naming one\n // reasonably means — not any file the CI process happens to be able to open.\n // Applies in `any` as well as `local`: containment costs no existing setup a\n // feature, so it is not something a repo should have to opt into.\n //\n // No `trustRoot` means the caller did not settle a boundary; see the field's\n // documentation for why that is the caller's job and not this function's.\n const root = params.trustRoot;\n if (!root) return;\n const abs = resolve(params.fileBase ?? process.cwd(), ref);\n const within = relative(root.dir, abs);\n // `\"\"` is the root directory itself, which is not a file either way.\n // `path.relative` compares case-insensitively on Windows, so a differently\n // cased spelling of an in-repo path is still recognized as inside.\n if (within !== \"\" && !within.startsWith(\"..\") && !isAbsolute(within)) return;\n // The boundary is named by the rule that produced it. Saying \"the config's\n // own directory\" to someone who has no config file sends them looking for a\n // file that is not there, and the `cwd` case is the one where the boundary\n // moves depending on where the command was run — which is worth saying out\n // loud rather than leaving them to infer it.\n const boundary =\n root.source === \"git\"\n ? `the repository root (${root.dir})`\n : root.source === \"config\"\n ? `${root.dir} — no git repository was found, so the config file's own directory is the boundary`\n : `${root.dir} — no git repository and no config file were found, so the directory the command was run from is the boundary`;\n const scope = root.source === \"git\" ? \"the repository\" : \"the project\";\n throw new DocmetaError(\n `Refusing the \"${FILE_SCHEMA_KEY}\" path \"${ref}\": it resolves outside ${boundary}. A document may only name a schema inside ${scope}; a path in \\`schemas:\\` or on \\`--schema\\` is not restricted this way.`,\n );\n}\n\n/** Which precedence level produced a schema set. */\nexport type SchemaSetSource =\n | \"cli\"\n | \"document\"\n | \"override\"\n | \"config\"\n | \"default\";\n\nexport interface ResolvedSchemaSet {\n schemas: string[];\n source: SchemaSetSource;\n /**\n * Which `overrides[]` entry won, when `source` is `\"override\"`. Absent for\n * every other source.\n *\n * Under proposal 0027 this decided collection membership, and so which SQL\n * view a file appeared in. It no longer does: 0041 decides membership from\n * the collection's own globs, independently of which contract judged the\n * file. What still needs the index is `query`'s split-set refusal, which\n * names the override groups a run spans so it can suggest one to re-run\n * over.\n */\n overrideIndex?: number;\n}\n\n/**\n * `resolveSchemaSet`, plus the branch that won.\n *\n * The caller needs this to answer one question: if a ref in this set fails to\n * *load*, whose problem is it? A schema the **document** chose is that\n * document's problem and belongs in its own finding. A schema the **operator**\n * configured invalidates every file in the run, so it stays operational and\n * aborts. Without the source those two are indistinguishable by the time a\n * `DocmetaError` comes back from `loadSchema`, and both aborted — which let one\n * contributed document take down validation of every other file.\n *\n * Kept as a separate export rather than widening `resolveSchemaSet`'s return,\n * which is public API and is what every existing caller wants.\n */\nexport function resolveSchemaSetWithSource(\n params: ResolveParams,\n): ResolvedSchemaSet {\n const { filePath, fileSchema, cliSchemas, config } = params;\n\n if (cliSchemas && cliSchemas.length > 0) {\n return { schemas: dedupe(cliSchemas), source: \"cli\" };\n }\n\n const fromFile = coerceFileSchema(fileSchema);\n if (fromFile && fromFile.length > 0) {\n // The one branch a trust boundary can be applied in. `none` drops the refs\n // and falls through to the levels below; the other two modes vet each ref\n // and throw on the first they refuse.\n const mode = config?.schemaTrust?.documentRefs ?? \"any\";\n if (mode === \"none\") {\n params.onNotice?.(\n `${filePath}: \"${FILE_SCHEMA_KEY}\" is ignored (${fromFile.join(\", \")}) — schemaTrust.documentRefs is \"none\", so the schema set comes from the config instead. Remove the key from the document, or set schemaTrust.documentRefs to \"local\" or \"any\" to honor it.`,\n );\n } else {\n for (const ref of fromFile) assertDocumentRefAllowed(ref, mode, params);\n return { schemas: dedupe(fromFile), source: \"document\" };\n }\n }\n\n if (config?.overrides) {\n const memberOf = params.memberOf ?? [];\n for (const [i, ov] of config.overrides.entries()) {\n if (overrideMatches(ov, filePath, memberOf) && ov.schemas.length > 0) {\n return { schemas: dedupe(ov.schemas), source: \"override\", overrideIndex: i };\n }\n }\n }\n\n if (config?.schemas && config.schemas.length > 0) {\n return {\n schemas: dedupe(config.schemas.map(schemaEntryRef)),\n source: \"config\",\n };\n }\n\n return { schemas: [...DEFAULT_SCHEMAS], source: \"default\" };\n}\n\nexport function resolveSchemaSet(params: ResolveParams): string[] {\n return resolveSchemaSetWithSource(params).schemas;\n}\n\n/**\n * The `elements:` paths that apply to one file.\n *\n * Accumulating, not first-match-wins. `schemas:` replaces because a schema set\n * is a complete statement about how a file is judged; `elements:` is a list of\n * extra places to look, so the repo-wide list and every matching override all\n * contribute. An override that silently dropped the repo-wide paths would turn\n * adding a directory rule into losing checks elsewhere.\n */\nexport function resolveElements(\n filePath: string,\n config: DocmetaConfig | null | undefined,\n memberOf: readonly string[] = [],\n): string[] {\n const out: string[] = [];\n if (config?.elements) out.push(...config.elements);\n for (const ov of config?.overrides ?? []) {\n if (ov.elements && overrideMatches(ov, filePath, memberOf)) {\n out.push(...ov.elements);\n }\n }\n return dedupe(out);\n}\n","/**\n * Fetch a remote manifest (proposal 0038).\n *\n * A manifest named by URL is fetched at the start of every run and never\n * cached: it is data that changes with every page, and a stale copy validates\n * the corpus against the wrong values. The bounds are the schema fetch's —\n * the same timeout, the same body cap, one narrow retry — because they exist\n * for the same reason there (0008 § stress test 4), and a manifest is\n * smaller than most schemas.\n *\n * The credential, when there is one, comes from the environment and is sent\n * as a bearer token to the origin the config named and nowhere else. It\n * never appears in a message: every error here names the URL and the status,\n * and the URL was checked at config time to carry no userinfo.\n */\nimport { DocmetaError } from \"../types.js\";\n\n/** Default network timeout, matching the schema fetch. */\nexport const EXTERNAL_METADATA_FETCH_TIMEOUT_MS = 10_000;\n\n/** Body cap, matching the schema fetch. */\nexport const EXTERNAL_METADATA_FETCH_MAX_BYTES = 5 * 1024 * 1024;\n\n/** Redirects followed before giving up. */\nconst MAX_REDIRECTS = 5;\n\n/** Backoff before the single retry. */\nconst RETRY_DELAY_MS = 500;\n\nexport interface ExternalMetadataFetchOptions {\n /** Environment variable holding a bearer token. Absent means an anonymous request. */\n tokenEnv?: string;\n timeoutMs?: number;\n maxBytes?: number;\n /** `--offline` / `offline:`: refuse rather than fetch. */\n offline?: boolean;\n /** For tests: the environment to read `tokenEnv` from. Defaults to `process.env`. */\n env?: Record<string, string | undefined>;\n}\n\n/** Fetch one remote manifest. Resolves to its text; throws `DocmetaError`. */\nexport async function fetchExternalMetadata(\n url: string,\n opts: ExternalMetadataFetchOptions = {},\n): Promise<string> {\n if (opts.offline) {\n throw new DocmetaError(\n `Manifest ${url} is remote and the run is offline. Vendor it to a path, or drop --offline.`,\n );\n }\n const timeoutMs = opts.timeoutMs ?? EXTERNAL_METADATA_FETCH_TIMEOUT_MS;\n const maxBytes = opts.maxBytes ?? EXTERNAL_METADATA_FETCH_MAX_BYTES;\n const env = opts.env ?? process.env;\n let token: string | undefined;\n if (opts.tokenEnv !== undefined) {\n token = env[opts.tokenEnv];\n if (token === undefined || token === \"\") {\n throw new DocmetaError(\n `Manifest ${url}: the environment variable ${opts.tokenEnv} named by \"tokenEnv\" is not set.`,\n );\n }\n }\n\n let res = await requestWithRedirects(url, token, timeoutMs);\n // One retry, on the failures that can heal: a network error or a 5xx. A\n // 4xx will not, and retrying it only doubles the time to the same answer.\n if (res instanceof Error || res.status >= 500) {\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));\n res = await requestWithRedirects(url, token, timeoutMs);\n }\n if (res instanceof Error) {\n throw new DocmetaError(\n `Manifest ${url} could not be fetched: ${res.message}`,\n );\n }\n if (!res.ok) {\n const hint =\n res.status === 404 && token === undefined\n ? \" (a private file answers 404 without a token; set \\\"tokenEnv\\\")\"\n : res.status === 404\n ? \" (a private file answers 404 without a valid token)\"\n : \"\";\n throw new DocmetaError(\n `Manifest ${url} could not be fetched: HTTP ${res.status}${hint}.`,\n );\n }\n return readCapped(url, res, maxBytes);\n}\n\n/**\n * GET with manual redirect handling, so the bearer token follows only a\n * same-origin redirect. A cross-origin hop is followed without it, the way\n * browsers and curl behave; if the manifest lives where the token does not\n * reach, the 401 that results is reported rather than the token leaked.\n *\n * Resolves to the final `Response`, or to the `Error` a network failure or\n * timeout raised, so the caller can decide what to retry.\n */\nasync function requestWithRedirects(\n url: string,\n token: string | undefined,\n timeoutMs: number,\n): Promise<Response | Error> {\n const origin = new URL(url).origin;\n let current = url;\n for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {\n const sameOrigin = new URL(current).origin === origin;\n const headers: Record<string, string> = { accept: \"text/plain, application/x-yaml, */*\" };\n if (token !== undefined && sameOrigin) headers.authorization = `Bearer ${token}`;\n let res: Response;\n try {\n res = await fetch(current, {\n headers,\n redirect: \"manual\",\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (err) {\n const isAbort = err instanceof Error && err.name === \"TimeoutError\";\n return isAbort\n ? new Error(`timed out after ${timeoutMs}ms`)\n : new Error(err instanceof Error ? err.message : String(err));\n }\n if (res.status >= 300 && res.status < 400) {\n const location = res.headers.get(\"location\");\n if (location === null) return res;\n await res.body?.cancel();\n current = new URL(location, current).toString();\n continue;\n }\n return res;\n }\n return new Error(`more than ${MAX_REDIRECTS} redirects`);\n}\n\n/** Read a body, aborting once it exceeds `maxBytes`; content-length is advisory. */\nasync function readCapped(\n url: string,\n res: Response,\n maxBytes: number,\n): Promise<string> {\n const body = res.body;\n if (!body) return \"\";\n // `Response.body` is typed `ReadableStream<any>`; name the chunk type once\n // at the boundary, as the schema fetch does, so the cap is counted in\n // numbers rather than `any` arithmetic.\n const reader = body.getReader() as ReadableStreamDefaultReader<Uint8Array>;\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const { done, value }: { done: boolean; value?: Uint8Array } =\n await reader.read();\n if (done || value === undefined) break;\n total += value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new DocmetaError(\n `Manifest ${url} is too large: the response exceeds the ${maxBytes}-byte limit.`,\n );\n }\n chunks.push(value);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n","/**\n * Shared front matter extractor, used by the Markdown, MDX, AsciiDoc, and\n * reStructuredText formats. Three fenced flavors are supported, matching Vale\n * (the `adrg/frontmatter` convention):\n *\n * - YAML — fenced by `--- … ---` (or `...` close).\n * - TOML — fenced by `+++ … +++`.\n * - JSON — fenced by `;;; … ;;;`, with a JSON object inside.\n *\n * Every flavor is the same-shape fenced block (open fence on line 1, content\n * from line 2, matching close fence), so we split them uniformly and only the\n * inner parse differs. YAML and JSON are parsed with the `yaml` AST + a\n * LineCounter to recover a JSON-Pointer -> source-line map (JSON is a strict\n * subset of YAML, so the same walk gives per-key and per-array-item lines for\n * free). TOML is parsed with `smol-toml` for native typing, with a best-effort\n * top-level-key line scan.\n */\nimport { parseDocument, LineCounter, isMap, isSeq, isScalar } from \"yaml\";\nimport { parse as parseToml } from \"smol-toml\";\nimport { isoDateValue } from \"./date-value.js\";\nimport type { ExtractedMetadata, FrontmatterFlavor } from \"../types.js\";\n\ntype Flavor = FrontmatterFlavor;\n\n/** Any recognized opening fence, for the adoc/rst delegation gate. */\nconst OPEN_FENCE = /^(?:---|\\+\\+\\+|;;;)\\r?\\n/;\n\ninterface Fence {\n open: RegExp;\n flavor: Flavor;\n isClose(line: string): boolean;\n}\n\nconst FENCES: Fence[] = [\n { open: /^---\\r?\\n/, flavor: \"yaml\", isClose: (l) => l === \"---\" || l === \"...\" },\n { open: /^\\+\\+\\+\\r?\\n/, flavor: \"toml\", isClose: (l) => l === \"+++\" },\n { open: /^;;;\\r?\\n/, flavor: \"json\", isClose: (l) => l === \";;;\" },\n];\n\n/**\n * Character offsets bracketing the leading fenced block, measured against the\n * *original* content — BOM included, CRLF intact. Writing metadata back is a\n * surgical splice of `[innerStart, innerEnd)`, so everything outside that range\n * (the BOM, both fences, the whole body, the file's final-newline state) is\n * preserved byte for byte by construction rather than by careful reassembly.\n */\nexport interface FrontmatterLocation {\n /** Which flavor the opening fence selected. */\n flavor: Flavor;\n /** Offset of the opening fence's first char (1 when a BOM precedes it). */\n openStart: number;\n /** Offset just past the opening fence's terminator == start of inner text. */\n innerStart: number;\n /** Offset of the closing fence line's first char == end of inner text. */\n innerEnd: number;\n /** Offset just past the closing fence's terminator (or EOF). */\n closeEnd: number;\n /** Line terminator of the opening fence line — the block's EOL on re-emission. */\n eol: \"\\n\" | \"\\r\\n\";\n /** 1-based file line of the first content line (always 2). */\n firstContentLine: number;\n}\n\n/** Strip a leading BOM; it stays part of line 1 and doesn't shift line numbers. */\nfunction stripBom(content: string): string {\n return content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;\n}\n\n/** True when the content opens with a recognized front matter fence. */\nexport function hasFrontmatterFence(content: string): boolean {\n return OPEN_FENCE.test(stripBom(content));\n}\n\n/**\n * Locate the leading fenced front matter block, if any. Returns null when there\n * is no opening fence *or* no matching closing fence — an unterminated fence is\n * not front matter (see the rst extractor, which relies on that distinction).\n */\nexport function locateFrontmatter(content: string): FrontmatterLocation | null {\n const bom = content.charCodeAt(0) === 0xfeff ? 1 : 0;\n const body = bom === 1 ? content.slice(1) : content;\n const fence = FENCES.find((f) => f.open.test(body));\n if (!fence) return null;\n\n // The open regexes all require a terminator, so this newline always exists.\n const openNl = body.indexOf(\"\\n\");\n const eol = openNl > 0 && body.charCodeAt(openNl - 1) === 13 ? \"\\r\\n\" : \"\\n\";\n const innerStart = openNl + 1;\n\n let cursor = innerStart;\n while (cursor <= body.length) {\n const nl = body.indexOf(\"\\n\", cursor);\n const hasNl = nl !== -1;\n const lineEnd = hasNl ? nl : body.length;\n const hadCr = lineEnd > cursor && body.charCodeAt(lineEnd - 1) === 13;\n const line = body.slice(cursor, hadCr ? lineEnd - 1 : lineEnd);\n if (fence.isClose(line)) {\n return {\n flavor: fence.flavor,\n openStart: bom,\n innerStart: innerStart + bom,\n innerEnd: cursor + bom,\n closeEnd: (hasNl ? lineEnd + 1 : lineEnd) + bom,\n eol,\n firstContentLine: 2,\n };\n }\n if (!hasNl) break;\n cursor = lineEnd + 1;\n }\n return null;\n}\n\n/**\n * The block's inner text, LF-normalized with the final terminator removed —\n * byte-identical to what the parsers have always received, which is what lets\n * `extractFrontmatter` sit on top of the locator with no behavior change.\n */\nexport function frontmatterInnerText(\n content: string,\n loc: FrontmatterLocation,\n): string {\n return content\n .slice(loc.innerStart, loc.innerEnd)\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/\\n$/, \"\");\n}\n\n// Re-exported so `asciidoc` and `rst` keep one import site while the\n// implementations live with the other pointer helpers, where `html` and `xml`\n// can share them instead of each keeping a copy.\nexport {\n escapePointerSegment,\n positionForFactory as lineForFactory,\n} from \"./pointer.js\";\nimport { escapePointerSegment, positionForFactory } from \"./pointer.js\";\n\n/** Build a JSON-Pointer -> 1-based file line map from a parsed YAML/JSON block. */\nfunction buildLineMap(\n doc: ReturnType<typeof parseDocument>,\n lc: LineCounter,\n prefixLines: number,\n): Map<string, number> {\n const map = new Map<string, number>();\n // Root pointer maps to the opening fence line (block start).\n map.set(\"\", 1);\n\n const lineAt = (offset: number | undefined): number | undefined =>\n offset == null ? undefined : lc.linePos(offset).line + prefixLines;\n\n const walk = (node: unknown, pointer: string): void => {\n if (isMap(node)) {\n for (const pair of node.items) {\n const key = isScalar(pair.key)\n ? String(pair.key.value)\n : String(pair.key);\n const ptr = `${pointer}/${escapePointerSegment(key)}`;\n // `| null` in the asserted type, not decoration: `yaml` types a\n // Pair's key as nullable, and asserting it away would make the `?.`\n // below read as dead code while the null it guards is still reachable.\n const line = lineAt(\n (pair.key as { range?: [number, number, number] } | null)?.range?.[0],\n );\n if (line != null) map.set(ptr, line);\n if (pair.value) walk(pair.value, ptr);\n }\n } else if (isSeq(node)) {\n node.items.forEach((item, i) => {\n const ptr = `${pointer}/${i}`;\n // `| null` for the same reason as the Pair key above.\n const line = lineAt(\n (item as { range?: [number, number, number] } | null)?.range?.[0],\n );\n if (line != null) map.set(ptr, line);\n walk(item, ptr);\n });\n }\n };\n\n if (doc.contents) walk(doc.contents, \"\");\n return map;\n}\n\n// A top-level TOML key assignment — bare (`key = …`) or simply quoted\n// (`\"my key\" = …` / `'my-key' = …`) — or a `[table]` / `[[array of tables]]`\n// header. Dotted keys and basic-quoted keys containing escape sequences are not\n// matched (best-effort: they fall back to the block's opening line).\nconst TOML_KEY = /^\\s*(?:([A-Za-z0-9_-]+)|\"([^\"\\\\]*)\"|'([^']*)')\\s*=/;\nconst TOML_TABLE = /^\\s*\\[\\[?\\s*([A-Za-z0-9_-]+)/;\n\n/**\n * Best-effort TOML line map: `smol-toml` returns a plain object without\n * positions, so scan the raw block for top-level `key =` assignments and\n * `[table]` / `[[array of tables]]` headers. Only keys in the root-table context are\n * top-level pointers — once a table header appears, subsequent `key =` lines are\n * nested under it, so they are not recorded as top-level keys (that would\n * mis-attribute e.g. `[meta]\\ntitle = …` to the root `/title`). Nested pointers\n * resolve to the nearest recorded ancestor via `lineForFactory`.\n */\nfunction buildTomlLineMap(raw: string, prefixLines: number): Map<string, number> {\n const map = new Map<string, number>();\n map.set(\"\", 1);\n // First occurrence wins; record a pointer only if not already seen.\n const record = (key: string, i: number): void => {\n const ptr = `/${escapePointerSegment(key)}`;\n if (!map.has(ptr)) map.set(ptr, i + 1 + prefixLines);\n };\n\n let inRootTable = true;\n raw.split(\"\\n\").forEach((line, i) => {\n const table = TOML_TABLE.exec(line);\n if (table?.[1] != null) {\n // A `[table]` / `[[array of tables]]` header: record it, then leave root\n // context — every following `key =` belongs to a table, not the root.\n record(table[1], i);\n inRootTable = false;\n return;\n }\n if (!inRootTable) return;\n const km = TOML_KEY.exec(line);\n // Group 1 = bare key, 2 = basic-quoted, 3 = literal-quoted.\n const key = km?.[1] ?? km?.[2] ?? km?.[3];\n if (key != null) record(key, i);\n });\n return map;\n}\n\n/**\n * Coerce a parsed document root to the metadata object shape. An empty document\n * (`null`/`undefined`) is treated as no metadata (`{}`). A scalar or array root\n * is malformed frontmatter — metadata is a key/value object — so it throws,\n * uniformly across flavors. `label` names the flavor for the error message.\n */\nfunction rootObject(parsed: unknown, label: string): Record<string, unknown> {\n if (parsed == null) return {};\n if (typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n throw new Error(`Invalid ${label} frontmatter: root must be an object`);\n}\n\nfunction parseYamlBlock(\n raw: string,\n prefixLines: number,\n format: string,\n): ExtractedMetadata {\n const lc = new LineCounter();\n const doc = parseDocument(raw, { lineCounter: lc });\n if (doc.errors.length > 0) {\n const e = doc.errors[0];\n // Surface as a thrown error; the command layer records it as a per-file\n // failure so the rest of the run continues.\n throw new Error(`Invalid YAML frontmatter: ${e?.message ?? \"parse error\"}`);\n }\n const data = rootObject(doc.toJS({ maxAliasCount: 100 }) as unknown, \"YAML\");\n const map = buildLineMap(doc, lc, prefixLines);\n return { data, present: true, format, lineFor: positionForFactory(map) };\n}\n\nfunction emptyBlock(format: string): ExtractedMetadata {\n // An empty fenced block is present with no data (parity with empty YAML).\n const map = new Map<string, number>([[\"\", 1]]);\n return { data: {}, present: true, format, lineFor: positionForFactory(map) };\n}\n\nfunction parseJsonBlock(\n raw: string,\n prefixLines: number,\n format: string,\n): ExtractedMetadata {\n if (raw.trim() === \"\") return emptyBlock(format);\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n throw new Error(\n `Invalid JSON frontmatter: ${e instanceof Error ? e.message : \"parse error\"}`,\n );\n }\n // Thrown outside the try so its message isn't re-wrapped as a parse error.\n const data = rootObject(parsed, \"JSON\");\n // JSON is a strict subset of YAML: reuse the YAML AST purely for the line map.\n const lc = new LineCounter();\n const doc = parseDocument(raw, { lineCounter: lc });\n const map = buildLineMap(doc, lc, prefixLines);\n return { data, present: true, format, lineFor: positionForFactory(map) };\n}\n\n/**\n * Replace TOML's native dates with the strings they were authored as.\n *\n * TOML is the only flavor with a real date type: `date = 2026-06-25` parses to\n * a `Date`, where the same line under a YAML or JSON fence yields a string. A\n * schema sees the parsed value, so without this a field typed `\"string\"` —\n * OKF's `timestamp`, Hugo's `date` and `lastmod` — rejects the *unquoted*\n * spelling, which is the idiomatic one, and accepts only the quoted one.\n *\n * The per-value spelling is `isoDateValue`, shared with `schemas infer` so the\n * two cannot disagree about what a `Date` looks like as JSON.\n *\n * Recursive, because a date can sit inside a `[table]` or an array.\n */\nfunction withoutNativeDates(value: unknown): unknown {\n if (value instanceof Date) return isoDateValue(value);\n if (Array.isArray(value)) return value.map(withoutNativeDates);\n if (value !== null && typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value).map(([k, v]) => [k, withoutNativeDates(v)]),\n );\n }\n return value;\n}\n\nfunction parseTomlBlock(\n raw: string,\n prefixLines: number,\n format: string,\n): ExtractedMetadata {\n if (raw.trim() === \"\") return emptyBlock(format);\n let parsed: unknown;\n try {\n parsed = parseToml(raw);\n } catch (e) {\n throw new Error(\n `Invalid TOML frontmatter: ${e instanceof Error ? e.message : \"parse error\"}`,\n );\n }\n // A valid TOML document is always a table, but stay uniform with the others.\n const data = rootObject(withoutNativeDates(parsed), \"TOML\");\n const map = buildTomlLineMap(raw, prefixLines);\n return { data, present: true, format, lineFor: positionForFactory(map) };\n}\n\n/** Core front matter extraction shared by the markdown, mdx, adoc, rst formats. */\nexport function extractFrontmatter(\n content: string,\n format: string,\n): ExtractedMetadata {\n const loc = locateFrontmatter(content);\n if (!loc) {\n return { data: {}, present: false, format, lineFor: () => undefined };\n }\n\n const raw = frontmatterInnerText(content, loc);\n const prefixLines = loc.firstContentLine - 1;\n // `fenced` is stamped here, the one place that just located a complete\n // block — a per-extraction fact, not an extractor capability: RST and\n // AsciiDoc reach their native-header fallbacks through their own extract()\n // and never pass this point for those files.\n switch (loc.flavor) {\n case \"yaml\":\n return { ...parseYamlBlock(raw, prefixLines, format), fenced: true };\n case \"json\":\n return { ...parseJsonBlock(raw, prefixLines, format), fenced: true };\n case \"toml\":\n return { ...parseTomlBlock(raw, prefixLines, format), fenced: true };\n }\n}\n","/**\n * The JSON spelling of a parsed date.\n *\n * Two callers need this and they need it to agree. TOML is the only front\n * matter flavor with a real date type, so `date = 2026-06-25` reaches us as a\n * `Date` where the identical line under a YAML or JSON fence yields a string —\n * and both the extractor (which hands values to a schema) and `schemas infer`\n * (which reports the JSON type it saw) have to render that `Date` the same way,\n * or a field is a string in one and something else in the other.\n *\n * `smol-toml` returns a `TomlDate`, whose `toISOString` round-trips the form the\n * author wrote rather than widening it: a local date stays `YYYY-MM-DD` instead\n * of becoming a datetime, and an offset is restored rather than rewritten to\n * `Z`. That is what lets `format: \"date\"` still match a date.\n *\n * Its own module rather than a copy in each caller, for the reason `patch-util`\n * gives for `deepEqual`: a second copy is a second chance for the two to\n * disagree, and the disagreement would be silent.\n */\n\n/** A `Date` as its authored ISO string; any other value unchanged. */\nexport function isoDateValue(value: unknown): unknown {\n if (!(value instanceof Date)) return value;\n // An invalid date cannot reach here from `parseToml`, which throws first, but\n // `toISOString` throws on NaN — so fall back to the \"Invalid Date\" spelling\n // rather than letting an exception escape a parser.\n return Number.isNaN(value.getTime()) ? String(value) : value.toISOString();\n}\n","/**\n * JSON Pointer helpers shared by every extractor.\n *\n * These lived in `frontmatter.ts` and were imported from there by `asciidoc`\n * and `rst`, while `html` and `xml` each carried a byte-identical private copy\n * — three implementations of two functions, and nothing keeping them in step.\n * Adding the column map made that concrete: the same fix would have had to be\n * applied in three places, and a reader had no way to tell which copy was\n * canonical.\n *\n * A pointer is not a frontmatter concept, so this is their home rather than\n * that one.\n */\n\n/**\n * Escape one JSON Pointer segment, per RFC 6901.\n *\n * `~` first, or the `/` replacement's `~1` would be re-escaped to `~01`.\n */\nexport function escapePointerSegment(key: string): string {\n return key.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n}\n\n/**\n * Build a pointer -> position lookup over one map.\n *\n * Position-agnostic on purpose: a line map and a column map share exactly one\n * resolution rule, so they cannot drift into answering from different nodes and\n * pair a line from one place with a column from another.\n *\n * Three steps, in order: a bare top-level key is normalized to its pointer, an\n * exact hit wins, and otherwise it walks up to the nearest recorded ancestor —\n * Ajv reports nested pointers like `/tags/0` for a value the extractor recorded\n * only at `/tags`. The document root is the last resort.\n */\nexport function positionForFactory(\n map: Map<string, number>,\n): (pointer: string) => number | undefined {\n return (pointer: string) => {\n // A bare top-level key (e.g. \"type\") maps to its \"/type\" JSON pointer.\n const start =\n pointer !== \"\" && !pointer.startsWith(\"/\")\n ? `/${escapePointerSegment(pointer)}`\n : pointer;\n if (map.has(start)) return map.get(start);\n let p = start;\n while (p.length > 0) {\n const idx = p.lastIndexOf(\"/\");\n if (idx < 0) break;\n p = p.slice(0, idx);\n if (map.has(p)) return map.get(p);\n }\n return map.get(\"\");\n };\n}\n","/**\n * Front matter write-back, the inverse of `extractFrontmatter`.\n *\n * The whole design rests on one idea: splice only the characters *between* the\n * fences. `locateFrontmatter` gives offsets into the original content, so the\n * BOM, both fences, the entire document body, and the file's final-newline state\n * survive byte for byte by construction rather than by careful reassembly.\n *\n * Per flavor the merge differs, because the fidelity hazards differ:\n *\n * - YAML re-emits the block through the `yaml` Document API, which preserves\n * comments, key order, and scalar styles. Setting a *raw JS scalar* (not a\n * Node) is deliberate: `YAMLMap.add` then mutates the existing node's value\n * in place, keeping its comments and quoting.\n * - TOML splices one key's line span at a time. Re-emitting the block through\n * `smol-toml` would delete every comment and silently rewrite untouched\n * values (`2026-06-25T10:00:00Z` becomes `2026-06-25T10:00:00.000Z`), which\n * is exactly the corruption this module exists to prevent.\n * - JSON re-emits wholesale: it has no comments to lose, and a spread keeps key\n * order, so a surgical splice would buy nothing.\n *\n * Every merge is verified by re-parsing the result and comparing it against the\n * expected data before anything is returned, so a serializer bug becomes a\n * refusal rather than a damaged document.\n */\nimport { parseDocument, isMap, isCollection } from \"yaml\";\nimport { parse as parseToml, stringify as stringifyToml } from \"smol-toml\";\nimport {\n DocmetaError,\n type ApplyOptions,\n type FrontmatterFlavor,\n type MetadataPatch,\n} from \"../types.js\";\nimport {\n hasFrontmatterFence,\n locateFrontmatter,\n frontmatterInnerText,\n} from \"./frontmatter.js\";\nimport { dropUndefined, deepEqual } from \"./patch-util.js\";\nimport { detectJsonIndent } from \"../core/json-text.js\";\n\nconst FENCE: Record<FrontmatterFlavor, string> = {\n yaml: \"---\",\n toml: \"+++\",\n json: \";;;\",\n};\n\n/**\n * Merge `patch` into the document's leading metadata block and return the new\n * content. Pure: no IO, no mutation, and the input string itself is returned\n * when the patch is a no-op.\n */\nexport function applyFrontmatter(\n content: string,\n patch: MetadataPatch,\n options: ApplyOptions = {},\n): string {\n const loc = locateFrontmatter(content);\n\n // Structural checks run before the empty-patch shortcut, so an empty patch\n // is a usable pre-flight probe for \"can this document be written at all?\".\n // `fill` uses it to avoid paying for inference on a file it could never\n // write. Returning the content unchanged here would report a false all-clear.\n if (!loc && hasFrontmatterFence(content)) {\n // An opening fence with no closing fence is not front matter, so the\n // locator returns null — but prepending a fresh block above a stray `---`\n // would produce two overlapping fences and corrupt the file. Refuse.\n throw new DocmetaError(\n \"Unterminated front matter fence: the opening fence has no matching close. Add a closing fence before filling metadata.\",\n );\n }\n\n const clean = dropUndefined(patch);\n // A key both set and deleted would be ambiguous; the set wins, matching the\n // rule that `patch` is applied and `deletions` removes what remains.\n const deletions = (options.deletions ?? []).filter(\n (k) => !Object.prototype.hasOwnProperty.call(clean, k),\n );\n if (Object.keys(clean).length === 0 && deletions.length === 0) return content;\n\n // No block: nothing to delete from, so deletions are no-ops by contract —\n // only a set may create a block. Without this guard a delete-only call on a\n // block-less document would insert a bare `---\\n---\\n`.\n if (!loc) {\n if (Object.keys(clean).length === 0) return content;\n return createBlock(content, clean, options.newBlockFlavor ?? \"yaml\");\n }\n\n const inner = frontmatterInnerText(content, loc);\n const merged = mergeBlock(loc.flavor, inner, clean, deletions);\n verify(loc.flavor, inner, merged, clean, deletions);\n\n /* c8 ignore next 3 -- defensive: every serializer above emits LF only. */\n if (merged.includes(\"\\r\")) {\n throw new DocmetaError(\"Internal error: serialized front matter contains CR.\");\n }\n const emitted = loc.eol === \"\\r\\n\" ? merged.replace(/\\n/g, \"\\r\\n\") : merged;\n\n return (\n content.slice(0, loc.innerStart) +\n (emitted === \"\" ? \"\" : emitted + loc.eol) +\n content.slice(loc.innerEnd)\n );\n}\n\n/**\n * Remove the fenced front matter block entirely — fences included, plus the\n * single blank separator line that conventionally follows the close. This is\n * not the same as deleting every key, which leaves an empty block behind\n * (`_present` still 1). A document with no located block returns unchanged.\n */\nexport function stripFrontmatter(content: string): string {\n const loc = locateFrontmatter(content);\n if (!loc) return content;\n const bom = content.slice(0, loc.openStart);\n let rest = content.slice(loc.closeEnd);\n if (rest.startsWith(loc.eol)) rest = rest.slice(loc.eol.length);\n return bom + rest;\n}\n\n/**\n * Write-back for formats that *also* have a native metadata syntax (rst\n * docinfo, AsciiDoc document headers). Those native reads are lossy — values\n * are coerced through a YAML scalar parse, and an rst `title` is synthesized\n * from the section heading — so they are not round-trippable. Nor can a fenced\n * block simply be created: a bare `---` is a transition in reStructuredText and\n * an open-block delimiter in AsciiDoc, so inventing one would silently change\n * how the document renders. Write only into a block that already exists.\n */\nexport function applyFencedOnly(\n content: string,\n patch: MetadataPatch,\n options: ApplyOptions | undefined,\n format: string,\n): string {\n // Checked before the empty-patch shortcut so this doubles as a writability\n // probe — see the note in applyFrontmatter.\n if (locateFrontmatter(content) === null) {\n if (hasFrontmatterFence(content)) {\n throw new DocmetaError(\n \"Unterminated front matter fence: the opening fence has no matching close. Add a closing fence before filling metadata.\",\n );\n }\n throw new DocmetaError(\n `This ${format} document has no fenced front matter block; manni can only write fenced front matter for ${format}. Add a fenced block, or set the field manually.`,\n );\n }\n if (\n Object.keys(dropUndefined(patch)).length === 0 &&\n (options?.deletions ?? []).length === 0\n ) {\n return content;\n }\n return applyFrontmatter(content, patch, options);\n}\n// ---------------------------------------------------------------------------\n// Block creation\n// ---------------------------------------------------------------------------\n\nfunction createBlock(\n content: string,\n patch: MetadataPatch,\n flavor: FrontmatterFlavor,\n): string {\n const bom = content.charCodeAt(0) === 0xfeff ? \"\\uFEFF\" : \"\";\n const rest = bom === \"\" ? content : content.slice(1);\n // Take the document's *first* terminator, not any CRLF anywhere in it \\u2014 a\n // stray CRLF inside a pasted code block must not make an otherwise\n // LF-normalized file gain a CRLF front matter block.\n const eol = /\\r\\n|\\n/.exec(rest)?.[0] === \"\\r\\n\" ? \"\\r\\n\" : \"\\n\";\n const fence = FENCE[flavor];\n\n const body = mergeBlock(flavor, \"\", patch);\n verify(flavor, \"\", body, patch);\n\n const block = [fence, ...body.split(\"\\n\"), fence].join(eol) + eol;\n // One blank line between the block and the document, unless the document is\n // empty or already starts with one.\n const gap = rest === \"\" || rest.startsWith(\"\\n\") || rest.startsWith(\"\\r\\n\") ? \"\" : eol;\n return bom + block + gap + rest;\n}\n\n// ---------------------------------------------------------------------------\n// Per-flavor merge\n// ---------------------------------------------------------------------------\n\nfunction mergeBlock(\n flavor: FrontmatterFlavor,\n inner: string,\n patch: MetadataPatch,\n deletions: readonly string[] = [],\n): string {\n switch (flavor) {\n case \"yaml\":\n return mergeYaml(inner, patch, deletions);\n case \"toml\":\n return mergeToml(inner, patch, deletions);\n case \"json\":\n return mergeJson(inner, patch, deletions);\n }\n}\n\nfunction mergeYaml(\n inner: string,\n patch: MetadataPatch,\n deletions: readonly string[] = [],\n): string {\n const doc = parseDocument(inner);\n if (doc.errors.length > 0) {\n throw new DocmetaError(\n `Cannot rewrite invalid YAML front matter: ${doc.errors[0]?.message ?? \"parse error\"}`,\n );\n }\n if (doc.contents != null && !isMap(doc.contents)) {\n throw new DocmetaError(\n \"Cannot rewrite front matter: the root must be a mapping.\",\n );\n }\n\n for (const [key, value] of Object.entries(patch)) {\n if (value !== null && typeof value === \"object\") {\n // Collections must be rebuilt, but carry the previous flow/block style so\n // `tags: [a, b]` doesn't silently become a block sequence.\n const prev = doc.get(key, true);\n const node = doc.createNode(value);\n if (isCollection(prev) && isCollection(node) && prev.flow) node.flow = true;\n doc.set(key, node);\n } else {\n // Raw scalar: takes YAMLMap.add's in-place branch, preserving the\n // existing node's comments and quoting style.\n doc.set(key, value);\n }\n }\n // Deleting through the Document API removes the key's node — and its own\n // comments with it — while every other node stays untouched.\n for (const key of deletions) doc.delete(key);\n // lineWidth: 0 disables folding. The default (80) would wrap long values onto\n // continuation lines, rewriting keys the patch never touched.\n return doc.toString({ lineWidth: 0 }).replace(/\\n$/, \"\");\n}\n\nfunction mergeJson(\n inner: string,\n patch: MetadataPatch,\n deletions: readonly string[] = [],\n): string {\n const parsed = parseJsonBlockText(inner);\n const indent = detectJsonIndent(inner);\n const merged = Object.fromEntries(\n Object.entries({ ...parsed, ...patch }).filter(\n ([key]) => !deletions.includes(key),\n ),\n );\n return JSON.stringify(merged, null, indent);\n}\n\n// ---------------------------------------------------------------------------\n// TOML: surgical per-key line splicing\n// ---------------------------------------------------------------------------\n\n// A top-level key assignment, bare or simply quoted. Mirrors the reader's\n// TOML_KEY so read and write agree on what \"top-level\" means.\nconst TOML_KEY = /^\\s*(?:([A-Za-z0-9_-]+)|\"([^\"\\\\]*)\"|'([^']*)')\\s*=/;\nconst TOML_TABLE = /^\\s*\\[\\[?\\s*([A-Za-z0-9_-]+)/;\n\ninterface RootAssignment {\n key: string;\n /** Line index of the assignment's first line. */\n start: number;\n /** Line index just past its last line (values may span lines). */\n end: number;\n}\n\n/**\n * Index the root table's key assignments. Once a `[table]` header appears every\n * following assignment belongs to that table, not the root, so scanning stops\n * there — `rootEnd` is where new root keys must be inserted.\n */\nfunction scanRootTable(lines: string[]): {\n assignments: RootAssignment[];\n rootEnd: number;\n} {\n const assignments: RootAssignment[] = [];\n let i = 0;\n for (; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (TOML_TABLE.test(line)) break;\n const m = TOML_KEY.exec(line);\n const key = m?.[1] ?? m?.[2] ?? m?.[3];\n if (key == null) continue;\n const end = assignmentEnd(lines, i);\n assignments.push({ key, start: i, end });\n i = end - 1;\n }\n return { assignments, rootEnd: i };\n}\n\n/**\n * Line index just past an assignment starting at `start`. A value continues\n * across lines while brackets/braces are unbalanced or a multi-line string is\n * open, so quotes and `#` comments must be tracked to avoid counting brackets\n * that sit inside them.\n */\nfunction assignmentEnd(lines: string[], start: number): number {\n let depth = 0;\n let multi: string | null = null;\n let i = start;\n for (; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n let j = 0;\n while (j < line.length) {\n if (multi != null) {\n if (line.startsWith(multi, j)) {\n multi = null;\n j += 3;\n } else j++;\n continue;\n }\n if (line.startsWith('\"\"\"', j) || line.startsWith(\"'''\", j)) {\n multi = line.slice(j, j + 3);\n j += 3;\n continue;\n }\n const ch = line[j] ?? \"\";\n if (ch === '\"' || ch === \"'\") {\n j = skipString(line, j, ch);\n continue;\n }\n if (ch === \"#\") break; // comment runs to end of line\n if (ch === \"[\" || ch === \"{\") depth++;\n else if (ch === \"]\" || ch === \"}\") depth--;\n j++;\n }\n if (multi == null && depth <= 0) return i + 1;\n }\n return i;\n}\n\n/** Index just past the string literal opening at `from`. */\nfunction skipString(line: string, from: number, quote: string): number {\n let j = from + 1;\n while (j < line.length) {\n const c = line[j];\n if (quote === '\"' && c === \"\\\\\") {\n j += 2;\n continue;\n }\n j++;\n if (c === quote) break;\n }\n return j;\n}\n\n/** Emit one `key = value` line, rejecting values TOML cannot express inline. */\nfunction emitTomlLine(key: string, value: unknown): string {\n if (value === null) {\n throw new DocmetaError(\n `TOML has no null value; cannot set \"${key}\" in TOML front matter.`,\n );\n }\n if (\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n !(value instanceof Date)\n ) {\n throw new DocmetaError(\n `Cannot write the object value for \"${key}\" into TOML front matter.`,\n );\n }\n const line = stringifyToml({ [key]: value }).trimEnd();\n if (line.includes(\"\\n\") || line.startsWith(\"[\")) {\n throw new DocmetaError(\n `Cannot write the value for \"${key}\" into TOML front matter.`,\n );\n }\n return line;\n}\n\nfunction mergeToml(\n inner: string,\n patch: MetadataPatch,\n deletions: readonly string[] = [],\n): string {\n const lines = inner === \"\" ? [] : inner.split(\"\\n\");\n const { assignments, rootEnd } = scanRootTable(lines);\n const byKey = new Map(assignments.map((a) => [a.key, a]));\n\n // Replace in place, marking replaced spans; collect the rest for appending.\n const replaced = new Map<number, string>();\n const dropped = new Set<number>();\n const appended: string[] = [];\n\n for (const [key, value] of Object.entries(patch)) {\n const line = emitTomlLine(key, value);\n const hit = byKey.get(key);\n if (!hit) {\n appended.push(line);\n continue;\n }\n replaced.set(hit.start, line);\n for (let i = hit.start + 1; i < hit.end; i++) dropped.add(i);\n }\n\n // Deletion is the replacement's degenerate case: the whole span goes,\n // nothing comes back. The same splice discipline keeps comments and every\n // untouched line byte-identical.\n for (const key of deletions) {\n const hit = byKey.get(key);\n if (!hit) continue;\n for (let i = hit.start; i < hit.end; i++) dropped.add(i);\n }\n\n // New keys go at the end of the root table, above any blank lines that\n // separate it from the first `[table]` header.\n let insertAt = rootEnd;\n while (insertAt > 0 && (lines[insertAt - 1] ?? \"\").trim() === \"\") insertAt--;\n\n const out: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n if (i === insertAt) out.push(...appended);\n if (dropped.has(i)) continue;\n out.push(replaced.get(i) ?? lines[i] ?? \"\");\n }\n if (insertAt >= lines.length) out.push(...appended);\n return out.join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Verification\n// ---------------------------------------------------------------------------\n\nfunction parseJsonBlockText(text: string): Record<string, unknown> {\n if (text.trim() === \"\") return {};\n const parsed: unknown = JSON.parse(text);\n if (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new DocmetaError(\n \"Cannot rewrite front matter: the root must be an object.\",\n );\n }\n return parsed as Record<string, unknown>;\n}\n\n/**\n * Read a block back with its own flavor's parser, for the verification pass.\n *\n * **TOML dates stay native here, unlike on the read path.** `extractFrontmatter`\n * normalizes a `TomlDate` to the string it was authored as, because a schema\n * typed `\"string\"` must accept the unquoted spelling. Verification must not:\n * `emitTomlLine` accepts a `Date` and `stringifyToml` needs one to emit an\n * unquoted date, so a patch value arrives here as a `Date` and the re-read has\n * to produce a `Date` for `deepEqual` to match. Normalizing this call for\n * consistency would make every `Date` write fail its own verify step and be\n * refused. `test/frontmatter-write.test.ts` pins both halves.\n */\nfunction parseBlock(\n flavor: FrontmatterFlavor,\n text: string,\n): Record<string, unknown> {\n switch (flavor) {\n case \"json\":\n return parseJsonBlockText(text);\n case \"toml\":\n return text.trim() === \"\"\n ? {}\n : parseToml(text);\n case \"yaml\": {\n const doc = parseDocument(text);\n if (doc.errors.length > 0) {\n throw new DocmetaError(\n `Cannot rewrite invalid YAML front matter: ${doc.errors[0]?.message ?? \"parse error\"}`,\n );\n }\n const js: unknown = doc.toJS({ maxAliasCount: 100 });\n if (js == null) return {};\n if (typeof js !== \"object\" || Array.isArray(js)) {\n throw new DocmetaError(\n \"Cannot rewrite front matter: the root must be a mapping.\",\n );\n }\n return js as Record<string, unknown>;\n }\n }\n}\n\n/**\n * Re-read the merged block and confirm it says exactly what it should. This is\n * the difference between a serializer bug being a refusal and a serializer bug\n * being a corrupted file.\n */\nfunction verify(\n flavor: FrontmatterFlavor,\n inner: string,\n merged: string,\n patch: MetadataPatch,\n deletions: readonly string[] = [],\n): void {\n const expected = Object.fromEntries(\n Object.entries({ ...parseBlock(flavor, inner), ...patch }).filter(\n ([key]) => !deletions.includes(key),\n ),\n );\n const actual = parseBlock(flavor, merged);\n if (!deepEqual(actual, expected)) {\n throw new DocmetaError(\n \"Refusing to write front matter: the rewritten block did not read back as expected.\",\n );\n }\n}\n","/**\n * Helpers shared by every `apply` implementation.\n *\n * These began as private functions in `frontmatter-write.ts`. They moved here\n * when HTML and XML gained write support, because a second copy of `deepEqual`\n * is a second chance for the verify step to disagree with itself — and a verify\n * step that quietly accepts what it should reject is worse than none.\n */\nimport type { MetadataPatch } from \"../types.js\";\n\n/** Keys explicitly set to `undefined` mean \"no opinion\", not \"set to null\". */\nexport function dropUndefined(patch: MetadataPatch): MetadataPatch {\n const out: MetadataPatch = {};\n for (const [k, v] of Object.entries(patch)) if (v !== undefined) out[k] = v;\n return out;\n}\n\n/** Structural equality, used by every writer's verify-before-return step. */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (a instanceof Date || b instanceof Date) {\n const at = a instanceof Date ? a.getTime() : NaN;\n const bt = b instanceof Date ? b.getTime() : NaN;\n return at === bt;\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) {\n return false;\n }\n return a.every((x, i) => deepEqual(x, b[i]));\n }\n if (a == null || b == null || typeof a !== \"object\" || typeof b !== \"object\") {\n return false;\n }\n const ao = a as Record<string, unknown>;\n const bo = b as Record<string, unknown>;\n const ak = Object.keys(ao);\n const bk = Object.keys(bo);\n if (ak.length !== bk.length) return false;\n return ak.every(\n (k) => Object.prototype.hasOwnProperty.call(bo, k) && deepEqual(ao[k], bo[k]),\n );\n}\n","/**\n * Markdown frontmatter extractor. Delegates to the shared, flavor-detecting\n * `extractFrontmatter`, which reads YAML (`--- … ---`), TOML (`+++ … +++`), or\n * JSON (`;;; … ;;;`) fenced front matter.\n */\nimport type { MetadataExtractor } from \"../types.js\";\nimport { extractFrontmatter } from \"./frontmatter.js\";\nimport { applyFrontmatter } from \"./frontmatter-write.js\";\n\nexport const markdownExtractor: MetadataExtractor = {\n name: \"markdown\",\n extensions: [\".md\", \".markdown\"],\n implemented: true,\n extract: (content) => extractFrontmatter(content, \"markdown\"),\n apply: (content, patch, options) =>\n applyFrontmatter(content, patch, options),\n};\n","/**\n * MDX extractor. MDX frontmatter is identical to Markdown's, so we reuse the\n * same logic (YAML/TOML/JSON fenced blocks). Parsing `export const meta = {...}`\n * is future work.\n */\nimport { extractFrontmatter } from \"./frontmatter.js\";\nimport { applyFrontmatter } from \"./frontmatter-write.js\";\nimport type { MetadataExtractor } from \"../types.js\";\n\nexport const mdxExtractor: MetadataExtractor = {\n name: \"mdx\",\n extensions: [\".mdx\"],\n implemented: true,\n extract: (content) => extractFrontmatter(content, \"mdx\"),\n apply: (content, patch, options) =>\n applyFrontmatter(content, patch, options),\n};\n","/**\n * AsciiDoc metadata extractor.\n *\n * Two metadata styles are accepted:\n * 1. A leading fenced frontmatter block (YAML `--- … ---`, TOML `+++ … +++`,\n * or JSON `;;; … ;;;`), as some static-site generators use. This delegates\n * to the shared `extractFrontmatter` so the values are typed and the line\n * map comes for free.\n * 2. The native AsciiDoc document header: the `= Title` line plus `:key: value`\n * attribute entries, running from the first line until the first blank line.\n * Attribute values are parsed as YAML scalars so `2` -> number, `true` ->\n * boolean, etc., consistent with frontmatter typing.\n */\nimport { parse as parseYamlScalar } from \"yaml\";\nimport type { ExtractedMetadata, MetadataExtractor } from \"../types.js\";\nimport {\n extractFrontmatter,\n hasFrontmatterFence,\n escapePointerSegment,\n lineForFactory,\n} from \"./frontmatter.js\";\nimport { applyFencedOnly } from \"./frontmatter-write.js\";\n\nconst TITLE = /^=\\s+(.+?)\\s*$/;\n// `:!name:` or `:name!:` — an unset attribute.\nconst UNSET = /^:(?:!([^:\\s]+)|([^:\\s]+)!):\\s*$/;\n// `:name:` or `:name: value` — a set attribute (value optional).\nconst SET = /^:([^:\\s!][^:\\s]*):(?:\\s+(.*\\S))?\\s*$/;\n\n/** Parse a raw attribute value as a YAML scalar, falling back to the string. */\nfunction typeValue(raw: string): unknown {\n try {\n return parseYamlScalar(raw);\n } catch {\n return raw;\n }\n}\n\n/**\n * Parse the native AsciiDoc document header (title + attribute entries).\n * `lineOffset` shifts reported source lines when the caller has sliced content\n * off the front (e.g. a stray fence line), so annotations stay aligned.\n */\nfunction extractHeader(content: string, lineOffset = 0): ExtractedMetadata {\n const body = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;\n const lines = body.split(/\\r?\\n/);\n\n const data: Record<string, unknown> = {};\n const map = new Map<string, number>();\n map.set(\"\", 1 + lineOffset);\n\n const setKey = (key: string, value: unknown, line: number): void => {\n data[key] = value;\n map.set(`/${escapePointerSegment(key)}`, line);\n };\n\n for (const [i, line] of lines.entries()) {\n // The header ends at the first blank line.\n if (line.trim() === \"\") break;\n\n if (i === 0) {\n const title = TITLE.exec(line);\n if (title?.[1] != null) {\n setKey(\"title\", title[1], i + 1 + lineOffset);\n continue;\n }\n }\n\n const unset = UNSET.exec(line);\n if (unset) {\n const name = unset[1] ?? unset[2];\n if (name != null) setKey(name, false, i + 1 + lineOffset);\n continue;\n }\n\n const set = SET.exec(line);\n if (set?.[1] != null) {\n const value = set[2] === undefined ? true : typeValue(set[2]);\n setKey(set[1], value, i + 1 + lineOffset);\n continue;\n }\n // Non-attribute header lines (e.g. author/revision) are ignored.\n }\n\n const present = Object.keys(data).length > 0;\n return {\n data,\n present,\n format: \"asciidoc\",\n lineFor: lineForFactory(map),\n };\n}\n\nexport const asciidocExtractor: MetadataExtractor = {\n name: \"asciidoc\",\n extensions: [\".adoc\", \".asciidoc\"],\n implemented: true,\n apply: (content, patch, options) =>\n applyFencedOnly(content, patch, options, \"asciidoc\"),\n extract(content) {\n if (hasFrontmatterFence(content)) {\n // Delegate only when a complete frontmatter block is actually present;\n // a stray opening fence with no closing delimiter should not shadow a\n // native AsciiDoc header that follows.\n const fm = extractFrontmatter(content, \"asciidoc\");\n if (fm.present) return fm;\n // A stray opening fence with no closing delimiter is not frontmatter. Slice\n // the fence line off entirely (not blank it — `extractHeader` stops at the\n // first blank line) so a native `= Title` lands at the header start, and\n // pass a matching line offset so every attribute keeps its true source\n // line. `= Title` on line 2 must be at the header start to count, since an\n // AsciiDoc document title is only recognized as the first header line.\n const nl = content.indexOf(\"\\n\");\n if (nl !== -1) return extractHeader(content.slice(nl + 1), 1);\n }\n return extractHeader(content);\n },\n};\n","/**\n * reStructuredText metadata extractor.\n *\n * Two metadata styles are accepted:\n * 1. A leading fenced frontmatter block (YAML `--- … ---`, TOML `+++ … +++`,\n * or JSON `;;; … ;;;`), as some static-site generators (e.g. MyST) use.\n * This delegates to the shared `extractFrontmatter` so the values are typed\n * and the line map comes for free.\n * 2. The native reStructuredText docinfo field list: the run of `:name: value`\n * entries at the top of the document, optionally preceded by a section\n * title (which we skip — only page-level metadata is extracted, not\n * headings). Field values are parsed as YAML scalars so `2` -> number,\n * `[a, b]` -> array, etc., consistent with frontmatter typing.\n */\nimport { parse as parseYamlScalar } from \"yaml\";\nimport type { ExtractedMetadata, MetadataExtractor } from \"../types.js\";\nimport {\n extractFrontmatter,\n hasFrontmatterFence,\n escapePointerSegment,\n lineForFactory,\n} from \"./frontmatter.js\";\nimport { applyFencedOnly } from \"./frontmatter-write.js\";\n\n// `:name:` or `:name: value` — a docinfo field (value optional). The name may\n// contain spaces but not a colon; the value (if any) may.\nconst FIELD = /^:([^:]+):(?:\\s+(.*\\S))?\\s*$/;\n// A section-title adornment: a line of two or more identical punctuation chars.\nconst ADORN = /^([=\\-~:.'\"*+#_^<>])\\1+$/;\n\n/** Parse a raw field value as a YAML scalar, falling back to the string. */\nfunction typeValue(raw: string): unknown {\n try {\n return parseYamlScalar(raw);\n } catch {\n return raw;\n }\n}\n\n/**\n * Detect a leading section title — a text line underlined with punctuation,\n * optionally also overlined — after any blank lines. The title is collected as\n * page metadata; `next` is the index where docinfo field-list parsing resumes.\n */\ninterface TitleInfo {\n /** Title text, when a leading section title is present. */\n title?: string;\n /** 1-based source line of the title text. */\n line?: number;\n /** Index of the first line after the title (and its adornment lines). */\n next: number;\n}\n\n/** A run of identical title-adornment punctuation, or null for any other line. */\nfunction adornment(line: string): { char: string; length: number } | null {\n const m = ADORN.exec(line);\n return m && m[1] != null ? { char: m[1], length: line.length } : null;\n}\n\nfunction parseTitle(lines: string[]): TitleInfo {\n let i = 0;\n while (i < lines.length && (lines[i] ?? \"\").trim() === \"\") i++;\n if (i >= lines.length) return { next: i };\n\n const first = lines[i] ?? \"\";\n // A field line starts the docinfo block, not a title.\n if (FIELD.test(first)) return { next: i };\n\n const over = adornment(first);\n if (over) {\n // Over- and under-lined: adornment / title text / matching adornment. RST\n // requires the over- and underline to use the same character and length,\n // and to be at least as long as the title text.\n const text = lines[i + 1] ?? \"\";\n const under = adornment(lines[i + 2] ?? \"\");\n if (\n text.trim() !== \"\" &&\n !FIELD.test(text) &&\n under != null &&\n under.char === over.char &&\n under.length === over.length &&\n over.length >= text.trim().length\n ) {\n return { title: text.trim(), line: i + 2, next: i + 3 };\n }\n // A lone adornment that isn't a valid overlined title — not metadata.\n return { next: i };\n }\n\n // Underlined: title text / adornment at least as long as the title.\n const under = adornment(lines[i + 1] ?? \"\");\n if (under != null && under.length >= first.trim().length) {\n return { title: first.trim(), line: i + 1, next: i + 2 };\n }\n\n return { next: i };\n}\n\n/**\n * Parse the native reStructuredText page metadata: a leading section title\n * (collected as `title`) followed by the docinfo field list. An explicit\n * `:title:` field takes precedence over the heading.\n */\nfunction extractDocinfo(content: string): ExtractedMetadata {\n const body = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;\n const lines = body.split(/\\r?\\n/);\n\n const data: Record<string, unknown> = {};\n const map = new Map<string, number>();\n // First source line of the metadata block (title or, failing that, a field).\n let blockStart = -1;\n\n const titleInfo = parseTitle(lines);\n if (titleInfo.title != null && titleInfo.line != null) {\n data.title = titleInfo.title;\n map.set(\"/title\", titleInfo.line);\n blockStart = titleInfo.line;\n }\n\n // Skip blank lines between the title and the field list.\n let i = titleInfo.next;\n while (i < lines.length && (lines[i] ?? \"\").trim() === \"\") i++;\n\n for (; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n // The field list ends at the first blank or non-field line.\n if (line.trim() === \"\") break;\n const field = FIELD.exec(line);\n if (!field || field[1] == null) break;\n\n const name = field[1].trim();\n const value = field[2] === undefined ? true : typeValue(field[2]);\n if (blockStart === -1) blockStart = i + 1;\n data[name] = value;\n map.set(`/${escapePointerSegment(name)}`, i + 1);\n }\n\n const present = blockStart !== -1;\n // Root pointer maps to the block start. When no metadata is present we record\n // nothing, so `lineFor` reports unknown rather than misleadingly annotating\n // missing-metadata errors at line 1.\n if (present) map.set(\"\", blockStart);\n\n return {\n data,\n present,\n format: \"rst\",\n lineFor: lineForFactory(map),\n };\n}\n\nexport const rstExtractor: MetadataExtractor = {\n name: \"rst\",\n extensions: [\".rst\"],\n implemented: true,\n apply: (content, patch, options) =>\n applyFencedOnly(content, patch, options, \"rst\"),\n extract(content) {\n if (hasFrontmatterFence(content)) {\n // Delegate only when a complete frontmatter block is actually present.\n const fm = extractFrontmatter(content, \"rst\");\n if (fm.present) return fm;\n // A stray opening fence with no closing delimiter is not frontmatter, and\n // it must not shadow a native docinfo field list that follows. Blank the\n // fence line (keeping its newline so source lines stay aligned) before\n // reading the native metadata — otherwise docinfo parsing would stop on\n // the fence line.\n const nl = content.indexOf(\"\\n\");\n if (nl !== -1) return extractDocinfo(content.slice(nl));\n }\n return extractDocinfo(content);\n },\n};\n","/**\n * The XML read model, split out so that `xml.ts` (which extracts) and\n * `xml-write.ts` (which writes back) share one implementation of it.\n *\n * Metadata comes from the root element's attributes. Namespace declarations\n * (`xmlns`, `xmlns:*`) are dropped as transport noise. Attribute values are\n * parsed as YAML scalars so `\"2\"` -> number and `\"true\"` -> boolean, consistent\n * with the AsciiDoc and HTML extractors.\n *\n * The parsed root is handed back along with the data, because the writer needs\n * the same node the reader drew its values from. Deciding \"which attribute is\n * this key\" twice, in two modules, is how a write ends up landing somewhere the\n * read does not look.\n */\nimport { DOMParser } from \"@xmldom/xmldom\";\nimport { parse as parseYamlScalar } from \"yaml\";\nimport { escapePointerSegment, positionForFactory } from \"./pointer.js\";\nimport {\n childElements,\n ditaShape,\n liftRoot,\n metadataContainers,\n otherMetaEntries,\n DITA_CONTENT_MODEL,\n DITA_LIFTS,\n type DitaLift,\n type DitaShape,\n} from \"./dita.js\";\nimport {\n liftKey,\n pairValues,\n parseElementPath,\n type ElementPath,\n} from \"./element-key.js\";\nimport type { ExtractedMetadata, ExtractOptions } from \"../types.js\";\n\ntype XmlDocument = ReturnType<DOMParser[\"parseFromString\"]>;\nexport type XmlElement = NonNullable<XmlDocument[\"documentElement\"]>;\n\n/** Where a key's effective value came from. */\nexport type XmlSource =\n | { kind: \"attr\"; name: string }\n | { kind: \"othermeta\"; el: XmlElement }\n /**\n * A value read from element text. `els` carries every occurrence, in document\n * order, because the key is a list — a write replaces the whole set, and one\n * element out of several is not a location a write can aim at.\n */\n | { kind: \"element-text\"; els: XmlElement[] }\n /**\n * A value read from an element's *attribute* — `<created date=…/>`. Kept\n * distinct from `element-text` because a writer aiming at the text of an\n * empty element would produce `<created>2026-01-15</created>`, which is\n * neither what the reader looks at nor valid against the DTD.\n */\n | { kind: \"element-attr\"; els: XmlElement[]; name: string };\n\nexport interface XmlRead {\n data: Record<string, unknown>;\n lineMap: Map<string, number>;\n colMap: Map<string, number>;\n /** The root element, or undefined for a document that has none. */\n root: XmlElement | undefined;\n /** The text actually parsed — the source minus any leading BOM. */\n body: string;\n /**\n * The element each key's effective value was read from, so a write can land\n * on the same one. DITA has two channels; plain XML has one.\n */\n sources: Map<string, XmlSource>;\n /** Set when the document is DITA, describing where its metadata belongs. */\n dita: DitaShape | undefined;\n}\n\n/** Parse a raw attribute value as a YAML scalar, falling back to the string. */\nexport function typeValue(raw: string): unknown {\n // An explicitly empty attribute (`title=\"\"`) is the empty string, not the\n // YAML `null` that parsing \"\" would yield.\n if (raw === \"\") return \"\";\n try {\n return parseYamlScalar(raw);\n } catch {\n return raw;\n }\n}\n\n/** Whether an attribute carries metadata, as opposed to describing the document. */\nexport function isMetadataAttribute(name: string): boolean {\n return name !== \"xmlns\" && !name.startsWith(\"xmlns:\");\n}\n\n/**\n * The text an element carries, or `undefined` when it carries none worth\n * lifting.\n *\n * Two exclusions, and both are the reason this returns `undefined` rather than\n * an empty string:\n *\n * - **An element with element children is structure, not a value.** `<body>`\n * full of `<p>` is a container; lifting it would concatenate the prose of the\n * whole document into one key.\n * - **Whitespace-only text is not a value either.** Indented markup puts a\n * newline and some spaces inside every container, so treating that as content\n * would lift every element in the file.\n *\n * Comments and processing instructions are ignored rather than disqualifying,\n * so `<title><!-- note -->Set up</title>` is still a value.\n *\n * A deliberately empty element (`<title></title>`) therefore yields nothing by\n * convention. That is right for the convention, which has to keep structural\n * elements out of the key set without a hardcoded ignore list, and wrong for a\n * path someone named in `elements:` config — where \"present but empty\" is\n * exactly what they want checked. The config path passes `allowEmpty`.\n */\nexport function elementText(\n el: XmlElement,\n allowEmpty = false,\n): string | undefined {\n let text = \"\";\n for (let n = el.firstChild; n; n = n.nextSibling) {\n if (n.nodeType === 1) return undefined;\n if (n.nodeType === 3 || n.nodeType === 4) text += n.nodeValue ?? \"\";\n }\n if (!allowEmpty && text.trim() === \"\") return undefined;\n return text.trim();\n}\n\n/**\n * DITA's typed metadata elements, grouped by the key each contributes.\n *\n * Walks down from `<prolog>` or `<topicmeta>`, descending into any child the\n * content-model table knows — which is how `<critdates>`, `<metadata>` and\n * `<prodinfo>` are reached without either being named here. What is lifted, and\n * whether from text or an attribute, is `DITA_LIFTS`' decision; this only\n * traverses.\n */\nfunction ditaLiftedElements(\n container: XmlElement,\n): Map<string, { els: XmlElement[]; spec: DitaLift }> {\n const out = new Map<string, { els: XmlElement[]; spec: DitaLift }>();\n const add = (key: string, el: XmlElement, spec: DitaLift): void => {\n const found = out.get(key);\n if (found) found.els.push(el);\n else out.set(key, { els: [el], spec });\n };\n const walk = (parent: XmlElement): void => {\n const parentName = parent.nodeName.toLowerCase();\n const lifts = own(DITA_LIFTS, parentName);\n for (const child of childElements(parent)) {\n const childName = child.nodeName.toLowerCase();\n const spec = lifts ? own(lifts, childName) : undefined;\n if (spec?.attrKeys) {\n // One element, several values. The key is named for the *element*,\n // because for an attribute that is the containing thing.\n for (const attr of spec.attrKeys) {\n add(liftKey(childName, attr), child, {\n attr,\n repeatable: spec.repeatable,\n });\n }\n } else if (spec) {\n add(liftKey(parentName, childName), child, spec);\n }\n if (own(DITA_CONTENT_MODEL, childName) !== undefined) walk(child);\n }\n };\n walk(container);\n return out;\n}\n\n/**\n * Own-property lookup on a plain-object table.\n *\n * A document supplies these names, and `Object.prototype` answers to plenty of\n * them: a `<constructor>` element would find `DITA_LIFTS.constructor` and a\n * `<toString>` would descend into a content model that does not exist. `get.ts`\n * already guards the same way where a *field* name indexes an object, for the\n * same reason.\n */\nfunction own<T>(table: Record<string, T>, key: string): T | undefined {\n return Object.prototype.hasOwnProperty.call(table, key)\n ? table[key]\n : undefined;\n}\n\n/**\n * The root's direct children that are values, grouped by the key they\n * contribute, in document order.\n *\n * Grouped rather than emitted one at a time because repeated element names\n * share a key, and every occurrence has to survive — dropping all but the first\n * would discard data silently, which is the failure this whole mechanism exists\n * to avoid.\n */\nfunction liftableChildren(\n root: XmlElement,\n): Map<string, { els: XmlElement[]; values: unknown[] }> {\n const out = new Map<string, { els: XmlElement[]; values: unknown[] }>();\n for (const child of childElements(root)) {\n // Read once. Testing with `elementText` and then reading with it again\n // walked every child element's text twice, on every file.\n const text = elementText(child);\n if (text === undefined) continue;\n const key = liftKey(root.nodeName, child.nodeName);\n const group = out.get(key);\n if (group) {\n group.els.push(child);\n group.values.push(typeValue(text));\n } else {\n out.set(key, { els: [child], values: [typeValue(text)] });\n }\n }\n return out;\n}\n\n/**\n * Every element a config path selects, walked down the child axis from the\n * document root.\n *\n * A plain descent, deliberately: no predicates, no axes, no wildcards. The\n * syntax is documented as a subset of XPath's child axis, and matching that\n * promise exactly is cheaper than explaining which parts of XPath work.\n */\nfunction matchElementPath(\n root: XmlElement,\n segments: string[],\n): XmlElement[] {\n if (root.nodeName.toLowerCase() !== segments[0]) return [];\n let current: XmlElement[] = [root];\n for (const segment of segments.slice(1)) {\n const next: XmlElement[] = [];\n for (const el of current) next.push(...childElements(el, segment));\n current = next;\n }\n return current;\n}\n\n/**\n * Parse and read. Throws for malformed XML, which the command layer records as\n * a per-file failure so the rest of the run continues (mirroring frontmatter).\n */\nexport function readXml(\n content: string,\n filePath?: string,\n options?: ExtractOptions,\n): XmlRead {\n // A BOM stays part of line 1; it doesn't shift line numbers.\n const body = content.charCodeAt(0) === 0xfeff ? content.slice(1) : content;\n\n const errors: string[] = [];\n const doc = new DOMParser({\n onError: (level, msg) => {\n if (level !== \"error\" && level !== \"fatalError\") return;\n // An entity the parser can't resolve is not structural damage. Only the\n // five built-in XML entities are known, and no external DTD is ever\n // fetched, so every DTD-declared entity (`&nbsp;`, `&mdash;` — the norm\n // in DITA) lands here while the document itself is fine. The root\n // element and its attributes still parse, so extraction continues; a\n // reference that is genuinely malformed reports a different error.\n // Matches the @xmldom/xmldom >=0.9 message; re-check on a major bump.\n // The DITA entity test fails loudly if the wording changes.\n if (/entity not found/i.test(msg)) return;\n errors.push(msg);\n },\n }).parseFromString(body, \"text/xml\");\n\n if (errors.length > 0) {\n throw new Error(`Invalid XML: ${errors[0] ?? \"parse error\"}`);\n }\n\n const lineMap = new Map<string, number>();\n const colMap = new Map<string, number>();\n const data: Record<string, unknown> = {};\n const sources = new Map<string, XmlSource>();\n const root = doc.documentElement ?? undefined;\n if (!root) {\n return {\n data,\n lineMap,\n colMap,\n root: undefined,\n body,\n sources,\n dita: undefined,\n };\n }\n\n // Both are 1-based, verified against the parser rather than its typings:\n // `@xmldom/xmldom` documents `lineNumber` as zero-based and `columnNumber`\n // as one-based, but it reports a root element opening on source line 3 as\n // `lineNumber: 3`. The doc comment is wrong; both count from 1.\n const rootLine = root.lineNumber ?? 1;\n const rootCol = root.columnNumber ?? 1;\n lineMap.set(\"\", rootLine);\n colMap.set(\"\", rootCol);\n\n const attrs = root.attributes;\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs.item(i);\n if (!attr) continue;\n const name = attr.name;\n if (!isMetadataAttribute(name)) continue;\n data[name] = typeValue(attr.value);\n sources.set(name, { kind: \"attr\", name });\n const pointer = `/${escapePointerSegment(name)}`;\n lineMap.set(pointer, attr.lineNumber ?? rootLine);\n // An attribute's `columnNumber` is the opening quote of its value, so\n // the caret lands on the value that failed. Recorded only when the line\n // came from the same attribute: pairing a real column with the root's\n // fallback line would point at a character on the wrong line, and an\n // absent entry falls back to the root pair, which is at least coherent.\n if (attr.lineNumber != null && attr.columnNumber != null) {\n colMap.set(pointer, attr.columnNumber);\n }\n }\n\n // Element-derived metadata. Plain XML carries no content model, so the\n // convention stops at the root's direct children and lifts only the ones that\n // are values rather than structure — see `elementText`. Anything deeper needs\n // an explicit `elements:` path, because guessing which nested element is\n // metadata and which is prose is how a document body turns into a key per\n // paragraph.\n for (const [key, { els, values }] of liftableChildren(root)) {\n // Overwrites, deliberately, and only one thing can be overwritten: a root\n // attribute *literally named* `article.title`, since a dot is a legal XML\n // NameChar. The element convention owns its key space — a reader looking at\n // `<article><title>` expects that to be what `article.title` means — so the\n // element wins. `assertNoElementCollision` in the writer is the other half:\n // it refuses to *create* such an attribute, so docmeta never authors the\n // collision it resolves here.\n //\n // Always a list. XML says nothing about cardinality, so a type that\n // depended on how many elements this document happened to carry would be\n // unwritable against; a schema that means \"exactly one\" says `maxItems: 1`.\n data[key] = values;\n sources.set(key, { kind: \"element-text\", els });\n const first = els[0];\n const pointer = `/${escapePointerSegment(key)}`;\n // The caret goes on the first occurrence: it is where a reader looks, and\n // where a write that replaces the set begins.\n if (first?.lineNumber != null) lineMap.set(pointer, first.lineNumber);\n if (first?.columnNumber != null) colMap.set(pointer, first.columnNumber);\n }\n\n // DITA keeps document metadata in <prolog>/<topicmeta>, not on the root\n // element. Reading it is not optional once `fill` can write it: a value the\n // writer puts in an <othermeta> that the reader cannot see leaves the field\n // missing, so `validate` fails again and the next run rewrites it forever.\n const dita = ditaShape(body, root, filePath);\n if (dita) {\n // The typed elements first. They are namespaced by their container, so they\n // cannot collide with the flat `<othermeta>` names below — which is what\n // lets a topic carry the same fact in both channels and have both checked,\n // rather than one quietly overwriting the other.\n const liftContainer = liftRoot(root, dita);\n if (liftContainer) {\n for (const [key, { els, spec }] of ditaLiftedElements(liftContainer)) {\n // Elements and values are kept **paired**. An element that contributes\n // nothing — a second `<vrm>` with no `@release`, a `<created>` with no\n // `@date` — must not stay in `els`, or `els[i]` stops naming the\n // element `values[i]` came from and a write aims at an attribute that\n // is not there.\n const found = pairValues(\n els,\n (el) => (spec.attr ? el.getAttribute(spec.attr) : elementText(el)),\n typeValue,\n );\n if (found.values.length === 0) continue;\n data[key] = spec.repeatable ? found.values : found.values[0];\n sources.set(\n key,\n spec.attr\n ? { kind: \"element-attr\", els: found.els, name: spec.attr }\n : { kind: \"element-text\", els: found.els },\n );\n const first = found.els[0];\n const pointer = `/${escapePointerSegment(key)}`;\n if (first?.lineNumber != null) lineMap.set(pointer, first.lineNumber);\n if (first?.columnNumber != null) colMap.set(pointer, first.columnNumber);\n }\n }\n\n const { container } = metadataContainers(root, dita);\n if (container) {\n for (const { key, value, el } of otherMetaEntries(container)) {\n // othermeta wins over a root attribute of the same name: it is the\n // explicit metadata channel, while root attributes are mostly\n // structural.\n data[key] = typeValue(value);\n sources.set(key, { kind: \"othermeta\", el });\n const pointer = `/${escapePointerSegment(key)}`;\n if (el.lineNumber != null) lineMap.set(pointer, el.lineNumber);\n if (el.columnNumber != null) colMap.set(pointer, el.columnNumber);\n }\n }\n }\n\n // Config paths last. The convention and DITA's content model both ran above,\n // so a path naming a key they already filled is a no-op — which is what keeps\n // adding one from retyping `prolog.source` from a scalar into a list.\n for (const raw of options?.elements ?? []) {\n const spec: ElementPath = parseElementPath(raw);\n if (data[spec.key] !== undefined) continue;\n const matched = matchElementPath(root, spec.segments);\n const found = pairValues(\n matched,\n (el) => (spec.attr ? el.getAttribute(spec.attr) : elementText(el, true)),\n typeValue,\n );\n if (found.values.length === 0) continue;\n data[spec.key] = found.values;\n sources.set(\n spec.key,\n spec.attr\n ? { kind: \"element-attr\", els: found.els, name: spec.attr }\n : { kind: \"element-text\", els: found.els },\n );\n const first = found.els[0];\n const pointer = `/${escapePointerSegment(spec.key)}`;\n if (first?.lineNumber != null) lineMap.set(pointer, first.lineNumber);\n if (first?.columnNumber != null) colMap.set(pointer, first.columnNumber);\n }\n\n return { data, lineMap, colMap, root, body, sources, dita };\n}\n\n/** Shape the read into the generic extractor result. */\nexport function toExtracted(read: XmlRead): ExtractedMetadata {\n return {\n data: read.data,\n present: Object.keys(read.data).length > 0,\n format: \"xml\",\n lineFor: positionForFactory(read.lineMap),\n colFor: positionForFactory(read.colMap),\n };\n}\n","/**\n * The naming rule for element-derived metadata, shared by every structured\n * format.\n *\n * **The containing element is the namespace.** A value that lives in an element\n * rather than in an attribute is keyed `<immediate parent>.<element name>`:\n *\n * <prolog><author>Ada</author> -> prolog.author\n * <head><title>Docs</title> -> head.title\n * <article><byline>Ada</byline> -> article.byline\n *\n * Existing flat keys do not move. Root attributes, `<meta>`, `<othermeta>` and\n * HTML's `<title>` keep the names they have always had, so a document can carry\n * the same fact in two channels and **both are validated** — neither wins, and\n * neither is silently discarded.\n *\n * The separator is a dot in the key and a slash in an `elements:` config path,\n * and the asymmetry is deliberate. XML element names may legally contain dots\n * (`.` is a NameChar, just not a NameStartChar), so a dotted *path* cannot be\n * parsed: `a.b.c` could be `<a.b><c>`, `<a><b.c>` or `<a><b><c>`. That never\n * reaches the key, because nothing parses a key back into a path — a schema\n * names the exact string. It only reaches config, which must parse, and `/`\n * cannot appear in an element name.\n *\n * This is not a new convention. docmeta already prints exactly it: JSON Pointer\n * separates structure with slashes and tolerates a dot inside one segment,\n * which is why `/ms.date` has worked since `microsoft:learn:1.0` shipped.\n */\n\nimport { DocmetaError } from \"../types.js\";\n\n/** The metadata key an element contributes, given its parent's name. */\nexport function liftKey(parentName: string, elementName: string): string {\n return `${parentName.toLowerCase()}.${elementName.toLowerCase()}`;\n}\n\n/**\n * Read a value out of each element, dropping the ones that have none — and\n * dropping the element with it.\n *\n * The pairing is the point. `values[i]` must have come from `els[i]`, because\n * that is how a write knows where to put the replacement back. Filtering the\n * values alone leaves the two lists a different length and silently\n * misaligned, which surfaces later as a write aimed at an attribute the element\n * does not carry, or a caret on an element that contributed nothing.\n *\n * Generic over the node type, and shared, because the XML and HTML readers each\n * had their own copy of the loop and only one of them was fixed the first time.\n */\nexport function pairValues<E>(\n els: readonly E[],\n read: (el: E) => string | null | undefined,\n type: (raw: string) => unknown,\n): { els: E[]; values: unknown[] } {\n const keptEls: E[] = [];\n const values: unknown[] = [];\n for (const el of els) {\n const raw = read(el);\n if (raw == null) continue;\n keptEls.push(el);\n values.push(type(raw));\n }\n return { els: keptEls, values };\n}\n\n/** One `elements:` entry, parsed. */\nexport interface ElementPath {\n /** Element names from the document root down, lowercased. At least two. */\n segments: string[];\n /** Attribute carrying the value. Absent means the element's text. */\n attr?: string;\n /** The key this path contributes, derived by {@link liftKey}. */\n key: string;\n}\n\n/**\n * Parsed paths, keyed by their source string.\n *\n * `elements:` paths are a handful of strings reused for every file in the run,\n * so re-splitting them per document is pure waste — a thousand files and three\n * paths is three thousand parses of the same three strings.\n *\n * Capped, because this module is also reachable through the exported\n * `readXml`/`readHtml`. In the CLI the key set is the config and stays tiny; an\n * embedding that passed a different path per request would otherwise grow a map\n * that never evicts. Past the cap parsing simply happens again, which is the\n * behaviour before the cache existed.\n */\nconst parsed = new Map<string, ElementPath>();\nconst PARSE_CACHE_MAX = 256;\n\n/**\n * Parse an `elements:` path — a slash-separated child path from the document\n * root, optionally ending in `@attribute`.\n *\n * article/byline/author -> key `byline.author`, from element text\n * html/head/link@href -> key `head.link`, from the href attribute\n *\n * A deliberate subset of XPath's child axis. Naming the subset sets the\n * expectation that predicates, axes and functions are not coming, rather than\n * leaving someone to try `article/byline[1]` and file a bug.\n *\n * Two segments are the minimum because the key needs a parent to be the\n * namespace. A bare `title` names an element with no container, so there is no\n * key to derive — that is a config error, not an empty result, since silently\n * ignoring it would leave someone waiting for a check that never runs.\n */\nexport function parseElementPath(path: string): ElementPath {\n const hit = parsed.get(path);\n if (hit) return hit;\n const result = parseElementPathUncached(path);\n if (parsed.size < PARSE_CACHE_MAX) parsed.set(path, result);\n return result;\n}\n\nfunction parseElementPathUncached(path: string): ElementPath {\n const at = path.indexOf(\"@\");\n const attr = at === -1 ? undefined : path.slice(at + 1).trim();\n const body = at === -1 ? path : path.slice(0, at);\n const segments = body\n .split(\"/\")\n .map((s) => s.trim().toLowerCase())\n .filter((s) => s !== \"\");\n\n if (segments.length < 2) {\n throw new DocmetaError(\n `Invalid elements path \"${path}\": it needs at least two segments, ` +\n \"because the key is named after the element's parent \" +\n '(so \"article/title\" gives `article.title`).',\n );\n }\n if (at !== -1 && attr === \"\") {\n throw new DocmetaError(\n `Invalid elements path \"${path}\": \"@\" must be followed by an attribute name.`,\n );\n }\n\n // Both indices are in bounds — the length check above guarantees it. The\n // fallbacks are how `noUncheckedIndexedAccess` is satisfied, not a defence\n // against a case that can happen: it widens `string[][n]` to\n // `string | undefined` regardless of any guard the compiler cannot follow.\n const parent = segments[segments.length - 2] ?? \"\";\n const name = segments[segments.length - 1] ?? \"\";\n return { segments, ...(attr ? { attr } : {}), key: liftKey(parent, name) };\n}\n","/**\n * What docmeta knows about DITA, shared by the reader and the writer.\n *\n * DITA is XML, but its document metadata does not live where the generic XML\n * reader looks. A topic keeps it in\n * `<prolog><metadata><othermeta name=\"…\" content=\"…\"/></metadata></prolog>`;\n * a map keeps it in `<topicmeta>`. The root element's attributes are mostly\n * structural — `id`, `xml:lang`, `class`, `DITAArchVersion` — and, crucially,\n * the DTD declares which of them are allowed. Adding one it does not declare\n * produces a topic that fails validation in the user's own toolchain, which is\n * why the metadata channel and not the root element is the place to write.\n */\nimport type { XmlElement } from \"./xml-read.js\";\nimport { liftKey } from \"./element-key.js\";\n\n/** Which flavour of DITA a document is, and where its metadata belongs. */\nexport interface DitaShape {\n kind: \"topic\" | \"map\";\n /** The element that directly contains `<othermeta>`. */\n container: \"metadata\" | \"topicmeta\";\n /**\n * Elements that must precede the metadata container in the content model. A\n * new container is inserted after the last of these, which in practice means\n * \"before the first child that is not one of them\".\n */\n preamble: Set<string>;\n}\n\nconst TOPIC_ROOTS = new Set([\n \"topic\",\n \"concept\",\n \"task\",\n \"reference\",\n \"glossentry\",\n \"glossgroup\",\n]);\n\nconst MAP_ROOTS = new Set([\"map\", \"bookmap\", \"subjectscheme\"]);\n\n/** Every root element name that suggests DITA, for the extension-backed signal. */\nexport const DITA_ROOTS = new Set([...TOPIC_ROOTS, ...MAP_ROOTS]);\n\n/**\n * Whether this document is DITA, and if so what shape.\n *\n * Positive signals only, in descending order of confidence. A root element\n * merely *named* `map` or `task` is far too weak on its own — those are ordinary\n * names in hand-rolled XML — so the name counts only when the file extension\n * agrees.\n */\nexport function ditaShape(\n content: string,\n root: XmlElement,\n filePath: string | undefined,\n): DitaShape | undefined {\n const name = root.nodeName.toLowerCase();\n const cls = root.getAttribute(\"class\") ?? \"\";\n\n const byDoctype = hasDitaDoctype(content);\n // DITA-OT output carries the specialization ancestry in @class.\n const byClass = /^\\s*[-+]\\s+(topic|map)\\//.test(cls);\n const byArch = root.getAttribute(\"DITAArchVersion\") != null;\n const lower = filePath?.toLowerCase() ?? \"\";\n const byExtension =\n (lower.endsWith(\".dita\") || lower.endsWith(\".ditamap\")) &&\n DITA_ROOTS.has(name);\n\n if (!byDoctype && !byClass && !byArch && !byExtension) return undefined;\n\n // `@class` is the most precise statement of which model applies; the root\n // name and the extension are the fallbacks, in that order.\n const isMap =\n /^\\s*[-+]\\s+map\\//.test(cls) ||\n MAP_ROOTS.has(name) ||\n lower.endsWith(\".ditamap\");\n\n return isMap\n ? { kind: \"map\", container: \"topicmeta\", preamble: new Set([\"title\"]) }\n : {\n kind: \"topic\",\n container: \"metadata\",\n preamble: new Set([\n \"title\",\n \"titlealts\",\n \"shortdesc\",\n \"abstract\",\n \"prolog\",\n ]),\n };\n}\n\n/**\n * Whether the document declares a DITA DTD.\n *\n * Comments are blanked first, at their original length so offsets still line up.\n * Two things go wrong otherwise, and both are silent: a comment containing a\n * tag-like `<word` ends the search window early — `<!-- covers <integration> -->`\n * ahead of the DOCTYPE hides it entirely — and a comment that merely *mentions*\n * a DITA DTD would announce one that isn't there.\n *\n * Missing the DOCTYPE is the dangerous direction. A hand-authored DITA topic\n * carries no `@class` or `@DITAArchVersion` to fall back on, so the file would\n * be taken for plain XML and written as such — a root attribute its DTD does\n * not declare, which is the one outcome this whole module exists to avoid.\n */\nfunction hasDitaDoctype(content: string): boolean {\n // Cheap exit before the expensive one. Masking allocates a same-length string\n // per comment match, and this runs once per file — including on DITA-OT\n // output, which is already identified by `@class` and rarely carries a\n // DOCTYPE at all. Sound in one direction only, which is the direction needed:\n // masking replaces text with spaces and never introduces any, so a document\n // whose raw bytes hold no `<!DOCTYPE` cannot have one after masking either.\n if (!content.includes(\"<!DOCTYPE\")) return false;\n const masked = content.replace(/<!--[\\s\\S]*?-->/g, (m) => \" \".repeat(m.length));\n const doctype = doctypeText(masked);\n if (doctype === undefined) return false;\n\n // A DITA public identifier is unambiguous on its own.\n if (/\\/\\/DTD DITA/i.test(doctype)) return true;\n\n // A SYSTEM-only declaration has no public identifier to match, and DITA\n // written against a local DTD copy looks exactly like that. Two weak signals\n // are required together, because either alone is ordinary in hand-rolled XML:\n // the declared root element has to be a DITA type, *and* the system\n // identifier has to name a DITA DTD.\n const declared = /<!DOCTYPE\\s+([A-Za-z_][\\w.-]*)/.exec(doctype)?.[1];\n if (declared === undefined || !DITA_ROOTS.has(declared.toLowerCase())) {\n return false;\n }\n return /\\b(?:concept|task|reference|topic|map|bookmap|glossentry|glossgroup|ditabase|subjectscheme)\\.dtd\\b/i.test(\n doctype,\n );\n}\n\n/**\n * The whole `<!DOCTYPE …>` declaration, internal subset included.\n *\n * Scanning rather than matching `[^>]*`: an internal subset is full of `>` —\n * `<!ENTITY nbsp \"&#160;\">` is why most DITA files have one at all — and a\n * pattern that stopped at the first would read only part of the declaration.\n * Quotes and `[ … ]` nesting are tracked so the `>` that ends the declaration is\n * the one actually found.\n */\nfunction doctypeText(masked: string): string | undefined {\n const start = masked.indexOf(\"<!DOCTYPE\");\n if (start === -1) return undefined;\n let quote: string | undefined;\n let depth = 0;\n for (let i = start + \"<!DOCTYPE\".length; i < masked.length; i++) {\n const ch = masked[i];\n if (quote !== undefined) {\n if (ch === quote) quote = undefined;\n continue;\n }\n if (ch === '\"' || ch === \"'\") quote = ch;\n else if (ch === \"[\") depth++;\n else if (ch === \"]\") depth--;\n else if (ch === \">\" && depth === 0) return masked.slice(start, i + 1);\n }\n return undefined;\n}\n\n/**\n * One element docmeta lifts out of DITA's typed metadata, and how.\n *\n * `repeatable` is not a guess. It is read straight off the OASIS content model:\n * `author*` is a list, `source?` is a scalar. Generic XML defaults everything to\n * a list because it has no such statement to consult; DITA does, so its keys are\n * typed exactly and a schema can say `format: date` on a scalar rather than\n * reaching through a one-item array.\n */\nexport interface DitaLift {\n /** Attribute carrying the value. Absent means the element's text. */\n attr?: string;\n /**\n * Attributes that are each a value in their own right, rather than one\n * attribute being where the element's single value happens to sit.\n *\n * `<created date=\"…\"/>` is the first case: the element means one thing and\n * `@date` is where it lives, so the key stays `critdates.created`. `<vrm\n * version=\"2\" release=\"1\" modification=\"0\"/>` is the second: three separate\n * facts on one EMPTY element, and keying it `vrmlist.vrm` would have to pick\n * one and discard two.\n *\n * The naming rule does not change to accommodate it — it applies one level\n * down. For an attribute the containing thing is the *element*, so these are\n * `vrm.version`, `vrm.release`, `vrm.modification`.\n */\n attrKeys?: readonly string[];\n /** Whether the content model permits more than one. */\n repeatable: boolean;\n}\n\n/**\n * The typed metadata elements docmeta reads, keyed by the element that contains\n * them — which is also the namespace their key takes.\n *\n * A container appearing as a key here is descended into, so `<prolog>` reaches\n * `<critdates>`, `<metadata>` and `<prodinfo>` without any of them being named\n * as a special case in the walker.\n *\n * `topicmeta` repeats most of `prolog` rather than deferring to it because the\n * two models genuinely differ: `<topicmeta>` holds `audience`, `category`,\n * `prodinfo`, `othermeta` and `resourceid` as **direct children**, where a topic\n * nests them inside `<prolog><metadata>`. Verified against the OASIS\n * content-model appendix rather than assumed — the same fact reads as\n * `topicmeta.audience` in a map and `metadata.audience` in a topic, and both are\n * correct, because each key names where the value actually is.\n *\n * Covers the whole prolog vocabulary docmeta reads. An earlier draft deferred\n * `<copyright>`, `<keywords>` and the `<prodinfo>` tail; proposal 0020 records\n * why each turned out to be reachable by the same mechanism that was said not\n * to reach it.\n */\nexport const DITA_LIFTS: Readonly<\n Record<string, Readonly<Record<string, DitaLift>>>\n> = {\n prolog: {\n author: { repeatable: true },\n source: { repeatable: false },\n publisher: { repeatable: false },\n permissions: { attr: \"entitlement\", repeatable: false },\n resourceid: { attr: \"id\", repeatable: true },\n },\n topicmeta: {\n author: { repeatable: true },\n source: { repeatable: false },\n publisher: { repeatable: false },\n permissions: { attr: \"entitlement\", repeatable: false },\n resourceid: { attr: \"id\", repeatable: true },\n audience: { attr: \"type\", repeatable: true },\n category: { repeatable: true },\n },\n critdates: {\n created: { attr: \"date\", repeatable: false },\n revised: { attr: \"modified\", repeatable: true },\n },\n metadata: {\n audience: { attr: \"type\", repeatable: true },\n category: { repeatable: true },\n },\n copyright: {\n copyryear: { attr: \"year\", repeatable: true },\n copyrholder: { repeatable: false },\n },\n keywords: {\n keyword: { repeatable: true },\n indexterm: { repeatable: true },\n },\n prodinfo: {\n prodname: { repeatable: false },\n brand: { repeatable: true },\n component: { repeatable: true },\n featnum: { repeatable: true },\n platform: { repeatable: true },\n prognum: { repeatable: true },\n series: { repeatable: true },\n },\n vrmlist: {\n vrm: {\n attrKeys: [\"version\", \"release\", \"modification\"],\n repeatable: true,\n },\n },\n};\n\n/**\n * Keys produced by {@link DitaLift.attrKeys} — `vrm.version` and friends.\n *\n * Derived rather than written out, so the two cannot disagree. The writer needs\n * it to tell such a key apart from an ordinary `container.element` one: they\n * look identical, and creating `vrm.version` would mean synthesising a\n * `<vrmlist><vrm/></vrmlist>` and folding three keys into one element, which is\n * not what the create path does.\n */\nexport const DITA_ATTR_KEYS: ReadonlySet<string> = new Set(\n Object.entries(DITA_LIFTS).flatMap(([, lifts]) =>\n Object.entries(lifts).flatMap(([element, spec]) =>\n (spec.attrKeys ?? []).map((attr) => liftKey(element, attr)),\n ),\n ),\n);\n\n/**\n * The ordered content models, for placing an element that does not exist yet.\n *\n * A DITA container is a *sequence*, not a set: `<critdates>` after `<metadata>`\n * is invalid even though both are allowed, so a writer creating an element has\n * to know what may precede it. `shape.preamble` answers that question for one\n * position — where a whole new `<prolog>` goes — and this answers it for every\n * position inside one.\n *\n * Names not listed for a container are unknown to docmeta and sort last, which\n * keeps a specialization docmeta has never seen from being inserted in the\n * middle of a model it does not understand.\n */\nexport const DITA_CONTENT_MODEL: Readonly<Record<string, readonly string[]>> = {\n prolog: [\n \"author\",\n \"source\",\n \"publisher\",\n \"copyright\",\n \"critdates\",\n \"permissions\",\n \"metadata\",\n \"resourceid\",\n \"data\",\n ],\n topicmeta: [\n \"navtitle\",\n \"linktext\",\n \"searchtitle\",\n \"shortdesc\",\n \"author\",\n \"source\",\n \"publisher\",\n \"copyright\",\n \"critdates\",\n \"permissions\",\n \"metadata\",\n \"audience\",\n \"category\",\n \"keywords\",\n \"exportanchors\",\n \"prodinfo\",\n \"othermeta\",\n \"resourceid\",\n \"ux-window\",\n \"data\",\n ],\n critdates: [\"created\", \"revised\"],\n metadata: [\n \"audience\",\n \"category\",\n \"keywords\",\n \"prodinfo\",\n \"othermeta\",\n \"data\",\n ],\n copyright: [\"copyryear\", \"copyrholder\"],\n // `(indexterm | keyword)*` — a repeatable *choice*, so any interleaving is\n // valid and the order here only decides where a created element lands.\n keywords: [\"indexterm\", \"keyword\"],\n vrmlist: [\"vrm\"],\n // `prodname, vrmlist?, (brand | component | featnum | platform | prognum |\n // series)*`. The tail is a choice group too, so its internal order is\n // likewise a placement preference rather than a rule.\n prodinfo: [\n \"prodname\",\n \"vrmlist\",\n \"brand\",\n \"component\",\n \"featnum\",\n \"platform\",\n \"prognum\",\n \"series\",\n ],\n};\n\n/**\n * The container an element of this name lives inside, or `undefined` when it\n * hangs directly off the root.\n *\n * A map is flatter than a topic. `<topicmeta>` holds `audience`, `category` and\n * `prodinfo` as direct children, where a topic nests the first two inside\n * `<prolog><metadata>` and `prodinfo` one deeper still. Encoding it here keeps\n * that asymmetry in the one file that already knows about it.\n */\nexport function ditaContainerParent(\n shape: DitaShape,\n name: string,\n): string | undefined {\n if (name === \"prolog\" || name === \"topicmeta\") return undefined;\n // Two levels below the root are the same in both flavours: `<keywords>` and\n // `<prodinfo>` hang off `<metadata>`, and `<vrmlist>` off `<prodinfo>`. Only\n // the *top* level differs, which is what the fallthrough handles.\n if (name === \"vrmlist\") return \"prodinfo\";\n if (name === \"keywords\" || name === \"prodinfo\") {\n // A map may hold these directly under `<topicmeta>` or nest them in a\n // `<metadata>`; both are legal. Creating one goes to `<metadata>` in a\n // topic, where it is the only option, and directly under `<topicmeta>` in\n // a map, where it is the shorter of the two.\n return shape.kind === \"map\" ? \"topicmeta\" : \"metadata\";\n }\n return shape.kind === \"map\" ? \"topicmeta\" : \"prolog\";\n}\n\n/**\n * Where a new child goes inside a container, by content-model position.\n *\n * Returns the element it should be inserted *before*, or `undefined` for \"at the\n * end\", which the caller turns into an offset.\n *\n * Children the model does not list are skipped rather than used as anchors.\n * They are specializations docmeta has never seen, and inserting before one\n * would be a guess about a model it does not understand; going last is at least\n * a position the author can see and move.\n */\nexport function childAnchor(\n container: XmlElement,\n containerName: string,\n childName: string,\n): XmlElement | undefined {\n const model = DITA_CONTENT_MODEL[containerName] ?? [];\n const target = model.indexOf(childName);\n if (target === -1) return undefined;\n for (const child of childElements(container)) {\n const at = model.indexOf(child.nodeName.toLowerCase());\n if (at === -1) continue;\n if (at > target) return child;\n }\n return undefined;\n}\n\n/** Find a metadata container by name, searching down from the lift root. */\nexport function findContainer(\n from: XmlElement,\n name: string,\n): XmlElement | undefined {\n if (from.nodeName.toLowerCase() === name) return from;\n for (const child of childElements(from)) {\n const found = findContainer(child, name);\n if (found) return found;\n }\n return undefined;\n}\n\n/**\n * The element a document's typed metadata hangs off: `<prolog>` in a topic,\n * `<topicmeta>` in a map. Undefined when the document has neither.\n *\n * Distinct from {@link metadataContainers}, which finds the element holding\n * `<othermeta>` — one level deeper in a topic.\n */\nexport function liftRoot(\n root: XmlElement,\n shape: DitaShape,\n): XmlElement | undefined {\n const { prolog, container } = metadataContainers(root, shape);\n return shape.kind === \"map\" ? container : prolog;\n}\n\n/** Direct child elements of `el`, optionally filtered by name. */\nexport function childElements(el: XmlElement, name?: string): XmlElement[] {\n const out: XmlElement[] = [];\n for (let n = el.firstChild; n; n = n.nextSibling) {\n if (n.nodeType !== 1) continue;\n const child = n as unknown as XmlElement;\n if (name === undefined || child.nodeName.toLowerCase() === name) {\n out.push(child);\n }\n }\n return out;\n}\n\n/**\n * The element that directly holds `<othermeta>`, if the document already has\n * one, along with the `<prolog>` that would hold it for a topic.\n *\n * Both are reported because the writer needs to know which one is missing: a\n * topic with a `<prolog>` but no `<metadata>` needs only the inner element\n * created, while one with neither needs the whole block.\n */\nexport function metadataContainers(\n root: XmlElement,\n shape: DitaShape,\n): { prolog: XmlElement | undefined; container: XmlElement | undefined } {\n if (shape.kind === \"map\") {\n return { prolog: undefined, container: childElements(root, \"topicmeta\")[0] };\n }\n const prolog = childElements(root, \"prolog\")[0];\n return {\n prolog,\n container: prolog ? childElements(prolog, \"metadata\")[0] : undefined,\n };\n}\n\n/** The `<othermeta>` entries inside a metadata container, in document order. */\nexport function otherMetaEntries(\n container: XmlElement,\n): { key: string; value: string; el: XmlElement }[] {\n const out: { key: string; value: string; el: XmlElement }[] = [];\n for (const el of childElements(container, \"othermeta\")) {\n const key = el.getAttribute(\"name\");\n const value = el.getAttribute(\"content\");\n if (key != null && key !== \"\" && value != null) out.push({ key, value, el });\n }\n return out;\n}\n","/**\n * XML write-back, the inverse of the root-attribute read in `xml-read.ts`.\n *\n * Same discipline as `frontmatter-write.ts` and `html-write.ts`: splice, never\n * re-serialize. `XMLSerializer` would normalize the DOCTYPE's spelling, rewrite\n * single-quoted attributes as double-quoted, re-encode `>` inside values, and —\n * worst for the DITA-adjacent files this extractor also reads — turn an\n * unresolvable `&nbsp;` into `&amp;nbsp;`, because the parser keeps such a\n * reference only as literal text. `xml-read.ts` goes out of its way to keep\n * those files readable; re-serializing would corrupt them on the way back out.\n *\n * The ranges come from `xml-locate.ts`, because xmldom reports positions and not\n * offsets. See that module for why the line index has to recognise six break\n * forms rather than one.\n *\n * Metadata lives in the root element's attributes, so that is where a write\n * goes. There is only the one channel, so \"write back to where the value was\n * read from\" holds by construction here — unlike DITA, which keeps metadata in\n * `<prolog>` and is refused below until it has a writer of its own.\n */\nimport { stringify as stringifyYaml } from \"yaml\";\nimport {\n DocmetaError,\n type ApplyOptions,\n type MetadataPatch,\n} from \"../types.js\";\nimport { dropUndefined, deepEqual } from \"./patch-util.js\";\nimport {\n readXml,\n isMetadataAttribute,\n type XmlElement,\n} from \"./xml-read.js\";\nimport { elementEdits } from \"./element-write.js\";\nimport { ditaEdits } from \"./dita-write.js\";\nimport {\n lineStarts,\n offsetAt,\n attrValueSpan,\n afterElementName,\n} from \"./xml-locate.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\ninterface Edit {\n start: number;\n end: number;\n text: string;\n}\n\nconst DQ = String.fromCharCode(34);\nconst BOM_CODE = 0xfeff;\n\nexport function applyXml(\n original: string,\n patch: MetadataPatch,\n options: ApplyOptions = {},\n): string {\n // `readXml` strips a BOM before parsing, so every position it reports is\n // relative to the stripped text. Splice against the same text and put the BOM\n // back afterwards — a prefix, so there is no offset arithmetic to get wrong.\n const bom = original.charCodeAt(0) === BOM_CODE;\n\n let before;\n try {\n before = readXml(original, options.filePath, { elements: options.elements });\n } catch (err) {\n // A document the reader rejects has no trustworthy positions, so there is\n // nothing safe to splice.\n throw new DocmetaError(\n `Refusing to write metadata: ${errorMessage(err)}`,\n );\n }\n\n const content = before.body;\n const root = before.root;\n if (root === undefined) {\n throw new DocmetaError(\n \"This XML document has no root element, so there is nowhere to write metadata.\",\n );\n }\n\n const clean = dropUndefined(patch);\n if (Object.keys(clean).length === 0) return original;\n\n // DITA keeps its metadata in <prolog>/<topicmeta>, and its DTD declares which\n // root attributes a topic may carry — so the generic root-attribute write\n // below would produce a document the user's own toolchain rejects.\n if (before.dita) {\n const next = spliceAll(\n content,\n ditaEdits(content, before, before.dita, clean, emitScalar, escapeAttr),\n );\n verify(next, before.data, clean, options);\n return bom ? original.slice(0, 1) + next : next;\n }\n\n const starts = lineStarts(content);\n const quoteOffsets = new Map<string, number>();\n const attrs = root.attributes;\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs.item(i);\n if (!attr || !isMetadataAttribute(attr.name)) continue;\n if (attr.lineNumber == null || attr.columnNumber == null) continue;\n // An attribute's reported column is the opening quote of its value.\n quoteOffsets.set(\n attr.name,\n offsetAt(starts, attr.lineNumber, attr.columnNumber),\n );\n }\n\n const edits: Edit[] = [];\n const inserts: string[] = [];\n for (const [key, value] of Object.entries(clean)) {\n // Element-derived keys first. Without this the key falls through to the\n // attribute branch below and `article.title` is written as a *root\n // attribute* — a legal XML Name, so nothing would stop it — while the\n // reader keeps taking that key from the element. Proposal 0018 calls that\n // asymmetry a loop.\n const source = before.sources.get(key);\n if (source && source.kind !== \"attr\") {\n edits.push(\n ...elementEdits(content, starts, source, key, value, emitScalar, escapeAttr),\n );\n continue;\n }\n\n const emitted = emitScalar(key, value);\n const quoteOffset = quoteOffsets.get(key);\n if (quoteOffset === undefined) {\n // The key becomes an attribute *name*, which — unlike a value — cannot be\n // escaped into safety. A key that is not a legal XML Name would produce a\n // document that no longer parses, and the failure would surface from the\n // parser rather than from here.\n assertWritableName(key);\n assertNoElementCollision(key, root);\n inserts.push(`${key}=\"${escapeAttr(emitted, DQ)}\"`);\n continue;\n }\n const span = attrValueSpan(content, quoteOffset);\n if (span === undefined) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": its attribute value could not be located precisely.`,\n );\n }\n edits.push({\n start: span.start,\n end: span.end,\n text: escapeAttr(emitted, span.quote),\n });\n }\n\n if (inserts.length > 0) {\n const at = rootNameEnd(content, starts, root);\n edits.push({ start: at, end: at, text: ` ${inserts.join(\" \")}` });\n }\n\n const next = spliceAll(content, edits);\n verify(next, before.data, clean, options);\n return bom ? original.slice(0, 1) + next : next;\n}\n\n/** Where a new attribute goes: just past the root element's name. */\nfunction rootNameEnd(\n content: string,\n starts: number[],\n root: XmlElement,\n): number {\n const tagOffset = offsetAt(\n starts,\n root.lineNumber ?? 1,\n root.columnNumber ?? 1,\n );\n const at = afterElementName(content, tagOffset);\n if (at === undefined) {\n throw new DocmetaError(\n \"Refusing to write XML metadata: the root element's start tag could not be located.\",\n );\n }\n return at;\n}\n\n/**\n * Refuse a key that cannot be an XML attribute name.\n *\n * Values are escaped on the way in, so any value is writable; a *name* has no\n * such escape hatch. This covers the practical cases — a leading digit, a\n * space, a namespace prefix manni cannot declare, or an `xmlns:` that would\n * rewrite a namespace declaration — rather than the full XML Name production,\n * and errs toward refusing rather than emitting something the parser will\n * reject downstream.\n *\n * Deliberately stricter than XML itself: `xml:lang` is a perfectly legal name,\n * and its prefix is even predefined, but allowing colons in general would let\n * through prefixes with no binding in the document. Refusing something safe\n * costs a rename; allowing something unsafe costs a file that will not parse.\n * The message says which of the two reasons applied.\n */\nfunction assertWritableName(key: string): void {\n if (!/^[A-Za-z_][A-Za-z0-9._-]*$/.test(key)) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": it is not a valid XML attribute name, or uses a namespace prefix manni cannot declare. Writing it would produce a document that no longer parses. Rename the property, or set it manually.`,\n );\n }\n}\n\n/**\n * Refuse to *create* an attribute whose name collides with an element-derived\n * key on this document.\n *\n * A dot is legal in an XML Name, so nothing in `assertWritableName` stops\n * `article.title` becoming a root attribute on `<article>`. It must not: the\n * convention lifts the root's children as `<root>.<child>`, so the moment the\n * document grows an `<article><title>`, the reader takes that key from the\n * element and the attribute written here goes silently unread — one key meaning\n * two places depending on what the document happens to contain.\n *\n * Narrow on purpose. Only a first segment matching *this* root's name can\n * collide, so `dc.title` and `ms.date` stay writable, as they have always been.\n */\nfunction assertNoElementCollision(key: string, root: XmlElement): void {\n const [head, ...rest] = key.split(\".\");\n if (rest.length === 0 || head !== root.nodeName.toLowerCase()) return;\n throw new DocmetaError(\n `Refusing to create \"${key}\" as an attribute of <${root.nodeName}>: that name is how manni reads <${root.nodeName}><${rest.join(\".\")}>, so an attribute here would go unread as soon as the element exists. Add the element to the document and manni will update it in place.`,\n );\n}\n\n/** Emit a value the way the reader will parse it back: as a YAML scalar. */\nfunction emitScalar(key: string, value: unknown): string {\n const text = stringifyYaml(value).replace(/\\n$/, \"\");\n if (text.includes(\"\\n\")) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": the value needs more than one line, which an XML attribute cannot hold. Set it manually.`,\n );\n }\n return text;\n}\n\nfunction escapeAttr(value: string, quote: string): string {\n const escaped = value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n return quote === \"'\"\n ? escaped.replace(/'/g, \"&apos;\")\n : escaped.replace(/\"/g, \"&quot;\");\n}\n\n/** Apply every edit back-to-front, so earlier offsets stay valid. */\nfunction spliceAll(content: string, edits: Edit[]): string {\n const ordered = [...edits].sort((a, b) => b.start - a.start);\n let out = content;\n let lastStart = Number.POSITIVE_INFINITY;\n for (const edit of ordered) {\n /* c8 ignore next 5 -- defensive: attributes are distinct spans by construction. */\n if (edit.end > lastStart) {\n throw new DocmetaError(\n \"Internal error: overlapping edits while writing XML metadata.\",\n );\n }\n out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);\n lastStart = edit.start;\n }\n return out;\n}\n\n/**\n * Re-read the written document and confirm it says exactly what it should. A\n * bug above becomes a refusal rather than a corrupted file.\n */\nfunction verify(\n next: string,\n before: Record<string, unknown>,\n patch: MetadataPatch,\n options: ApplyOptions,\n): void {\n const expected = { ...before, ...patch };\n // Same path as the original read: a `.dita` file re-read as plain XML would\n // not see the <othermeta> just written, and the check would fail for the\n // wrong reason.\n //\n // The re-parse is guarded because it is the one place a writer bug shows up\n // as a *parse* failure rather than a mismatch, and `apply`'s contract is that\n // a document it cannot rewrite safely raises `DocmetaError` — not whatever\n // the parser happened to throw.\n let actual;\n try {\n // Re-read with the *same* options the write used. Without the config\n // element paths this cannot see a key an `elements:` path produced, so it\n // would find the key missing and refuse every write to one.\n actual = readXml(next, options.filePath, {\n elements: options.elements,\n }).data;\n } catch (err) {\n throw new DocmetaError(\n `Refusing to write XML metadata: the rewritten document did not parse (${errorMessage(err)}).`,\n );\n }\n if (!deepEqual(actual, expected)) {\n throw new DocmetaError(\n \"Refusing to write XML metadata: the rewritten document did not read back as expected.\",\n );\n }\n}\n","/**\n * Turning xmldom's positions into character offsets.\n *\n * xmldom reports only where a node *starts*, as `lineNumber` and\n * `columnNumber` — there is no `startOffset`, no end position, and no marker for\n * the end of a start tag. (The SAX layer does compute an offset per attribute\n * and then discards it converting to line/column.) Splicing needs ranges, so\n * this module rebuilds them.\n *\n * The subtlety is which characters count as line breaks. xmldom measures against\n * `normalizeLineEndings(source)`, which folds CR LF, lone CR, NEL (U+0085), LINE\n * SEPARATOR (U+2028) and PARAGRAPH SEPARATOR (U+2029) all down to LF before\n * counting. An index that recognised only LF would drift the moment a document\n * used any of the others, and the symptom is not a wrong answer — it is a splice\n * at the wrong offset, which is a corrupted file. So the index below counts\n * exactly those six forms, and `xml-write.test.ts` pins each one.\n *\n * CR LF is two characters folding to one, which shortens the normalized string.\n * That is harmless here because reconstruction goes from (line, line-relative\n * column) against the *original*, so a length change earlier in the file cannot\n * shift anything.\n */\n\n/** The six break forms xmldom folds to LF before counting lines. */\nconst LINE_BREAK = /\\r\\n|\\r|\\n|\\u0085|\\u2028|\\u2029/g;\n\n/** Character offsets at which each 1-based line begins. */\nexport function lineStarts(source: string): number[] {\n const starts = [0];\n LINE_BREAK.lastIndex = 0;\n let match: RegExpExecArray | null;\n while ((match = LINE_BREAK.exec(source)) !== null) {\n starts.push(match.index + match[0].length);\n }\n return starts;\n}\n\n/**\n * The offset of a 1-based (line, column) pair. Out-of-range lines clamp to the\n * start of the document rather than returning NaN, so a caller that mis-reads a\n * position gets a refusal from the verify step rather than a silent splice at\n * an undefined index.\n */\nexport function offsetAt(starts: number[], line: number, column: number): number {\n const base = starts[line - 1];\n if (base === undefined) return 0;\n return base + column - 1;\n}\n\n/**\n * The span of a quoted attribute value, given the offset of its opening quote —\n * which is exactly what xmldom's `columnNumber` points at for an attribute.\n *\n * Returns the range *inside* the quotes and the quote character in use, so a\n * rewrite keeps the document's original quoting style.\n */\nexport function attrValueSpan(\n source: string,\n quoteOffset: number,\n): { start: number; end: number; quote: string } | undefined {\n const quote = source[quoteOffset];\n if (quote !== '\"' && quote !== \"'\") return undefined;\n const close = source.indexOf(quote, quoteOffset + 1);\n if (close === -1) return undefined;\n return { start: quoteOffset + 1, end: close, quote };\n}\n\n/**\n * The offset just past a start tag's element name, which is where a new\n * attribute can always be inserted.\n *\n * Inserting here rather than before the closing `>` is deliberate: finding that\n * `>` means scanning past attribute values that may themselves contain one,\n * while the name ends at the first whitespace, `/` or `>` and cannot be\n * mistaken. `tagOffset` is the offset of the `<`.\n */\nexport function afterElementName(\n source: string,\n tagOffset: number,\n): number | undefined {\n if (source[tagOffset] !== \"<\") return undefined;\n let i = tagOffset + 1;\n while (i < source.length && !/[\\s/>]/.test(source[i] ?? \"\")) i++;\n return i > tagOffset + 1 ? i : undefined;\n}\n\n/**\n * The offset just past a start tag's closing `>`, and whether it self-closed.\n *\n * Attribute values can contain `>`, so this tracks quoting rather than scanning\n * for the first one. `tagOffset` is the offset of the `<`.\n */\nexport function startTagEnd(\n source: string,\n tagOffset: number,\n): { end: number; selfClosing: boolean } | undefined {\n if (source[tagOffset] !== \"<\") return undefined;\n let quote: string | undefined;\n for (let i = tagOffset + 1; i < source.length; i++) {\n const ch = source[i];\n if (quote !== undefined) {\n if (ch === quote) quote = undefined;\n continue;\n }\n if (ch === '\"' || ch === \"'\") {\n quote = ch;\n } else if (ch === \">\") {\n return { end: i + 1, selfClosing: source[i - 1] === \"/\" };\n }\n }\n return undefined;\n}\n\n/**\n * The offset of `</name>` searching forward from `from`.\n *\n * Used only for the shallow, non-recursive containers DITA metadata lives in\n * (`prolog`, `metadata`, `topicmeta`), none of which nests inside itself, so a\n * forward search cannot find the wrong one.\n *\n * This is a text search, not a lexer: it does not skip comments or CDATA, so a\n * `<!-- </prolog> -->` ahead of the real close tag would match here and the\n * write would splice into the comment. That cannot reach disk — the caller\n * re-reads the result, finds the key absent because xmldom ignores comment\n * text, and refuses — but the refusal reads as the generic \"did not read back\n * as expected\", so this note is the missing half of that diagnosis.\n */\nexport function closeTagStart(\n source: string,\n from: number,\n name: string,\n): number | undefined {\n const needle = `</${name}`;\n let i = source.indexOf(needle, from);\n while (i !== -1) {\n const after = source[i + needle.length];\n if (after === \">\" || (after !== undefined && /\\s/.test(after))) return i;\n i = source.indexOf(needle, i + 1);\n }\n return undefined;\n}\n","/**\n * Writing back to element-derived metadata, shared by the plain-XML and DITA\n * writers.\n *\n * Both cases here **replace a span that already exists**, which is what makes\n * them safe in a dialect docmeta knows nothing about: swapping the text between\n * `<title>` and `</title>`, or the value inside an attribute's quotes, cannot\n * change whether the document is valid. Creating an element that is *not* there\n * is a different problem — it needs to know where the element is legal — and\n * lives with the content model that can answer that.\n *\n * The count rule is the other half. A key backed by N elements receiving M\n * values is only unambiguous when M equals N: each value replaces one element,\n * in document order. Fewer values would mean deleting elements and more would\n * mean creating them, and both change the document's shape rather than its\n * content. Those are refused by name rather than guessed at, because a `fill`\n * that quietly dropped an `<author>` is worse than one that declines.\n */\nimport { DocmetaError } from \"../types.js\";\nimport type { XmlElement, XmlSource } from \"./xml-read.js\";\nimport {\n attrValueSpan,\n closeTagStart,\n offsetAt,\n startTagEnd,\n} from \"./xml-locate.js\";\n\n/** One character-range replacement in the source. */\nexport interface Edit {\n start: number;\n end: number;\n text: string;\n}\n\n/**\n * Escape text destined for element content.\n *\n * `&` and `<` are mandatory. `>` is escaped too — not required by XML except\n * after `]]`, but linters flag it and the attribute path already escapes it, so\n * matching keeps one rule rather than two.\n */\nexport function escapeText(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n}\n\n/**\n * The values a write should distribute across the elements backing a key.\n *\n * A scalar key is one value; a list key is its items. Anything else — a list\n * whose length no longer matches, or an object where text was read — is refused\n * here rather than partially applied.\n */\nexport function valuesFor(\n key: string,\n value: unknown,\n count: number,\n): unknown[] {\n const values = Array.isArray(value) ? value : [value];\n if (values.length !== count) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": the document has ${count} element${\n count === 1 ? \"\" : \"s\"\n } for it and ${values.length} value${\n values.length === 1 ? \"\" : \"s\"\n } was given. manni updates elements in place; adding or removing one ` +\n \"changes the document's shape, which it will not do on your behalf.\",\n );\n }\n return values;\n}\n\n/** Replace the text between an element's start and end tags. */\nexport function elementTextEdit(\n content: string,\n starts: number[],\n el: XmlElement,\n key: string,\n emitted: string,\n): Edit {\n const from = elementOffset(starts, el, key);\n const open = startTagEnd(content, from);\n if (open === undefined) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": the <${el.nodeName}> start tag could not be located.`,\n );\n }\n if (open.selfClosing) {\n // `<title/>` has no text span to replace. Turning it into `<title>x</title>`\n // is a shape change, and the count rule above says those are the author's\n // to make.\n throw new DocmetaError(\n `Refusing to write \"${key}\": <${el.nodeName}> is self-closing, so it has no text to replace.`,\n );\n }\n const close = closeTagStart(content, open.end, el.nodeName);\n if (close === undefined) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": <${el.nodeName}> has no closing tag.`,\n );\n }\n return { start: open.end, end: close, text: escapeText(emitted) };\n}\n\n/** Replace the value inside an element attribute's quotes. */\nexport function elementAttrEdit(\n content: string,\n starts: number[],\n el: XmlElement,\n attrName: string,\n key: string,\n emitted: string,\n escape: (value: string, quote: string) => string,\n): Edit {\n const attrs = el.attributes;\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs.item(i);\n if (!attr || attr.name !== attrName) continue;\n /* c8 ignore next -- xmldom always reports a position for an attribute it parsed. */\n if (attr.lineNumber == null || attr.columnNumber == null) break;\n const span = attrValueSpan(\n content,\n offsetAt(starts, attr.lineNumber, attr.columnNumber),\n );\n if (span === undefined) break;\n return {\n start: span.start,\n end: span.end,\n text: escape(emitted, span.quote),\n };\n }\n throw new DocmetaError(\n `Refusing to write \"${key}\": the \"${attrName}\" attribute on <${el.nodeName}> could not be located precisely.`,\n );\n}\n\nfunction elementOffset(\n starts: number[],\n el: XmlElement,\n key: string,\n): number {\n /* c8 ignore next 5 -- xmldom reports a position for every element it parsed. */\n if (el.lineNumber == null || el.columnNumber == null) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": <${el.nodeName}> has no recorded position.`,\n );\n }\n return offsetAt(starts, el.lineNumber, el.columnNumber);\n}\n\n/**\n * Edits for a key whose value lives in elements rather than a root attribute.\n *\n * One edit per element, in document order, after `valuesFor` has confirmed the\n * counts line up.\n */\nexport function elementEdits(\n content: string,\n starts: number[],\n source: Exclude<XmlSource, { kind: \"attr\" }>,\n key: string,\n value: unknown,\n emit: (key: string, value: unknown) => string,\n escape: (value: string, quote: string) => string,\n): Edit[] {\n if (source.kind === \"othermeta\") {\n return [\n elementAttrEdit(\n content,\n starts,\n source.el,\n \"content\",\n key,\n emit(key, value),\n escape,\n ),\n ];\n }\n const values = valuesFor(key, value, source.els.length);\n return source.els.map((el, i) =>\n source.kind === \"element-attr\"\n ? elementAttrEdit(\n content,\n starts,\n el,\n source.name,\n key,\n emit(key, values[i]),\n escape,\n )\n : elementTextEdit(content, starts, el, key, emit(key, values[i])),\n );\n}\n","/**\n * DITA write-back.\n *\n * The proposal that introduced write support called a `<prolog>` writer \"a\n * separate project\" and left DITA read-only permanently. This is that project.\n * The reason it is not simply \"XML, but deeper\" is the content model: DITA\n * declares which attributes a topic may carry, so the generic XML writer's move\n * — add an attribute to the root element — produces a topic the user's own\n * toolchain rejects. Metadata has a designated home instead:\n * `<prolog><metadata><othermeta/></metadata></prolog>` for topics,\n * `<topicmeta>` for maps.\n *\n * Which of those a given key uses is not this module's decision. `fill` corrects\n * values that are present but *invalid*, not only missing ones, so a rule like\n * \"new values go in an othermeta\" would add a correction beside the stale root\n * attribute a DITA processor actually reads — docmeta reporting green over a\n * topic that still says the wrong thing. So:\n *\n * 1. read from a root attribute -> update that attribute's value span\n * 2. read from an <othermeta> -> update its `content` span\n * 3. absent from both -> insert an <othermeta>, creating\n * <metadata> and <prolog> only as needed\n *\n * Cases 1 and 2 replace spans that already exist and so cannot change whether\n * the document is valid. Only case 3 adds structure, and it adds it where the\n * DTD already allows it.\n */\nimport {\n DocmetaError,\n type MetadataPatch,\n} from \"../types.js\";\nimport {\n childAnchor,\n childElements,\n ditaContainerParent,\n findContainer,\n liftRoot,\n metadataContainers,\n DITA_ATTR_KEYS,\n DITA_CONTENT_MODEL,\n DITA_LIFTS,\n type DitaLift,\n type DitaShape,\n} from \"./dita.js\";\nimport { elementEdits, escapeText } from \"./element-write.js\";\nimport type { XmlElement, XmlRead } from \"./xml-read.js\";\nimport {\n lineStarts,\n offsetAt,\n attrValueSpan,\n startTagEnd,\n closeTagStart,\n} from \"./xml-locate.js\";\n\nexport interface Edit {\n start: number;\n end: number;\n text: string;\n}\n\n/**\n * Build the edits that set `patch` on a DITA document. The caller splices and\n * verifies, so this stays a pure description of what should change.\n */\nexport function ditaEdits(\n content: string,\n read: XmlRead,\n shape: DitaShape,\n patch: MetadataPatch,\n emit: (key: string, value: unknown) => string,\n escape: (value: string, quote: string) => string,\n): Edit[] {\n const root = read.root;\n /* c8 ignore next 3 -- the caller has already refused a rootless document. */\n if (!root) {\n throw new DocmetaError(\"This DITA document has no root element.\");\n }\n\n const starts = lineStarts(content);\n const edits: Edit[] = [];\n const fresh: { key: string; value: string }[] = [];\n const freshElements: FreshElement[] = [];\n\n for (const [key, raw] of Object.entries(patch)) {\n const source = read.sources.get(key);\n // Emitted per branch rather than up front. A list-valued key — `author*` in\n // the content model — is emitted one item at a time by `elementEdits`;\n // emitting the whole array here would serialize it as a YAML block, hit the\n // \"needs more than one line\" guard, and refuse a write that is perfectly\n // expressible as two `<author>` elements.\n if (source?.kind === \"attr\") {\n edits.push(\n attributeEdit(content, starts, root, source.name, emit(key, raw), escape),\n );\n } else if (source?.kind === \"othermeta\") {\n edits.push(\n otherMetaEdit(content, starts, source.el, key, emit(key, raw), escape),\n );\n } else if (\n source?.kind === \"element-text\" ||\n source?.kind === \"element-attr\"\n ) {\n // A typed prolog element — <author>, <created date=…>. Written where it\n // was read, which for DITA also means written where the DTD already\n // allows it: the element exists, so only its value changes.\n edits.push(...elementEdits(content, starts, source, key, raw, emit, escape));\n } else {\n // A key naming a typed element docmeta knows — `prolog.author` — is\n // created as that element. Anything else keeps the othermeta channel,\n // which is where a key with no place in the content model belongs.\n const dot = key.indexOf(\".\");\n const container = dot === -1 ? \"\" : key.slice(0, dot);\n const element = dot === -1 ? \"\" : key.slice(dot + 1);\n if (DITA_ATTR_KEYS.has(key)) {\n // `vrm.version` and friends look exactly like a `container.element`\n // key and are not one: the key names an *attribute*, three of which\n // share one `<vrm>`. Creating it would mean synthesising the element\n // and folding the sibling keys into it, which is not what the create\n // path does — and falling through to an `<othermeta>` would put the\n // value where the reader stops looking the moment a real `<vrm>`\n // appears. Refusing is the only honest option until it has a writer.\n throw new DocmetaError(\n `manni meta fill cannot create \"${key}\": it names an attribute of an element the document does not have. Add the <${key.slice(0, key.indexOf(\".\"))}> element, and manni will keep it up to date.`,\n );\n }\n const spec = ownLift(container, element);\n if (spec) {\n freshElements.push({ key, container, element, spec, value: raw });\n } else {\n fresh.push({ key, value: emit(key, raw) });\n }\n }\n }\n\n if (fresh.length > 0) {\n edits.push(insertEdit(content, starts, root, shape, fresh, escape));\n }\n if (freshElements.length > 0) {\n edits.push(\n ...newElementEdits(\n content,\n starts,\n root,\n shape,\n freshElements,\n emit,\n escape,\n ),\n );\n }\n return edits;\n}\n\n/**\n * Own-property lookup into the lift table.\n *\n * The key comes from a patch, so `constructor.name` would otherwise find\n * `Object.prototype` and be treated as a liftable element.\n */\nfunction ownLift(container: string, element: string): DitaLift | undefined {\n if (!Object.prototype.hasOwnProperty.call(DITA_LIFTS, container)) {\n return undefined;\n }\n const lifts = DITA_LIFTS[container];\n return lifts && Object.prototype.hasOwnProperty.call(lifts, element)\n ? lifts[element]\n : undefined;\n}\n\n/** A typed element the document does not have yet. */\ninterface FreshElement {\n key: string;\n container: string;\n element: string;\n spec: DitaLift;\n value: unknown;\n}\n\n/**\n * Create typed elements the document is missing, in content-model order.\n *\n * This is the one place in the DITA writer that adds structure rather than\n * replacing a span, so it is the one place that can produce a topic the user's\n * DTD rejects. Four things keep it honest:\n *\n * - **Position comes from the content model, not from convenience.** A DITA\n * container is a sequence, so `<critdates>` after `<metadata>` is invalid even\n * though both are allowed.\n * - **Blocks are grouped by anchor, not by container.** Two containers can\n * resolve to one insertion point, and two edits at one offset overlap —\n * which `spliceAll` refuses, turning a legitimate multi-field `fill` into an\n * internal error.\n * - **Containers that do not exist yet are merged into one nest.** Every\n * placement is computed against the *original* document, so three keys that\n * each need a `<metadata>` would each create one. `metadata*` is repeatable,\n * so three siblings are technically valid and no content-model check catches\n * it — it is simply not what a person would write, and `fill` is not supposed\n * to be identifiable by its output.\n * - **Tags and created containers interleave by model position.** `<source>`\n * has to precede a `<copyright>` created in the same edit, so ordering cannot\n * be \"values first, then containers\".\n */\nfunction newElementEdits(\n content: string,\n starts: number[],\n root: XmlElement,\n shape: DitaShape,\n items: FreshElement[],\n emit: (key: string, value: unknown) => string,\n escape: (value: string, quote: string) => string,\n): Edit[] {\n const eol = content.includes(CRLF) ? CRLF : LF;\n const liftRootEl = liftRoot(root, shape);\n\n /** `<author>Ada</author>` or `<created date=\"…\"/>`, one per value. */\n const tagsFor = (item: FreshElement): Tag[] => {\n const values = Array.isArray(item.value) ? item.value : [item.value];\n return values.map((v) => {\n const emitted = emit(item.key, v);\n return {\n name: item.element,\n text: item.spec.attr\n ? `<${item.element} ${item.spec.attr}=\"${escape(emitted, DQ)}\"/>`\n : `<${item.element}>${escapeText(emitted)}</${item.element}>`,\n };\n });\n };\n\n const byContainer = new Map<string, FreshElement[]>();\n for (const item of items) {\n const group = byContainer.get(item.container);\n if (group) group.push(item);\n else byContainer.set(item.container, [item]);\n }\n\n const placements: Placement[] = [];\n for (const [containerName, group] of byContainer) {\n const missing: string[] = [];\n let name: string | undefined = containerName;\n let host: XmlElement | undefined;\n while (name !== undefined) {\n const found = liftRootEl ? findContainer(liftRootEl, name) : undefined;\n if (found) {\n host = found;\n break;\n }\n missing.unshift(name);\n name = ditaContainerParent(shape, name);\n }\n\n const tags = group.flatMap(tagsFor);\n const outermost = missing[0] ?? group[0]?.element ?? \"\";\n\n if (host) {\n const hostName = host.nodeName.toLowerCase();\n const before = childAnchor(host, hostName, outermost);\n const at = before\n ? offsetAt(starts, before.lineNumber ?? 1, before.columnNumber ?? 1)\n : closeOf(content, starts, host, host.nodeName);\n placements.push({\n at,\n base: \"\",\n hostName,\n missing,\n tags,\n atClose: before === undefined,\n });\n } else {\n placements.push({\n at: newContainerAnchor(content, starts, root, shape),\n base: siblingIndent(content, starts, root),\n hostName: \"\",\n missing,\n tags,\n atClose: false,\n });\n }\n }\n\n const byAnchor = new Map<number, Placement[]>();\n for (const p of placements) {\n const group = byAnchor.get(p.at);\n if (group) group.push(p);\n else byAnchor.set(p.at, [p]);\n }\n\n const edits: Edit[] = [];\n for (const [at, group] of byAnchor) {\n const base = group.find((p) => p.base !== \"\")?.base ?? \"\";\n const anchor = anchorBefore(content, at, base || \" \");\n const atClose = group.some((p) => p.atClose);\n const indent = base || anchor.indent + (atClose ? \" \" : \"\");\n const hostName = group.find((p) => p.hostName !== \"\")?.hostName ?? \"\";\n\n // Merge every placement at this anchor into one tree, so containers that\n // do not exist yet are created once rather than once per key.\n const nest: Nest = { tags: [], children: new Map() };\n for (const p of group) {\n let node = nest;\n for (const name of p.missing) {\n let child = node.children.get(name);\n if (!child) {\n child = { tags: [], children: new Map() };\n node.children.set(name, child);\n }\n node = child;\n }\n node.tags.push(...p.tags);\n }\n\n edits.push({\n start: anchor.start,\n end: anchor.end,\n text:\n (anchor.lead ? eol : \"\") +\n renderNest(nest, hostName, indent, 0).join(eol) +\n eol +\n anchor.indent,\n });\n }\n return edits;\n}\n\n/** A tag to emit, with the element name its model position is looked up by. */\ninterface Tag {\n name: string;\n text: string;\n}\n\n/** Values and sub-containers to create inside one container. */\ninterface Nest {\n tags: Tag[];\n children: Map<string, Nest>;\n}\n\n/**\n * Serialize a nest, interleaving values and sub-containers by model position.\n *\n * Sorting the two separately would put `<source>` after a `<copyright>` created\n * beside it, which the content model forbids.\n */\nfunction renderNest(\n nest: Nest,\n containerName: string,\n indent: string,\n depth: number,\n): string[] {\n const pad = indent + \" \".repeat(depth);\n const entries: { order: number; lines: string[] }[] = [];\n\n for (const tag of nest.tags) {\n entries.push({\n order: modelIndex(containerName, tag.name),\n lines: [pad + tag.text],\n });\n }\n for (const [name, child] of nest.children) {\n entries.push({\n order: modelIndex(containerName, name),\n lines: [\n pad + `<${name}>`,\n ...renderNest(child, name, indent, depth + 1),\n pad + `</${name}>`,\n ],\n });\n }\n\n // A stable sort keeps repeated values (two `<author>`) in the order they were\n // given, since they share one model position.\n return entries\n .sort((a, b) => a.order - b.order)\n .flatMap((e) => e.lines);\n}\n\n/** One block of new markup, and where it goes. */\ninterface Placement {\n at: number;\n base: string;\n /** The existing container the block goes inside, or \"\" for the root. */\n hostName: string;\n missing: string[];\n tags: Tag[];\n /**\n * Whether the anchor is the container's closing tag rather than an existing\n * sibling. It changes the indent by one level: a sibling already sits where\n * the new block goes, but a closing tag sits a level out from the children it\n * closes over.\n */\n atClose: boolean;\n}\n\n/** Position of `name` in `container`'s content model; unknown sorts last. */\nfunction modelIndex(container: string, name: string): number {\n const model = DITA_CONTENT_MODEL[container] ?? [];\n const at = model.indexOf(name);\n return at === -1 ? Number.MAX_SAFE_INTEGER : at;\n}\n\n/** Replace a root attribute's value span — case 1. */\nfunction attributeEdit(\n content: string,\n starts: number[],\n root: XmlElement,\n name: string,\n emitted: string,\n escape: (value: string, quote: string) => string,\n): Edit {\n const attrs = root.attributes;\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs.item(i);\n if (!attr || attr.name !== name) continue;\n /* c8 ignore next -- xmldom always reports a position for an attribute it parsed. */\n if (attr.lineNumber == null || attr.columnNumber == null) break;\n const span = attrValueSpan(\n content,\n offsetAt(starts, attr.lineNumber, attr.columnNumber),\n );\n if (span === undefined) break;\n return { start: span.start, end: span.end, text: escape(emitted, span.quote) };\n }\n throw new DocmetaError(\n `Refusing to write \"${name}\": its attribute value could not be located precisely.`,\n );\n}\n\n/** Replace an existing `<othermeta>`'s `content` value span — case 2. */\nfunction otherMetaEdit(\n content: string,\n starts: number[],\n el: XmlElement,\n key: string,\n emitted: string,\n escape: (value: string, quote: string) => string,\n): Edit {\n const attrs = el.attributes;\n for (let i = 0; i < attrs.length; i++) {\n const attr = attrs.item(i);\n if (!attr || attr.name !== \"content\") continue;\n /* c8 ignore next -- xmldom always reports a position for an attribute it parsed. */\n if (attr.lineNumber == null || attr.columnNumber == null) break;\n const span = attrValueSpan(\n content,\n offsetAt(starts, attr.lineNumber, attr.columnNumber),\n );\n if (span === undefined) break;\n return { start: span.start, end: span.end, text: escape(emitted, span.quote) };\n }\n throw new DocmetaError(\n `Refusing to write \"${key}\": its <othermeta> content attribute could not be located precisely.`,\n );\n}\n\n/**\n * Insert new `<othermeta>` entries, creating whatever containers are missing —\n * case 3.\n *\n * Each insertion replaces the whitespace run in front of an anchor rather than\n * inserting at the anchor itself. Inserting would leave that run stranded as a\n * blank line, and a `fill` that reformats the file around its own edit is the\n * thing the splice-only rule exists to prevent.\n */\nfunction insertEdit(\n content: string,\n starts: number[],\n root: XmlElement,\n shape: DitaShape,\n fresh: { key: string; value: string }[],\n escape: (value: string, quote: string) => string,\n): Edit {\n const { prolog, container } = metadataContainers(root, shape);\n const eol = content.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const tag = (f: { key: string; value: string }): string =>\n `<othermeta name=\"${escape(f.key, DQ)}\" content=\"${escape(f.value, DQ)}\"/>`;\n const build = (a: Anchor, lines: string[]): Edit => ({\n start: a.start,\n end: a.end,\n text: (a.lead ? eol : \"\") + lines.join(eol) + eol + a.indent,\n });\n\n // The container exists: append inside it. `<othermeta>` sits late in the\n // metadata content model, so appending keeps the order the DTD expects.\n if (container) {\n const anchor = anchorBefore(\n content,\n closeOf(content, starts, container, container.nodeName),\n );\n return build(\n anchor,\n fresh.map((f) => anchor.indent + \" \" + tag(f)),\n );\n }\n\n // A topic with a <prolog> but no <metadata>: create just the inner element.\n if (prolog) {\n const anchor = anchorBefore(\n content,\n closeOf(content, starts, prolog, prolog.nodeName),\n );\n const meta = anchor.indent + \" \";\n return build(anchor, [\n meta + \"<metadata>\",\n ...fresh.map((f) => meta + \" \" + tag(f)),\n meta + \"</metadata>\",\n ]);\n }\n\n // Neither exists: create the whole block, in the position the content model\n // requires — after the title and friends, before the body.\n const at = newContainerAnchor(content, starts, root, shape);\n // Two different indents. `anchor.indent` is the anchor's own, restored after\n // the block so the element that follows keeps its position; `base` is where\n // the new block sits. They differ when the anchor is the root's closing tag,\n // which sits a level out from the children the block joins.\n const base = siblingIndent(content, starts, root);\n const anchor = anchorBefore(content, at, base);\n if (shape.kind === \"map\") {\n return build(anchor, [\n base + \"<topicmeta>\",\n ...fresh.map((f) => base + \" \" + tag(f)),\n base + \"</topicmeta>\",\n ]);\n }\n return build(anchor, [\n base + \"<prolog>\",\n base + \" <metadata>\",\n ...fresh.map((f) => base + \" \" + tag(f)),\n base + \" </metadata>\",\n base + \"</prolog>\",\n ]);\n}\n\ninterface Anchor {\n start: number;\n end: number;\n indent: string;\n lead: boolean;\n}\n\n/**\n * The whitespace run in front of `at`, so new lines can replace it and put it\n * back — which is what keeps the anchor's own indentation intact.\n *\n * When `at` does not begin its line there is no run to reuse, so the caller\n * emits a leading newline and falls back to a supplied indent.\n */\nfunction anchorBefore(content: string, at: number, fallback = \" \"): Anchor {\n let i = at;\n while (i > 0 && (content[i - 1] === \" \" || content[i - 1] === \"\\t\")) i--;\n if (i > 0 && content[i - 1] === \"\\n\") {\n return { start: i, end: at, indent: content.slice(i, at), lead: false };\n }\n return { start: at, end: at, indent: fallback, lead: true };\n}\n\n/**\n * The indentation of the root's first child element, used when a new container\n * is anchored on the root's closing tag — which sits at the parent's indent and\n * so would put the block a level too far out.\n */\nfunction siblingIndent(\n content: string,\n starts: number[],\n root: XmlElement,\n): string {\n const first = childElements(root)[0];\n if (!first) return \" \";\n const at = offsetAt(starts, first.lineNumber ?? 1, first.columnNumber ?? 1);\n const lineStart = content.lastIndexOf(\"\\n\", at - 1) + 1;\n const between = content.slice(lineStart, at);\n return /^[ \\t]*$/.test(between) ? between : \" \";\n}\n\nconst DQ = String.fromCharCode(34);\nconst CRLF = String.fromCharCode(13, 10);\nconst LF = String.fromCharCode(10);\n\n/**\n * The offset of a container's close tag, which is where new children go.\n *\n * `name` is the element's own `nodeName`, not the canonical lowercase one the\n * shape carries. The reader finds these containers by comparing lowercased\n * names, so it accepts a `<Metadata>`; searching for `</metadata>` here would\n * then refuse a document the reader had just read, with a message describing a\n * tag the file does not contain.\n */\nfunction closeOf(\n content: string,\n starts: number[],\n el: XmlElement,\n name: string,\n): number {\n const from = offsetAt(starts, el.lineNumber ?? 1, el.columnNumber ?? 1);\n const open = startTagEnd(content, from);\n if (open === undefined || open.selfClosing) {\n // `<metadata/>` has no inside to append to. Refusing beats rewriting the\n // tag, which would take this out of splice-only territory.\n throw new DocmetaError(\n `Refusing to write DITA metadata: <${name}> is self-closing, so there is nowhere to add an entry. Expand it to <${name}></${name}> and retry.`,\n );\n }\n const close = closeTagStart(content, open.end, name);\n if (close === undefined) {\n throw new DocmetaError(\n `Refusing to write DITA metadata: <${name}> has no closing tag.`,\n );\n }\n return close;\n}\n\n/**\n * Where a brand-new metadata container goes: immediately before the first child\n * that is not part of the preamble, or before the root's close tag when every\n * child is (a topic with a title and nothing else).\n */\nfunction newContainerAnchor(\n content: string,\n starts: number[],\n root: XmlElement,\n shape: DitaShape,\n): number {\n for (const child of childElements(root)) {\n if (shape.preamble.has(child.nodeName.toLowerCase())) continue;\n return offsetAt(starts, child.lineNumber ?? 1, child.columnNumber ?? 1);\n }\n const from = offsetAt(starts, root.lineNumber ?? 1, root.columnNumber ?? 1);\n const open = startTagEnd(content, from);\n const close =\n open === undefined\n ? undefined\n : closeTagStart(content, open.end, root.nodeName);\n if (close === undefined) {\n throw new DocmetaError(\n \"Refusing to write DITA metadata: the root element's closing tag could not be located.\",\n );\n }\n return close;\n}\n","/**\n * XML metadata extractor.\n *\n * Also handles DITA topics (`.dita`) and maps (`.ditamap`), which are XML.\n *\n * Reads metadata from the document's root-element attributes, e.g.\n * `<document type=\"concept\" version=\"2\">` yields `{ type: \"concept\", version: 2 }`.\n * Attribute values are parsed as YAML scalars so `\"2\"` -> number and `\"true\"` ->\n * boolean, consistent with the AsciiDoc header extractor. Namespace declarations\n * (`xmlns`, `xmlns:*`) are dropped as transport noise. Per-node line and column\n * numbers from the parser give JSON-Pointer -> source-line and -> source-column\n * maps for precise annotations. Both are 1-based.\n *\n * Malformed XML is surfaced as a thrown error; the command layer records it as a\n * per-file failure so the rest of the run continues (mirroring frontmatter).\n *\n * The read itself lives in `xml-read.ts`, shared with `xml-write.ts` so that a\n * write lands on the attribute the read took its value from.\n */\nimport { readXml, toExtracted } from \"./xml-read.js\";\nimport { applyXml } from \"./xml-write.js\";\nimport type { ExtractedMetadata, MetadataExtractor } from \"../types.js\";\n\nexport const xmlExtractor: MetadataExtractor = {\n name: \"xml\",\n // DITA topics and maps are XML, and their metadata lives on the root element\n // (`id`, `type`, `xml:lang`, …), so they need no extractor of their own.\n extensions: [\".xml\", \".dita\", \".ditamap\"],\n implemented: true,\n extract(content, filePath, options): ExtractedMetadata {\n return toExtracted(readXml(content, filePath, options));\n },\n apply: applyXml,\n};\n","/**\n * The HTML read model, split out so that `html.ts` (which extracts) and\n * `html-write.ts` (which writes back) share one implementation of it.\n *\n * That sharing is the point, not tidiness. A write has to land in the same\n * place the read takes its value from; if the two disagree about which tag wins,\n * `fill` writes somewhere the reader ignores, the field stays invalid, and the\n * next run proposes it again. So precedence is decided exactly once, here, and\n * `sources` reports the winner so the writer can aim at it.\n */\nimport { parse, defaultTreeAdapter, type DefaultTreeAdapterMap } from \"parse5\";\nimport { parse as parseYamlScalar } from \"yaml\";\nimport { escapePointerSegment } from \"./pointer.js\";\nimport {\n liftKey,\n pairValues,\n parseElementPath,\n type ElementPath,\n} from \"./element-key.js\";\nimport type { ExtractOptions } from \"../types.js\";\n\nexport type Element = DefaultTreeAdapterMap[\"element\"];\n\n/** Where a key's winning value came from. */\nexport type HtmlSource =\n | { kind: \"meta\"; el: Element }\n | { kind: \"title\"; el: Element }\n /**\n * A value read from the text of a `<head>` child. `els` carries every\n * occurrence because the key may be a list — a write replaces the whole set,\n * and one element out of several is not a location a write can aim at.\n */\n | { kind: \"element-text\"; els: Element[] }\n /** A value read from an element's attribute — `<link href=…>`. */\n | { kind: \"element-attr\"; els: Element[]; name: string };\n\nexport interface HtmlRead {\n data: Record<string, unknown>;\n /** The text actually parsed — the source minus any leading BOM. */\n body: string;\n lineMap: Map<string, number>;\n colMap: Map<string, number>;\n /** The element each key's effective value was read from. */\n sources: Map<string, HtmlSource>;\n /** The `<head>` element, or undefined when the document has none. */\n head: Element | undefined;\n}\n\n/** Parse a raw value as a YAML scalar, falling back to the string. */\nexport function typeValue(raw: string): unknown {\n // Empty meta content (`content=\"\"`) is the empty string, not the YAML `null`\n // that parsing \"\" would yield.\n if (raw === \"\") return \"\";\n try {\n return parseYamlScalar(raw);\n } catch {\n return raw;\n }\n}\n\nexport function attrValue(el: Element, name: string): string | undefined {\n return el.attrs.find((a) => a.name === name)?.value;\n}\n\n/**\n * `<head>` children that carry text but are not metadata.\n *\n * Both are text-bearing, so the generic rule would lift them, and neither says\n * anything about the document: lifting them would put a stylesheet and a line\n * of JavaScript into the key set of every page docmeta reads.\n */\nconst HEAD_NOT_METADATA = new Set([\"script\", \"style\"]);\n\n/**\n * `<head>` children the HTML content model permits at most once, which are\n * therefore scalars rather than one-item lists.\n *\n * `<base>` is here for completeness; being void it carries no text and so never\n * reaches the convention at all. `<meta>`, `<link>` and the rest may repeat.\n */\nconst HEAD_SINGLETONS = new Set([\"title\", \"base\"]);\n\nconst elementName = (el: Element | undefined): string =>\n el ? el.tagName.toLowerCase() : \"\";\n\n/**\n * The text a `<head>` child carries, or `undefined` when it carries none worth\n * lifting — an element child makes it a container, and whitespace-only text is\n * indentation rather than content.\n */\nfunction headText(el: Element, allowEmpty = false): string | undefined {\n let text = \"\";\n for (const node of el.childNodes) {\n if (defaultTreeAdapter.isElementNode(node)) return undefined;\n if (defaultTreeAdapter.isTextNode(node)) text += node.value;\n }\n if (!allowEmpty && text.trim() === \"\") return undefined;\n return text.trim();\n}\n\n/**\n * The `<head>` children that are values, grouped by the key they contribute.\n *\n * Void elements — `<meta>`, `<link>`, `<base>` — hold their value in an\n * attribute and so produce nothing here. That is deliberate rather than an\n * omission: lifting `<link>` by `href` would collapse a canonical URL and three\n * stylesheets into one list and discard the `rel` that distinguished them. An\n * `elements:` path naming the attribute addresses them instead.\n */\nfunction liftableHeadChildren(\n head: Element,\n): Map<string, { els: Element[]; texts: string[] }> {\n const out = new Map<string, { els: Element[]; texts: string[] }>();\n for (const node of head.childNodes) {\n if (!defaultTreeAdapter.isElementNode(node)) continue;\n const name = node.tagName.toLowerCase();\n if (HEAD_NOT_METADATA.has(name)) continue;\n // Read once and carried out with the element. Testing here and reading\n // again at the call site walked every child's text twice.\n const text = headText(node);\n if (text === undefined) continue;\n const key = liftKey(\"head\", name);\n const group = out.get(key);\n if (group) {\n group.els.push(node);\n group.texts.push(text);\n } else {\n out.set(key, { els: [node], texts: [text] });\n }\n }\n return out;\n}\n\n/** Every element a config path selects, walked down the child axis. */\nfunction matchHtmlPath(\n doc: DefaultTreeAdapterMap[\"document\"],\n segments: string[],\n): Element[] {\n const childrenNamed = (\n nodes: readonly DefaultTreeAdapterMap[\"childNode\"][],\n name: string,\n ): Element[] => {\n const out: Element[] = [];\n for (const n of nodes) {\n if (defaultTreeAdapter.isElementNode(n) && n.tagName.toLowerCase() === name) {\n out.push(n);\n }\n }\n return out;\n };\n\n let current = childrenNamed(doc.childNodes, segments[0] ?? \"\");\n for (const segment of segments.slice(1)) {\n const next: Element[] = [];\n for (const el of current) next.push(...childrenNamed(el.childNodes, segment));\n current = next;\n }\n return current;\n}\n\n/** Read metadata, positions, and per-key provenance from HTML source. */\nexport function readHtml(\n source: string,\n options?: ExtractOptions,\n): HtmlRead {\n // A BOM is invisible in an editor, so letting the parser count it as a\n // character puts every caret on line 1 one column to the right of what the\n // reader sees. `xml-read.ts` has always stripped it for that reason.\n //\n // For HTML there is a second, sharper reason. The BOM is character data as\n // far as the HTML parser is concerned, and it lands *before* `<html>` — which\n // pushes parse5 into a mode where `<html>`, `<head>` and `<body>` are all\n // reported as implied, with no source locations, even when the document\n // spells them out. Everything downstream that needs to know where `<head>`\n // is would then be looking at a document that appears not to have one.\n //\n // Stripping is safe for line numbers: the BOM sits on line 1 and removing it\n // deletes no line. `body` is returned so a caller that splices — the writer —\n // measures against the same text these positions describe.\n const body = source.charCodeAt(0) === 0xfeff ? source.slice(1) : source;\n const doc = parse(body, { sourceCodeLocationInfo: true });\n\n const data: Record<string, unknown> = {};\n const lineMap = new Map<string, number>();\n const colMap = new Map<string, number>();\n const sources = new Map<string, HtmlSource>();\n let head: Element | undefined;\n // The document node has no location; anchor the root pointer at 1:1.\n lineMap.set(\"\", 1);\n colMap.set(\"\", 1);\n\n const setKey = (\n key: string,\n value: unknown,\n source: HtmlSource,\n line: number | undefined,\n col: number | undefined,\n ): void => {\n data[key] = value;\n sources.set(key, source);\n const pointer = `/${escapePointerSegment(key)}`;\n if (line != null) lineMap.set(pointer, line);\n if (col != null) colMap.set(pointer, col);\n };\n\n const visit = (node: DefaultTreeAdapterMap[\"childNode\"]): void => {\n if (defaultTreeAdapter.isElementNode(node)) {\n const location = node.sourceCodeLocation;\n const line = location?.startLine;\n if (node.tagName === \"head\" && head === undefined) {\n head = node;\n } else if (node.tagName === \"title\") {\n // The first <title> wins; later ones (e.g. in SVG) are ignored. A\n // <meta name=\"title\"> still overwrites it, in either document order.\n if (data.title === undefined) {\n const first = node.childNodes[0];\n const text =\n first && defaultTreeAdapter.isTextNode(first) ? first.value : \"\";\n setKey(\"title\", text, { kind: \"title\", el: node }, line, location?.startCol);\n }\n } else if (node.tagName === \"meta\") {\n const key = attrValue(node, \"name\") ?? attrValue(node, \"property\");\n const value = attrValue(node, \"content\");\n if (key != null && value != null) {\n // parse5 locates each attribute separately, so the caret can land\n // on `content=` — the thing that failed — rather than on `<meta`.\n //\n // Only when it is on the *same* line as the tag, though. `line`\n // stays the tag's opening line (changing that would move existing\n // annotations), so borrowing a column from an attribute wrapped\n // onto a later line would pair a real line with a column measured\n // somewhere else, and point at nothing.\n const attrLocation = location?.attrs?.[\"content\"];\n const col =\n attrLocation != null && attrLocation.startLine === line\n ? attrLocation.startCol\n : location?.startCol;\n setKey(key, typeValue(value), { kind: \"meta\", el: node }, line, col);\n }\n }\n // Same guard, same node, nothing between that could change the answer:\n // recursion belongs inside the one check rather than behind a second.\n for (const child of node.childNodes) visit(child);\n }\n };\n\n for (const child of doc.childNodes) visit(child);\n\n // Element-derived metadata, lifted from `<head>` only. The body is prose, and\n // an SVG `<title>` down in it labels a graphic rather than the page — which is\n // also why this walks `head` directly instead of reusing the visitor above.\n if (head) {\n for (const [key, { els, texts }] of liftableHeadChildren(head)) {\n // Not `pairValues` here, and still paired: `els` and `texts` are appended\n // in the same iteration, so index i names the element value i came from\n // by construction rather than by a helper enforcing it afterwards. That\n // is the invariant the config paths need `pairValues` for — those match\n // elements first and only then discover which ones carry a value.\n const values = texts.map(typeValue);\n // HTML has a content model, so where it fixes the cardinality the key\n // follows it. `<title>` is permitted once, so it is a scalar rather than\n // a one-item list; generic XML defaults to a list precisely because it\n // has no such statement to follow.\n const singleton = HEAD_SINGLETONS.has(elementName(els[0]));\n data[key] = singleton ? values[0] : values;\n sources.set(key, { kind: \"element-text\", els });\n const first = els[0];\n const location = first?.sourceCodeLocation;\n const pointer = `/${escapePointerSegment(key)}`;\n if (location?.startLine != null) lineMap.set(pointer, location.startLine);\n if (location?.startCol != null) colMap.set(pointer, location.startCol);\n }\n }\n\n // Config paths last, so a path naming a key the convention already filled is\n // a no-op rather than a silent retype.\n for (const raw of options?.elements ?? []) {\n const spec: ElementPath = parseElementPath(raw);\n if (data[spec.key] !== undefined) continue;\n // Paired, so `els[i]` still names the element `values[i]` came from — a\n // `<link>` with no `@href` must leave the element list with its value.\n const found = pairValues(\n matchHtmlPath(doc, spec.segments),\n (el) => (spec.attr ? attrValue(el, spec.attr) : headText(el, true)),\n typeValue,\n );\n if (found.values.length === 0) continue;\n data[spec.key] = found.values;\n sources.set(\n spec.key,\n spec.attr\n ? { kind: \"element-attr\", els: found.els, name: spec.attr }\n : { kind: \"element-text\", els: found.els },\n );\n const location = found.els[0]?.sourceCodeLocation;\n const pointer = `/${escapePointerSegment(spec.key)}`;\n if (location?.startLine != null) lineMap.set(pointer, location.startLine);\n if (location?.startCol != null) colMap.set(pointer, location.startCol);\n }\n\n return { data, body, lineMap, colMap, sources, head };\n}\n","/**\n * HTML write-back, the inverse of `readHtml`.\n *\n * Same idea as `frontmatter-write.ts`: never re-serialize, only splice. parse5's\n * serializer would materialize implied `<html>`/`<head>`/`<body>`, re-encode\n * entities, drop the original attribute quoting and rewrite the doctype — a\n * hand-authored page would come back reformatted and `fill` would produce a diff\n * touching every line. Instead every edit is a character range taken from\n * parse5's `sourceCodeLocation`, so everything outside the ranges survives by\n * construction rather than by careful reassembly.\n *\n * Where a value goes is decided by `readHtml`'s `sources` map, not by a rule of\n * this module's own. `fill` rewrites values that are present but *invalid*, not\n * just missing ones, so \"new values go in a fresh <meta>\" would leave the stale\n * tag the reader actually honors sitting right beside the correction — green\n * report, wrong page. A write lands on whatever the read took its value from.\n *\n * Values are emitted as YAML scalars because that is how they are read back\n * (`typeValue`). The string \"2\" therefore emits with its quotes and survives the\n * round trip; a value needing more than one line cannot fit in an attribute at\n * all and is refused rather than truncated.\n */\nimport { stringify as stringifyYaml } from \"yaml\";\nimport {\n DocmetaError,\n type ApplyOptions,\n type MetadataPatch,\n} from \"../types.js\";\nimport { dropUndefined, deepEqual } from \"./patch-util.js\";\nimport { readHtml, type Element, type HtmlRead } from \"./html-read.js\";\nimport { escapeText, valuesFor } from \"./element-write.js\";\n\n/** One character-range replacement in the source. */\ninterface Edit {\n start: number;\n end: number;\n text: string;\n}\n\nexport function applyHtml(\n original: string,\n patch: MetadataPatch,\n options: ApplyOptions = {},\n): string {\n // `readHtml` strips a leading BOM before parsing — see there for why parse5\n // makes that necessary — so every position it reports is relative to the text\n // it hands back. Splice against that same text and restore the BOM as a\n // prefix, which leaves no offset arithmetic to get wrong.\n const before = readHtml(original, { elements: options.elements });\n const content = before.body;\n\n // Structural checks run before the empty-patch shortcut, so an empty patch is\n // a usable pre-flight probe for \"can this document be written at all?\".\n // `fill` uses it to skip paying for inference on a file it could never write.\n const headStart = before.head?.sourceCodeLocation?.startTag;\n if (before.head === undefined || headStart == null) {\n throw new DocmetaError(\n \"This HTML document has no <head> element; manni meta fill writes metadata into <head>. Add one, or set the field manually.\",\n );\n }\n\n const clean = dropUndefined(patch);\n if (Object.keys(clean).length === 0) return original;\n\n const edits: Edit[] = [];\n const inserts: string[] = [];\n /** Elements this write touches, so `verify` knows which keys move with them. */\n const moved = new Set<Element>();\n for (const [key, value] of Object.entries(clean)) {\n const source = before.sources.get(key);\n // Emitted per branch rather than up front. A list-valued key is emitted one\n // item at a time below; emitting the whole array here would serialize it as\n // a YAML block and refuse it as \"needs more than one line\" — a write that\n // is perfectly expressible as one value per element.\n if (source === undefined) {\n const name = escapeAttr(key, DQ);\n inserts.push(\n \"<meta name=\" + DQ + name + DQ + \" content=\" + DQ +\n escapeAttr(emitScalar(key, value), DQ) + DQ + \">\",\n );\n } else if (source.kind === \"meta\") {\n edits.push(metaEdit(content, source.el, key, emitScalar(key, value)));\n moved.add(source.el);\n } else if (source.kind === \"title\") {\n edits.push(elementTextEdit(source.el, key, emitScalar(key, value)));\n moved.add(source.el);\n } else {\n // An element-derived key — `head.title`, or a config `@attr` path.\n // Written where it was read, exactly as the XML side does: both replace\n // a span that already exists, which changes content and not shape and so\n // cannot make the document invalid.\n const values = valuesFor(key, value, source.els.length);\n source.els.forEach((el, i) => {\n const one = emitScalar(key, values[i]);\n edits.push(\n source.kind === \"element-attr\"\n ? headAttrEdit(content, el, source.name, key, one)\n : elementTextEdit(el, key, one),\n );\n moved.add(el);\n });\n }\n }\n\n if (inserts.length > 0) {\n edits.push(insertEdit(content, before.head, headStart.endOffset, inserts));\n }\n\n const next = spliceAll(content, edits);\n verify(next, before, clean, moved, options);\n // `content === original` is the BOM test: `readHtml` returns `body` with any\n // leading BOM removed, so the two are the same value exactly when there was\n // none to remove. When there was, it is the single character at `original[0]`,\n // put back in front of the spliced text.\n return content === original ? next : original.slice(0, 1) + next;\n}\n\nconst DQ = String.fromCharCode(34);\nconst SQ = String.fromCharCode(39);\n\n/** Replace the value span of an existing `<meta>`'s `content` attribute. */\nfunction metaEdit(\n content: string,\n el: Element,\n key: string,\n emitted: string,\n): Edit {\n return headAttrEdit(content, el, \"content\", key, emitted);\n}\n\n/**\n * Replace the value span of a named attribute on any element.\n *\n * Named apart from `element-write.ts`'s exported `elementAttrEdit`, which this\n * module already imports from. The two do the same job on different trees —\n * parse5 nodes here, xmldom nodes there — and cannot be shared, so they should\n * at least not read as the same function.\n */\nfunction headAttrEdit(\n content: string,\n el: Element,\n attrName: string,\n key: string,\n emitted: string,\n): Edit {\n const attrs = el.sourceCodeLocation?.attrs;\n const attrLocation =\n attrs && Object.prototype.hasOwnProperty.call(attrs, attrName)\n ? attrs[attrName]\n : undefined;\n if (attrLocation == null) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": <${el.tagName}> has no locatable \"${attrName}\" attribute.`,\n );\n }\n const span = attrValueSpan(\n content,\n attrLocation.startOffset,\n attrLocation.endOffset,\n );\n if (span === undefined) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": its \"${attrName}\" attribute could not be located precisely.`,\n );\n }\n const value = escapeAttr(emitted, span.quote);\n return {\n start: span.start,\n end: span.end,\n text: span.wrap ? span.quote + value + span.quote : value,\n };\n}\n\n/**\n * Replace the text span of an element — `<title>`, or any `<head>` child a\n * lifted key was read from.\n *\n * `<title>` is RCDATA, so markup is not parsed inside it, but an unescaped \"<\"\n * still ends the element for some consumers. `escapeText` escapes \">\" too,\n * which RCDATA does not require but linters and stricter parsers flag, and\n * which the attribute path already does.\n */\nfunction elementTextEdit(el: Element, key: string, emitted: string): Edit {\n const location = el.sourceCodeLocation;\n const open = location?.startTag;\n const close = location?.endTag;\n if (open == null || close == null) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": the <${el.tagName}> element is not explicitly closed.`,\n );\n }\n return {\n start: open.endOffset,\n end: close.startOffset,\n text: escapeText(emitted),\n };\n}\n\n/**\n * Insert new `<meta>` tags immediately after `<head>`'s start tag, indented to\n * match whatever is already inside it.\n */\nfunction insertEdit(\n content: string,\n head: Element,\n at: number,\n tags: string[],\n): Edit {\n const { eol, indent } = headStyle(content, head, at);\n const text = tags.map((t) => `${eol}${indent}${t}`).join(\"\");\n return { start: at, end: at, text };\n}\n\n/**\n * The line ending and indentation to use inside `<head>`, taken from its first\n * existing child so an inserted tag looks like the ones around it.\n */\nfunction headStyle(\n content: string,\n head: Element,\n at: number,\n): { eol: string; indent: string } {\n for (const child of head.childNodes) {\n const start = child.sourceCodeLocation?.startOffset;\n if (start == null || start < at) continue;\n const lineStart = content.lastIndexOf(\"\\n\", start - 1) + 1;\n const between = content.slice(lineStart, start);\n // Only whitespace counts as indentation; a tag sharing a line with other\n // content tells us nothing about how the file is laid out.\n if (/^[ \\t]*$/.test(between)) {\n return {\n eol: crlfAt(content, lineStart) ? \"\\r\\n\" : \"\\n\",\n indent: between,\n };\n }\n }\n // Reached only for an empty `<head></head>`, where there is no child to copy\n // the style from. Look only at the text above the insertion point: a document\n // that mixes endings — an LF head in a generator's CRLF body — would\n // otherwise take its head's line ending from the body below it.\n const above = content.slice(0, at);\n return { eol: above.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\", indent: \" \" };\n}\n\nfunction crlfAt(content: string, lineStart: number): boolean {\n return lineStart >= 2 && content.slice(lineStart - 2, lineStart) === \"\\r\\n\";\n}\n\n/**\n * Find the value span inside an attribute's `name=\"value\"` range, and the quote\n * character in use, so the original quoting style survives the write.\n */\nfunction attrValueSpan(\n content: string,\n start: number,\n end: number,\n): { start: number; end: number; quote: string; wrap: boolean } | undefined {\n const eq = content.indexOf(\"=\", start);\n if (eq === -1 || eq >= end) return undefined;\n let i = eq + 1;\n while (i < end && /\\s/.test(content[i] ?? \"\")) i++;\n // Nothing but whitespace after the `=`. parse5 should never report an\n // attribute that way, but falling through would return a zero-width span at\n // `end`, and the write would *insert* beside the attribute rather than\n // replace its value. `verify` would catch it; refusing here says which\n // attribute could not be located instead of reporting a mismatch later.\n if (i >= end) return undefined;\n const quote = content[i];\n if (quote === DQ || quote === SQ) {\n const close = content.indexOf(quote, i + 1);\n if (close === -1 || close > end) return undefined;\n return { start: i + 1, end: close, quote, wrap: false };\n }\n // Unquoted value: it runs to the end of the attribute's range, and the\n // replacement has to supply its own quotes — `wrap`. Leaving it bare would\n // hold only while the new value had no spaces: `content=hello world`\n // tokenizes as `content=\"hello\"` plus a boolean `world` attribute, which the\n // verify step then rejects with its generic message instead of the write\n // simply working.\n return { start: i, end, quote: DQ, wrap: true };\n}\n\n/** Emit a value the way the reader will parse it back: as a YAML scalar. */\nfunction emitScalar(key: string, value: unknown): string {\n const text = stringifyYaml(value).replace(/\\n$/, \"\");\n if (text.includes(\"\\n\")) {\n throw new DocmetaError(\n `Refusing to write \"${key}\": the value needs more than one line, which an HTML attribute cannot hold. Set it manually.`,\n );\n }\n return text;\n}\n\nfunction escapeAttr(value: string, quote: string): string {\n const escaped = value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\");\n return quote === SQ\n ? escaped.replace(/'/g, \"&#39;\")\n : escaped.replace(/\"/g, \"&quot;\");\n}\n\n/** Apply every edit back-to-front, so earlier offsets stay valid. */\nfunction spliceAll(content: string, edits: Edit[]): string {\n const ordered = [...edits].sort((a, b) => b.start - a.start);\n let out = content;\n let lastStart = Number.POSITIVE_INFINITY;\n for (const edit of ordered) {\n /* c8 ignore next 5 -- defensive: sources are distinct tags by construction. */\n if (edit.end > lastStart) {\n throw new DocmetaError(\n \"Internal error: overlapping edits while writing HTML metadata.\",\n );\n }\n out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);\n lastStart = edit.start;\n }\n return out;\n}\n\n/**\n * Re-read the written document and confirm it says exactly what it should. This\n * is the difference between a bug here being a refusal and a bug here being a\n * corrupted page.\n *\n * `moved` names the elements this write edited. Since element-derived metadata\n * arrived, one element can back **two** keys — `<title>` is read as both the\n * flat `title` and as `head.title` — so writing one of them necessarily moves\n * the other. Holding the co-derived key to its *old* value would fail every\n * `<title>` write, which is exactly what it did before this argument existed.\n *\n * The invariant is not weakened by exempting them. A co-derived key reads from\n * the same text as the key that was written, and that key is still checked\n * strictly: if the element had not been updated, the written key would mismatch\n * and this would still throw. Everything sourced from an element the write did\n * not touch is still held to its old value exactly.\n */\nfunction verify(\n next: string,\n before: HtmlRead,\n patch: MetadataPatch,\n moved: Set<Element>,\n options: ApplyOptions,\n): void {\n // Re-read with the *same* options the write used, or a key an `elements:`\n // path produced is invisible here and every write to one is refused.\n const actual = readHtml(next, { elements: options.elements }).data;\n const expected: Record<string, unknown> = { ...before.data, ...patch };\n for (const [key, source] of before.sources) {\n if (key in patch) continue;\n const els =\n source.kind === \"element-text\" || source.kind === \"element-attr\"\n ? source.els\n : [source.el];\n if (els.some((el: Element) => moved.has(el))) expected[key] = actual[key];\n }\n if (!deepEqual(actual, expected)) {\n throw new DocmetaError(\n \"Refusing to write HTML metadata: the rewritten document did not read back as expected.\",\n );\n }\n}\n","/**\n * HTML metadata extractor.\n *\n * Reads document metadata from `<meta>` tags and `<title>`:\n * - `<title>…</title>` -> `title` (the text content, kept verbatim).\n * - `<meta name=\"X\" content=\"Y\">` (or `property=\"X\"` for OpenGraph-style tags)\n * -> `X: Y`. `content` values are parsed as YAML scalars so `\"2\"` -> number\n * and `\"true\"` -> boolean, consistent with the AsciiDoc/XML extractors.\n *\n * Tags with neither `name` nor `property` (e.g. `charset`, `http-equiv`) carry no\n * document metadata and are skipped. Duplicate keys: last tag wins; the first\n * `<title>` wins. The parser (parse5) decodes HTML entities and recovers from\n * malformed markup, so extraction never throws. Per-node — and per-attribute —\n * positions give JSON-Pointer -> source-line and -> source-column maps for\n * annotations. Both are 1-based, as parse5 reports them.\n *\n * The read itself lives in `html-read.ts`, shared with `html-write.ts` so that a\n * write lands wherever the read took its value from. See that module for why\n * the two must not each carry their own copy of the precedence rule.\n */\nimport { readHtml } from \"./html-read.js\";\nimport { applyHtml } from \"./html-write.js\";\nimport { positionForFactory } from \"./pointer.js\";\nimport type { ExtractedMetadata, MetadataExtractor } from \"../types.js\";\n\nexport const htmlExtractor: MetadataExtractor = {\n name: \"html\",\n extensions: [\".html\", \".htm\"],\n implemented: true,\n extract(content, _filePath, options): ExtractedMetadata {\n const { data, lineMap, colMap } = readHtml(content, options);\n return {\n data,\n present: Object.keys(data).length > 0,\n format: \"html\",\n lineFor: positionForFactory(lineMap),\n colFor: positionForFactory(colMap),\n };\n },\n apply: applyHtml,\n};\n","/**\n * Extractor registry. Maps file extensions to extractors and resolves an\n * extractor by name (for the `--as` override). Every registered extractor is\n * implemented today; the `implemented` filters below are what would keep a\n * declared-but-unwired format out of directory walks, so an unfinished format\n * can be registered without becoming \"supported\".\n */\nimport type { MetadataExtractor } from \"../types.js\";\nimport { markdownExtractor } from \"./markdown.js\";\nimport { mdxExtractor } from \"./mdx.js\";\nimport { asciidocExtractor } from \"./asciidoc.js\";\nimport { rstExtractor } from \"./rst.js\";\nimport { xmlExtractor } from \"./xml.js\";\nimport { htmlExtractor } from \"./html.js\";\n\nexport const EXTRACTORS: MetadataExtractor[] = [\n markdownExtractor,\n mdxExtractor,\n asciidocExtractor,\n rstExtractor,\n xmlExtractor,\n htmlExtractor,\n];\n\nconst byExtension = new Map<string, MetadataExtractor>();\nconst byName = new Map<string, MetadataExtractor>();\nfor (const ex of EXTRACTORS) {\n byName.set(ex.name, ex);\n for (const ext of ex.extensions) byExtension.set(ext.toLowerCase(), ex);\n}\n\n/** Resolve an implemented extractor for a file extension (incl. dot). */\nexport function extractorForExtension(\n ext: string,\n): MetadataExtractor | undefined {\n const ex = byExtension.get(ext.toLowerCase());\n return ex?.implemented ? ex : undefined;\n}\n\n/** Resolve an extractor by its `--as` name (implemented or not). */\nexport function extractorByName(name: string): MetadataExtractor | undefined {\n return byName.get(name.toLowerCase());\n}\n\n/** Extensions handled by implemented extractors (used for directory walks). */\nexport function supportedExtensions(): string[] {\n return EXTRACTORS.filter((e) => e.implemented).flatMap((e) => e.extensions);\n}\n\n/** All registered format names, with their implemented and writable status. */\nexport function listFormats(): {\n name: string;\n extensions: string[];\n implemented: boolean;\n writable: boolean;\n}[] {\n return EXTRACTORS.map((e) => ({\n name: e.name,\n extensions: e.extensions,\n implemented: e.implemented,\n // Writability is the presence of the optional `apply` method, so a format\n // never has to declare it twice and the two can't drift apart.\n writable: typeof e.apply === \"function\",\n }));\n}\n","/**\n * External metadata (proposal 0037): a private manifest joined to public\n * documents.\n *\n * A manifest is a YAML mapping from document to a mapping of owned keys. Its\n * values are merged into each named document's extracted metadata before\n * schema resolution, so every command sees one object. The manifest itself\n * is never a document: it registers no extractor, appears in no `docs` row,\n * and is what 0031 called a join table rather than the standalone data file\n * it rejected.\n *\n * Three rules decide everything else here:\n *\n * - **Keys are owned.** Each manifest declares the top-level keys it supplies,\n * ownership is disjoint across manifests (asserted by the config parser), and\n * a manifest entry supplying a key it does not own is an operational error.\n * Ownership is what gives a write to an absent key somewhere to go, and it\n * is what makes a document carrying a private key visible with or without\n * a manifest entry.\n * - **A document carrying an owned key is a collision, not a tiebreak.** 0020's\n * rule across files: neither channel wins, because the discarded value is\n * exactly the one nobody checked. The caller files the finding; the merge\n * keeps the document's value so the report shows what the public site\n * would publish.\n * - **A manifest names documents by exact path, or by one frontmatter field.**\n * No globs and no cascade (0004 rejected partial merges of config for the\n * reason that a silently merged result changes what the contract means).\n * A path is relative to the config's directory. A field join (0039)\n * matches the extracted value of that field, so a rename cannot orphan an\n * entry; what can is two pages sharing one value, which is a finding on\n * both.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport {\n LineCounter,\n isMap,\n isNode,\n isScalar,\n parseDocument,\n type Node,\n} from \"yaml\";\nimport type {\n CollectionConfig,\n ExternalMetadataConfig,\n} from \"../../shared/collections.js\";\nimport { FILE_SCHEMA_KEY } from \"./resolve-schema.js\";\nimport { classifyRef } from \"./schema-registry.js\";\nimport { fetchExternalMetadata } from \"./external-metadata-fetch.js\";\nimport { STDIN_LABEL } from \"./load-files.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\nimport { DocmetaError, type ExtractedMetadata } from \"../types.js\";\n\n/**\n * The `schema` ref a collision finding carries, and so its baseline and rule\n * identity: `external:owned/external`. Shaped like `check:<name>` so\n * `classifyRef` passes it through as a built-in id rather than resolving it\n * as a cwd-relative file path, and reserved in the registry for the same\n * reason `check` is.\n */\nexport const EXTERNAL_OWNED_SCHEMA = \"external:owned\";\n\n/**\n * The `schema` ref of a duplicate-join finding (0039): two documents carry\n * the same value of a join field, so one manifest entry matched both.\n */\nexport const EXTERNAL_DUPLICATE_SCHEMA = \"external:duplicate\";\n\n/**\n * The `keyword` every external-metadata finding carries: no Ajv keyword\n * produced it.\n */\nexport const EXTERNAL_KEYWORD = \"external\";\n\n/** The join that names documents by path, and the default. */\nexport const PATH_JOIN = \"path\";\n\n/** One value a manifest supplied, and where it was written. */\nexport interface ExternalMetadataValue {\n value: unknown;\n /** The collection whose manifest supplied it (proposal 0041). */\n collection: string;\n /** Manifest path as the run reports it: relative to the run's base, posix — or the URL. */\n file: string;\n /** 1-based line of the key in the manifest, when known. */\n line?: number;\n}\n\n/** One manifest entry, for the orphan checks. */\nexport interface ExternalMetadataEntry {\n /** The collection whose manifest declared it (proposal 0041). */\n collection: string;\n /** `path`, or the frontmatter field this entry is keyed by. */\n join: string;\n /** Absolute document path, for a path entry. */\n abs?: string;\n /** The key exactly as written in the manifest. */\n spelled: string;\n /** Manifest path as the run reports it. */\n file: string;\n /** 1-based line of the entry in the manifest, when known. */\n line?: number;\n}\n\ntype Values = Map<string, ExternalMetadataValue>;\n\n/** Every manifest of a run, loaded once and consulted per document. */\nexport interface ExternalMetadataIndex {\n /**\n * Owned key -> every collection that owns it, with the manifest that does.\n *\n * A list rather than one entry, because two collections may legitimately\n * each own the same key (0041 rule 5): `guides` and `blog` can both supply\n * `owner`. Ambiguity only exists for a file that is a member of both, which\n * is decided per file in `mergeExternalMetadata`.\n */\n owners: ReadonlyMap<string, readonly { collection: string; file: string }[]>;\n /** Path-joined manifests: absolute document path -> owned key -> value. */\n byPath: ReadonlyMap<string, ReadonlyMap<string, ExternalMetadataValue>>;\n /** Field-joined manifests: field -> value -> owned key -> value. */\n byField: ReadonlyMap<string, ReadonlyMap<string, ReadonlyMap<string, ExternalMetadataValue>>>;\n /** Every manifest entry, in manifest order. */\n entries: readonly ExternalMetadataEntry[];\n}\n\nexport interface LoadExternalMetadataOptions {\n /** Directory `externalMetadata[].file` and every manifest key resolve from. */\n configDir: string;\n /** Directory the run's file labels are relative to; manifests are reported the same way. */\n base: string;\n /** `--offline` / `offline:`: a URL manifest is refused rather than fetched (0038). */\n offline?: boolean;\n /** Network timeout for a URL manifest; the schema fetch's default otherwise. */\n timeoutMs?: number;\n /** For tests: the environment `tokenEnv` is read from. */\n env?: Record<string, string | undefined>;\n}\n\n/** A place a merged value lives, for a finding that must name it. */\nexport interface SourceLocation {\n file: string;\n line?: number;\n col?: number;\n}\n\n/** A key the document carries that a manifest owns. */\nexport interface ExternalMetadataCollision {\n key: string;\n /** The owning manifest, as the run reports it. */\n file: string;\n /** The collection that manifest belongs to (proposal 0041). */\n collection: string;\n}\n\n/** A field-joined entry a document matched (0039). */\nexport interface ExternalMetadataJoin {\n field: string;\n value: string;\n /** The manifest, as the run reports it. */\n file: string;\n /** The collection that manifest belongs to (proposal 0041). */\n collection: string;\n}\n\n/** What `mergeExternalMetadata` hands back. */\nexport interface MergedMetadata {\n /** The document's metadata with every owned key the manifest supplied. */\n extracted: ExtractedMetadata;\n /**\n * Owned keys the document itself also carried, in document order, each\n * with the manifest that owns it — so the finding names it without a\n * second lookup, and without a fallback for an index that is not there.\n */\n collisions: ExternalMetadataCollision[];\n /** Field-joined entries this document matched, one per manifest at most. */\n joins: ExternalMetadataJoin[];\n /**\n * Where a merged pointer's value lives. Answers only for a value the\n * manifest supplied — a bare key or its `/key` pointer, and anything\n * beneath it — and `undefined` for everything the document owns, which is\n * what `lineFor` is for.\n */\n locate: (pointer: string) => SourceLocation | undefined;\n}\n\nconst posix = (p: string): string => p.split(sep).join(\"/\");\n\n/** How a run spells a manifest: relative to its base, like every file label. */\nfunction reportedPath(abs: string, base: string): string {\n const rel = relative(base, abs);\n return rel === \"\" ? \".\" : posix(rel);\n}\n\n/** The join an external-metadata config asks for: `path` unless it names a field. */\nexport function externalMetadataJoin(\n manifest: Pick<ExternalMetadataConfig, \"join\">,\n): string {\n return manifest.join ?? PATH_JOIN;\n}\n\n/**\n * Load every manifest of every collection the run covers. Resolves to `null`\n * when none of them declares one, which is every setup that existed before\n * this feature.\n *\n * Every refusal is a `DocmetaError`: the manifest is a config-supplied input,\n * and one that is missing or misshapen is the run's problem, not a\n * document's (0014).\n */\nexport async function loadExternalMetadata(\n collections: readonly CollectionConfig[],\n opts: LoadExternalMetadataOptions,\n): Promise<ExternalMetadataIndex | null> {\n const configured = collections.flatMap((c) =>\n c.externalMetadata.map((m) => ({ collection: c.name, manifest: m })),\n );\n if (configured.length === 0) return null;\n\n const owners = new Map<string, { collection: string; file: string }[]>();\n const byPath = new Map<string, Values>();\n const byField = new Map<string, Map<string, Values>>();\n const entries: ExternalMetadataEntry[] = [];\n\n for (const { collection, manifest } of configured) {\n // A URL manifest (0038) is reported as the URL itself, and fetched every\n // run: it is data, and a stale copy would validate against the wrong\n // values. A path is reported relative to the run's base, like every\n // file label. Either way the manifest's *keys* resolve from the config\n // directory, so a remote manifest names documents the same way a local\n // one does.\n let text: string;\n let file: string;\n if (classifyRef(manifest.file).kind === \"url\") {\n file = manifest.file;\n text = await fetchExternalMetadata(manifest.file, {\n ...(manifest.tokenEnv !== undefined ? { tokenEnv: manifest.tokenEnv } : {}),\n ...(opts.offline !== undefined ? { offline: opts.offline } : {}),\n ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n });\n } else {\n const abs = isAbsolute(manifest.file)\n ? manifest.file\n : resolve(opts.configDir, manifest.file);\n file = reportedPath(abs, opts.base);\n text = await readManifest(abs, file);\n }\n for (const key of manifest.keys) {\n const list = owners.get(key);\n if (list) list.push({ collection, file });\n else owners.set(key, [{ collection, file }]);\n }\n const join = externalMetadataJoin(manifest);\n let target: Map<string, Values>;\n if (join === PATH_JOIN) {\n target = byPath;\n } else {\n const existing = byField.get(join);\n if (existing) target = existing;\n else {\n target = new Map<string, Values>();\n byField.set(join, target);\n }\n }\n parseManifest(\n manifest,\n collection,\n text,\n file,\n opts.configDir,\n join,\n target,\n entries,\n );\n }\n return { owners, byPath, byField, entries };\n}\n\nasync function readManifest(abs: string, file: string): Promise<string> {\n try {\n return await readFile(abs, \"utf8\");\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n throw new DocmetaError(\n `Manifest ${file} could not be read: ${reason}`,\n );\n }\n}\n\nfunction parseManifest(\n manifest: ExternalMetadataConfig,\n collection: string,\n text: string,\n file: string,\n configDir: string,\n join: string,\n target: Map<string, Values>,\n entries: ExternalMetadataEntry[],\n): void {\n const lc = new LineCounter();\n // `uniqueKeys: false`, so a document named twice reaches the dedicated\n // check below and is reported by name and line, rather than as a generic\n // \"map keys must be unique\" parse error.\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const problem = doc.errors[0];\n if (problem) {\n throw new DocmetaError(\n `Manifest ${file} is not valid YAML: ${problem.message}`,\n );\n }\n const root = doc.contents;\n // An empty manifest is a mapping with no entries: legal, and merges nothing.\n if (root === null || (isScalar(root) && root.value === null)) return;\n if (!isMap(root)) {\n throw new DocmetaError(\n `Manifest ${file}: the manifest must be a mapping from document ${join === PATH_JOIN ? \"path\" : `\"${join}\"`} to owned keys.`,\n );\n }\n const owned = new Set(manifest.keys);\n const lineAt = (node: unknown): number | undefined => {\n const range = isNode(node) ? node.range : undefined;\n return range ? lc.linePos(range[0]).line : undefined;\n };\n\n // A document named twice would otherwise resolve last-wins per key, with\n // both entries counted and no diagnostic: `yaml` files a duplicate mapping\n // key under `doc.warnings`, not `doc.errors`. It is almost always a typo,\n // and it is refused by name rather than merged.\n const seen = new Map<string, number | undefined>();\n for (const pair of root.items) {\n const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);\n const entryLine = lineAt(pair.key);\n const where = entryLine === undefined ? file : `${file}:${entryLine}`;\n if (seen.has(spelled)) {\n const first = seen.get(spelled);\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" is named twice (first at line ${first ?? \"?\"}). Merge the two entries into one.`,\n );\n }\n seen.set(spelled, entryLine);\n if (!isMap(pair.value)) {\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" must be a mapping of owned keys to values.`,\n );\n }\n // A path entry is indexed by its absolute path; a field entry by the\n // spelled value, which a document's field is compared to as a string.\n const indexKey = join === PATH_JOIN ? resolve(configDir, spelled) : spelled;\n const values = target.get(indexKey) ?? new Map<string, ExternalMetadataValue>();\n for (const kv of pair.value.items) {\n const key = isScalar(kv.key) ? String(kv.key.value) : String(kv.key);\n if (key === FILE_SCHEMA_KEY) {\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" sets \"${FILE_SCHEMA_KEY}\" — a manifest never chooses the schema a document is judged by; use \"overrides\" in the config.`,\n );\n }\n if (!owned.has(key)) {\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" sets \"${key}\", which this manifest does not own. Add it to the manifest's \"keys\", or remove it from the entry.`,\n );\n }\n const value: unknown =\n kv.value === null\n ? null\n : (kv.value as Node).toJS(doc, { maxAliasCount: 100 });\n const line = lineAt(kv.key);\n values.set(key, {\n value,\n collection,\n file,\n ...(line === undefined ? {} : { line }),\n });\n }\n target.set(indexKey, values);\n entries.push({\n collection,\n join,\n ...(join === PATH_JOIN ? { abs: indexKey } : {}),\n spelled,\n file,\n ...(entryLine === undefined ? {} : { line: entryLine }),\n });\n }\n}\n\n/** The string a document's join field compares as; undefined when it cannot. */\nfunction joinValue(raw: unknown): string | undefined {\n if (typeof raw === \"string\") return raw;\n if (typeof raw === \"number\" || typeof raw === \"bigint\") return String(raw);\n if (typeof raw === \"boolean\") return String(raw);\n return undefined;\n}\n\n/**\n * Merge the external metadata for one document into its extracted metadata.\n *\n * `label` is the document as the run spells it, relative to `base`; a path\n * entry matches on the resolved absolute path, never on the spelling, so a\n * positional run from a subdirectory finds the same entry a config-corpus\n * run does. A field entry matches on the document's own value of the join\n * field, wherever the document lives. Stdin never matches a path entry:\n * there is no file behind it.\n *\n * `memberOf` names the collections this document belongs to, and only their\n * manifests are consulted (0041 rule 4). It is the caller's `memberOf(...)`\n * result, computed once per file.\n *\n * `present`, `format` and the document's own positions are untouched. A\n * manifest key is not in the document, so `lineFor` keeps answering\n * `undefined` for it, and `locate` answers instead.\n */\nexport function mergeExternalMetadata(\n label: string,\n extracted: ExtractedMetadata,\n index: ExternalMetadataIndex | null,\n memberOf: readonly string[],\n base: string,\n): MergedMetadata {\n const none = (): undefined => undefined;\n // A file that belongs to no collection gets nothing merged, and carries no\n // collision either: a key only counts as owned by a manifest that applies to\n // this file (0041 rule 4). A positional `README.md` is the case.\n if (!index || memberOf.length === 0) {\n return { extracted, collisions: [], joins: [], locate: none };\n }\n const mine = (collection: string): boolean => memberOf.includes(collection);\n\n const collisions: ExternalMetadataCollision[] = [];\n for (const key of Object.keys(extracted.data)) {\n for (const owner of index.owners.get(key) ?? []) {\n if (mine(owner.collection)) {\n collisions.push({ key, file: owner.file, collection: owner.collection });\n }\n }\n }\n\n const sources: ReadonlyMap<string, ExternalMetadataValue>[] = [];\n const joins: ExternalMetadataJoin[] = [];\n if (label !== STDIN_LABEL) {\n const byPath = index.byPath.get(resolve(base, label));\n if (byPath) sources.push(byPath);\n }\n for (const [field, byValue] of index.byField) {\n const value = joinValue(extracted.data[field]);\n if (value === undefined) continue;\n const hit = byValue.get(value);\n if (!hit) continue;\n sources.push(hit);\n // Exactly one join per (field, value), whatever the collections behind it.\n // The duplicate-join finding (0039) counts *documents* per value, so a\n // second entry for one document would read as a second document.\n const first = [...hit.values()].find((sv) => mine(sv.collection));\n if (first) {\n joins.push({ field, value, file: first.file, collection: first.collection });\n }\n }\n\n // Two of this file's collections owning one key the manifests actually\n // supply for it is an operational error, not a finding: there is nothing\n // about the document to fix, and picking a winner would be the tiebreak\n // 0020 and 0037 both refuse (0041 rule 5). The legitimate case — two\n // collections each owning `owner`, with no file in both — is untouched,\n // which is why this is decided per file rather than at parse time.\n for (const supplied of sources) {\n for (const key of supplied.keys()) {\n const owners = (index.owners.get(key) ?? []).filter((o) =>\n mine(o.collection),\n );\n const [a, b] = owners;\n if (a && b) {\n throw new DocmetaError(\n `${label}: \"${key}\" is owned by manifests in two of its collections, ${a.collection} (${a.file}) and ${b.collection} (${b.file}); a key has one manifest per file. Narrow one collection's paths or exclude.`,\n );\n }\n }\n }\n\n if (sources.length === 0) {\n return { extracted, collisions, joins, locate: none };\n }\n\n const data: Record<string, unknown> = { ...extracted.data };\n const merged = new Map<string, ExternalMetadataValue>();\n for (const supplied of sources) {\n for (const [key, sv] of supplied) {\n // Only the manifests of collections this file belongs to.\n if (!mine(sv.collection)) continue;\n // The document's value stays: the collision is filed by the caller,\n // and the report should show what the public site would publish.\n if (key in extracted.data) continue;\n data[key] = sv.value;\n merged.set(key, sv);\n }\n }\n const locate = (pointer: string): SourceLocation | undefined => {\n const top = topLevelKey(pointer);\n if (top === undefined) return undefined;\n const sv = merged.get(top);\n if (!sv) return undefined;\n return { file: sv.file, ...(sv.line === undefined ? {} : { line: sv.line }) };\n };\n return { extracted: { ...extracted, data }, collisions, joins, locate };\n}\n\n/** The top-level key a pointer (or bare key) addresses; undefined for the root. */\nfunction topLevelKey(pointer: string): string | undefined {\n if (pointer === \"\") return undefined;\n if (!pointer.startsWith(\"/\")) return pointer;\n const seg = pointer.slice(1).split(\"/\")[0] ?? \"\";\n return seg.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/** The `/key` pointer for an external-metadata finding, RFC 6901 escaped. */\nexport function externalMetadataPointer(key: string): string {\n return `/${escapePointerSegment(key)}`;\n}\n\n/**\n * Path entries naming no loaded document.\n *\n * `loaded` are the run's file labels, relative to `base`. Checked only when\n * the run is the config corpus (the same invariant corpus checks use): a\n * positional path means the operator chose to look at part of the corpus,\n * and an entry for the rest is expected, not orphaned.\n */\nexport function orphanEntries(\n index: ExternalMetadataIndex | null,\n loaded: readonly string[],\n base: string,\n collections?: readonly string[],\n): ExternalMetadataEntry[] {\n if (!index) return [];\n const have = new Set(loaded.map((l) => resolve(base, l)));\n return index.entries.filter(\n (e) =>\n inCollections(e, collections) &&\n e.join === PATH_JOIN &&\n e.abs !== undefined &&\n !have.has(e.abs),\n );\n}\n\n/**\n * Is this entry's collection one the run covers whole?\n *\n * `undefined` means every collection, which is a run with no `--collection`.\n * Naming collections makes each named one its own corpus (proposal 0041 rule\n * 6): the run loaded all of it, so an entry of that collection pointing at a\n * document that is not there is as orphaned as it would be in a full run. An\n * entry belonging to a collection nobody selected is not — the run never\n * claimed to cover it.\n */\nfunction inCollections(\n entry: ExternalMetadataEntry,\n collections: readonly string[] | undefined,\n): boolean {\n return collections === undefined || collections.includes(entry.collection);\n}\n\n/**\n * Field entries no loaded document matched (0039). `matched` is field -> the\n * values documents in the run carried, which the caller collects from each\n * document's `joins` — so this runs after the per-file loop, under the same\n * corpus invariant as `orphanEntries`.\n */\nexport function orphanJoins(\n index: ExternalMetadataIndex | null,\n matched: ReadonlyMap<string, ReadonlySet<string>>,\n collections?: readonly string[],\n): ExternalMetadataEntry[] {\n if (!index) return [];\n return index.entries.filter(\n (e) =>\n inCollections(e, collections) &&\n e.join !== PATH_JOIN &&\n !(matched.get(e.join)?.has(e.spelled) ?? false),\n );\n}\n\n/** The operational error an orphan check raises, naming the first entry. */\nexport function orphanError(orphans: readonly ExternalMetadataEntry[]): DocmetaError {\n const first = orphans[0];\n if (!first) throw new Error(\"orphanError called with no orphans\");\n const where = first.line === undefined ? first.file : `${first.file}:${first.line}`;\n const more = orphans.length > 1 ? ` (${orphans.length - 1} more)` : \"\";\n const what =\n first.join === PATH_JOIN\n ? `names \"${first.spelled}\", which this run did not load`\n : `names ${first.join} \"${first.spelled}\", which no loaded document carries`;\n return new DocmetaError(\n `Manifest ${where} ${what}${more}. Fix the entry, or remove it.`,\n );\n}\n","/**\n * Resolve a mix of explicit files, directories, and globs into a concrete,\n * de-duplicated, sorted list of file paths (posix-style, relative to cwd).\n * Directory and glob expansion is restricted to the given extensions; explicit\n * file arguments are always included so the user can target any single file.\n */\nimport { stat } from \"node:fs/promises\";\nimport { extname, relative, resolve } from \"node:path\";\nimport fg from \"fast-glob\";\nimport picomatch from \"picomatch\";\nimport { supportedExtensions } from \"../extractors/index.js\";\nimport { DocmetaError } from \"../types.js\";\nimport { GITIGNORE_UNAVAILABLE, gitIgnored } from \"./gitignore.js\";\n\nconst DEFAULT_IGNORE = [\"**/node_modules/**\", \"**/.git/**\"];\n\nexport const STDIN_TOKEN = \"-\";\n\n/**\n * What a stdin result is labelled in output. Lives here beside the input token\n * so the two spellings cannot drift: commands set it, reporters test for it,\n * and a reporter that missed a rename would give a `<stdin>` result an\n * `artifactLocation.uri` naming a file that does not exist.\n */\nexport const STDIN_LABEL = \"<stdin>\";\n\nfunction toPosix(p: string): string {\n return p.replace(/\\\\/g, \"/\");\n}\n\nasync function statOrNull(p: string) {\n try {\n return await stat(p);\n } catch {\n return null;\n }\n}\n\nexport interface ResolveOptions {\n /** Positional inputs: files, directories, or globs. `-` is ignored here. */\n inputs: string[];\n /** Extensions to keep during dir/glob expansion (default: supported). */\n exts?: string[];\n /** Extra exclude globs (added to node_modules/.git defaults). */\n exclude?: string[];\n cwd?: string;\n /**\n * Do not report inputs that name a path which does not exist. Set by\n * `--allow-empty` / `allowEmpty:` for callers that legitimately run against\n * a repo where the targets may be absent (a shared CI template, a\n * pre-commit hook with an empty file list).\n */\n allowEmpty?: boolean;\n /**\n * Skip files `.gitignore` covers during directory and glob expansion.\n * Default true; `--no-gitignore` / `respectGitignore: false` turns it off.\n *\n * Explicitly named files are never filtered — the user who types a path\n * means it — which mirrors how an explicit file already bypasses `--ext`.\n */\n respectGitignore?: boolean;\n /**\n * Called when filtering was asked for but git could not answer (no\n * repository, no git binary). Callers pass this only when the user asked\n * for filtering *explicitly*, since on the default it would put a line of\n * stderr on every run outside a repo.\n */\n onGitignoreUnavailable?: () => void;\n}\n\nexport interface ResolvedTargets {\n /** The files to process, posix-style and relative to `cwd`. */\n files: string[];\n /**\n * Candidate documents `.gitignore` removed. Counted **after** the extension\n * filter, so the number answers \"how many files I would otherwise have\n * checked did .gitignore take away\" rather than including every ignored\n * `.png` under `build/`. `--exclude` removals are not counted here; those\n * are the caller's own instruction, not a surprise.\n */\n gitignoreSkipped: number;\n}\n\n/**\n * Settle the two gitignore knobs every command core passes down, so the three\n * of them cannot drift on either the precedence or the diagnostic.\n *\n * `flag` is `--no-gitignore` (or a programmatic override), `configured` is\n * `respectGitignore:` from config, and the default is on.\n */\nexport function gitignoreOptions(opts: {\n flag?: boolean;\n configured?: boolean;\n onNotice?: (message: string) => void;\n}): Pick<ResolveOptions, \"respectGitignore\" | \"onGitignoreUnavailable\"> {\n // Only a value someone actually wrote is worth a diagnostic. On the default,\n // a note would land on every run outside a repository — an extracted\n // tarball, `npm pack` output, some Docker build contexts — for a filter\n // nobody asked for.\n const asked =\n opts.flag === true || (opts.flag === undefined && opts.configured === true);\n const notice = opts.onNotice;\n return {\n respectGitignore: opts.flag ?? opts.configured ?? true,\n ...(asked && notice\n ? {\n onGitignoreUnavailable: () => {\n notice(GITIGNORE_UNAVAILABLE);\n },\n }\n : {}),\n };\n}\n\n/** The file list alone, for callers with no use for what was filtered out. */\nexport async function resolveTargets(opts: ResolveOptions): Promise<string[]> {\n return (await resolveTargetSet(opts)).files;\n}\n\nexport async function resolveTargetSet(\n opts: ResolveOptions,\n): Promise<ResolvedTargets> {\n const cwd = opts.cwd ?? process.cwd();\n const exts = (opts.exts ?? supportedExtensions()).map((e) =>\n e.toLowerCase().startsWith(\".\") ? e.toLowerCase() : `.${e.toLowerCase()}`,\n );\n const ignore = [...DEFAULT_IGNORE, ...(opts.exclude ?? [])];\n // Kept apart until the end: `named` is what the user typed and is never\n // filtered, `walked` is what a directory or glob produced and is.\n const named = new Set<string>();\n const walked = new Set<string>();\n\n const keepByExt = (file: string): boolean =>\n exts.includes(extname(file).toLowerCase());\n\n // Inputs that name a single path rather than describing a pattern, and that\n // do not exist. Collected rather than thrown on first sight so one error can\n // name every mistake.\n const missing: string[] = [];\n\n for (const input of opts.inputs) {\n if (input === STDIN_TOKEN) continue;\n\n // Normalize before resolving, not after. `path.resolve` treats a backslash\n // as a separator on Windows and as an ordinary filename character on Linux,\n // so `nested\\doc.md` would stat successfully on a developer's machine and\n // then fail on Linux CI — while the not-found message, built from the posix\n // form, named a different path than the one actually looked for. Normalizing\n // here keeps the stat, the glob, and the message on one spelling.\n //\n // The cost is that a Linux file whose name genuinely contains a backslash is\n // not addressable. That is accepted: this module already treats backslash as\n // a separator everywhere else (glob expansion and the returned labels both\n // go through `toPosix`), and a docs tree containing such a name is a\n // hypothetical, whereas Windows-authored paths reaching Linux CI is routine.\n const posixInput = toPosix(input);\n const abs = resolve(cwd, posixInput);\n const st = await statOrNull(abs);\n\n if (st?.isFile()) {\n named.add(toPosix(relative(cwd, abs)));\n continue;\n }\n\n if (st?.isDirectory()) {\n const found = await fg(`${posixInput}/**/*`, {\n cwd,\n ignore,\n onlyFiles: true,\n dot: false,\n });\n for (const f of found) if (keepByExt(f)) walked.add(f);\n continue;\n }\n\n // Nothing on disk. Decide whether this input was a *name* or a *pattern*:\n // a name that does not exist is a mistake worth reporting, while a pattern\n // matching nothing is the caller's business (the command cores check for an\n // empty result set).\n if (!picomatch.scan(posixInput).isGlob) {\n missing.push(posixInput);\n continue;\n }\n\n const found = await fg(posixInput, {\n cwd,\n ignore,\n onlyFiles: true,\n dot: false,\n });\n for (const f of found) if (keepByExt(f)) walked.add(f);\n }\n\n if (missing.length > 0 && !opts.allowEmpty) {\n const names = missing.map((m) => `\"${m}\"`).join(\", \");\n throw new DocmetaError(\n missing.length === 1\n ? `File not found: ${names}.`\n : `Files not found: ${names}.`,\n );\n }\n\n // Gitignore runs last, over the extension-filtered walk only. A file the\n // user also named explicitly is excluded from the question rather than from\n // the answer, so it can neither be dropped nor inflate the skipped count.\n let gitignoreSkipped = 0;\n if (opts.respectGitignore !== false && walked.size > 0) {\n const candidates = [...walked].filter((f) => !named.has(f));\n const { ignored, available } = await gitIgnored(candidates, cwd);\n if (available) {\n for (const f of ignored) {\n if (walked.delete(f)) gitignoreSkipped += 1;\n }\n } else {\n opts.onGitignoreUnavailable?.();\n }\n }\n\n return {\n files: [...new Set([...named, ...walked])].sort(),\n gitignoreSkipped,\n };\n}\n\nexport interface NonEmptyParams {\n /** Files actually resolved. */\n files: string[];\n /** The positional inputs, stdin token already removed. */\n inputs: string[];\n /** Whether `-` was among the inputs; stdin is one input, so it is not empty. */\n usingStdin: boolean;\n allowEmpty?: boolean;\n exclude?: string[];\n exts?: string[];\n /** Candidates `.gitignore` removed, so an empty set says so rather than baffles. */\n gitignoreSkipped?: number;\n /** Past-tense verb for the message: \"validated\", \"read\", \"filled\". */\n action: string;\n}\n\n/**\n * Resolving zero files is an operational error, not a pass.\n *\n * Exit 0 means \"every file passed\"; with no files there is no verdict, so\n * reporting success turns a broken glob, a moved directory, or a too-broad\n * `--exclude` into a permanently green gate that checks nothing. Exit 2 (a\n * `DocmetaError`) is the documented code for \"docmeta could not produce a\n * verdict\", which is exactly this case.\n */\nexport function assertNonEmpty(p: NonEmptyParams): void {\n if (p.allowEmpty || p.usingStdin || p.files.length > 0) return;\n\n const tried = p.inputs.map((i) => `\"${i}\"`).join(\", \");\n const notes: string[] = [];\n // Name the filters, because \"no files matched\" is baffling when the pattern\n // plainly matches files on disk and an --ext or --exclude removed them.\n if (p.exts && p.exts.length > 0) {\n notes.push(`extensions: ${p.exts.join(\", \")}`);\n }\n if (p.exclude && p.exclude.length > 0) {\n notes.push(`excludes: ${p.exclude.map((e) => `\"${e}\"`).join(\", \")}`);\n }\n // The one filter the user never wrote down, so it is the one most worth\n // naming: a docs tree the repo happens to ignore looks like a broken glob.\n if (p.gitignoreSkipped && p.gitignoreSkipped > 0) {\n notes.push(\n `.gitignore skipped ${p.gitignoreSkipped} (pass --no-gitignore to check them)`,\n );\n }\n\n throw new DocmetaError(\n [\n `No files matched. Patterns tried: ${tried}.`,\n ...(notes.length > 0 ? [`Filters applied — ${notes.join(\"; \")}.`] : []),\n `Nothing was ${p.action}, so this is an error rather than a pass.`,\n `Pass --allow-empty (or set allowEmpty: true) if matching nothing is expected.`,\n ].join(\"\\n\"),\n );\n}\n","/**\n * Ask git which paths `.gitignore` covers.\n *\n * Delegated to `git check-ignore` rather than reimplemented. Gitignore is not a\n * flat pattern list: precedence stacks across nested `.gitignore` files,\n * directory-only patterns and leading-`/` anchoring change what a pattern means,\n * `**` differs from glob `**`, and `.git/info/exclude` and `core.excludesFile`\n * contribute rules that are not in the tree at all. The rule that settles it is\n * that a negation cannot re-include a file below an excluded directory — given\n * `tmp/` then `!keep.md`, git still ignores `docs/tmp/keep.md`. No translation\n * into picomatch patterns expresses that, and being subtly wrong here silently\n * changes which files get validated.\n *\n * One subprocess per repository the candidates live in, fed that repository's\n * candidates on stdin — one per run in the ordinary single-checkout case. Measured at\n * 5,000 candidates: 0.111 s with none ignored, 0.260 s with half ignored.\n */\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport { findGitRoot } from \"../../shared/git-root.js\";\n\nexport interface GitignoreAnswer {\n /** Ignored paths, spelled exactly as they were handed in. */\n ignored: Set<string>;\n /**\n * Whether git answered for at least one repository the candidates live in.\n * False means no candidate was inside a repository git could answer for —\n * no repository, no `git` on `PATH`, or git failed everywhere — in which\n * case **nothing** is filtered and `ignored` is empty.\n *\n * A run spanning several repositories where git answers for some and not\n * others is *available*: the answered roots are filtered, and a root git\n * could not answer for is treated like no repository at all, so its\n * candidates are kept. A partial answer is never reported as none, because\n * the notice for `false` says \"no files were skipped\" and that would be a\n * lie about the roots that did answer.\n */\n available: boolean;\n}\n\n/** Said once, on stderr, when a run explicitly asked for filtering it did not get. */\nexport const GITIGNORE_UNAVAILABLE =\n \".gitignore filtering was requested but git could not answer here (no repository, or no git on PATH); no files were skipped.\";\n\nconst unavailable = (): GitignoreAnswer => ({\n ignored: new Set(),\n available: false,\n});\n\n/**\n * `paths` are relative to `cwd`, posix-style, spelled however the caller\n * spelled them; the answer uses the same spelling.\n *\n * Candidates may lie in more than one repository (proposal 0037): a config in\n * one checkout whose `paths:` reach into another, or a nested checkout under\n * the run's own root. `git check-ignore` refuses a path outside the repository\n * it runs in with exit 128, and it must not be allowed to refuse for the whole\n * batch — one cross-root candidate then switched filtering off for every file\n * in the run, silently, while the notice blamed a missing repository. So the\n * candidates are grouped by the repository that contains them and git is asked\n * once per root, from that root, with paths relative to it. A candidate inside\n * no repository is kept: there is no `.gitignore` that could cover it.\n *\n * `available` is false only when git failed to answer for a repository that\n * exists, or when no candidate was in any repository at all — the two cases\n * where filtering was asked for and nothing could be filtered.\n */\nexport async function gitIgnored(\n paths: string[],\n cwd: string,\n): Promise<GitignoreAnswer> {\n // Nothing to ask about. Skipping the subprocess also keeps a run over\n // explicitly named files alone from reporting git as unavailable.\n if (paths.length === 0) {\n return { ignored: new Set<string>(), available: true };\n }\n\n // Group by containing repository. The root walk is one `existsSync` per\n // directory level and memoized per directory, so a 5,000-file corpus in a\n // handful of directories costs a handful of walks.\n const rootOf = new Map<string, string | null>();\n const byRoot = new Map<string, { rel: string; spelled: string }[]>();\n let inSomeRepo = false;\n for (const spelled of paths) {\n const abs = resolve(cwd, spelled);\n const dir = dirname(abs);\n let root = rootOf.get(dir);\n if (root === undefined) {\n root = findGitRoot(dir);\n rootOf.set(dir, root);\n }\n if (root === null) continue;\n inSomeRepo = true;\n const rel = relative(root, abs).split(sep).join(\"/\");\n const bucket = byRoot.get(root);\n if (bucket) bucket.push({ rel, spelled });\n else byRoot.set(root, [{ rel, spelled }]);\n }\n if (!inSomeRepo) return unavailable();\n\n const ignored = new Set<string>();\n let answered = 0;\n for (const [root, bucket] of byRoot) {\n const answer = await checkIgnore(\n bucket.map((b) => b.rel),\n root,\n );\n // A root git cannot answer for (a broken `.git`, say) is treated like no\n // repository: its candidates are kept. See `GitignoreAnswer.available`.\n if (!answer.available) continue;\n answered += 1;\n for (const b of bucket) {\n if (answer.ignored.has(b.rel)) ignored.add(b.spelled);\n }\n }\n return answered > 0 ? { ignored, available: true } : unavailable();\n}\n\n/** One `git check-ignore` run, from `cwd`, over paths relative to it. */\nfunction checkIgnore(paths: string[], cwd: string): Promise<GitignoreAnswer> {\n return new Promise((settle) => {\n let done = false;\n const finish = (answer: GitignoreAnswer): void => {\n if (done) return;\n done = true;\n settle(answer);\n };\n\n // Explicitly typed rather than relying on evolving-`let` inference, so\n // the stream handles below are checked rather than merely assumed.\n let child: ChildProcessWithoutNullStreams;\n try {\n // -z: NUL-delimited in *and* out. Newline delimiting would corrupt a\n // filename containing a newline, for no benefit.\n child = spawn(\"git\", [\"check-ignore\", \"--stdin\", \"-z\"], {\n cwd,\n windowsHide: true,\n });\n } catch {\n finish(unavailable());\n return;\n }\n\n let out = \"\";\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n out += chunk;\n });\n // Drain stderr so a chatty git cannot fill the pipe and stall.\n child.stderr.resume();\n // No binary on PATH lands here rather than throwing from spawn().\n child.on(\"error\", () => {\n finish(unavailable());\n });\n // A dead child makes the pipe write fail; that is reported by 'error'/'close'.\n child.stdin.on(\"error\", () => {});\n\n child.on(\"close\", (code) => {\n // Exit 1 means *nothing matched* — a successful answer meaning \"keep\n // everything\", not a failure. Treating it as one would make the filter\n // silently no-op on every clean repo, which is the whole common case.\n // Only a real failure (128 outside a repo, or a signal, which is null)\n // means git could not answer.\n if (code !== 0 && code !== 1) {\n finish(unavailable());\n return;\n }\n finish({\n ignored: new Set(out.split(\"\\0\").filter((p) => p !== \"\")),\n available: true,\n });\n });\n\n child.stdin.end(paths.join(\"\\0\"));\n });\n}\n","/**\n * The project boundary: the nearest directory at or above `cwd` holding a\n * `.git` entry. A file or a directory, since a worktree's `.git` is a file.\n *\n * Two callers need it for opposite reasons and only one of them wants a\n * chain. Config discovery walks the chain and stops here. The SARIF reporter\n * needs the root itself, and needs \"there is no repository\" to be\n * distinguishable from \"the repository root is where you are standing\" — a\n * one-element chain conflates the two, and getting that wrong means emitting\n * paths GitHub silently drops.\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nexport function findGitRoot(cwd: string): string | null {\n let dir = resolve(cwd);\n for (;;) {\n if (existsSync(join(dir, \".git\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * The directories a discovery walk may look in, nearest first.\n *\n * The walk stops at the project boundary `findGitRoot` reports, which is\n * included in the search. Only that one call touches the filesystem; the chain\n * itself is then assembled from path strings.\n *\n * With **no** boundary anywhere above cwd, only cwd is considered. A\n * project-scoped config has no meaning without a project, and walking on would\n * let a stray config file in a home or temp directory silently govern\n * unrelated runs — including this repo's own tests, which work in OS temp\n * directories under the user's home.\n */\nexport function searchPath(cwd: string): string[] {\n const start = resolve(cwd);\n const root = findGitRoot(start);\n if (root === null) return [start];\n const chain: string[] = [];\n let dir = start;\n for (;;) {\n chain.push(dir);\n if (dir === root) return chain;\n const parent = dirname(dir);\n // `root` is an ancestor of `start` by construction, so this is unreachable\n // — but a filesystem race (the boundary removed mid-walk) must not loop.\n if (parent === dir) return chain;\n dir = parent;\n }\n}\n","/**\n * The derived metadata channel: values computed from git history, CODEOWNERS\n * and the review record on GitHub or GitLab rather than written by hand.\n *\n * A derived value never merges into what the schema sees. `manni meta derive`\n * stamps the managed fields (`derive.fields` in the config) into the\n * document, and `validate` reports a managed field whose asserted value\n * differs from the derived one as a finding. This module holds the shared\n * vocabulary — which fields can be derived, from which sources — and the two\n * pure steps every source feeds: comparing an asserted value with a derived\n * one, and turning the stale comparisons into findings.\n */\nimport type { ExtractedMetadata, FieldError } from \"../../types.js\";\nimport { escapePointerSegment } from \"../../extractors/pointer.js\";\nimport { toJsonText } from \"../json-text.js\";\n\n/** The six built-in fields, in the order messages list them. */\nexport const DERIVABLE_FIELDS = [\n \"created\",\n \"last-updated\",\n \"authors\",\n \"owner\",\n \"reviewed-by\",\n \"last-reviewed\",\n] as const;\n\nexport type BuiltinDerivableField = (typeof DERIVABLE_FIELDS)[number];\n\n/**\n * A managed field name: one of the six built-ins, or a key with an entry in\n * `derive.commands`. The config parser guarantees one or the other.\n */\nexport type DerivableField = string;\n\nexport function isBuiltinField(x: string): x is BuiltinDerivableField {\n return (DERIVABLE_FIELDS as readonly string[]).includes(x);\n}\n\n/** Every source `derive.sources` may name; absent means all five. */\nexport const DERIVE_SOURCES = [\"git\", \"codeowners\", \"github\", \"gitlab\", \"command\"] as const;\n\nexport type DeriveSource = (typeof DERIVE_SOURCES)[number];\n\n/**\n * One configured command, as `derive.commands` reads after parsing: the argv\n * to run, the program first, and how long to wait for it.\n */\nexport interface DeriveCommand {\n run: readonly string[];\n timeoutMs: number;\n}\n\nexport function isDeriveSource(x: string): x is DeriveSource {\n return (DERIVE_SOURCES as readonly string[]).includes(x);\n}\n\n/**\n * Every field a run can derive: the built-ins in the order messages list\n * them, then the command keys sorted, so the list is the same whatever\n * order the config wrote them in.\n */\nexport function derivableFields(\n commands?: Readonly<Record<string, DeriveCommand>>,\n): DerivableField[] {\n return [...DERIVABLE_FIELDS, ...Object.keys(commands ?? {}).sort()];\n}\n\n/**\n * One fact a source produced, with where it came from. `evidence` is the\n * short human-readable trail a finding quotes — a commit, a CODEOWNERS line,\n * a pull request — so the reader can check the claim without re-running.\n */\nexport interface DerivedValue {\n value: unknown;\n source: DeriveSource;\n evidence: string;\n}\n\n/**\n * Everything derived for one document. A `null` field means a source was\n * consulted and had no fact to offer (a file with no commits yet, a path no\n * CODEOWNERS rule matches); an absent field means no source answered for it.\n */\nexport interface DerivedRecord {\n file: string;\n fields: Record<DerivableField, DerivedValue | null>;\n}\n\n/** Whether a source can answer at all; `reason` names the fix when not. */\nexport interface SourceStatus {\n available: boolean;\n reason?: string;\n}\n\n/** Which host the origin remote points at, and what to call the project there. */\nexport interface RemoteIdentity {\n kind: \"github\" | \"gitlab\";\n host: string;\n /** `owner/repo` on GitHub; the full namespace path on GitLab. */\n project: string;\n}\n\n/** One `APPROVED` review, the latest per reviewer. */\nexport interface Approval {\n login: string;\n /** ISO-8601. */\n submittedAt: string;\n}\n\n/** The merged PR/MR that carried a commit. Immutable once merged, so cacheable. */\nexport interface MergedChange {\n /** The PR number or MR iid. */\n id: number;\n /** ISO-8601. */\n mergedAt: string;\n /** Approvals only, deduplicated by login; the built-in clients order them oldest first. */\n approvals: Approval[];\n}\n\n/**\n * The review half of the derive context: the merged change behind a commit and\n * who approved it. Reached through `gh` / `glab`, never an HTTP client — see\n * `reviews.ts`.\n */\nexport interface ReviewClient {\n detect(): Promise<RemoteIdentity | null>;\n /** Binary on PATH and authenticated for the host; `reason` names the fix. */\n status(): Promise<SourceStatus>;\n /** The merged PR/MR that contains the commit, or null (open, none, or unknown). */\n mergedChangeFor(sha: string): Promise<MergedChange | null>;\n}\n\n/** One document as the sources see it. */\nexport interface DeriveInput {\n label: string;\n absPath: string;\n content: string;\n extracted: ExtractedMetadata;\n}\n\n/** What a derive run holds constant across every document it visits. */\nexport interface DeriveContext {\n /** The run's working directory, the fallback when no config directory applies. */\n cwd: string;\n /** Directory the input labels are relative to, as `resolveRunConfig` settled it. */\n base: string;\n configDir?: string;\n sources: readonly DeriveSource[];\n fields: readonly DerivableField[];\n /** CODEOWNERS path, when the config names one; resolved from `configDir`. */\n codeowners?: string;\n /** The `command` source's table, by the field each command derives; absent means none configured. */\n commands?: Readonly<Record<string, DeriveCommand>>;\n cache: boolean;\n now: () => Date;\n /** The review client for every repository in the run; the built-in `gh` / `glab` clients when absent. */\n reviews?: ReviewClient;\n}\n\n/**\n * How an asserted value stands against the derived one.\n *\n * - `current` — they agree.\n * - `stale` — the document says one thing and a source says another.\n * - `unset` — the document says nothing and a source has a value.\n * - `unknown` — no source could answer, so nothing is claimed either way.\n */\nexport type DerivedStatus = \"current\" | \"stale\" | \"unset\" | \"unknown\";\n\nexport interface DerivedField {\n field: DerivableField;\n /** What the document carries; absent when it carries nothing. */\n asserted?: unknown;\n /**\n * What the sources say. `null` when they could not answer, which is exactly\n * when `status` is `unknown`.\n */\n derived: unknown;\n source?: DeriveSource;\n evidence?: string;\n status: DerivedStatus;\n /** Whether `derive` wrote the value into the document. */\n written: boolean;\n}\n\n/**\n * The `schema` ref a stale-field finding carries, and so its baseline and\n * rule identity: `derived:stale/derived`. Shaped like `check:<name>` and\n * `external:owned` so `classifyRef` passes it through as a built-in id rather\n * than resolving it as a cwd-relative file path, and reserved in the registry\n * for the same reason those are.\n */\nexport const DERIVED_STALE_SCHEMA = \"derived:stale\";\n\n/** The `keyword` every derived finding carries: no Ajv keyword produced it. */\nexport const DERIVED_KEYWORD = \"derived\";\n\n/**\n * Compare what a document asserts with what a source derived.\n *\n * Pure. Lists compare as sets — order-insensitive, members deep-equal — so a\n * reordered `authors:` is not a stale one. A missing or `null` derived value\n * means the sources could not answer, which is `unknown` rather than a\n * verdict either way. `written` is always false here; only `derive` writes.\n */\nexport function compareDerived(\n field: DerivableField,\n asserted: unknown,\n derived: DerivedValue | null | undefined,\n): DerivedField {\n const base = {\n field,\n ...(asserted !== undefined ? { asserted } : {}),\n };\n if (derived == null) {\n return { ...base, derived: null, status: \"unknown\", written: false };\n }\n const status: DerivedStatus =\n asserted === undefined\n ? \"unset\"\n : deepEqual(asserted, derived.value)\n ? \"current\"\n : \"stale\";\n return {\n ...base,\n derived: derived.value,\n source: derived.source,\n evidence: derived.evidence,\n status,\n written: false,\n };\n}\n\n/**\n * The findings `validate` files for a document's managed fields: one per\n * field that is `stale` or `unset`. Current and unknown fields file nothing.\n *\n * `lineFor` is the document's own pointer lookup, so a finding lands on the\n * line the asserted key sits on; an unset field has no line.\n */\nexport function staleFindings(\n fields: readonly DerivedField[],\n lineFor: (pointer: string) => number | undefined,\n): FieldError[] {\n const findings: FieldError[] = [];\n for (const f of fields) {\n if (f.status !== \"stale\" && f.status !== \"unset\") continue;\n const instancePath = `/${escapePointerSegment(f.field)}`;\n const line = lineFor(instancePath);\n const says = `${f.source ?? \"a source\"} says ${fmt(f.derived)}`;\n const trail = f.evidence === undefined ? \"\" : ` (${f.evidence})`;\n const head =\n f.status === \"stale\"\n ? `${f.field} says ${fmt(f.asserted)}`\n : `${f.field} is not set`;\n findings.push({\n schema: DERIVED_STALE_SCHEMA,\n keyword: DERIVED_KEYWORD,\n subject: f.field,\n instancePath,\n message: `${head}; ${says}${trail} — run manni meta derive`,\n ...(line !== undefined ? { line } : {}),\n });\n }\n return findings;\n}\n\n/** Strings bare, everything else as compact JSON. */\nfunction fmt(value: unknown): string {\n if (typeof value === \"string\") return value;\n return toJsonText(value) ?? String(value);\n}\n\n/**\n * Structural equality with lists as multisets.\n *\n * Objects compare key by key; lists compare by matching each member of one\n * against an unused member of the other, so `[a, b]` equals `[b, a]` but not\n * `[a, a]`. Leaves compare through their JSON text, which is the projection\n * every reporter and the query table already use, so a `Date` and its ISO\n * string agree here exactly when they agree there.\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (isList(a) || isList(b)) {\n if (!isList(a) || !isList(b) || a.length !== b.length) return false;\n const unused = [...b];\n for (const x of a) {\n const i = unused.findIndex((y) => deepEqual(x, y));\n if (i === -1) return false;\n unused.splice(i, 1);\n }\n return true;\n }\n if (isPlainObject(a) || isPlainObject(b)) {\n if (!isPlainObject(a) || !isPlainObject(b)) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n return keys.every(\n (k) => Object.hasOwn(b, k) && deepEqual(a[k], b[k]),\n );\n }\n return toJsonText(a) === toJsonText(b);\n}\n\n/** `Array.isArray` narrows `unknown` to `any[]`; this keeps the members unknown. */\nfunction isList(v: unknown): v is unknown[] {\n return Array.isArray(v);\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return (\n typeof v === \"object\" && v !== null && !isList(v) && !(v instanceof Date)\n );\n}\n","/**\n * Optional lightweight YAML config: the `meta:` section of the family file\n * (`manni.config.yaml`), or the whole of a pre-family `docmeta.config.yaml`.\n * Supplies the default schema set and optional per-glob or per-collection\n * overrides, so CI can run a bare `manni meta validate`. Which documents exist\n * is not here: proposal 0041 moved that to the family-level `collections:`.\n *\n * Finding the file is shared with every tool under the umbrella\n * (src/shared/config-file.ts); what the section may contain is decided here.\n */\nimport { resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { DocmetaError } from \"../types.js\";\nimport {\n findConfigFile,\n readConfigFile,\n type ConfigFileOptions,\n} from \"../../shared/config-file.js\";\nimport { findGitRoot } from \"../../shared/git-root.js\";\nimport {\n selectCollections,\n type CollectionConfig,\n} from \"../../shared/collections.js\";\nimport { FILE_SCHEMA_KEY, rebaseConfigSchemaRefs } from \"./resolve-schema.js\";\nimport { classifyRef } from \"./schema-registry.js\";\nimport { INTEGRITY_SHAPE, isIntegrity } from \"./integrity.js\";\nimport { parseElementPath } from \"../extractors/element-key.js\";\nimport {\n DERIVABLE_FIELDS,\n DERIVE_SOURCES,\n isBuiltinField,\n isDeriveSource,\n type BuiltinDerivableField,\n type DerivableField,\n type DeriveSource,\n} from \"./derive/types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\nexport interface SchemaOverride {\n /**\n * The glob, or globs, this override governs. A file matches when **any** of\n * them matches, so a list groups path shapes that brace expansion cannot\n * express as one pattern: a per-skill `SKILL.md` one directory down and a\n * flat `.claude/agents` file share a schema set but have no common stem.\n *\n * Kept as written rather than normalized to a list, because a programmatic\n * caller may hand `runValidate` a config object it built itself, and that\n * caller's bare string must keep working. Read it through `overrideGlobs`\n * rather than directly — that is the one place the two shapes collapse.\n *\n * Optional since proposal 0041: an entry carries **exactly one** of `files`\n * or `collection`.\n */\n files?: string | string[];\n schemas: string[];\n /**\n * The collection this override governs (proposal 0041), in place of globs of\n * its own: it matches the members of the named collection, which are decided\n * once, at the top level of the family file, for every tool. Must name a\n * collection `collections:` defines — checked by `loadConfig`, which is the\n * first place both halves of the file are known.\n *\n * This is what `overrides[].name` was for under 0027, inverted: a collection\n * is the thing that has a name, and an override points at it.\n */\n collection?: string;\n /**\n * Extra element paths for files matching `files`. Unlike `schemas`, which the\n * first matching override *replaces* because a schema set is a complete\n * statement, these accumulate: every matching override contributes, on top of\n * the top-level `elements:`. A list of extra places to look is additive by\n * nature, and an override that silently dropped the repo-wide ones would be a\n * trap.\n */\n elements?: string[];\n}\n\n/**\n * A `schemas:` entry in its long form: a reference plus where it came from and\n * what it must hash to.\n *\n * Written by `manni meta schemas vendor`, which downloads a remote schema into the\n * repository and records both. `source` keeps the provenance the URL used to\n * carry, so a re-vendor knows where to look and an error can say what to\n * re-download; `integrity` makes an edited or corrupted copy a loud failure\n * rather than a silently changed contract.\n */\nexport interface SchemaRefEntry {\n /** What is loaded: a built-in id, a local `.json` path, or a URL. */\n ref: string;\n /** Where `ref` was vendored from — a URL, or a path for a local copy. */\n source?: string;\n /** `sha256-<64 hex>` over the bytes of `ref`. Local files only. */\n integrity?: string;\n}\n\n/**\n * One `schemas:` entry. A bare string is the original form and is unchanged by\n * 0008; the mapping form adds provenance and a pin.\n */\nexport type SchemaEntry = string | SchemaRefEntry;\n\n/** The keys a `schemas:` mapping entry may carry. */\nconst SCHEMA_ENTRY_KEYS = [\"ref\", \"source\", \"integrity\"] as const;\n\n/**\n * What a **document** is allowed to name in its own `$schema`.\n *\n * - `any` — the default, and today's behavior: a built-in id, a file in the\n * repository, or a URL. `schemaTrust.hosts` narrows the URL case.\n * - `local` — a built-in id or a file in the repository; a URL is refused.\n * - `none` — the document's `$schema` is ignored and config decides, with a\n * notice on stderr naming the file whose key was dropped.\n */\nexport type DocumentRefTrust = \"any\" | \"local\" | \"none\";\n\n/** The values `schemaTrust.documentRefs` accepts, in the order documented. */\nexport const DOCUMENT_REF_TRUST = [\"any\", \"local\", \"none\"] as const;\n\n/**\n * How far a **document** is trusted to choose the contract it is judged by.\n *\n * Nothing here touches a ref an *operator* supplied: `schemas:`,\n * `overrides[].schemas`, and `-s/--schema` are never filtered, in any mode. A\n * person who can edit the config or pass a flag is not the attacker this key\n * has in mind — a pull request against a public docs repo is.\n */\nexport interface SchemaTrustConfig {\n /** Defaults to `any`, which is exactly what docmeta has always done. */\n documentRefs?: DocumentRefTrust;\n /**\n * Hosts a document-supplied URL may name. Consulted **only** under\n * `documentRefs: any`; absent means any host, as before.\n *\n * A convenience for pointing at one known publisher, not a security\n * boundary: `fetch` follows redirects, so an allowlisted host that answers\n * `302` sends the fetch anywhere it likes. A repo that genuinely distrusts\n * its contributors wants `documentRefs: local`.\n */\n hosts?: string[];\n}\n\n/** The keys a `schemaTrust:` mapping may carry. */\nconst SCHEMA_TRUST_KEYS = [\"documentRefs\", \"hosts\"] as const;\n\n/** The keys a `schemaCache:` mapping may carry. */\nconst SCHEMA_CACHE_KEYS = [\"ttlHours\"] as const;\n\n/**\n * Validate an `elements:` list, rejecting a path that cannot produce a key.\n *\n * Parsed here rather than at extraction so a typo is an error when the config\n * loads, naming the file and the key. Left to extraction it would be a silent\n * no-op: the path would match nothing, no key would appear, and the check the\n * author thought they had configured would simply never run.\n */\nfunction asElementPaths(\n value: unknown,\n where: string,\n source: string,\n): string[] {\n const list = asStringList(value, where, source);\n for (const path of list) {\n try {\n parseElementPath(path);\n } catch (err) {\n throw new DocmetaError(`${source}: ${where} — ${errorMessage(err)}`);\n }\n }\n return list;\n}\n\n/** The keys one `overrides:` entry may carry. */\nconst OVERRIDE_KEYS = [\"collection\", \"files\", \"schemas\", \"elements\"] as const;\n\n/**\n * One named corpus check (proposal 0026): SQL run over the `docs` projection\n * by `validate`, whose result rows are findings under the id `check:<name>`.\n */\nexport interface CheckConfig {\n /** The check's name — the durable half of its findings' identity. */\n name: string;\n /** One SQL statement whose rows follow the finding column convention. */\n query: string;\n}\n\n/** The keys one `checks:` entry may carry. */\nconst CHECK_KEYS = [\"name\", \"query\"] as const;\n\n/**\n * One `derive.commands` entry: a program to run for a field's value, as the\n * config spells it. `run` is the argv, the program first; `timeout` is in\n * seconds. The derive context carries the parsed form, `DeriveCommand`.\n */\nexport interface DeriveCommandConfig {\n run: string[];\n timeout?: number;\n}\n\n/**\n * The derived channel: managed fields `manni meta derive` stamps from git\n * history, CODEOWNERS, the review record on GitHub or GitLab, or a configured\n * command, and `validate` checks for drift.\n */\nexport interface DeriveConfig {\n /**\n * The managed fields. Each is one of `DERIVABLE_FIELDS` or a key of\n * `commands`, never `$schema`, and never a key a manifest owns: a value\n * with two authorities has none.\n */\n fields: DerivableField[];\n /** Which sources to consult; absent means all of `DERIVE_SOURCES`. */\n sources?: DeriveSource[];\n /**\n * CODEOWNERS path, relative to the config file's directory, when it is not\n * in one of the places the codeowners source looks by itself. Checked for\n * existence at run time, not here.\n */\n codeowners?: string;\n /**\n * The `command` source's table, by the field each command derives. A key\n * is never a built-in field, `$schema`, or a key a manifest owns.\n */\n commands?: Record<string, DeriveCommandConfig>;\n}\n\n/** The keys a `derive:` mapping may carry. */\nconst DERIVE_KEYS = [\"fields\", \"sources\", \"codeowners\", \"commands\"] as const;\n\n/** The keys one `derive.commands` entry may carry. */\nconst DERIVE_COMMAND_KEYS = [\"run\", \"timeout\"] as const;\n\n/** Which built-in source claims each built-in field, as a refusal names it. */\nconst BUILTIN_CLAIMED_BY: Readonly<Record<BuiltinDerivableField, string>> = {\n created: \"git\",\n \"last-updated\": \"git\",\n authors: \"git\",\n owner: \"codeowners\",\n \"reviewed-by\": \"GitHub or GitLab\",\n \"last-reviewed\": \"GitHub or GitLab\",\n};\n\n/**\n * The `derived` table's own columns, which a command key may not be spelled\n * like: the view is `_path`, the derivable fields, then `_sources`.\n */\nconst DERIVED_TABLE_RESERVED: ReadonlySet<string> = new Set([\"_path\", \"_sources\"]);\n\n/** The tail every not-derivable message ends with. */\nconst DERIVABLE_LIST = `Derivable fields: ${DERIVABLE_FIELDS.join(\", \")}, or any key with an entry in derive.commands.`;\n\n/**\n * The grammar a check's name must satisfy: one built-in id *segment*.\n *\n * Not taste. The finding's `schema` field carries `check:<name>` and the\n * baseline canonicalizes that field through `classifyRef` before\n * fingerprinting — so the name must make `check:<name>` classify as a builtin\n * id (`BUILTIN_ID`, schema-registry.ts). A name with a space, a slash, or a\n * `.json` tail would classify as a **file path** and be resolved cwd-relative:\n * a fingerprint that changes with the directory you run from, the exact bug\n * `canonicalSchemaRef` exists to prevent. Enforced at parse time so the\n * failure names the config line, not a baseline mismatch three runs later.\n *\n * Exported for `checkSchemaRef`, which asserts the same grammar for\n * programmatic `CheckConfig` callers that never pass through this parser.\n */\nexport const CHECK_NAME = /^[a-z0-9][a-z0-9._-]*$/;\n\n/**\n * Check names a config may not claim, each with why.\n *\n * `query` is reserved: `manni meta query --check` files its ad-hoc findings as\n * the pseudo-check `check:query`, and a configured check with that name would\n * mint the identical rule id — two different rules sharing one baseline\n * identity. `derive` is reserved beside it: `manni meta derive` is a verb of\n * its own with its own finding identity (`derived:stale`), and a check\n * reporting as `check:derive` would read as that verb's findings.\n */\nconst RESERVED_CHECK_NAMES = new Map<string, string>([\n [\n \"query\",\n \"`manni meta query --check` files its ad-hoc findings as check:query, and a configured check with the same name would share their identity\",\n ],\n [\n \"derive\",\n \"`manni meta derive` is a verb of its own, and a check reporting as check:derive would read as its findings\",\n ],\n]);\n\n/** The keys a `fill:` mapping may carry. */\nconst FILL_KEYS = [\n \"provider\",\n \"model\",\n \"confidenceThreshold\",\n \"maxTurns\",\n \"chunkChars\",\n \"concurrency\",\n] as const;\n\n/**\n * The keys the config's top level may carry.\n *\n * Adding a key to `DocmetaConfig` means adding it here too, or a config using\n * it is rejected. That coupling is the point: the alternative is the silence\n * this list exists to end.\n */\nconst CONFIG_KEYS = [\n \"schemas\",\n \"overrides\",\n \"checks\",\n \"derive\",\n \"baseline\",\n \"allowEmpty\",\n \"respectGitignore\",\n \"offline\",\n \"schemaCache\",\n \"schemaTrust\",\n \"fill\",\n \"elements\",\n] as const;\n\n/**\n * Reject any key outside `allowed`, naming what was supported.\n *\n * One helper so every level of the config reports a typo the same way. A key\n * the parser does not recognize is dropped in silence otherwise, which is the\n * failure this whole class of check exists to prevent: a misspelled\n * `schemaTust:` leaves a repository that reads as guarded and is not, and a\n * misspelled `intergrity:` leaves a schema that reads as pinned and is not.\n * Neither produces a diagnostic anywhere, at any verbosity.\n *\n * `where` names the mapping as the user would recognize it — `\"schemaTrust\"`,\n * `schemas[0]`, or `the top level`.\n */\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw new DocmetaError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\n/** Defaults for the `fill` command; every key is overridable by a CLI flag. */\nexport interface FillConfig {\n provider?: string;\n model?: string;\n /** Minimum self-reported confidence to write a value (0-1). */\n confidenceThreshold?: number;\n /** Stop after this many inference calls. Counts calls, not files. */\n maxTurns?: number;\n /** Characters of document per call. Default 12000. */\n chunkChars?: number;\n concurrency?: number;\n}\n\n/** Settings for the cross-run cache of schemas fetched over `http(s)`. */\nexport interface SchemaCacheConfig {\n /**\n * Hours a cached schema is served before it is re-fetched. `0` disables the\n * cache entirely, in both directions.\n */\n ttlHours?: number;\n}\n\n/**\n * Upper bound on `schemaCache.ttlHours` — one year.\n *\n * Not tidiness: freshness compares elapsed time against `ttlHours * 3_600_000`,\n * and a finite-but-enormous value overflows that product to `Infinity`, so no\n * entry is ever older than the limit and the cache silently stops expiring.\n * `Number.isFinite` alone does not catch it, because `1e308` is finite.\n */\nconst MAX_TTL_HOURS = 8760;\n\nexport interface DocmetaConfig {\n /**\n * The default schema set. Each entry is either a reference string or a\n * `{ ref, source?, integrity? }` mapping — see `SchemaEntry`.\n */\n schemas?: SchemaEntry[];\n overrides?: SchemaOverride[];\n /**\n * Named corpus checks `validate` runs after the per-file schemas, when the\n * run's file set is the config-resolved corpus. See `CheckConfig`.\n */\n checks?: CheckConfig[];\n /**\n * The managed fields `derive` stamps and `validate` checks for drift. See\n * `DeriveConfig`.\n */\n derive?: DeriveConfig;\n /**\n * Element paths to lift in addition to each format's convention. See\n * `parseElementPath` for the syntax.\n */\n elements?: string[];\n fill?: FillConfig;\n /**\n * Path to a validation baseline, relative to **this config file**. Setting it\n * implies `--baseline` on every run; `--no-baseline` suppresses it for one.\n */\n baseline?: string;\n /**\n * Treat an input set that resolves to zero files as success rather than an\n * operational error. Off by default: a glob that stops matching would\n * otherwise leave a permanently green gate that checks nothing.\n */\n allowEmpty?: boolean;\n /**\n * Skip files `.gitignore` covers when expanding directories and globs. On by\n * default; set false to check generated or vendored documents the repo does\n * not track. Setting it **true** explicitly also asks to be told when git\n * cannot answer — see `GITIGNORE_UNAVAILABLE`.\n */\n respectGitignore?: boolean;\n /** Defaults for the cross-run schema cache. See `SchemaCacheConfig`. */\n schemaCache?: SchemaCacheConfig;\n /**\n * Never fetch a remote schema. A URL reference resolves from the schema\n * cache; an uncached one is an operational error naming the URL. Built-in and\n * local-file references are unaffected — neither touches the network.\n */\n offline?: boolean;\n /**\n * How far a document's own `$schema` is trusted. Absent means `any` — every\n * setup that exists today, unchanged. See `SchemaTrustConfig`.\n */\n schemaTrust?: SchemaTrustConfig;\n}\n\n/** The metadata tool's key in the family config file. */\nexport const META_SECTION = \"meta\";\n\n/**\n * The tool's own filenames from before the family file. Still discovered,\n * with a deprecation warning; their whole document is the `meta:` section.\n */\nexport const LEGACY_CONFIG_NAMES: readonly string[] = [\n \"docmeta.config.yaml\",\n \"docmeta.config.yml\",\n];\n\nconst CONFIG_FILE: ConfigFileOptions = {\n section: META_SECTION,\n legacyNames: LEGACY_CONFIG_NAMES,\n toError: (message) => new DocmetaError(message),\n};\n\nfunction asStringList(value: unknown, field: string, source: string): string[] {\n if (!Array.isArray(value) || value.some((v) => typeof v !== \"string\")) {\n throw new DocmetaError(\n `${source}: \"${field}\" must be a list of strings.`,\n );\n }\n return value as string[];\n}\n\n/**\n * Parse `overrides[].files`, which accepts a single glob or a list of them.\n *\n * Deliberately not `asStringList`: that helper rejects a bare string, and the\n * single form is what every existing config and every doc example is written\n * in. The shape is preserved rather than normalized — see `SchemaOverride.files`\n * for why — so this validates and returns, it does not convert.\n *\n * The refusals are the ones a silently-matching-nothing rule would otherwise\n * cause: an empty list, and a blank glob in either shape. Both read as\n * configured and are not, which is the same false green the neighbouring\n * \"sets neither schemas nor elements\" check exists to end.\n */\nfunction asFileGlobs(\n value: unknown,\n where: string,\n source: string,\n): string | string[] {\n if (typeof value === \"string\") {\n if (value.trim() === \"\") {\n throw new DocmetaError(`${source}: ${where} must be a non-empty glob string.`);\n }\n return value;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n throw new DocmetaError(\n `${source}: ${where} is an empty list, so it matches nothing and the override has no effect.`,\n );\n }\n // Indexed, because \"one of these six globs is blank\" is not actionable.\n value.forEach((glob, j) => {\n if (typeof glob !== \"string\" || glob.trim() === \"\") {\n throw new DocmetaError(\n `${source}: ${where}[${j}] must be a non-empty glob string.`,\n );\n }\n });\n return value as string[];\n }\n throw new DocmetaError(\n `${source}: ${where} must be a glob string or a list of glob strings.`,\n );\n}\n\n/**\n * Parse the top-level `schemas:` list, which accepts both forms.\n *\n * Separate from `asStringList` on purpose. That helper also validates\n * `elements` and `overrides[].schemas`, and widening it in place would have\n * quietly widened those too — `elements: [{ref: …}]` would have started\n * parsing and then failed somewhere far from the config file.\n */\nfunction asSchemaList(\n value: unknown,\n field: string,\n source: string,\n): SchemaEntry[] {\n if (!Array.isArray(value)) {\n throw new DocmetaError(\n `${source}: \"${field}\" must be a list of schema references.`,\n );\n }\n return value.map((entry, i) => parseSchemaEntry(entry, `${field}[${i}]`, source));\n}\n\nfunction parseSchemaEntry(\n entry: unknown,\n where: string,\n source: string,\n): SchemaEntry {\n if (typeof entry === \"string\") return entry;\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new DocmetaError(\n `${source}: ${where} must be a schema reference string, or a mapping with \"ref\" (and optionally \"source\" and \"integrity\").`,\n );\n }\n const raw = entry as Record<string, unknown>;\n\n // A misspelled key is the failure worth catching here: `intergrity:` would\n // otherwise be dropped in silence, leaving a config that reads as pinned and\n // a schema that is not.\n rejectUnknownKeys(raw, SCHEMA_ENTRY_KEYS, where, source);\n\n if (typeof raw.ref !== \"string\" || raw.ref.trim() === \"\") {\n throw new DocmetaError(\n `${source}: ${where}.ref must be a non-empty schema reference string.`,\n );\n }\n const parsed: SchemaRefEntry = { ref: raw.ref };\n\n if (raw.source !== undefined) {\n if (typeof raw.source !== \"string\" || raw.source.trim() === \"\") {\n throw new DocmetaError(\n `${source}: ${where}.source must be a non-empty string naming where \"${raw.ref}\" was vendored from.`,\n );\n }\n parsed.source = raw.source;\n }\n\n if (raw.integrity !== undefined) {\n if (typeof raw.integrity !== \"string\" || !isIntegrity(raw.integrity)) {\n throw new DocmetaError(\n `${source}: ${where}.integrity must look like \"${INTEGRITY_SHAPE}\". Record one with \\`manni meta schemas vendor\\`.`,\n );\n }\n // A pin is checked against bytes on disk. On a built-in id there are no\n // bytes to read, and on a URL the copy that satisfies a run may come from\n // the schema cache, which stores the parsed schema rather than what the\n // server sent. Accepting either would record a pin nothing ever verifies —\n // a config that reads as pinned and is not.\n const kind = classifyRef(parsed.ref).kind;\n if (kind !== \"file\") {\n throw new DocmetaError(\n `${source}: ${where}.integrity applies to a vendored local file, but \"${parsed.ref}\" is a ${kind === \"url\" ? \"URL\" : \"built-in id\"}. Vendor it first with \\`manni meta schemas vendor\\`, or drop the pin.`,\n );\n }\n parsed.integrity = raw.integrity;\n }\n\n return parsed;\n}\n\n/**\n * Parse and validate config YAML text whose top level *is* the metadata\n * tool's config — a pre-family `docmeta.config.yaml`, or a section already\n * cut out of the family file.\n */\nexport function parseConfig(text: string, source: string): DocmetaConfig {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (err) {\n throw new DocmetaError(\n `${source}: invalid YAML: ${errorMessage(err)}`,\n );\n }\n return parseConfigValue(raw, source);\n}\n\n/**\n * Validate an already-parsed config value.\n *\n * `section` is the family-file key the value was cut from, when it was. The\n * validator labels fields relative to the document it is handed — `\"paths\"`,\n * `overrides[0]` — and the one place that knows those fields sit under\n * `meta:` is here, so the label gains the section on the way out rather than\n * every check learning to spell it.\n */\nexport function parseConfigValue(\n raw: unknown,\n source: string,\n section?: string,\n): DocmetaConfig {\n // Deliberately outside the `withSection` wrapper below, and outside both\n // branches' `try`. These four messages name `meta` in their own prose, so\n // `withSection` rewriting `\"paths\"` into `\"meta.paths\"` would produce\n // `\"meta.paths\" is no longer a meta key` — a sentence that contradicts\n // itself. They run for the unwrapped legacy form too, because a\n // `docmeta.config.yaml` that still says `paths:` is exactly the file whose\n // owner needs to be told where the key went (0041 § discovery).\n assertNoMovedKeys(raw, source);\n if (section === undefined) return parseConfigDocument(raw, source);\n try {\n return parseConfigDocument(raw, source);\n } catch (err) {\n if (err instanceof DocmetaError) {\n throw new DocmetaError(withSection(err.message, source, section));\n }\n throw err;\n }\n}\n\n/**\n * Every message the validator produces opens with `${source}: ` and then\n * names what is wrong in one of three shapes: a quoted key (`\"paths\"`,\n * `\"fill.model\"`), an unquoted path (`overrides[0].files`, `checks[1]`,\n * `elements — …`), or \"the top level\". Each gains the section.\n */\nfunction withSection(message: string, source: string, section: string): string {\n const head = `${source}: `;\n if (!message.startsWith(head)) return message;\n const rest = message.slice(head.length);\n if (rest.startsWith(\"the top level \")) {\n return `${head}\\`${section}:\\`${rest.slice(\"the top level\".length)}`;\n }\n if (rest.startsWith('\"')) return `${head}\"${section}.${rest.slice(1)}`;\n if (/^[a-zA-Z]+(\\[|\\.| —)/.test(rest)) return `${head}${section}.${rest}`;\n return message;\n}\n\n/** Where the configuration reference documents each moved key. */\nconst CONFIG_REF = \"https://hawkeyexl.github.io/manni/meta/reference/configuration/\";\n\n/**\n * The three keys proposal 0041 moved out of `meta:` and up to the family\n * level, with the sentence that says where each went.\n *\n * Refused rather than aliased: an alias is a permanent second surface for one\n * concept, and the whole point of `collections:` is that the document set is\n * declared **once** for every tool. This is the umbrella's rule for a moved\n * command, applied to a moved key.\n */\nconst MOVED_KEYS: readonly (readonly [string, string])[] = [\n [\n \"paths\",\n `Document sets are declared once for every tool, under a top-level collections: list. See ${CONFIG_REF}#collections`,\n ],\n [\n \"exclude\",\n `Document sets are declared once for every tool, under a top-level collections: list. See ${CONFIG_REF}#collections`,\n ],\n [\n \"sidecars\",\n `It is externalMetadata on a collection, under the top-level collections: list. See ${CONFIG_REF}#external-metadata`,\n ],\n];\n\n/**\n * Refuse a key 0041 moved, in either the wrapped or the unwrapped form.\n *\n * Reads the raw value as a mapping rather than going through\n * `parseConfigDocument`, because it must run *before* the unknown-key check\n * (which would report `paths` as a typo) and before `withSection` (which would\n * rewrite the key into the message's own subject).\n */\nfunction assertNoMovedKeys(raw: unknown, source: string): void {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return;\n const obj = raw as Record<string, unknown>;\n for (const [key, remedy] of MOVED_KEYS) {\n if (Object.hasOwn(obj, key)) {\n throw new DocmetaError(\n `${source}: \"${key}\" is no longer a meta key. ${remedy}`,\n );\n }\n }\n // `overrides[].name` went the same way, one level down: a collection is the\n // thing that has a name now (0041 supersedes 0027), and an override points\n // at one. Indexed, because a long `overrides:` list needs to say which entry.\n if (!Array.isArray(obj.overrides)) return;\n for (const [i, entry] of obj.overrides.entries()) {\n if (\n typeof entry === \"object\" &&\n entry !== null &&\n !Array.isArray(entry) &&\n Object.hasOwn(entry as Record<string, unknown>, \"name\")\n ) {\n throw new DocmetaError(\n `${source}: overrides[${i}] no longer carries \"name\". Define a collection with that name and point the override at it with collection:.`,\n );\n }\n }\n}\n\n/**\n * A message from a rule that runs outside `parseConfigValue`, with the prefix\n * that parser gives its own. A check in `loadConfig` needs both halves of the\n * family file, so it cannot sit inside the parser, but its message should\n * still name the key the way the reader wrote it: `meta.overrides[0] …`, as\n * the configuration reference documents. A legacy per-tool file has no\n * section, so its message is unchanged.\n */\nfunction inSection(message: string, source: string, section: string | undefined): string {\n return section === undefined ? message : withSection(message, source, section);\n}\n\n/**\n * Refuse an `overrides[].collection` naming a collection nobody declared.\n *\n * Checked here rather than in the section parser because it is the one\n * override rule that needs the *other* half of the family file: `collections:`\n * is a top-level key, parsed by the shared loader, and the section parser\n * never sees it. The message goes through `inSection`, so it reads\n * `meta.overrides[i].collection` like every error the section parser raises\n * (0041 § interface).\n */\nfunction assertOverrideCollections(\n config: DocmetaConfig,\n collections: readonly CollectionConfig[],\n source: string,\n section: string | undefined,\n): void {\n const names = new Set(collections.map((c) => c.name));\n for (const [i, ov] of (config.overrides ?? []).entries()) {\n if (ov.collection === undefined || names.has(ov.collection)) continue;\n const defined =\n collections.length === 0\n ? \"(none)\"\n : collections.map((c) => c.name).join(\", \");\n throw new DocmetaError(\n inSection(\n `${source}: overrides[${i}].collection names \"${ov.collection}\", which collections: does not define. Defined: ${defined}.`,\n source,\n section,\n ),\n );\n }\n}\n\n/** Where a key is owned: the manifest, and its place in the family file. */\nexport interface ManifestOwner {\n /** Index into `collections:`. */\n collection: number;\n /** The collection's name, for a message a person reads. */\n name: string;\n /** Index into that collection's `externalMetadata:`. */\n entry: number;\n /** The manifest's `file`, as the config wrote it. */\n file: string;\n}\n\n/**\n * The manifest that owns `key`, if any declared collection has one.\n *\n * Every declared collection counts, not only the ones a run selected: a\n * manifest's `keys:` list is a claim about the key everywhere, not about one\n * run. No manifest is read, because the config's own `keys:` list is the whole\n * claim.\n */\nexport function manifestOwning(\n key: string,\n collections: readonly CollectionConfig[],\n): ManifestOwner | undefined {\n for (const [c, collection] of collections.entries()) {\n for (const [e, manifest] of collection.externalMetadata.entries()) {\n if (manifest.keys.includes(key)) {\n return { collection: c, name: collection.name, entry: e, file: manifest.file };\n }\n }\n }\n return undefined;\n}\n\n/**\n * Refuse a `derive.fields` entry or a `derive.commands` key that some manifest\n * owns (proposals 0040 and 0042).\n *\n * A managed field has one authority, and a manifest key already has one. The\n * rule needs both halves of the family file, `meta.derive` and the top-level\n * `collections:`, so it runs here for the same reason\n * `assertOverrideCollections` does. `manni meta derive --fields` asks\n * `manifestOwning` directly, because that flag never passes through here.\n *\n * The message goes through `inSection`, as `assertOverrideCollections` does, so\n * it reads `meta.derive.fields[1]` the way the configuration reference says a\n * `meta:` error reads. Manifests exist only in a family file, so in practice\n * the section is always there.\n */\nfunction assertManagedFieldsUnowned(\n config: DocmetaConfig,\n collections: readonly CollectionConfig[],\n source: string,\n section: string | undefined,\n): void {\n const refuse = (path: string, owner: ManifestOwner): never => {\n const message = `${source}: ${path} is owned by collections[${owner.collection}].externalMetadata[${owner.entry}] (${owner.file}) — a managed field has one authority, and a manifest key already has one. Drop it from one side.`;\n throw new DocmetaError(\n inSection(message, source, section),\n );\n };\n // Commands first, as the parser reads them: a command's key is where a\n // field outside the built-ins is claimed, so that is the line to name.\n for (const key of Object.keys(config.derive?.commands ?? {})) {\n const owner = manifestOwning(key, collections);\n if (owner !== undefined) refuse(`derive.commands.${key}`, owner);\n }\n for (const [i, field] of (config.derive?.fields ?? []).entries()) {\n const owner = manifestOwning(field, collections);\n if (owner !== undefined) refuse(`derive.fields[${i}] \"${field}\"`, owner);\n }\n}\n\n/**\n * Parse `derive:`.\n *\n * A `derive:` must say something: `fields` to manage, or `sources` or\n * `codeowners` to shape the reads (`get --derived`, the `derived` table). A\n * bare `derive:` reads as configured and is not — the same silence\n * `rejectUnknownKeys` exists to end. `fields` defaults to none when the\n * other keys carry the block, so a repository without `gh` can narrow\n * `sources` for its reads without inventing a managed field.\n * A field is refused when it is not derivable (nothing could ever fill it)\n * or repeated. `$schema` falls out of the derivable list, so it never needs a\n * rule of its own there. A field a manifest owns is refused as well, by\n * `assertManagedFieldsUnowned` in `loadConfig`, because manifests are declared\n * on the top-level `collections:` this parser never sees.\n *\n * `commands` is parsed before `fields`, because a key of `commands` is what\n * makes a non-built-in field derivable. A command may only derive a field\n * no built-in source claims, and the refusal names the source that does.\n */\nfunction parseDerive(\n raw: unknown,\n source: string,\n): DeriveConfig {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new DocmetaError(\n `${source}: \"derive\" must be a mapping. Write it as \\`derive:\\` with \\`fields:\\` beneath it.`,\n );\n }\n const e = raw as Record<string, unknown>;\n rejectUnknownKeys(e, DERIVE_KEYS, '\"derive\"', source);\n\n if (\n e.fields === undefined &&\n e.sources === undefined &&\n e.codeowners === undefined &&\n e.commands === undefined\n ) {\n throw new DocmetaError(\n `${source}: \"derive\" sets nothing. Give it \\`fields:\\` to manage, \\`commands:\\` to derive from a command, or \\`sources:\\` or \\`codeowners:\\` to shape the reads.`,\n );\n }\n\n const commands =\n e.commands === undefined ? undefined : parseDeriveCommands(e.commands, source);\n\n if (\n e.fields !== undefined &&\n (!Array.isArray(e.fields) ||\n e.fields.length === 0 ||\n e.fields.some((f) => typeof f !== \"string\"))\n ) {\n throw new DocmetaError(\n `${source}: derive.fields must be a non-empty list of field names. ${DERIVABLE_LIST}`,\n );\n }\n const fields: DerivableField[] = [];\n ((e.fields ?? []) as string[]).forEach((f, i) => {\n if (!isBuiltinField(f) && !(commands !== undefined && Object.hasOwn(commands, f))) {\n throw new DocmetaError(\n `${source}: derive.fields[${i}] \"${f}\" is not derivable. ${DERIVABLE_LIST}`,\n );\n }\n if (fields.includes(f)) {\n throw new DocmetaError(`${source}: derive.fields lists \"${f}\" twice.`);\n }\n fields.push(f);\n });\n const derive: DeriveConfig = { fields };\n\n if (e.sources !== undefined) {\n if (\n !Array.isArray(e.sources) ||\n e.sources.length === 0 ||\n e.sources.some((s) => typeof s !== \"string\")\n ) {\n throw new DocmetaError(\n `${source}: derive.sources must be a non-empty list of source names. Sources: ${DERIVE_SOURCES.join(\", \")}.`,\n );\n }\n const sources: DeriveSource[] = [];\n (e.sources as string[]).forEach((s, i) => {\n if (!isDeriveSource(s)) {\n throw new DocmetaError(\n `${source}: derive.sources[${i}] \"${s}\" is not a source. Sources: ${DERIVE_SOURCES.join(\", \")}.`,\n );\n }\n if (sources.includes(s)) {\n throw new DocmetaError(`${source}: derive.sources lists \"${s}\" twice.`);\n }\n sources.push(s);\n });\n derive.sources = sources;\n }\n\n if (e.codeowners !== undefined) {\n if (typeof e.codeowners !== \"string\" || e.codeowners.trim() === \"\") {\n throw new DocmetaError(\n `${source}: derive.codeowners must be a non-empty path to a CODEOWNERS file, relative to the config file.`,\n );\n }\n derive.codeowners = e.codeowners;\n }\n\n if (commands !== undefined) derive.commands = commands;\n\n return derive;\n}\n\n/**\n * Parse `derive.commands`: a mapping of field name to command. A key is\n * refused when it is empty, `$schema`, or a built-in field (a command may\n * only derive a field no built-in source claims). A key a manifest owns is\n * refused too, by `assertManagedFieldsUnowned` in `loadConfig`. Each command\n * carries `run`, the argv with the program first, and an optional `timeout`\n * in seconds.\n */\nfunction parseDeriveCommands(\n raw: unknown,\n source: string,\n): Record<string, DeriveCommandConfig> {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n throw new DocmetaError(\n `${source}: derive.commands must be a mapping of field name to command.`,\n );\n }\n const commands: Record<string, DeriveCommandConfig> = {};\n for (const [key, value] of Object.entries(raw as Record<string, unknown>)) {\n if (key.trim() === \"\") {\n throw new DocmetaError(`${source}: derive.commands has an empty field name.`);\n }\n if (key === FILE_SCHEMA_KEY) {\n throw new DocmetaError(\n `${source}: derive.commands may not derive \"${FILE_SCHEMA_KEY}\" — a command never chooses the schema a document is judged by.`,\n );\n }\n if (isBuiltinField(key)) {\n throw new DocmetaError(\n `${source}: derive.commands.${key} targets a field ${BUILTIN_CLAIMED_BY[key]} already derives; a command may only derive a field no built-in source claims.`,\n );\n }\n // Every command key is a column of the `derived` table beside `_path`\n // and `_sources`, so one spelled like either would be declared twice and\n // SQLite would refuse the table with a raw error, mid-query. Refused\n // here for the reason a collection named `derived` is (see\n // `parseCollections`): a name collision is a config mistake, said at\n // parse time.\n if (DERIVED_TABLE_RESERVED.has(key)) {\n throw new DocmetaError(\n `${source}: derive.commands.${key} collides with a column of the derived table a query builds (${[...DERIVED_TABLE_RESERVED].join(\", \")}). Pick another field name.`,\n );\n }\n\n const where = `derive.commands.${key}`;\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new DocmetaError(\n `${source}: ${where} must be a mapping with \\`run:\\` beneath it.`,\n );\n }\n const c = value as Record<string, unknown>;\n rejectUnknownKeys(c, DERIVE_COMMAND_KEYS, where, source);\n\n if (!Array.isArray(c.run) || c.run.length === 0) {\n throw new DocmetaError(\n `${source}: ${where}.run must be a non-empty list of strings, the program first.`,\n );\n }\n const run: string[] = [];\n (c.run as unknown[]).forEach((arg, j) => {\n if (typeof arg !== \"string\" || arg.trim() === \"\") {\n throw new DocmetaError(`${source}: ${where}.run[${j}] must be a non-empty string.`);\n }\n run.push(arg);\n });\n const command: DeriveCommandConfig = { run };\n\n if (c.timeout !== undefined) {\n // Whole seconds, because the reference says so and because a fraction\n // reads as a budget while acting as a kill switch: `timeout: 0.001` is\n // a 1 ms allowance that ends every spawn before it can answer.\n if (typeof c.timeout !== \"number\" || !Number.isInteger(c.timeout) || c.timeout <= 0) {\n throw new DocmetaError(\n `${source}: ${where}.timeout must be a whole number of seconds, greater than zero.`,\n );\n }\n command.timeout = c.timeout;\n }\n commands[key] = command;\n }\n return commands;\n}\n\nfunction parseConfigDocument(raw: unknown, source: string): DocmetaConfig {\n if (raw == null) return {};\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new DocmetaError(`${source}: top level must be a mapping.`);\n }\n const obj = raw as Record<string, unknown>;\n rejectUnknownKeys(obj, CONFIG_KEYS, \"the top level\", source);\n const config: DocmetaConfig = {};\n\n if (obj.schemas !== undefined)\n config.schemas = asSchemaList(obj.schemas, \"schemas\", source);\n\n if (obj.overrides !== undefined) {\n if (!Array.isArray(obj.overrides)) {\n throw new DocmetaError(`${source}: \"overrides\" must be a list.`);\n }\n config.overrides = obj.overrides.map((entry, i) => {\n if (typeof entry !== \"object\" || entry === null) {\n throw new DocmetaError(`${source}: overrides[${i}] must be a mapping.`);\n }\n const e = entry as Record<string, unknown>;\n // Before the field checks, so a misspelling is reported as the typo it\n // is. `schemass:` beside a correct `schemas:` was dropped in silence and\n // the run passed — the false green this whole check exists to end, in the\n // one section it had not reached. Alone, it produced `\"overrides[0].\n // schemas\" must be a list of strings`, blaming the key that is missing\n // rather than the one that is wrong.\n rejectUnknownKeys(e, OVERRIDE_KEYS, `overrides[${i}]`, source);\n // Exactly one of the two ways to say which files an override governs\n // (0041 rule 8). Both would need a rule for how they combine, and\n // neither is a rule that governs nothing — the same reads-as-configured\n // silence the no-effect refusal below exists to end.\n const hasFiles = e.files !== undefined;\n const hasCollection = e.collection !== undefined;\n if (hasFiles === hasCollection) {\n throw new DocmetaError(\n `${source}: overrides[${i}] must carry exactly one of \"files\" or \"collection\".`,\n );\n }\n const files = hasFiles\n ? asFileGlobs(e.files, `overrides[${i}].files`, source)\n : undefined;\n let collection: string | undefined;\n if (hasCollection) {\n if (typeof e.collection !== \"string\" || e.collection.trim() === \"\") {\n throw new DocmetaError(\n `${source}: overrides[${i}].collection must be a non-empty string naming a collection.`,\n );\n }\n collection = e.collection;\n }\n const schemas =\n e.schemas === undefined\n ? []\n : asStringList(e.schemas, `overrides[${i}].schemas`, source);\n const elements =\n e.elements === undefined\n ? undefined\n : asElementPaths(e.elements, `overrides[${i}].elements`, source);\n // An override naming neither is a rule that does nothing, which reads as\n // configured and is not — the same silence `rejectUnknownKeys` exists to\n // end, one level down.\n if (schemas.length === 0 && (elements === undefined || elements.length === 0)) {\n throw new DocmetaError(\n `${source}: overrides[${i}] sets neither \"schemas\" nor \"elements\", so it has no effect.`,\n );\n }\n // Whether `collection` names a *declared* collection is checked by\n // `loadConfig`, the first place both halves of the family file are\n // known. Every view-name refusal 0027 made here — blank, `docs`,\n // `sqlite_`, duplicate — now lives in `parseCollections`, beside the\n // name it belongs to.\n return {\n ...(files !== undefined ? { files } : {}),\n ...(collection !== undefined ? { collection } : {}),\n schemas,\n ...(elements ? { elements } : {}),\n };\n });\n }\n\n if (obj.checks !== undefined) {\n config.checks = parseChecks(obj.checks, source);\n }\n\n // Whether a managed field is a key some manifest owns is checked by\n // `loadConfig`, beside the override collections: manifests are declared on\n // the top-level `collections:`, which this parser never sees.\n if (obj.derive !== undefined) {\n config.derive = parseDerive(obj.derive, source);\n }\n\n if (obj.elements !== undefined) {\n config.elements = asElementPaths(obj.elements, \"elements\", source);\n }\n\n if (obj.baseline !== undefined) {\n if (typeof obj.baseline !== \"string\" || obj.baseline.trim() === \"\") {\n throw new DocmetaError(\n `${source}: \"baseline\" must be a path to a baseline file.`,\n );\n }\n config.baseline = obj.baseline;\n }\n\n if (obj.allowEmpty !== undefined) {\n if (typeof obj.allowEmpty !== \"boolean\") {\n throw new DocmetaError(`${source}: \"allowEmpty\" must be a boolean.`);\n }\n config.allowEmpty = obj.allowEmpty;\n }\n\n if (obj.respectGitignore !== undefined) {\n if (typeof obj.respectGitignore !== \"boolean\") {\n throw new DocmetaError(`${source}: \"respectGitignore\" must be a boolean.`);\n }\n config.respectGitignore = obj.respectGitignore;\n }\n\n if (obj.offline !== undefined) {\n if (typeof obj.offline !== \"boolean\") {\n throw new DocmetaError(`${source}: \"offline\" must be a boolean.`);\n }\n config.offline = obj.offline;\n }\n\n if (obj.schemaCache !== undefined) {\n config.schemaCache = parseSchemaCache(obj.schemaCache, source);\n }\n\n if (obj.schemaTrust !== undefined) {\n config.schemaTrust = parseSchemaTrust(obj.schemaTrust, source);\n }\n\n if (obj.fill !== undefined) config.fill = parseFill(obj.fill, source);\n\n return config;\n}\n\n/**\n * Parse the `checks:` list with the same shape discipline `overrides:` has:\n * array guard, per-entry mapping guard, unknown keys rejected before the field\n * checks (so a `querry:` typo is reported as the typo it is), and a missing\n * `name` or `query` refused by index.\n */\nfunction parseChecks(value: unknown, source: string): CheckConfig[] {\n if (!Array.isArray(value)) {\n throw new DocmetaError(`${source}: \"checks\" must be a list.`);\n }\n const seen = new Set<string>();\n return value.map((entry, i) => {\n if (typeof entry !== \"object\" || entry === null || Array.isArray(entry)) {\n throw new DocmetaError(\n `${source}: checks[${i}] must be a mapping with \"name\" and \"query\".`,\n );\n }\n const e = entry as Record<string, unknown>;\n rejectUnknownKeys(e, CHECK_KEYS, `checks[${i}]`, source);\n if (typeof e.name !== \"string\" || e.name === \"\") {\n throw new DocmetaError(\n `${source}: checks[${i}].name must be a non-empty string.`,\n );\n }\n // The grammar is baseline identity — see CHECK_NAME. The `.json` tail is\n // excluded separately because BUILTIN_ID excludes it: `check:slugs.json`\n // would classify as a file path.\n if (!CHECK_NAME.test(e.name) || e.name.toLowerCase().endsWith(\".json\")) {\n throw new DocmetaError(\n `${source}: checks[${i}].name \"${e.name}\" must match [a-z0-9][a-z0-9._-]* and not end in \".json\" — the name is part of each finding's identity (check:<name>).`,\n );\n }\n const reserved = RESERVED_CHECK_NAMES.get(e.name);\n if (reserved !== undefined) {\n throw new DocmetaError(\n `${source}: checks[${i}].name \"${e.name}\" is reserved — ${reserved}. Pick another name.`,\n );\n }\n // Two checks sharing a name would share every finding's identity, so the\n // baseline could not tell their findings apart.\n if (seen.has(e.name)) {\n throw new DocmetaError(\n `${source}: checks[${i}] reuses the name \"${e.name}\"; check names must be unique.`,\n );\n }\n seen.add(e.name);\n if (typeof e.query !== \"string\" || e.query.trim() === \"\") {\n throw new DocmetaError(\n `${source}: checks[${i}].query must be a non-empty SQL statement.`,\n );\n }\n return { name: e.name, query: e.query };\n });\n}\n\nfunction parseSchemaCache(value: unknown, source: string): SchemaCacheConfig {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new DocmetaError(`${source}: \"schemaCache\" must be a mapping.`);\n }\n const raw = value as Record<string, unknown>;\n rejectUnknownKeys(raw, SCHEMA_CACHE_KEYS, '\"schemaCache\"', source);\n const schemaCache: SchemaCacheConfig = {};\n\n const ttl = raw.ttlHours;\n if (ttl !== undefined) {\n // A YAML `1e999` parses to Infinity, and a bare range check would accept\n // it. A negative TTL is worse than useless: every entry would read as\n // stale, so the cache would silently do nothing at all.\n //\n // The upper bound is not tidiness. Freshness compares against\n // `ttlHours * 3_600_000`, and a finite-but-huge value overflows that\n // product to Infinity, so `elapsed >= Infinity` is never true and every\n // entry is served forever — a cache that silently stops expiring, which is\n // the opposite of what a TTL is for. One year is well past any real\n // setting, and anyone wanting \"never expire\" has a clearer way to say it.\n if (\n typeof ttl !== \"number\" ||\n !Number.isFinite(ttl) ||\n ttl < 0 ||\n ttl > MAX_TTL_HOURS\n ) {\n throw new DocmetaError(\n `${source}: \"schemaCache.ttlHours\" must be a number of hours between 0 and ${MAX_TTL_HOURS} (0 disables the cache).`,\n );\n }\n schemaCache.ttlHours = ttl;\n }\n\n return schemaCache;\n}\n\n/**\n * Parse `schemaTrust:`, shaped after `parseSchemaCache` — a nested mapping with\n * every key optional, so an absent one leaves the default in exactly one place.\n *\n * Unknown nested keys are rejected the way a `schemas:` mapping entry rejects\n * them, and for the same reason: a misspelled `documentRef:` would otherwise be\n * dropped in silence, leaving a repo that reads as guarded and is not. A\n * misspelled `schemaTrust:` is now rejected too — `parseConfig` checks the top\n * level against `CONFIG_KEYS` rather than walking only the keys it knows. What\n * remains, and cannot be fixed here, is an *older* docmeta reading a config\n * written for a newer one: it has never heard of the key and ignores it. See\n * the version-floor note in the configuration reference.\n */\nfunction parseSchemaTrust(value: unknown, source: string): SchemaTrustConfig {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new DocmetaError(\n `${source}: \"schemaTrust\" must be a mapping. Write it as \\`schemaTrust:\\` with \\`documentRefs:\\` and optionally \\`hosts:\\` beneath it.`,\n );\n }\n const raw = value as Record<string, unknown>;\n rejectUnknownKeys(raw, SCHEMA_TRUST_KEYS, '\"schemaTrust\"', source);\n const schemaTrust: SchemaTrustConfig = {};\n\n const mode = raw.documentRefs;\n if (mode !== undefined) {\n if (\n typeof mode !== \"string\" ||\n !(DOCUMENT_REF_TRUST as readonly string[]).includes(mode)\n ) {\n throw new DocmetaError(\n `${source}: \"schemaTrust.documentRefs\" must be one of: ${DOCUMENT_REF_TRUST.join(\", \")}. Use \\`documentRefs: any\\` for today's behavior, \\`local\\` to refuse a URL a document names, or \\`none\\` to let the config decide alone.`,\n );\n }\n schemaTrust.documentRefs = mode as DocumentRefTrust;\n }\n\n const hosts = raw.hosts;\n if (hosts !== undefined) {\n if (\n !Array.isArray(hosts) ||\n hosts.some((h) => typeof h !== \"string\" || h.trim() === \"\")\n ) {\n throw new DocmetaError(\n `${source}: \"schemaTrust.hosts\" must be a list of host names, such as \"schemas.example.com\". Remove the key to allow any host.`,\n );\n }\n schemaTrust.hosts = hosts as string[];\n }\n\n return schemaTrust;\n}\n\nfunction parseFill(value: unknown, source: string): FillConfig {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new DocmetaError(`${source}: \"fill\" must be a mapping.`);\n }\n const raw = value as Record<string, unknown>;\n rejectUnknownKeys(raw, FILL_KEYS, '\"fill\"', source);\n const fill: FillConfig = {};\n\n const asString = (key: \"provider\" | \"model\"): void => {\n const v = raw[key];\n if (v === undefined) return;\n if (typeof v !== \"string\") {\n throw new DocmetaError(`${source}: \"fill.${key}\" must be a string.`);\n }\n fill[key] = v;\n };\n asString(\"provider\");\n asString(\"model\");\n\n const asNumber = (\n key: \"confidenceThreshold\" | \"maxTurns\" | \"chunkChars\" | \"concurrency\",\n min: number,\n max: number,\n integer = false,\n ): void => {\n const v = raw[key];\n if (v === undefined) return;\n // A YAML `1e999` parses to Infinity, and a bare range check would accept\n // it, so require a finite number explicitly.\n if (typeof v !== \"number\" || !Number.isFinite(v) || v < min || v > max) {\n throw new DocmetaError(\n `${source}: \"fill.${key}\" must be a number between ${min} and ${max}.`,\n );\n }\n // A fractional worker count would be silently truncated downstream rather\n // than rejected, so catch it where the user can see the mistake.\n if (integer && !Number.isInteger(v)) {\n throw new DocmetaError(\n `${source}: \"fill.${key}\" must be a whole number.`,\n );\n }\n fill[key] = v;\n };\n asNumber(\"confidenceThreshold\", 0, 1);\n asNumber(\"maxTurns\", 1, Number.MAX_SAFE_INTEGER, true);\n asNumber(\"chunkChars\", 1, Number.MAX_SAFE_INTEGER, true);\n asNumber(\"concurrency\", 1, 64, true);\n\n return fill;\n}\n\nexport interface LoadedConfig {\n config: DocmetaConfig;\n /** Absolute path to the file the config was read from. */\n path: string;\n /**\n * Directory holding that file. Relative paths written *in* the config — a\n * collection's `paths:`, local-file schema refs — are meaningful relative to\n * this, not to the directory the command happened to be invoked from.\n */\n dir: string;\n /**\n * The file as the user would name it, which is how every config message\n * spells it. Threaded from `ConfigFile.source` so `selectCollections` can\n * name the file a `--collection` failed to find a collection in.\n */\n source: string;\n /**\n * The family-file key the config was read from under (`\"meta\"`), when it\n * was. Absent for a pre-family file, whose top level is the config. A\n * command that writes the file back (`schemas vendor`) needs to know.\n */\n section?: string;\n /**\n * Every collection the family file declares (proposal 0041), in declaration\n * order. `[]` for a legacy per-tool file, which carries no family-wide keys.\n */\n collections: CollectionConfig[];\n}\n\n// The project boundary lives with the family config discovery now; the SARIF\n// reporter still imports it from here.\nexport { findGitRoot };\n\n/**\n * The directory a **document-supplied** local schema path must stay inside.\n *\n * The git root rather than the config's directory, so a monorepo package whose\n * documents reference `../shared/x.json` keeps working — that path is still\n * inside the repository, which is what \"a schema in this project\" means.\n *\n * `source` is not decoration, and it has **three** values rather than a\n * boolean: with no repository the boundary falls back to the config's\n * directory, and with no config either it falls back to the run's `cwd`. Those\n * are progressively narrower and less obvious rules, and the refusal message\n * has to name the one it actually applied — telling someone with no config file\n * that \"the config's own directory is the boundary\" sends them looking for a\n * file that is not there.\n *\n * Same reasoning as `SARIF_NO_GIT_ROOT`: \"there is no repository\" and \"the\n * repository root is where you are standing\" must stay distinguishable.\n */\nexport interface SchemaTrustRoot {\n /** Absolute directory the path must resolve inside. */\n dir: string;\n /** Which rule produced `dir`, so a refusal can name it accurately. */\n source: \"git\" | \"config\" | \"cwd\";\n}\n\n/** Settle the containment root once per run, for `resolveSchemaSet`. */\nexport function schemaTrustRoot(\n cwd: string,\n configDir?: string,\n): SchemaTrustRoot {\n const git = findGitRoot(cwd);\n if (git !== null) return { dir: git, source: \"git\" };\n if (configDir !== undefined) return { dir: resolve(configDir), source: \"config\" };\n return { dir: resolve(cwd), source: \"cwd\" };\n}\n\n/**\n * Load config from an explicit path (error if missing) or by discovery.\n *\n * Discovery checks cwd and then each ancestor up to and including the nearest\n * `.git` boundary. Within a directory the order is the family file\n * (`manni.config.yaml`, then `.yml`, read at its `meta:` key), the pre-rename\n * family file (`moose.config.yaml`), then `docmeta.config.yaml` and `.yml`\n * whole. The **first file found wins** and the walk stops there — ancestor\n * configs are never merged, because `schemas:` is a set a file must satisfy in\n * full and `overrides:` is first-match-wins ordered, so a partial merge would\n * silently redefine what \"the contract\" means. See src/shared/config-file.ts\n * for the rest of the rules, the deprecation warnings included.\n *\n * Returns null when no config is found via discovery.\n */\nexport async function loadConfig(\n explicitPath?: string,\n cwd: string = process.cwd(),\n): Promise<LoadedConfig | null> {\n const file = explicitPath\n ? await readConfigFile(explicitPath, cwd, CONFIG_FILE)\n : await findConfigFile(cwd, CONFIG_FILE);\n if (file === null) return null;\n const section = file.wrapped ? META_SECTION : undefined;\n const config = parseConfigValue(file.value, file.source, section);\n assertOverrideCollections(config, file.collections, file.source, section);\n assertManagedFieldsUnowned(config, file.collections, file.source, section);\n return {\n config,\n path: file.path,\n dir: file.dir,\n source: file.source,\n collections: file.collections,\n ...(section !== undefined ? { section } : {}),\n };\n}\n\n/** Told to a caller once, when a run turns out to be governed by a config. */\nexport interface ConfigNotice {\n /** Absolute path to the config file. */\n path: string;\n /** Directory holding it. */\n dir: string;\n}\n\nexport interface RunConfigOptions {\n /** Defaults to `process.cwd()`, matching `loadConfig`. */\n cwd?: string;\n /** `-c/--config`. */\n configPath?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n /**\n * Positional inputs; empty means fall back to the configured collections'\n * `paths:` (proposal 0041).\n */\n inputs: string[];\n /**\n * `--collection <name>`, repeatable: the collections this run covers. Empty\n * or absent means every declared collection — the same thing, because\n * commander's repeatable collector hands a caller `[]` when the flag was\n * never passed (see `selectCollections`).\n */\n collections?: string[];\n onConfigLoaded?: (info: ConfigNotice) => void;\n}\n\n/**\n * The stdin token, `load-files.ts`'s `STDIN_TOKEN`, repeated as a literal so\n * this module does not depend on the file loader it sits below. It is the one\n * input allowed beside `--collection`: stdin is not a path, so it says nothing\n * about which collections the run covers.\n */\nconst STDIN_TOKEN_LITERAL = \"-\";\n\nexport interface RunConfig {\n /** The config, with its local file schema refs already rebased. */\n config: DocmetaConfig | null;\n /**\n * What to resolve: the positional inputs, or the selected collections'\n * `paths:`, concatenated in declaration order.\n */\n inputs: string[];\n /**\n * Directory those inputs — and so every resolved file path, and every file\n * read — are relative to.\n *\n * A run uses *either* positional paths *or* the collections' `paths:`, never\n * both, so there is exactly one base per run and no ambiguity about which it\n * is. Positional paths are typed by a person standing in a shell, so they\n * stay relative to the working directory; a collection's globs were written\n * next to the config, so they resolve from there.\n */\n base: string;\n /**\n * Directory holding the config that governed the run, when one did.\n *\n * Distinct from `base`: `base` follows *the inputs*, so it is the working\n * directory whenever positional paths were given. Anything written **in** the\n * config — the `baseline:` path — is relative to the config itself no matter\n * where the command was run from, which is the whole point of discovering an\n * ancestor config in the first place.\n */\n configDir?: string;\n /**\n * Absolute path of the config file itself, when one governs the run. The\n * one honest way to edit the governing config: discovery accepts both\n * `docmeta.config.yaml` and `.yml`, `-c` accepts any name, and the file may\n * live in an ancestor — so re-deriving the path from a directory plus an\n * assumed filename names the wrong file in every one of those setups.\n */\n configPath?: string;\n /**\n * The key the tool's config sits under in that file — `meta` for a family\n * file, `undefined` for a legacy per-tool file whose whole document is the\n * section.\n *\n * Anything that *rewrites* the config by hand has to know: `schemas:` is at\n * the top level of a legacy file and one level down in a family file, so a\n * rewriter that assumes the top level silently finds nothing in the shape\n * proposal 0033 made the default. `query`'s DDL repointing did exactly that\n * until the 0041 fixtures stopped being legacy files and made it visible.\n */\n configSection?: string;\n /**\n * The collections this run covers (proposal 0041): every declared one, or\n * the ones `--collection` named. `[]` when no config governs the run.\n *\n * Selected even when the inputs are positional, because membership is what\n * external metadata attaches to (rule 4) and a file the operator typed is\n * still a member of whatever collections contain it.\n */\n collections: CollectionConfig[];\n /**\n * Every collection the config declares, in declaration order — the same list\n * `collections` narrows. `query` needs both: membership and manifests follow\n * the *selected* set, while every *declared* collection is a SQL view (0041\n * rule 11), so a statement naming one the run did not select still answers.\n */\n declaredCollections: CollectionConfig[];\n /**\n * Whether `inputs` came from the collections rather than the command line.\n * The corpus invariant every scoped check reads: a positional path means the\n * operator chose part of the corpus.\n */\n fromCollections: boolean;\n}\n\n/**\n * Settle the three things every command core needs from config before it can\n * touch the filesystem: which config governs the run, what to resolve, and\n * what those relative paths are relative to.\n */\nexport async function resolveRunConfig(\n opts: RunConfigOptions,\n): Promise<RunConfig> {\n // `--no-config` wins over an explicit path. The CLI cannot supply both (they\n // are one commander option), but the cores are public API.\n const cwd = opts.cwd ?? process.cwd();\n\n // `--collection` names something only a config can define, and it selects a\n // set the operator did not type — so it composes with neither positional\n // paths nor `--no-config`. Both refusals come before discovery, so the\n // message is about the flags rather than about whatever the walk found.\n const wanted = opts.collections ?? [];\n if (wanted.length > 0) {\n const typed = opts.inputs.filter((i) => i !== STDIN_TOKEN_LITERAL);\n if (typed.length > 0) {\n throw new DocmetaError(\n \"--collection selects a configured collection; it cannot be combined with paths.\",\n );\n }\n }\n\n const loaded = opts.noConfig ? null : await loadConfig(opts.configPath, cwd);\n if (wanted.length > 0 && loaded === null) {\n throw new DocmetaError(\"--collection needs a config file to select from.\");\n }\n if (loaded) opts.onConfigLoaded?.({ path: loaded.path, dir: loaded.dir });\n\n const config = loaded\n ? rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd)\n : null;\n\n // Selected whatever the inputs are: a positional file is still a member of\n // the collections that contain it, so its manifests have to be loadable.\n const collections = loaded\n ? selectCollections(\n loaded.collections,\n opts.collections,\n loaded.source,\n (message) => new DocmetaError(message),\n )\n : [];\n\n const fromCollections = opts.inputs.length === 0;\n const inputs = fromCollections\n ? collections.flatMap((c) => c.paths)\n : opts.inputs;\n const base = fromCollections && inputs.length > 0 && loaded ? loaded.dir : cwd;\n\n return {\n config,\n inputs,\n base,\n collections,\n declaredCollections: loaded ? [...loaded.collections] : [],\n fromCollections,\n ...(loaded\n ? {\n configDir: loaded.dir,\n configPath: loaded.path,\n ...(loaded.section === undefined ? {} : { configSection: loaded.section }),\n }\n : {}),\n };\n}\n","/**\n * The family config file.\n *\n * One file per repository, `manni.config.yaml`, with one top-level key per\n * tool: `meta:` for the metadata tool, `docevals:`, `tracevals:`, `lint:`,\n * `kg:` as each lands. A tool reads its own key and leaves its siblings alone,\n * so adding a tool never invalidates a config that predates it.\n *\n * This module only finds the file and hands a tool its slice. What the slice\n * may contain is the tool's business; it validates the value with its own\n * parser and its own error class, which is why `toError` is an option rather\n * than an import.\n *\n * Two older spellings are still read, each with a warning on discovery:\n *\n * - `moose.config.yaml`, the family file under the pre-rename name. Same\n * shape, so only the filename is wrong.\n * - each tool's pre-family file (`docmeta.config.yaml` for the metadata\n * tool), whose whole document is the tool's section with no wrapper key.\n *\n * Within one directory the order is manni, moose, then the legacy names, and\n * `.yaml` before `.yml`. A family file that exists but has no key for this\n * tool is not this tool's config: discovery keeps looking, first at the legacy\n * names beside it (a repository mid-migration, where a sibling tool moved to\n * the family file first) and then up the tree. The walk stops at the nearest\n * `.git` boundary, nearest directory first, and the first hit wins; ancestor\n * files are never merged.\n *\n * An explicit path is read the same way minus the warning: the section key is\n * unwrapped when present and the whole document is taken otherwise, so a\n * `-c ./anything.yaml` needs no filename sniffing and no flag.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { parseCollections, type CollectionConfig } from \"./collections.js\";\nimport { searchPath } from \"./git-root.js\";\nimport { warn } from \"./warn.js\";\nimport { errorMessage } from \"./errors.js\";\n\n/** The canonical family filenames, in discovery order. */\nexport const FAMILY_CONFIG_NAMES: readonly string[] = [\n \"manni.config.yaml\",\n \"manni.config.yml\",\n];\n\n/** The family filenames before the rename, still read with a warning. */\nexport const MOOSE_CONFIG_NAMES: readonly string[] = [\n \"moose.config.yaml\",\n \"moose.config.yml\",\n];\n\nexport interface ConfigFileOptions {\n /** The tool's key in a family file, e.g. `\"meta\"`. */\n section: string;\n /**\n * The tool's own filenames from before the family file, in discovery order.\n * Their whole document is the tool's section.\n */\n legacyNames: readonly string[];\n /** Build the error for an unreadable document, in the tool's own class. */\n toError: (message: string) => Error;\n}\n\nexport interface ConfigFile {\n /** Absolute path to the file. */\n path: string;\n /** Directory holding it; relative paths in the config resolve from here. */\n dir: string;\n /**\n * The file as the user would name it: relative to `cwd`, posix separators,\n * or the spelling they typed for an explicit path. For error messages.\n */\n source: string;\n /** The file's text, for a tool that rewrites the file in place. */\n text: string;\n /**\n * The tool's slice: the value under `section:` when `wrapped`, otherwise\n * the whole document. `null` for an empty file or an empty section; the\n * tool decides what empty means.\n */\n value: unknown;\n /** Whether `value` came from under `section:`. */\n wrapped: boolean;\n /** How the file was found. Explicit paths are never warned about. */\n kind: \"manni\" | \"moose\" | \"legacy\" | \"explicit\";\n /**\n * The document's top-level `collections:` (proposal 0041), parsed once here\n * because every tool reads the same declaration. `[]` when the key is\n * absent, and always `[]` for a `legacy` file: a per-tool file's whole\n * document *is* the tool's section, so it carries no family-wide keys.\n */\n collections: CollectionConfig[];\n}\n\ninterface Document {\n text: string;\n /** Parsed YAML: a mapping, or `null` for an empty file. */\n doc: Record<string, unknown> | null;\n}\n\nasync function readDocument(\n path: string,\n source: string,\n opts: ConfigFileOptions,\n): Promise<Document | null> {\n let text: string;\n try {\n text = await readFile(path, \"utf8\");\n } catch {\n return null;\n }\n return { text, doc: parseMapping(text, source, opts) };\n}\n\n/**\n * Parse outside any \"not found\" handling. A discovered file with a typo must\n * be reported, not skipped: falling through to the next candidate, or to no\n * config at all, would run the tool on defaults and read as a clean pass.\n */\nfunction parseMapping(\n text: string,\n source: string,\n opts: ConfigFileOptions,\n): Record<string, unknown> | null {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (err) {\n throw opts.toError(`${source}: invalid YAML: ${errorMessage(err)}`);\n }\n if (raw == null) return null;\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw opts.toError(`${source}: top level must be a mapping.`);\n }\n return raw as Record<string, unknown>;\n}\n\n/** The top-level key holding the family's document sets. */\nconst COLLECTIONS_KEY = \"collections\";\n\nfunction slice(\n document: Document,\n opts: ConfigFileOptions,\n): { value: unknown; wrapped: boolean } | null {\n const { doc } = document;\n if (doc !== null && Object.hasOwn(doc, opts.section)) {\n return { value: doc[opts.section] ?? null, wrapped: true };\n }\n // A family file carrying `collections:` and no section is still this tool's\n // config: the documents are declared, the tool just has no options of its\n // own. Handing back an empty section is what stops discovery walking past a\n // file that says which documents exist (0041).\n if (doc !== null && Object.hasOwn(doc, COLLECTIONS_KEY)) {\n return { value: null, wrapped: true };\n }\n return null;\n}\n\n/**\n * The document's collections. Parsed with the tool's own `toError`, so a bad\n * `collections:` is reported in the class the tool already catches.\n */\nfunction collectionsOf(\n document: Document,\n source: string,\n opts: ConfigFileOptions,\n): CollectionConfig[] {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, COLLECTIONS_KEY)) return [];\n return parseCollections(doc[COLLECTIONS_KEY], source, opts.toError);\n}\n\nfunction relativeSource(cwd: string, path: string): string {\n return relative(cwd, path).replace(/\\\\/g, \"/\");\n}\n\n/**\n * Discover the tool's config from `cwd` upward. `null` when nothing exists.\n */\nexport async function findConfigFile(\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile | null> {\n const start = resolve(cwd);\n for (const dir of searchPath(start)) {\n const family: { names: readonly string[]; kind: \"manni\" | \"moose\" }[] = [\n { names: FAMILY_CONFIG_NAMES, kind: \"manni\" },\n { names: MOOSE_CONFIG_NAMES, kind: \"moose\" },\n ];\n for (const { names, kind } of family) {\n for (const name of names) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = await readDocument(path, source, opts);\n if (document === null) continue;\n const found = slice(document, opts);\n // A family file without this tool's key belongs to a sibling. Keep\n // looking, rather than treating the file as an empty config.\n if (found === null) continue;\n if (kind === \"moose\") {\n warn(\n `\"${name}\" is the pre-rename name of the family config file. Rename it to \"${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}\".`,\n );\n }\n return {\n path,\n dir,\n source,\n text: document.text,\n kind,\n collections: collectionsOf(document, source, opts),\n ...found,\n };\n }\n }\n for (const name of opts.legacyNames) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = await readDocument(path, source, opts);\n if (document === null) continue;\n warn(\n `\"${name}\" is a deprecated config file name and will stop being read in a future major version. Move its keys under \\`${opts.section}:\\` in \"${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}\", and its paths, exclude and sidecars keys to a top-level collections: list, where sidecars becomes externalMetadata.`,\n );\n return {\n path,\n dir,\n source,\n text: document.text,\n value: document.doc,\n wrapped: false,\n kind: \"legacy\",\n collections: [],\n };\n }\n }\n return null;\n}\n\n/**\n * Read the config at an explicit path. Missing is an error: a `-c` pointing\n * at a file that is not there is a mistake worth failing on, not a reason to\n * quietly run against something else.\n */\nexport async function readConfigFile(\n explicitPath: string,\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile> {\n const path = resolve(cwd, explicitPath);\n // Report the spelling the user typed, not the resolved absolute path.\n const document = await readDocument(path, explicitPath, opts);\n if (document === null) {\n throw opts.toError(`Config file not found: \"${explicitPath}\".`);\n }\n const found = slice(document, opts) ?? {\n value: document.doc,\n wrapped: false,\n };\n return {\n path,\n dir: dirname(path),\n source: explicitPath,\n text: document.text,\n kind: \"explicit\",\n collections: collectionsOf(document, explicitPath, opts),\n ...found,\n };\n}\n","/**\n * Warnings for the user: stderr, prefixed, and said once.\n *\n * stderr, because stdout belongs to the report (`--format json` has to stay\n * parseable). Once, because the same deprecated config file is discovered by\n * every command core a run touches, and a warning repeated five times reads as\n * five problems. Dedup is on the exact text, per process.\n */\nimport { programName } from \"./program-name.js\";\n\nconst said = new Set<string>();\n\nexport function warn(message: string): void {\n if (said.has(message)) return;\n said.add(message);\n process.stderr.write(`${programName()}: ${message}\\n`);\n}\n\n/** Forget what has been said, so a test can assert a warning fires again. */\nexport function resetWarnings(): void {\n said.clear();\n}\n","/**\n * Collection views, and the membership adapter that decides what a collection\n * contains.\n *\n * `memberOf` is proposal 0041's rule 10: which collections a file belongs to,\n * as path arithmetic against the config file's directory. It is what external\n * metadata attaches to, what an `overrides[].collection` resolves through, and\n * — since 0041 rule 7 — what a SQL view holds.\n *\n * One meaning of \"collection\", everywhere. 0027 built each view from the files\n * an override *won schema resolution for*, so views were disjoint, only a\n * collection an override pointed at had a view at all, and a file whose own\n * `$schema` outranked the override was announced as not being in it. 0041\n * makes a view the set the config says it is: every declared collection is a\n * view, two views may overlap, and `FROM authors` reads as \"the files the\n * authors collection selects\".\n *\n * That restores 0021's founding rule, which 0027 had to bend: a plain read\n * resolves no schemas. Nothing in this module resolves anything, so there is\n * no trust refusal to demote a file over, no per-file walk to pay for, and no\n * notice to print. Resolution still honours `overrides[].collection` — it\n * matches through `memberOf` in `resolve-schema.ts`, which is untouched.\n *\n * Shared by both projection consumers — `query` and the corpus checks\n * `validate` runs — so the two cannot drift on what a collection contains.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport { isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport { isMember, type CollectionConfig } from \"../../shared/collections.js\";\nimport { STDIN_LABEL } from \"./load-files.js\";\nimport { quoteIdent, type ProjectionEntry } from \"./projection.js\";\n\n/**\n * Names of the collections this file belongs to, in declaration order.\n *\n * Where the two bases meet. A run labels files relative to `base` — the\n * working directory for positional paths, the config's directory otherwise —\n * while membership is decided relative to the config file's directory, because\n * that is where a collection's globs were written (0004). So the label is\n * resolved against `base` and then measured from `configDir`.\n *\n * Pure path arithmetic (0041 rule 10): no `stat`, nothing that can fail, and\n * nothing that costs per file. Stdin and anything outside `configDir` are\n * members of nothing — stdin because there is no file behind it, and `isMember`\n * refuses a `../` path on its own.\n */\nexport function memberOf(\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n label: string,\n): string[] {\n if (collections.length === 0) return [];\n if (label === STDIN_LABEL) return [];\n const rel = relative(configDir, resolvePath(base, label))\n .split(sep)\n .join(\"/\");\n // `relative` gives back an *absolute* path when the two sides share no root\n // — a different drive letter on Windows. That is as far outside the config\n // directory as a path can be, and it carries no `../` for `isMember` to\n // refuse, so it is refused here.\n if (isAbsolute(rel)) return [];\n return collections.filter((c) => isMember(c, rel)).map((c) => c.name);\n}\n\n/**\n * Narrow a walked file set to the files that belong to a selected collection\n * (proposal 0041 rule 9).\n *\n * The walk applies the family-wide ignores and `--exclude` only, because a\n * collection's `paths:` and `exclude:` are two halves of one statement and the\n * walk sees just the first half. Without this second pass a collection's\n * `exclude:` shaped its SQL view but not what a bare run read, so one config\n * gave two different answers about the same collection — the ambiguity 0041\n * exists to remove.\n *\n * Apply it **only** when the inputs came from the collections. A path someone\n * typed is theirs, and no collection's exclusions filter it (rule 3); the\n * caller decides, which is why this takes the already-walked list rather than\n * consulting `fromCollections` itself.\n */\nexport function retainMembers(\n files: readonly string[],\n membersFor: (label: string) => readonly string[],\n): string[] {\n return files.filter((label) => membersFor(label).length > 0);\n}\n\n/** One collection, with the loaded files that belong to it. */\nexport interface Collection {\n name: string;\n /** `_path` labels of the member files. May be empty — an empty view. */\n members: string[];\n}\n\n/**\n * The declared collection names, in declaration order — the one list every\n * \"is this a collection?\" consumer shares: the view builder below, and\n * `query`'s eager-build trigger and lazy-retry match. Callers that compare\n * case-insensitively use `String.prototype.toLowerCase`, whose Unicode fold\n * is looser than SQLite's ASCII-only fold — that mismatch can only\n * over-trigger a harmless eager build or rebuild, never miss a real match.\n */\nexport function collectionNames(\n collections: readonly CollectionConfig[] | undefined,\n): string[] {\n return (collections ?? []).map((c) => c.name);\n}\n\nexport interface CollectionParams {\n /**\n * Every collection the config **declares** — not just the ones `--collection`\n * selected, and not just the ones an override points at. Each one is a view\n * (0041 rule 11), so narrowing a run never turns `FROM blog` into a SQL\n * error; it turns it into a view holding whatever of `blog` the run loaded.\n * Optional so the checks' run context can be this very shape; absent, or\n * empty, means there are no collections and so no views.\n */\n collections?: readonly CollectionConfig[];\n /**\n * The config file's directory: what a collection's globs are measured from\n * (0004). Only read when there is a collection to build a view for, which is\n * only ever true when a config governs the run.\n */\n configDir?: string;\n /** Directory the run's file labels are relative to (`RunConfig.base`). */\n base?: string;\n}\n\n/**\n * Compute every declared collection's member list from the loaded entries.\n *\n * Membership is the config's own arithmetic — `memberOf`, the same function\n * external metadata and `overrides[].collection` go through — so a view holds\n * exactly the loaded files the collection selects, and a file in two\n * collections is in both views. Nothing here resolves a schema, opens a file,\n * or can fail.\n */\nexport function collectCollections(\n entries: readonly ProjectionEntry[],\n params: CollectionParams,\n): Collection[] {\n const declared = params.collections ?? [];\n if (declared.length === 0) return [];\n // A collection can only be declared by a config file, so both bases are set\n // whenever there is a view to build; the fallbacks keep the arithmetic total\n // rather than optional.\n const base = params.base ?? \".\";\n const configDir = params.configDir ?? base;\n\n const members = new Map<string, string[]>();\n for (const entry of entries) {\n for (const name of memberOf(declared, configDir, base, entry.label)) {\n const list = members.get(name);\n if (list) list.push(entry.label);\n else members.set(name, [entry.label]);\n }\n }\n return declared.map((c) => ({ name: c.name, members: members.get(c.name) ?? [] }));\n}\n\n/** One member path as a SQL string literal (doubling internal quotes). */\nfunction quoteSqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Create one view per collection on an open database that already holds the\n * `docs` table.\n *\n * Each view is built from the computed member list — literal paths, `WHERE 0`\n * for an empty collection — never from a SQL translation of the config glob:\n * picomatch and SQLite `GLOB` are different languages, and membership was\n * already decided by the code that owns the decision. The IN-list scales past\n * any real corpus (0027 § stress test 4: SQLite's SQL-length ceiling is\n * ~1 GB; ten thousand long-ish paths are under a megabyte).\n *\n * Views live in `sqlite_master`, outside the two snapshots effect judgment\n * diffs (`SELECT * FROM docs`, `PRAGMA table_info(docs)`), so the effect gate\n * never sees them — and a `--db` export carries them, which is a feature.\n */\nexport function createCollectionViews(\n db: DatabaseSync,\n collections: readonly Collection[],\n): void {\n for (const c of collections) {\n const where =\n c.members.length === 0\n ? \"0\"\n : `_path IN (${c.members.map(quoteSqlString).join(\", \")})`;\n db.exec(\n `CREATE VIEW ${quoteIdent(c.name)} AS SELECT * FROM docs WHERE ${where}`,\n );\n }\n}\n","/**\n * The SQL projection of a metadata corpus — the `docs` table both `query`\n * (proposal 0021) and the named corpus checks (proposal 0026) run over.\n *\n * One file, one row: the four system columns plus one column per top-level\n * metadata key across the corpus. `query` adds statement-specific columns and\n * effect-judging on top; checks read the same table and nothing else. The\n * table-building lives here so the two entry points cannot drift.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport { DocmetaError, type ExtractedMetadata } from \"../types.js\";\n\n/**\n * The columns every `docs` table carries, reserved so ordinary frontmatter can\n * never shadow them. A frontmatter key with exactly one of these names is not\n * lifted to a column and stays reachable as `_data ->> '$.<key>'`; any other\n * `_`-prefixed key lifts normally — the reservation is four names, not a\n * namespace grab (proposal 0021 § stress test 4).\n */\nexport const SYSTEM_COLUMNS = [\"_path\", \"_format\", \"_present\", \"_data\"] as const;\nexport const RESERVED: ReadonlySet<string> = new Set<string>(SYSTEM_COLUMNS);\n\n/** What `node:sqlite` accepts as a bound parameter. */\nexport type SqlValue = null | number | bigint | string;\n\n/** One loaded file, as the projection needs it: its label and its extraction. */\nexport interface ProjectionEntry {\n label: string;\n extracted: ExtractedMetadata;\n}\n\n/** Any key becomes a legal quoted identifier by doubling internal quotes. */\nexport function quoteIdent(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\n/**\n * One frontmatter value, as SQLite stores it: booleans as 1/0 (`node:sqlite`\n * refuses to bind a boolean), arrays and objects as JSON text (which\n * `json_each` and `->>` then query directly), non-finite numbers as NULL\n * (SQLite has no NaN — it would store NULL anyway, this just does it without\n * an engine error).\n */\nexport function bindValue(value: unknown): SqlValue {\n if (value === undefined || value === null) return null;\n switch (typeof value) {\n case \"boolean\":\n return value ? 1 : 0;\n case \"number\":\n return Number.isFinite(value) ? value : null;\n case \"bigint\":\n case \"string\":\n return value;\n default:\n return JSON.stringify(value);\n }\n}\n\n/**\n * Data columns for a corpus: the union of top-level keys across `entries` —\n * the same scan boundary `schemas infer` chose — plus any `extraKeys` the\n * caller's statement names (a SET target no file has yet still deserves a\n * column). Sorted, so the column order (and any `SELECT *`) is deterministic\n * regardless of file order.\n */\nexport function corpusDataColumns(\n entries: readonly ProjectionEntry[],\n extraKeys: Iterable<string> = [],\n): string[] {\n const keys = new Set<string>();\n for (const { extracted } of entries) {\n for (const key of Object.keys(extracted.data)) {\n if (key !== \"\" && !RESERVED.has(key)) keys.add(key);\n }\n }\n for (const key of extraKeys) {\n if (key !== \"\" && !RESERVED.has(key)) keys.add(key);\n }\n return [...keys].sort();\n}\n\n/**\n * Create and load the `docs` table on an open database.\n *\n * Data columns get no type affinity, so SQLite stores exactly the value each\n * file had and never coerces one file's string into another's number. One\n * transaction for the bulk load: each bare run() would otherwise commit on its\n * own, which is where a large corpus spends its load time.\n */\nexport function createDocsTable(\n db: DatabaseSync,\n entries: readonly ProjectionEntry[],\n dataColumns: readonly string[],\n): void {\n db.exec(\n `CREATE TABLE docs (\"_path\" TEXT PRIMARY KEY, \"_format\" TEXT, \"_present\" INTEGER, \"_data\" TEXT${dataColumns\n .map((c) => `, ${quoteIdent(c)}`)\n .join(\"\")})`,\n );\n const insert = db.prepare(\n `INSERT INTO docs VALUES (${[\"?\", \"?\", \"?\", \"?\", ...dataColumns.map(() => \"?\")].join(\", \")})`,\n );\n db.exec(\"BEGIN\");\n // Committed or rolled back, never left open: a caller may keep using the\n // handle after a failed insert, and every later statement would otherwise\n // run inside the half-built transaction.\n let committed = false;\n try {\n for (const { label, extracted } of entries) {\n insert.run(\n label,\n extracted.format,\n extracted.present ? 1 : 0,\n JSON.stringify(extracted.data),\n ...dataColumns.map((c) => bindValue(extracted.data[c])),\n );\n }\n db.exec(\"COMMIT\");\n committed = true;\n } finally {\n if (!committed) db.exec(\"ROLLBACK\");\n }\n}\n\n/**\n * Register `lineFor(path, key)` as a SQL function on the run's database, so a\n * statement can name the source line a metadata key sits on (proposal 0026).\n *\n * Backed by each entry's `extracted.lineFor` — the contract every extractor\n * already fulfills for annotations — through the same `db.function` mechanism\n * that registers `explicit_null()`, plus `deterministic: true`: the answer\n * depends only on the arguments for the life of the statement, which lets\n * SQLite fold repeated calls. `NULL` for an unknown path, a key the extractor\n * cannot place, or a non-string argument.\n */\nexport function registerLineFor(\n db: DatabaseSync,\n entries: readonly ProjectionEntry[],\n): void {\n const byLabel = new Map(entries.map((e) => [e.label, e.extracted]));\n db.function(\"lineFor\", { deterministic: true }, (path, key) => {\n if (typeof path !== \"string\" || typeof key !== \"string\") return null;\n return byLabel.get(path)?.lineFor(key) ?? null;\n });\n}\n\n/**\n * Refuse a second statement instead of silently dropping it.\n *\n * `prepare()` compiles the first statement and ignores the rest, so\n * `SELECT 1; DROP TABLE docs` would run the SELECT and quietly skip the DROP —\n * a request half-honored with exit 0, the false-green shape 0016 exists to\n * keep out. The scan skips string literals, quoted identifiers, and both\n * comment forms; a trailing `;` (or several) is a terminator, not a chain.\n */\nexport function assertSingleStatement(sql: string): void {\n const cut = topLevelSemicolon(sql);\n if (cut === -1) return;\n if (!isTrivia(sql.slice(cut + 1))) {\n throw new DocmetaError(\n \"Run a single SQL statement per query; text after the first `;` would be silently ignored.\",\n );\n }\n}\n\n/**\n * The scanner primitives every SQL micro-lexer in the codebase is built on —\n * statement splitting and the parameter scan below, `query`'s SET/INSERT\n * target scans, and the 0028 catalog-CHECK parser. One implementation of\n * \"skip the region whose contents are data, not syntax\", so the consumers\n * cannot drift on what a string or a comment is.\n */\n\n/** Does `sql[i]` open a string literal or a quoted/bracketed identifier? */\nexport function startsStringOrIdent(sql: string, i: number): boolean {\n const ch = sql[i];\n return ch === \"'\" || ch === '\"' || ch === \"`\" || ch === \"[\";\n}\n\n/** Does a line comment (`--`) or block comment start at `i`? */\nexport function startsComment(sql: string, i: number): boolean {\n const ch = sql[i];\n return (\n (ch === \"-\" && sql[i + 1] === \"-\") || (ch === \"/\" && sql[i + 1] === \"*\")\n );\n}\n\n/**\n * Index just past a string literal or quoted/bracketed identifier opening at\n * `i` (`sql[i]` must satisfy `startsStringOrIdent`). The three quote forms\n * treat a doubled quote as an escape — `'a''b'` is one literal — and an\n * unterminated one consumes the rest of the input (returns `sql.length`).\n * A bracket identifier scans plainly to `]`: SQLite brackets have no `]]`\n * escape (unlike T-SQL), so no doubling branch — and an unterminated one\n * returns `sql.length + 1`, one past the close the terminated form counts,\n * which `readIdentifier`'s `end - 1` slicing relies on.\n */\nexport function skipStringOrIdent(sql: string, i: number): number {\n const quote = sql[i];\n if (quote === \"[\") {\n let j = i + 1;\n while (j < sql.length && sql[j] !== \"]\") j++;\n return j + 1;\n }\n let j = i + 1;\n while (j < sql.length) {\n if (sql[j] === quote) {\n if (sql[j + 1] === quote) {\n j += 2;\n continue;\n }\n return j + 1;\n }\n j++;\n }\n return j;\n}\n\n/**\n * Index just past a comment opening at `i` (`sql` must satisfy\n * `startsComment` there). A line comment ends past its newline, a block\n * comment past its closer; either unterminated consumes the rest of the\n * input. Consuming the line comment's newline is safe because every consumer\n * treats a bare newline as trivia.\n */\nexport function skipComment(sql: string, i: number): number {\n if (sql[i] === \"-\") {\n let j = i + 2;\n while (j < sql.length && sql[j] !== \"\\n\") j++;\n return j < sql.length ? j + 1 : j;\n }\n const end = sql.indexOf(\"*/\", i + 2);\n return end === -1 ? sql.length : end + 2;\n}\n\n/**\n * Index of the first `;` outside literals, identifiers, and comments.\n *\n * Parenthesis depth is deliberately not tracked: in valid SQLite, the only\n * semicolons outside strings are statement terminators — the grammar has no\n * parenthesized position where one may appear — so depth would be state with\n * nothing to distinguish. (Trigger bodies, the one construct with interior\n * semicolons, never reach here: the docs projection has no triggers.)\n */\nfunction topLevelSemicolon(sql: string): number {\n let i = 0;\n while (i < sql.length) {\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n } else if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n } else if (sql[i] === \";\") {\n return i;\n } else {\n i++;\n }\n }\n return -1;\n}\n\n/**\n * The one grammar for a named parameter's bare name. The scan below matches\n * it as a prefix; `isParamName` answers for a whole string — exported so the\n * CLI's `--param` validation cannot drift from what the scan recognizes.\n */\nconst PARAM_NAME_HEAD = /^[A-Za-z_][A-Za-z0-9_]*/;\nexport function isParamName(name: string): boolean {\n return PARAM_NAME_HEAD.exec(name)?.[0] === name;\n}\n\n/**\n * Named-parameter tokens (`$name`, `:name`, `@name`) the statement references\n * outside string literals, quoted identifiers, and comments — the same skip\n * rules as `topLevelSemicolon`, for the same reason: text inside a literal is\n * data, not syntax (proposal 0029).\n *\n * The tokens are returned as written, prefix included, first occurrence only.\n * The grammar is deliberately narrow: a prefix character must be followed\n * immediately by an identifier (`[A-Za-z_][A-Za-z0-9_]*`), so a bare `$`, a\n * spaced `:`, and a doubled `::` are all operators-or-noise, never parameters.\n *\n * One bare name under two prefixes (`$p` and `:p` in one statement) refuses\n * here: the engine rejects it anyway, but as a generic \"conflicting names\"\n * SQL error with neither spelling named.\n *\n * Why this exists: the engine throws on an *extra* bound parameter, but a\n * parameter the SQL references with nothing bound silently binds NULL — which\n * matches nothing, and a zero-row `--check` is a passing CI gate. The caller\n * uses this list to refuse that false green before the statement runs.\n */\nexport function collectNamedParameters(sql: string): string[] {\n const tokens: string[] = [];\n const seen = new Set<string>();\n const prefixOf = new Map<string, string>();\n let i = 0;\n while (i < sql.length) {\n const ch = sql[i];\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n } else if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n } else if (ch === \"$\" || ch === \":\" || ch === \"@\") {\n if (ch === \":\" && sql[i + 1] === \":\") {\n // `::` is no parameter; consume both so neither colon starts one.\n i += 2;\n continue;\n }\n const m = PARAM_NAME_HEAD.exec(sql.slice(i + 1));\n if (!m) {\n i++;\n continue;\n }\n const token = ch + m[0];\n const priorPrefix = prefixOf.get(m[0]);\n if (priorPrefix !== undefined && priorPrefix !== ch) {\n throw new DocmetaError(\n `The statement references both ${priorPrefix}${m[0]} and ${token} — one name under two prefixes, which the engine rejects as conflicting. Use one spelling throughout.`,\n );\n }\n prefixOf.set(m[0], ch);\n if (!seen.has(token)) {\n seen.add(token);\n tokens.push(token);\n }\n i += 1 + m[0].length;\n } else {\n i++;\n }\n }\n return tokens;\n}\n\n/**\n * The statement with leading whitespace and comments removed — the first real\n * token, for the callers that refuse a statement by name (`query`'s\n * ATTACH/VACUUM gate, and the checks' twin of it). Lived in query.ts until\n * the checks needed the identical scan.\n */\nexport function stripLeadingTrivia(sql: string): string {\n let i = 0;\n for (;;) {\n while (i < sql.length && /\\s/.test(sql[i] ?? \"\")) i++;\n if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n continue;\n }\n return sql.slice(i);\n }\n}\n\n/** Only whitespace, comments, and bare `;` — legal after the terminator. */\nfunction isTrivia(text: string): boolean {\n let i = 0;\n while (i < text.length) {\n const ch = text[i];\n if (ch === undefined || /\\s/.test(ch) || ch === \";\") {\n i++;\n continue;\n }\n if (startsComment(text, i)) {\n i = skipComment(text, i);\n continue;\n }\n return false;\n }\n return true;\n}\n\n/**\n * `node:sqlite`, imported on first use only.\n *\n * Two reasons this is not a top-level import. A static import would load the\n * module for every docmeta invocation, `validate` runs included. And on the\n * Node 24 engines floor the module is a release candidate that announces\n * itself with an ExperimentalWarning on load — which would open every CI log\n * with a scare line — so exactly that one warning is filtered while the\n * import runs. Delete the filter when `node:sqlite` reaches Stable.\n */\nlet sqliteModule: Promise<typeof import(\"node:sqlite\")> | undefined;\nexport function loadSqlite(): Promise<typeof import(\"node:sqlite\")> {\n sqliteModule ??= (async () => {\n // Bound, so the capture is a standalone function twice over: callable\n // here without a `this` surprise, and safe to leave installed as the\n // restored property.\n const original = process.emitWarning.bind(process);\n const filtered: typeof process.emitWarning = (warning, ...rest) => {\n const text = typeof warning === \"string\" ? warning : warning.message;\n if (text.includes(\"SQLite is an experimental feature\")) return;\n Reflect.apply(original, process, [warning, ...rest]);\n };\n process.emitWarning = filtered;\n try {\n return await import(\"node:sqlite\");\n } finally {\n process.emitWarning = original;\n }\n })();\n return sqliteModule;\n}\n","/**\n * JSON Schema validation engine. Compiles and caches an Ajv validator per\n * schema reference, validates extracted metadata against each schema in a set,\n * and maps every violation to a {schema, instancePath, line, col} FieldError.\n */\nimport * as AjvDraft07Ns from \"ajv\";\nimport * as Ajv2019Ns from \"ajv/dist/2019.js\";\nimport * as Ajv2020Ns from \"ajv/dist/2020.js\";\nimport * as AjvDraft04Ns from \"ajv-draft-04\";\nimport * as addFormatsNs from \"ajv-formats\";\nimport { createRequire } from \"node:module\";\nimport type {\n DefinedError,\n ErrorObject,\n ValidateFunction,\n} from \"ajv/dist/2020.js\";\nimport { DocmetaError, type FieldError } from \"../types.js\";\nimport type { SourceLocation } from \"./external-metadata.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\n\n// ajv ships its meta-schema refs as JSON. A static JSON import survives\n// bundling as a bare ESM import without the required `type: json` attribute, so\n// load it through `require` instead (ajv is an external dep at runtime).\nconst draft06MetaSchema = createRequire(import.meta.url)(\n \"ajv/dist/refs/json-schema-draft-06.json\",\n) as Record<string, unknown>;\n\n// ajv and ajv-formats are CommonJS with a default export; under NodeNext the\n// callable/constructable value lives on `.default`. Cast through the named\n// default types so tsc sees a constructor / callable. The per-dialect builds\n// expose the same shape, so we treat them all as the 2020 constructor type.\ntype AjvCtor = typeof import(\"ajv/dist/2020.js\").default;\nconst AjvDraft07 = AjvDraft07Ns.default as unknown as AjvCtor;\nconst Ajv2019 = Ajv2019Ns.default as unknown as AjvCtor;\nconst Ajv2020 = Ajv2020Ns.default as unknown as AjvCtor;\nconst AjvDraft04 = AjvDraft04Ns.default as unknown as AjvCtor;\nconst addFormats =\n addFormatsNs.default as unknown as typeof import(\"ajv-formats\").default;\nimport {\n loadSchema,\n publishedBuiltins,\n type LoadSchemaOptions,\n} from \"./schema-registry.js\";\nimport { FILE_SCHEMA_KEY } from \"./resolve-schema.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\ntype Dialect = \"2020\" | \"2019\" | \"draft7\" | \"draft4\";\n\n/**\n * Pick a JSON Schema dialect from a schema's own `$schema` meta-schema URI.\n * Remote schemas commonly target draft-07/draft-04, which the 2020 build can't\n * compile, so each dialect gets its own Ajv. A missing or unrecognized\n * `$schema` falls back to 2020 (the dialect of the built-ins).\n */\nfunction dialectOf(schema: Record<string, unknown>): Dialect {\n const meta = typeof schema.$schema === \"string\" ? schema.$schema : \"\";\n if (meta.includes(\"2019-09\")) return \"2019\";\n // draft-06 shares the draft-07 build (its meta-schema is registered there).\n if (\n meta.includes(\"draft-07\") ||\n meta.includes(\"draft/7\") ||\n meta.includes(\"draft-06\") ||\n meta.includes(\"draft/6\")\n ) {\n return \"draft7\";\n }\n if (meta.includes(\"draft-04\") || meta.includes(\"draft/4\")) return \"draft4\";\n return \"2020\";\n}\n\nfunction buildAjv(dialect: Dialect): InstanceType<AjvCtor> {\n // strict: false so user-supplied schemas with lax metadata still compile.\n const opts = { allErrors: true, strict: false } as const;\n const ajv =\n dialect === \"2019\"\n ? new Ajv2019(opts)\n : dialect === \"draft7\"\n ? new AjvDraft07(opts)\n : dialect === \"draft4\"\n ? new AjvDraft04(opts)\n : new Ajv2020(opts);\n addFormats(ajv);\n // draft-06 shares the draft-07 build; register its meta-schema so draft-06\n // schemas compile too rather than erroring on an unknown `$schema`.\n if (dialect === \"draft7\") ajv.addMetaSchema(draft06MetaSchema);\n registerBuiltins(ajv, dialect);\n return ajv;\n}\n\n/**\n * Make every built-in resolvable as a `$ref` target, under both of its names.\n *\n * Ajv is constructed with no `loadSchema`, so before this a user's schema could\n * not `$ref` a built-in by **any** route — not the published URL (nothing to\n * fetch it with) and not the docmeta id either, even though the schema was\n * bundled and would later be compiled into this very instance. Both failed with\n * \"can't resolve reference … from id #\", which reads like the published file is\n * broken. Proposal 0009 stress test 5.\n *\n * Three mechanics that are easy to get wrong:\n *\n * - **One call per built-in.** `addSchema(schema, url)` registers under the key\n * *and* under the schema's own `$id`, so the id form comes for free. Calling\n * it a second time under the id throws \"schema with key or id … already\n * exists\".\n * - **Meta-schema validation is off for these.** All the built-ins are\n * 2020-12, and the 2019/draft-07/draft-04 instances do not carry that\n * meta-schema — `addSchema` would throw `no schema with key or ref\n * \"https://json-schema.org/draft/2020-12/schema\"` and take out every Ajv but\n * one. These are docmeta's own files, covered by their own tests, so skipping\n * the check costs nothing. The flag is per call: a *user's* schema is still\n * validated normally.\n * - **All four dialects, not just 2020.** `dialectOf` picks the instance from\n * the *user's* `$schema`, so a draft-07 house schema extending OKF compiles in\n * the draft-07 Ajv and needs the built-ins registered there too.\n *\n * Registration is lazy — Ajv compiles a stored schema only when something\n * references it — so this costs a map insert per built-in, not fifteen compiles.\n *\n * Called from `buildAjv` rather than from `Validator`, deliberately:\n * `compileWithFormats` builds its own throwaway instance for `fill`'s proposal\n * envelope, which lifts subschemas out of the user's schemas and would\n * otherwise lose every `$ref` into a built-in.\n */\nfunction registerBuiltins(ajv: InstanceType<AjvCtor>, dialect: Dialect): void {\n for (const { id, url, legacyUrl, schema } of publishedBuiltins()) {\n ajv.addSchema(schema, url, undefined, false);\n // A user schema written before the rename `$ref`s the old URL. Same bytes,\n // same object; only the key differs.\n ajv.addSchema(schema, legacyUrl, undefined, false);\n // draft-04 predates `$id` — `ajv-draft-04` reads `id` instead — so the URL\n // key is the only registration the call above produces there, and the id\n // form has to be added explicitly. It does not throw as a duplicate for the\n // same reason: `$id` was never registered.\n if (dialect === \"draft4\") ajv.addSchema(schema, id, undefined, false);\n }\n}\n\n/**\n * Compile an ad-hoc 2020-12 schema with docmeta's format support.\n *\n * `fill` needs this for the proposal envelope it builds around a document\n * schema's own property subschemas: those routinely carry `format: \"date-time\"`\n * / `\"uri\"`, and an Ajv without `ajv-formats` refuses to compile them outright.\n */\nexport function compileWithFormats(\n schema: Record<string, unknown>,\n): ValidateFunction {\n return buildAjv(\"2020\").compile(schema);\n}\n\n/**\n * A bare Ajv carrying exactly the `addFormats` registration `buildAjv`\n * performs — the reference for what \"a format docmeta enforces\" means.\n * Shared by the two helpers below; built once, lazily.\n */\nlet formatRegistry: InstanceType<AjvCtor> | undefined;\nfunction formatsAjv(): InstanceType<AjvCtor> {\n if (!formatRegistry) {\n formatRegistry = new Ajv2020({ strict: false });\n addFormats(formatRegistry);\n }\n return formatRegistry;\n}\n\n/**\n * The format names docmeta's validators enforce on strings, derived from the\n * ajv-formats registration itself — never a hand-copied parallel list, so an\n * ajv-formats upgrade widens this set without anyone remembering it (proposal\n * 0028). Two exclusions, both because they do not constrain a string:\n * number-typed formats (`int32`, `float`, …) and always-pass placeholders\n * (`password`, `binary`, registered as `true`).\n */\nlet stringFormatsMemo: ReadonlySet<string> | undefined;\nexport function stringFormatNames(): ReadonlySet<string> {\n if (!stringFormatsMemo) {\n const names = new Set<string>();\n const registered: Record<string, unknown> = formatsAjv().formats;\n for (const [name, def] of Object.entries(registered)) {\n const enforcesStrings =\n def instanceof RegExp ||\n typeof def === \"function\" ||\n (typeof def === \"object\" &&\n def !== null &&\n ((def as { type?: string }).type === undefined ||\n (def as { type?: string }).type === \"string\"));\n if (enforcesStrings) names.add(name);\n }\n stringFormatsMemo = names;\n }\n return stringFormatsMemo;\n}\n\n/**\n * Does `value` satisfy the named format? Answered by compiling\n * `{type: \"string\", format: name}` in the same registry — the exact machinery\n * `validate` enforces the format with, so there is no second opinion about\n * what a `date` is (0028's DEFAULT guard).\n */\nconst formatCheckers = new Map<string, ValidateFunction>();\nexport function validatesFormat(name: string, value: string): boolean {\n let fn = formatCheckers.get(name);\n if (!fn) {\n fn = formatsAjv().compile({ type: \"string\", format: name });\n formatCheckers.set(name, fn);\n }\n return fn(value);\n}\n\nexport class Validator {\n /**\n * How this validator's schemas are loaded: the disk cache location, its TTL,\n * and `--offline`. Held per instance rather than read from module state, so\n * two differently-configured validations in one process each get their own\n * settings.\n *\n * That is not full isolation, and the difference matters to a library\n * caller: `schema-registry` keeps a process-wide memo of fetched schemas, so\n * one validator's successful fetch is visible to another. `offline` is\n * excluded from that sharing on purpose — an offline validator will not be\n * served something this process pulled over the network — but the memo is\n * still shared, so a URL fetched once is not re-fetched per instance.\n */\n constructor(private readonly schemaOptions: LoadSchemaOptions = {}) {}\n\n private ajvByDialect = new Map<Dialect, InstanceType<AjvCtor>>();\n /**\n * Keyed on the in-flight *promise*, not the resolved validator. Caching the\n * result made this a check-then-act race: `fill` walks files through a worker\n * pool, so every worker missed the cache while the first `loadSchema` was\n * still pending and they all then compiled the same schema into the one\n * shared per-dialect Ajv. Ajv registers a schema's `$id` on the first compile\n * and rejects the second with \"schema with key or id ... already exists\",\n * which took down any multi-file run against an $id-bearing schema. Storing\n * the promise before the first await lets the losers await the one compile.\n */\n private cache = new Map<string, Promise<ValidateFunction>>();\n\n private ajvFor(dialect: Dialect): InstanceType<AjvCtor> {\n let ajv = this.ajvByDialect.get(dialect);\n if (!ajv) {\n ajv = buildAjv(dialect);\n this.ajvByDialect.set(dialect, ajv);\n }\n return ajv;\n }\n\n /**\n * Synchronous by design: the `cache.set` has to happen in the same tick as\n * the miss, or a second caller can slip in before the entry exists.\n */\n private compile(ref: string): Promise<ValidateFunction> {\n const cached = this.cache.get(ref);\n if (cached) return cached;\n const pending = this.compileUncached(ref);\n this.cache.set(ref, pending);\n // A failed load or compile is not cached — a transient fetch failure must\n // stay retryable rather than poisoning the ref for this Validator's life.\n // The extra `catch` keeps the eviction off the returned promise's chain, so\n // it does not convert the rejection into a handled one for the caller.\n pending.catch(() => {\n if (this.cache.get(ref) === pending) this.cache.delete(ref);\n });\n return pending;\n }\n\n private async compileUncached(ref: string): Promise<ValidateFunction> {\n const schema = await loadSchema(ref, this.schemaOptions);\n try {\n const ajv = this.ajvFor(dialectOf(schema));\n // This cache is keyed on the ref string, but Ajv's registry is keyed on\n // `$id` — so one schema named two ways (a published URL in a document's\n // `$schema`, a local path on the command line) misses the cache twice and\n // Ajv rejects the second compile as a duplicate id. Reuse the existing\n // registration instead. `$id` is the schema's identity as far as Ajv is\n // concerned, so if two refs claim the same one, sharing a validator is\n // the only reading available — the alternative is the hard error this\n // replaces.\n //\n // Reused only when the registration really is *this* object. Sharing on\n // the id alone was tolerable while a registration could only come from an\n // earlier compile in the same run. It stopped being tolerable when\n // `registerBuiltins` began pre-loading every built-in into every\n // instance: an id collision is no longer a race whose outcome depends on\n // ordering, it is certain, and the built-in always wins.\n //\n // What that would silently override is a vendored built-in the user then\n // edited — the workflow proposal 0009 actively encourages. `schemas\n // vendor` writes a copy carrying `$id: google:okf:0.1`, so a house rule\n // added to that copy would simply not apply, while the report went on\n // naming the local path.\n //\n // A different schema claiming a taken id is compiled on its own merits,\n // with the id dropped from a shallow copy: Ajv refuses a second schema\n // under one id, and the id is not what identifies a schema here anyway —\n // the *ref* is what reports name, what baselines fingerprint, and what\n // this cache is keyed on.\n const id = typeof schema[\"$id\"] === \"string\" ? schema[\"$id\"] : undefined;\n const registered = id != null ? ajv.getSchema(id) : undefined;\n if (registered) {\n if (registered.schema === schema) return registered;\n const { $id: _taken, ...anonymous } = schema;\n return ajv.compile(anonymous);\n }\n return ajv.compile(schema);\n } catch (err) {\n throw new DocmetaError(\n `Schema \"${ref}\" failed to compile: ${errorMessage(err)}`,\n );\n }\n }\n\n /**\n * Validate `data` against every schema in `refs`. Returns all violations,\n * each tagged with the schema that produced it and a source line via\n * `lineFor`.\n *\n * `colFor` is optional and additive: this signature is public, so a fourth\n * *required* parameter — or a widened third one — would be a consumer break.\n * Callers with an extractor that supplies no column pass nothing and get the\n * previous behavior exactly.\n */\n async validate(\n data: Record<string, unknown>,\n refs: string[],\n lineFor: (pointer: string) => number | undefined,\n colFor?: (pointer: string) => number | undefined,\n /**\n * Where a merged value lives when it is not in the document (proposal\n * 0037): a manifest's file and line. Consulted before `lineFor`,\n * and additive in the way `colFor` was.\n */\n locate?: (pointer: string) => SourceLocation | undefined,\n ): Promise<FieldError[]> {\n // `$schema` is a docmeta directive, not part of the document's metadata —\n // strip it so schemas with additionalProperties:false don't flag it.\n const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;\n void _omit;\n\n const errors: FieldError[] = [];\n for (const ref of refs) {\n const fn = await this.compile(ref);\n const ok = fn(subject);\n if (ok) continue;\n for (const e of fn.errors ?? []) {\n errors.push(toFieldError(ref, e, lineFor, colFor, locate));\n }\n }\n return errors;\n }\n}\n\n/**\n * The stable identifier inside a violation's `params`, when there is one.\n *\n * Only keywords whose parameter names a *thing* qualify. `pattern` carries the\n * regex source and `enum`/`minLength`/`minimum` carry schema-authored values:\n * including those would change a violation's identity every time the schema\n * author edited the rule, which is exactly what a baseline must survive.\n *\n * `DefinedError` is Ajv's own discriminated union over `keyword`, so each arm\n * below is type-checked against the real `params` shape rather than duck-typed.\n */\nfunction subjectOf(e: DefinedError): string | undefined {\n switch (e.keyword) {\n case \"required\":\n return e.params.missingProperty;\n case \"additionalProperties\":\n return e.params.additionalProperty;\n case \"format\":\n return e.params.format;\n case \"type\":\n // A union schema (`\"type\": [\"string\", \"null\"]`) yields the comma-joined\n // `\"string,null\"` rather than a single name. That is stable, so it\n // fingerprints correctly — but anyone matching on `subject` downstream\n // should not assume one type per value.\n return e.params.type;\n default:\n return undefined;\n }\n}\n\nfunction toFieldError(\n schema: string,\n e: ErrorObject,\n lineFor: (pointer: string) => number | undefined,\n colFor?: (pointer: string) => number | undefined,\n locate?: (pointer: string) => SourceLocation | undefined,\n): FieldError {\n // Ajv's documented way to narrow: every error it raises for a built-in\n // vocabulary is a member of `DefinedError`, but `ValidateFunction.errors` is\n // typed as the open `ErrorObject` to leave room for custom keywords.\n const defined = e as DefinedError;\n const instancePath = e.instancePath;\n const subject = subjectOf(defined);\n // Both of these point `instancePath` at the *parent* object and name the\n // property in the message, so neither gets a column.\n //\n // The parent exists, so `colFor` answers happily — with the parent's column,\n // which is a different token from the one the message is about. For\n // `required` the property is not in the file at all; for\n // `additionalProperties` it is, but somewhere else entirely, and the parent\n // of a document's root is the root, whose recorded position is 1:1. So a\n // stray key on line 40 was annotated at line 1 column 1, a caret on the first\n // character of the file.\n //\n // A `line` on the parent is a useful \"look around here\". A caret is a claim\n // about one character, and for these two keywords it would be the wrong one.\n let message = e.message ?? \"is invalid\";\n let wantsColumn = true;\n if (defined.keyword === \"required\") {\n message = `must have required property '${defined.params.missingProperty}'`;\n wantsColumn = false;\n } else if (defined.keyword === \"additionalProperties\") {\n message = `must NOT have additional property '${defined.params.additionalProperty}'`;\n wantsColumn = false;\n }\n // A value a manifest supplied is not in the document, so `lineFor` has no\n // answer for it; `locate` does. `additionalProperties` is the one keyword\n // whose offending value sits at a *child* of `instancePath`, and when that\n // child came from the manifest, the manifest line is where a reader should\n // look — a public schema refusing a private key is exactly the case.\n const located =\n locate?.(instancePath) ??\n (defined.keyword === \"additionalProperties\"\n ? locate?.(\n `${instancePath}/${escapePointerSegment(defined.params.additionalProperty)}`,\n )\n : undefined);\n if (located) {\n return {\n schema,\n instancePath,\n message,\n keyword: e.keyword,\n ...(subject != null ? { subject } : {}),\n file: located.file,\n ...(located.line != null ? { line: located.line } : {}),\n ...(wantsColumn && located.col != null ? { col: located.col } : {}),\n };\n }\n const line = lineFor(instancePath);\n const col = wantsColumn ? colFor?.(instancePath) : undefined;\n return {\n schema,\n instancePath,\n message,\n keyword: e.keyword,\n ...(subject != null ? { subject } : {}),\n ...(line != null ? { line } : {}),\n ...(col != null ? { col } : {}),\n };\n}\n","/**\n * The GitHub or GitLab review cache: cross-run, for merged-change answers.\n *\n * A merged pull request is history: its approvals cannot change, so the\n * answer for `host/project/sha` is good forever and there is no TTL. An\n * *open* PR's answer is the opposite — the next approval changes it — so a\n * `null` from the host is never written. `--no-cache` disables both\n * directions for one run.\n *\n * Same shape as `schema-cache.ts`: one file per key under\n * `.manni/meta/review-cache/`, named by a digest so the key (which carries\n * `/`) can never decide where a write lands; a malformed entry is a miss;\n * a failed write is swallowed, because a read-only checkout must cost the\n * next run one `gh` call, not this run its result. Synchronous, because a\n * `set()` the caller does not await must still be on disk when the next\n * process starts.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ReviewClient, RemoteIdentity, MergedChange } from \"./types.js\";\n\n/** Where the GitHub or GitLab review cache lives, relative to the project root. `.manni/` is gitignored. */\nexport const REVIEW_CACHE_DIR = \".manni/meta/review-cache\";\n\n/** The only entry format this version understands. */\nexport const REVIEW_CACHE_VERSION = 1;\n\ninterface Entry {\n version: number;\n /** `host/project/sha`; re-checked on read. */\n key: string;\n change: MergedChange;\n}\n\n/** The GitHub or GitLab review cache: one immutable merged change per `host/project/sha`. */\nexport class ReviewCache {\n constructor(\n private readonly dir: string,\n private readonly enabled: boolean,\n ) {}\n\n entryPath(key: string): string {\n const digest = createHash(\"sha256\").update(key).digest(\"hex\");\n return join(this.dir, `${digest}.json`);\n }\n\n /** The cached change, or `undefined` for a miss. Never `null`: nulls are not stored. */\n get(key: string): MergedChange | undefined {\n if (!this.enabled) return undefined;\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(this.entryPath(key), \"utf8\"));\n } catch {\n return undefined;\n }\n if (!isRecord(raw)) return undefined;\n if (raw.version !== REVIEW_CACHE_VERSION || raw.key !== key) return undefined;\n const change = readChange(raw.change);\n return change ?? undefined;\n }\n\n set(key: string, value: MergedChange): void {\n if (!this.enabled) return;\n const entry: Entry = { version: REVIEW_CACHE_VERSION, key, change: value };\n const path = this.entryPath(key);\n // Temp file beside the target plus rename, so a reader never sees half an\n // entry. Synchronous: see the module comment.\n const tmp = `${path}.${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`;\n try {\n mkdirSync(this.dir, { recursive: true });\n writeFileSync(tmp, `${JSON.stringify(entry, null, 2)}\\n`, \"utf8\");\n renameSync(tmp, path);\n } catch {\n // Intentionally silent: see the module comment.\n try {\n rmSync(tmp, { force: true });\n } catch {\n // The temp file was never created, or cannot be removed either.\n }\n }\n }\n}\n\n/**\n * `client` with `mergedChangeFor` read through the cache. Only a merged\n * answer is stored. With no identity there is no key, and every call goes\n * straight through — which, for a client with no origin, is a `null`.\n */\nexport function cachedClient(\n client: ReviewClient,\n cache: ReviewCache,\n identity: RemoteIdentity | null,\n): ReviewClient {\n return {\n detect: () => client.detect(),\n status: () => client.status(),\n async mergedChangeFor(sha) {\n if (identity === null) return client.mergedChangeFor(sha);\n const key = `${identity.host}/${identity.project}/${sha}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n const change = await client.mergedChangeFor(sha);\n if (change !== null) cache.set(key, change);\n return change;\n },\n };\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** A stored change, or `null` when the file does not hold one. */\nfunction readChange(v: unknown): MergedChange | null {\n if (!isRecord(v)) return null;\n const { id, mergedAt, approvals } = v;\n if (typeof id !== \"number\" || typeof mergedAt !== \"string\") return null;\n if (!Array.isArray(approvals)) return null;\n const read: MergedChange[\"approvals\"] = [];\n for (const a of approvals as unknown[]) {\n if (!isRecord(a)) return null;\n if (typeof a.login !== \"string\" || typeof a.submittedAt !== \"string\") return null;\n read.push({ login: a.login, submittedAt: a.submittedAt });\n }\n return { id, mergedAt, approvals: read };\n}\n","/**\n * One child process, run to completion: stdout collected, stderr drained and\n * kept for the message, a timer that kills it. The review sources reach `gh`\n * and `glab` through this, and the `command` source reaches whatever the\n * config names; neither holds a token or opens a socket of its own.\n */\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\n\n/** How a client reaches the binary; tests point `bin` at node and a fake script. */\nexport interface SpawnOptions {\n /** Defaults to `gh` / `glab`, resolved on PATH. */\n bin?: string;\n /** Arguments placed before the command's own, such as a script for `node`. */\n prefixArgs?: string[];\n cwd: string;\n /** Kill the child after this long. Default 30 s. */\n timeoutMs?: number;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * How much of a child's output is kept, per stream. `gh` and `glab` answer\n * in JSON a page at a time, and a configured command reports one field's\n * value, so a stream past this is a program doing something else — `cat` on\n * the wrong file — and reading it to the end would trade the run's memory\n * for output nobody wants. The git walk caps itself the same way.\n */\nexport const MAX_OUTPUT_BYTES = 8 * 1024 * 1024;\n\nexport interface Run {\n /** Exit code; `null` when a signal ended the child. */\n code: number | null;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n /** A stream passed `MAX_OUTPUT_BYTES` and the child was killed. */\n tooLarge: boolean;\n}\n\n/** The binary could not be started at all: nothing on PATH by that name. */\nexport class BinMissing extends Error {}\n\n/** One child, stdout collected, stderr drained and kept for the message. */\nexport function run(bin: string, args: string[], opts: SpawnOptions): Promise<Run> {\n return new Promise((settle, reject) => {\n let done = false;\n const finish = (r: Run): void => {\n if (done) return;\n done = true;\n settle(r);\n };\n const fail = (err: Error): void => {\n if (done) return;\n done = true;\n reject(err);\n };\n\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(bin, [...(opts.prefixArgs ?? []), ...args], {\n cwd: opts.cwd,\n windowsHide: true,\n });\n } catch (err) {\n fail(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n let tooLarge = false;\n\n /**\n * Stop the child for good. `kill()` is SIGTERM, which a program may\n * trap, and `close` waits for the stdio streams as well as the exit —\n * a grandchild holding stdout keeps it pending. So the promise settles\n * here rather than waiting, and SIGKILL follows shortly after.\n *\n * `timer` is cleared here rather than left to `close`, for the same\n * reason: `close` is exactly the event this function refuses to wait\n * for. `clearTimeout` is idempotent, so the `close` handler may still\n * call it. The SIGKILL timer is deliberately not cleared — it is the\n * escalation, and it has to fire.\n *\n * `timer` is declared below this closure, so every caller must reach\n * `stop` from an async handler, as all of them do. Calling it straight\n * from the spawn path would hit the temporal dead zone.\n */\n const stop = (r: Omit<Run, \"code\">): void => {\n clearTimeout(timer);\n child.kill();\n setTimeout(() => child.kill(\"SIGKILL\"), 1_000).unref();\n finish({ code: null, ...r });\n };\n\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n if (stdout.length > MAX_OUTPUT_BYTES) {\n tooLarge = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }\n });\n // Drained *and* kept: a chatty CLI must not stall the pipe, and its last\n // line is what names the failure to the user.\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n if (stderr.length > MAX_OUTPUT_BYTES) {\n tooLarge = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }\n });\n child.stdin.end();\n\n const timer = setTimeout(() => {\n timedOut = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\n // No binary on PATH lands here rather than throwing from spawn().\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n clearTimeout(timer);\n fail(err.code === \"ENOENT\" ? new BinMissing(err.message) : err);\n });\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n finish({ code, stdout, stderr, timedOut, tooLarge });\n });\n });\n}\n\n/** `gh api --hostname h repos/…`: the command as the user would type it. */\nexport function commandLine(bin: string, args: readonly string[]): string {\n return [bin, ...args].join(\" \");\n}\n\nexport function lastLine(text: string): string {\n const lines = text.split(/\\r?\\n/).filter((l) => l.trim() !== \"\");\n return lines.at(-1) ?? \"\";\n}\n","/**\n * The `command` source: a field derived by running whatever `derive.commands`\n * names for it. The value is the program's stdout — JSON when it parses as\n * JSON, the trimmed text otherwise, `null` when there is none.\n *\n * A command is spawned once per run, and its value copied into every\n * document's record, unless its argv carries `{path}`, in which case it is\n * spawned once per document with the document's label in place. The argv is\n * never handed to a shell: what the config lists is what runs.\n *\n * The first failure ends the source for the whole run, with nothing further\n * spawned: a program that is not on PATH, a timeout, a non-zero exit. A\n * half-derived field would read as \"the command said nothing\" for the\n * documents it never reached, which is the false green the whole channel\n * refuses. Availability is reported, never thrown, as the other sources do.\n */\nimport {\n BinMissing,\n MAX_OUTPUT_BYTES,\n lastLine,\n run,\n type Run,\n type SpawnOptions,\n} from \"./spawn.js\";\nimport { errorMessage } from \"../../../shared/errors.js\";\nimport type { DerivedValue, DeriveCommand, DeriveInput, SourceStatus } from \"./types.js\";\n\n/** The argv token a per-file command carries where the document's label goes. */\nexport const PATH_PLACEHOLDER = \"{path}\";\n\nexport interface CommandSourceOptions {\n /** Where the commands run: the config directory, else the run cwd. */\n cwd: string;\n /** Test seam: `bin` and `prefixArgs` replace the configured program. */\n spawn?: Partial<SpawnOptions>;\n}\n\nexport interface CommandSourceResult {\n status: SourceStatus;\n /** By label; every input present when available, keyed by field within. */\n records: Map<string, Record<string, DerivedValue | null>>;\n}\n\n/** Whether any argv element carries `{path}`, so the command runs once per document. */\nexport function isPerFile(command: DeriveCommand): boolean {\n return command.run.some((arg) => arg.includes(PATH_PLACEHOLDER));\n}\n\n/** The argv with every `{path}` replaced by the label, forward slashes as the run spells it. */\nexport function argvFor(command: DeriveCommand, label: string): string[] {\n return command.run.map((arg) => arg.split(PATH_PLACEHOLDER).join(label));\n}\n\n/**\n * What a command's stdout means: nothing when blank, the parsed value when it\n * is *structured* JSON, the trimmed text otherwise. A date or a version string\n * stays a string; a list or an object arrives as one.\n *\n * Only `{`, `[` and `\"` open a parse, and that boundary is the whole point.\n * A bare scalar is text a person wrote, and reading it as JSON silently\n * rewrites it: `1.10` becomes the number `1.1`, so a command reporting\n * version 1.10 stamps 1.1 into the document. A field wants the characters\n * the command printed. The structured forms are the reason a parse exists at\n * all — `verified-against` takes an object, and a list of anchors is a list —\n * and neither of those can be confused with prose.\n */\nexport function valueOf(stdout: string): unknown {\n const text = stdout.trim();\n if (text === \"\") return null;\n if (!/^[{[\"]/.test(text)) return text;\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n}\n\nexport async function deriveFromCommands(\n inputs: readonly DeriveInput[],\n commands: Readonly<Record<string, DeriveCommand>>,\n opts: CommandSourceOptions,\n): Promise<CommandSourceResult> {\n const records = new Map<string, Record<string, DerivedValue | null>>();\n const fields = Object.keys(commands);\n if (fields.length === 0 || inputs.length === 0) {\n return { status: { available: true }, records };\n }\n for (const input of inputs) records.set(input.label, {});\n\n for (const field of fields) {\n const command = commands[field];\n if (command === undefined) continue;\n if (isPerFile(command)) {\n for (const [label, record] of records) {\n const outcome = await runOne(field, argvFor(command, label), command.timeoutMs, opts);\n if (\"reason\" in outcome) return unavailable(outcome.reason);\n record[field] = outcome.value;\n }\n } else {\n const outcome = await runOne(field, command.run, command.timeoutMs, opts);\n if (\"reason\" in outcome) return unavailable(outcome.reason);\n for (const record of records.values()) record[field] = outcome.value;\n }\n }\n return { status: { available: true }, records };\n}\n\nfunction unavailable(reason: string): CommandSourceResult {\n return { status: { available: false, reason }, records: new Map() };\n}\n\ntype Outcome = { value: DerivedValue | null } | { reason: string };\n\n/** One spawn, with every failure turned into the reason the status carries. */\nasync function runOne(\n field: string,\n argv: readonly string[],\n timeoutMs: number,\n opts: CommandSourceOptions,\n): Promise<Outcome> {\n const [program, ...args] = argv;\n const where = `(derive.commands.${field})`;\n if (program === undefined) {\n return { reason: `no program to run ${where}` };\n }\n const line = argv.join(\" \");\n let result: Run;\n try {\n result = await run(opts.spawn?.bin ?? program, args, {\n ...opts.spawn,\n cwd: opts.spawn?.cwd ?? opts.cwd,\n timeoutMs,\n });\n } catch (err) {\n if (err instanceof BinMissing) {\n return { reason: `\\`${program}\\` is not on PATH ${where}` };\n }\n return { reason: `\\`${line}\\` could not be run: ${errorMessage(err)} ${where}` };\n }\n if (result.timedOut) {\n return { reason: `\\`${line}\\` timed out after ${String(timeoutMs / 1000)}s ${where}` };\n }\n if (result.tooLarge) {\n return {\n reason: `\\`${line}\\` wrote more than ${String(MAX_OUTPUT_BYTES / (1024 * 1024))} MiB; a command reports one field's value ${where}`,\n };\n }\n if (result.code !== 0) {\n const last = lastLine(result.stderr);\n const detail = last === \"\" ? \"no output on stderr\" : last;\n const exit = result.code === null ? \"killed by a signal\" : `exit ${String(result.code)}`;\n return { reason: `\\`${line}\\` failed (${exit}): ${detail} ${where}` };\n }\n const value = valueOf(result.stdout);\n return { value: value === null ? null : { value, source: \"command\", evidence: line } };\n}\n","/**\n * The review sources, `github` and `gitlab`: `reviewed-by` and `last-reviewed` from the pull request\n * or merge request that merged a document's newest body-changing commit.\n *\n * Reached through `gh` or `glab`, never an HTTP client. The facts sit behind\n * two vendors' auth stores and two API grammars, and the vendor CLI is the\n * trust boundary: manni never holds a token, never reads one, never prints\n * one. `gh` is on every GitHub-hosted runner and `glab` is one package\n * install on GitLab's (proposal 0040, decision 7).\n *\n * Two answers are deliberately *not* errors. A commit the host has no merged\n * change for (an open PR, a direct push, a commit that came in through\n * another repository) is `null`. A commit the host does not know at all is\n * `null` too. Everything else that goes wrong — a non-zero exit, a timeout,\n * an answer that is not JSON — throws `DocmetaError`, because a half-answer\n * read as \"no approvals\" would file a stale finding against a document that\n * was in fact reviewed.\n */\nimport { resolve as resolvePath } from \"node:path\";\nimport { DocmetaError } from \"../../types.js\";\nimport { ReviewCache, cachedClient } from \"./cache.js\";\nimport {\n BinMissing,\n DEFAULT_TIMEOUT_MS,\n commandLine,\n lastLine,\n run,\n type Run,\n type SpawnOptions,\n} from \"./spawn.js\";\nimport type {\n Approval,\n DerivedValue,\n ReviewClient,\n RemoteIdentity,\n MergedChange,\n SourceStatus,\n} from \"./types.js\";\n\nexport type { Approval, ReviewClient, RemoteIdentity, MergedChange } from \"./types.js\";\nexport type { SpawnOptions } from \"./spawn.js\";\n\n// ---------------------------------------------------------------------------\n// Origin → identity\n\n/**\n * The host and project an origin URL names, for the three spellings git\n * writes: `git@host:owner/repo.git`, `https://[user@]host/owner/repo[.git]`,\n * `ssh://git@host[:port]/owner/repo`. The project keeps every path segment,\n * because a GitLab namespace can nest (`group/sub/repo`). Anything else —\n * a local path, a bare host — is `null`. A local path is recognised before\n * the scp form is tried, because git reads `C:/mirrors/repo.git` as a\n * directory on drive C and the scp regex would read it as host `C`.\n */\nexport function parseOriginUrl(\n url: string,\n): { host: string; project: string } | null {\n const trimmed = url.trim();\n if (trimmed === \"\") return null;\n if (isLocalPath(trimmed)) return null;\n\n const scp = /^(?:[^@/:]+@)?([^/:]+):(?!\\/\\/)(.+)$/.exec(trimmed);\n if (scp) {\n const host = scp[1];\n const path = scp[2];\n if (host === undefined || path === undefined) return null;\n // A one-letter \"host\" is a DOS drive, whichever slash follows it.\n if (/^[A-Za-z]$/.test(host)) return null;\n return project(host, path);\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n return null;\n }\n if (!/^(https?|ssh|git):$/.test(parsed.protocol)) return null;\n if (parsed.hostname === \"\") return null;\n return project(parsed.hostname, parsed.pathname);\n}\n\n/** Absolute, relative, or UNC: the spellings of a path that is not a URL. */\nfunction isLocalPath(s: string): boolean {\n return s.startsWith(\"/\") || s.startsWith(\"./\") || s.startsWith(\"../\") || s.startsWith(\"\\\\\\\\\");\n}\n\nfunction project(\n host: string,\n path: string,\n): { host: string; project: string } | null {\n const segments = path\n .replace(/\\.git$/, \"\")\n .split(\"/\")\n .filter((s) => s !== \"\");\n if (segments.length < 2) return null;\n return { host, project: segments.join(\"/\") };\n}\n\n/**\n * Which platform a host is, and so which CLI reaches it. A host whose name\n * says `github` (github.com, github.example.com) is GitHub; one that says\n * `gitlab` is GitLab. A host that says neither, such as `git.example.com`,\n * is decided by the config: when exactly one of the `github` and `gitlab`\n * sources is requested, that is the platform the operator named. Otherwise\n * the answer is null, and the caller reports it as a source that cannot\n * answer. Nothing is ever assumed: the `github` source applies to GitHub\n * and the `gitlab` source to GitLab, and neither stands in for the other.\n */\nexport function identityFromOrigin(\n host: string,\n project: string,\n requested?: readonly RemoteIdentity[\"kind\"][],\n): RemoteIdentity | null {\n const name = host.toLowerCase();\n if (name.includes(\"github\")) return { kind: \"github\", host, project };\n if (name.includes(\"gitlab\")) return { kind: \"gitlab\", host, project };\n const only = requested !== undefined && requested.length === 1 ? requested[0] : undefined;\n return only === undefined ? null : { kind: only, host, project };\n}\n\n/**\n * A client for an origin whose host names neither platform and whose config\n * does not say which it is. It answers nothing, and its status names the fix.\n */\nclass UnknownHostClient implements ReviewClient {\n constructor(private readonly host: string) {}\n detect(): Promise<RemoteIdentity | null> {\n return Promise.resolve(null);\n }\n status(): Promise<SourceStatus> {\n return Promise.resolve({\n available: false,\n reason: `the origin remote is ${this.host}, which names neither GitHub nor GitLab; list exactly one of github, gitlab in derive.sources to say which it is`,\n });\n }\n mergedChangeFor(): Promise<MergedChange | null> {\n return Promise.resolve(null);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Failure reading\n\n/** The HTTP status a `gh`/`glab` failure line carries, when it carries one. */\nfunction httpStatus(stderr: string): number | null {\n const m = /\\b(?:HTTP\\s+(\\d{3})|(\\d{3})\\s+Not\\s+Found)\\b/i.exec(stderr);\n const code = m?.[1] ?? m?.[2];\n return code === undefined ? null : Number(code);\n}\n\n/**\n * Whether a failed call is the host saying \"no such thing\" — a commit it\n * does not know (404, or GitHub's 422 \"No commit found for SHA\") — which is\n * an answer, not an error.\n */\nfunction isNotFound(r: Run): boolean {\n const status = httpStatus(r.stderr);\n return status === 404 || status === 422;\n}\n\n/**\n * The base for both CLIs: the same spawn, the same failure ladder, the same\n * status vocabulary. Subclasses supply the binary name and the lookups.\n */\nabstract class CliClient implements ReviewClient {\n protected abstract readonly tool: \"gh\" | \"glab\";\n\n constructor(\n protected readonly identity: RemoteIdentity | null,\n protected readonly spawnOpts: SpawnOptions,\n ) {}\n\n detect(): Promise<RemoteIdentity | null> {\n return Promise.resolve(this.identity);\n }\n\n async status(): Promise<SourceStatus> {\n if (this.identity === null) {\n return { available: false, reason: \"no origin remote to tell GitHub from GitLab\" };\n }\n const { host } = this.identity;\n let r: Run;\n try {\n r = await this.run([\"auth\", \"status\", \"--hostname\", host]);\n } catch (err) {\n if (err instanceof BinMissing) {\n return {\n available: false,\n reason: `${this.tool} is not on PATH (origin is ${host}); install ${this.tool} and run ${this.tool} auth login`,\n };\n }\n throw err;\n }\n if (r.timedOut) throw this.timeout([\"auth\", \"status\", \"--hostname\", host]);\n if (r.code !== 0) {\n return {\n available: false,\n reason: `${this.tool} is not authenticated for ${host}; run ${this.tool} auth login`,\n };\n }\n return { available: true };\n }\n\n async mergedChangeFor(sha: string): Promise<MergedChange | null> {\n if (this.identity === null) return null;\n return this.lookup(this.identity, sha);\n }\n\n protected abstract lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null>;\n\n protected get bin(): string {\n return this.spawnOpts.bin ?? this.tool;\n }\n\n protected run(args: string[]): Promise<Run> {\n return run(this.bin, args, this.spawnOpts);\n }\n\n private timeout(args: string[]): DocmetaError {\n const ms = this.spawnOpts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n return new DocmetaError(\n `${commandLine(this.tool, args)} timed out after ${ms}ms`,\n );\n }\n\n /**\n * Run a call whose stdout is JSON. A not-found answer is `null`; any other\n * failure throws, naming the command the user can re-run by hand. The\n * message quotes the tool's own name rather than `bin`, which under test\n * is `node`.\n */\n protected async json(args: string[]): Promise<unknown> {\n let r: Run;\n try {\n r = await this.run(args);\n } catch (err) {\n if (err instanceof BinMissing) {\n throw new DocmetaError(\n `${commandLine(this.tool, args)} failed: ${this.tool} is not on PATH`,\n );\n }\n throw err;\n }\n const cmd = commandLine(this.tool, args);\n if (r.timedOut) throw this.timeout(args);\n // A truncated answer must not be read as the whole one: half a page of\n // reviews would file a stale finding against a document that was\n // reviewed, which is the half-answer this class refuses everywhere.\n if (r.tooLarge) {\n throw new DocmetaError(`${cmd} wrote more output than manni will read`);\n }\n if (r.code !== 0) {\n if (isNotFound(r)) return null;\n const detail = lastLine(r.stderr) || lastLine(r.stdout);\n const exit = r.code === null ? \"signal\" : `exit ${r.code}`;\n throw new DocmetaError(\n `${cmd} failed (${exit})${detail === \"\" ? \"\" : `: ${detail}`}`,\n );\n }\n try {\n return JSON.parse(r.stdout) as unknown;\n } catch {\n throw new DocmetaError(`${cmd} did not return JSON`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Answer shapes, read defensively\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction items(v: unknown): Record<string, unknown>[] {\n return Array.isArray(v) ? v.filter(isRecord) : [];\n}\n\nfunction numberOf(v: unknown): number | null {\n return typeof v === \"number\" && Number.isInteger(v) ? v : null;\n}\n\nfunction stringOf(v: unknown): string | null {\n return typeof v === \"string\" && v !== \"\" ? v : null;\n}\n\n/** A field that is present and a string, present and null, or absent. */\ntype Tri = string | null | undefined;\n\nfunction timestampOf(v: unknown): Tri {\n if (v === undefined) return undefined;\n return stringOf(v);\n}\n\n/**\n * `claude[bot]` (REST) and `claude` (GraphQL) are one reviewer. The stripped\n * form is the dedupe key; the value keeps whichever spelling the latest\n * approval carried.\n */\nfunction normalizeLogin(login: string): string {\n return login.replace(/\\[bot\\]$/, \"\");\n}\n\n/** `APPROVED` only, the latest per reviewer, oldest approval first. */\nfunction latestApprovals(\n reviews: readonly { login: string; state: string; submittedAt: string }[],\n): Approval[] {\n const latest = new Map<string, Approval>();\n for (const r of reviews) {\n if (r.state !== \"APPROVED\") continue;\n const key = normalizeLogin(r.login);\n const seen = latest.get(key);\n if (seen === undefined || r.submittedAt > seen.submittedAt) {\n latest.set(key, { login: r.login, submittedAt: r.submittedAt });\n }\n }\n return byTime([...latest.values()]);\n}\n\nfunction byTime(approvals: readonly Approval[]): Approval[] {\n return [...approvals].sort((a, b) =>\n a.submittedAt < b.submittedAt ? -1 : a.submittedAt > b.submittedAt ? 1 : 0,\n );\n}\n\n// ---------------------------------------------------------------------------\n// GitHub\n\n/**\n * GitHub through `gh`. Every call carries `--hostname` (or `-R host/project`)\n * so a GHES origin is reached even when `gh`'s default host is github.com.\n *\n * - `gh api --hostname <host> repos/<project>/commits/<sha>/pulls`\n * - if empty: `gh pr list --search <sha> --state merged --json number,mergedAt -R <host>/<project>`\n * (a squash-merged commit's original sha is only findable through search,\n * and a commit that came in through another repository is `[]` here, which\n * is a legitimate non-error)\n * - `gh api --hostname <host> repos/<project>/pulls/<n>` only when the list\n * item does not say whether it merged\n * - `gh api --hostname <host> repos/<project>/pulls/<n>/reviews?per_page=100`\n */\nexport class GitHubClient extends CliClient {\n protected readonly tool = \"gh\";\n\n protected async lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null> {\n const { host, project } = identity;\n const api = (endpoint: string): Promise<unknown> =>\n this.json([\"api\", \"--hostname\", host, endpoint]);\n\n let candidates = items(await api(`repos/${project}/commits/${sha}/pulls`)).map(\n (p) => ({ number: numberOf(p.number), mergedAt: timestampOf(p.merged_at) }),\n );\n if (candidates.length === 0) {\n const found = await this.json([\n \"pr\", \"list\", \"--search\", sha, \"--state\", \"merged\",\n \"--json\", \"number,mergedAt\", \"-R\", `${host}/${project}`,\n ]);\n candidates = items(found).map((p) => ({\n number: numberOf(p.number),\n mergedAt: timestampOf(p.mergedAt),\n }));\n }\n\n for (const c of candidates) {\n if (c.number === null) continue;\n let mergedAt = c.mergedAt;\n if (mergedAt === undefined) {\n const pr = await api(`repos/${project}/pulls/${c.number}`);\n mergedAt = isRecord(pr) ? (stringOf(pr.merged_at) ?? null) : null;\n }\n if (mergedAt === null) continue;\n\n // The reviews endpoint lists oldest first, 100 per page, with no sort\n // parameter, so a long-lived PR's latest approvals sit past the first\n // page. Walk pages until one comes back short.\n const raw: Record<string, unknown>[] = [];\n for (let page = 1; ; page += 1) {\n const batch = items(\n await api(`repos/${project}/pulls/${c.number}/reviews?per_page=100&page=${page}`),\n );\n raw.push(...batch);\n if (batch.length < 100) break;\n }\n const reviews = raw\n .map((r) => ({\n login: isRecord(r.user) ? stringOf(r.user.login) : null,\n state: stringOf(r.state),\n submittedAt: stringOf(r.submitted_at),\n }))\n .filter(\n (r): r is { login: string; state: string; submittedAt: string } =>\n r.login !== null && r.state !== null && r.submittedAt !== null,\n );\n return { id: c.number, mergedAt, approvals: latestApprovals(reviews) };\n }\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// GitLab\n\n/**\n * GitLab through `glab`. `:fullpath` is substituted by glab from the current\n * repository, which is why the client runs from the checkout.\n *\n * - `glab api --hostname <host> projects/:fullpath/repository/commits/<sha>/merge_requests`\n * - `glab api --hostname <host> projects/:fullpath/merge_requests/<iid>/approvals`\n *\n * GitLab records who approved but not when, so every approval is stamped\n * with the MR's `merged_at`; `deriveFromReviews` says so in the evidence.\n */\nexport class GitLabClient extends CliClient {\n protected readonly tool = \"glab\";\n\n protected async lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null> {\n const { host } = identity;\n const api = (endpoint: string): Promise<unknown> =>\n this.json([\"api\", \"--hostname\", host, endpoint]);\n\n const merged = items(\n await api(`projects/:fullpath/repository/commits/${sha}/merge_requests`),\n )\n .map((mr) => ({ iid: numberOf(mr.iid), mergedAt: stringOf(mr.merged_at) }))\n .find(\n (mr): mr is { iid: number; mergedAt: string } =>\n mr.iid !== null && mr.mergedAt !== null,\n );\n if (merged === undefined) return null;\n\n const answer = await api(`projects/:fullpath/merge_requests/${merged.iid}/approvals`);\n const approvedBy = isRecord(answer) ? items(answer.approved_by) : [];\n const approvals: Approval[] = [];\n const seen = new Set<string>();\n for (const entry of approvedBy) {\n const login = isRecord(entry.user) ? stringOf(entry.user.username) : null;\n if (login === null) continue;\n const key = normalizeLogin(login);\n if (seen.has(key)) continue;\n seen.add(key);\n approvals.push({ login, submittedAt: merged.mergedAt });\n }\n return { id: merged.iid, mergedAt: merged.mergedAt, approvals };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Assembly\n\n/**\n * The client for the repository at `root`: origin read with\n * `git remote get-url origin`, the CLI chosen by `identityFromOrigin`, the\n * result wrapped in the on-disk cache. No origin (or no git) yields a client\n * whose `status()` says so; nothing throws here, because \"no host\" is a\n * source being unavailable, and that is reported where sources are reported.\n *\n * The CLI is spawned in `root`, not in the caller's `cwd`: `glab` fills in\n * `:fullpath` from the repository it runs in, and `gh` detects the\n * repository the same way, so the child must run from the checkout this\n * client answers for. `spawn.cwd` is the test seam that overrides that.\n */\nexport async function createReviewClient(\n root: string,\n opts: {\n cwd: string;\n cache: boolean;\n cacheDir: string;\n spawn?: Partial<SpawnOptions>;\n /** The review sources the run requested; decides a host that names neither platform. */\n requested?: readonly RemoteIdentity[\"kind\"][];\n },\n): Promise<ReviewClient> {\n const spawnOpts: SpawnOptions = { ...opts.spawn, cwd: opts.spawn?.cwd ?? root };\n const origin = await originUrl(root);\n const parsed = origin === null ? null : parseOriginUrl(origin);\n const identity =\n parsed === null ? null : identityFromOrigin(parsed.host, parsed.project, opts.requested);\n if (parsed !== null && identity === null) return new UnknownHostClient(parsed.host);\n const client =\n identity?.kind === \"gitlab\"\n ? new GitLabClient(identity, spawnOpts)\n : new GitHubClient(identity, spawnOpts);\n const cache = new ReviewCache(resolvePath(root, opts.cacheDir), opts.cache);\n return cachedClient(client, cache, identity);\n}\n\n/** `git remote get-url origin`, or null when there is no origin or no git. */\nasync function originUrl(root: string): Promise<string | null> {\n try {\n const r = await run(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd: root });\n if (r.code !== 0 || r.timedOut || r.tooLarge) return null;\n return stringOf(r.stdout.trim());\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The source\n\nexport interface ReviewSourceInput {\n label: string;\n /** The newest body-changing commit; `null` for a working-tree document. */\n sha: string | null;\n}\n\nexport interface ReviewFacts {\n \"reviewed-by\": DerivedValue | null;\n \"last-reviewed\": DerivedValue | null;\n}\n\nexport interface ReviewSourceResult {\n status: SourceStatus;\n /** By label. Empty when the source is unavailable. */\n records: Map<string, ReviewFacts>;\n}\n\nconst NOTHING: ReviewFacts = { \"reviewed-by\": null, \"last-reviewed\": null };\n\n/**\n * `reviewed-by` is every approver of the merged change, in approval order,\n * and every fact names the source of the host it came from, `github` or `gitlab`;\n * `last-reviewed` is the UTC date of the latest approval. A document with no\n * commit, no merged change, or a change nobody approved derives `null` for\n * both. One host lookup per distinct sha, however many documents share it.\n *\n * An unavailable client is reported and never called: `status.reason` names\n * the fix, and the caller decides whether that fails the run.\n */\nexport async function deriveFromReviews(\n inputs: readonly ReviewSourceInput[],\n client: ReviewClient,\n): Promise<ReviewSourceResult> {\n const records = new Map<string, ReviewFacts>();\n const status = await client.status();\n if (!status.available) return { status, records };\n\n const identity = await client.detect();\n // `status()` answering `available` means the client found its host, so both\n // built-in clients return an identity here. The fallback serves only a\n // custom `ReviewClient` that breaks that promise, and it attributes every\n // fact to GitHub. Such a client should return an identity from `detect()`.\n const kind = identity?.kind ?? \"github\";\n const bySha = new Map<string, Promise<MergedChange | null>>();\n const changeFor = (sha: string): Promise<MergedChange | null> => {\n let pending = bySha.get(sha);\n if (pending === undefined) {\n pending = client.mergedChangeFor(sha);\n bySha.set(sha, pending);\n }\n return pending;\n };\n\n for (const input of inputs) {\n if (input.sha === null) {\n records.set(input.label, NOTHING);\n continue;\n }\n const change = await changeFor(input.sha);\n records.set(input.label, factsFrom(change, kind));\n }\n return { status, records };\n}\n\nfunction factsFrom(change: MergedChange | null, kind: RemoteIdentity[\"kind\"]): ReviewFacts {\n if (change === null || change.approvals.length === 0) return NOTHING;\n // Sorted here too: a `ReviewClient` from outside this module makes no\n // ordering promise, and the field order is what the reader sees.\n const ordered = byTime(change.approvals);\n const latest = ordered.at(-1);\n if (latest === undefined) return NOTHING;\n const evidence = kind === \"gitlab\" ? `gitlab MR !${change.id}` : `github PR #${change.id}`;\n const dateEvidence =\n kind === \"gitlab\"\n ? `${evidence} (merge date; GitLab records no approval time)`\n : evidence;\n return {\n \"reviewed-by\": {\n value: ordered.map((a) => a.login),\n source: kind,\n evidence,\n },\n \"last-reviewed\": {\n value: utcDate(latest.submittedAt),\n source: kind,\n evidence: dateEvidence,\n },\n };\n}\n\n/** `YYYY-MM-DD` in UTC; the timestamp's own text when it does not parse. */\nfunction utcDate(iso: string): string {\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return iso;\n return new Date(ms).toISOString().slice(0, 10);\n}\n","/**\n * The derived channel's front door: one call resolves every requested field\n * for every input from the sources the run consults.\n *\n * Three rules live here and nowhere else:\n *\n * 1. **A source is consulted only when a requested field can come from it.**\n * `FIELD_SOURCES` says which for the built-ins, and `derive.commands`\n * which keys the `command` source answers; the run's `sources` list\n * narrows it. A source nobody asked for is never spawned and never\n * reported, and a command for a field the run did not request is never\n * spawned either.\n * 2. **The review sources ride on git, and the origin remote picks one.**\n * `github` and `gitlab` both read the merged change behind a document's\n * newest body-changing commit, which only the git walk can name, so\n * either without `git` is reported unavailable with the fix rather than\n * silently answering null. Per repository root, the origin remote says\n * which host the repository lives on, and only the review source of that\n * name is consulted and reported: a run that allows both on a GitHub\n * repository reports `github` alone. A run that allows only the other\n * one is told which host the origin is, and what to change.\n * 3. **Precedence is per field, first non-null wins.** `reviewed-by` and\n * `last-reviewed` prefer the host's approvals over a `Reviewed-by`\n * trailer; every other field has one source.\n *\n * Availability is reported, not thrown: a caller decides what an\n * unavailable source means for its run through `assertSourcesAvailable`,\n * because the hint differs per command (`--no-derive` on validate,\n * `--sources` on derive).\n */\nimport { dirname, resolve } from \"node:path\";\nimport { findGitRoot } from \"../../../shared/git-root.js\";\nimport { DocmetaError } from \"../../types.js\";\nimport { REVIEW_CACHE_DIR } from \"./cache.js\";\nimport { deriveFromCodeowners } from \"./codeowners.js\";\nimport { deriveFromCommands } from \"./command.js\";\nimport { createReviewClient, deriveFromReviews, type ReviewFacts } from \"./reviews.js\";\nimport { deriveFromGit, type GitFacts } from \"./git.js\";\nimport { isBuiltinField } from \"./types.js\";\nimport type {\n BuiltinDerivableField,\n DerivableField,\n DeriveCommand,\n DeriveContext,\n DerivedRecord,\n DerivedValue,\n DeriveInput,\n DeriveSource,\n RemoteIdentity,\n ReviewClient,\n SourceStatus,\n} from \"./types.js\";\n\n/** Which sources can state each built-in field, in precedence order. */\nexport const FIELD_SOURCES: Readonly<Record<BuiltinDerivableField, readonly DeriveSource[]>> = {\n created: [\"git\"],\n \"last-updated\": [\"git\"],\n authors: [\"git\"],\n owner: [\"codeowners\"],\n \"reviewed-by\": [\"github\", \"gitlab\", \"git\"],\n \"last-reviewed\": [\"github\", \"gitlab\", \"git\"],\n};\n\n/** The sources that read a host's review record; one per host, named for it. */\ntype ReviewSource = RemoteIdentity[\"kind\"];\n\nconst REVIEW_SOURCES: readonly ReviewSource[] = [\"github\", \"gitlab\"];\n\n/** How the host is spelled to a person, as opposed to as a source name. */\nconst HOST_NAME: Readonly<Record<ReviewSource, string>> = {\n github: \"GitHub\",\n gitlab: \"GitLab\",\n};\n\nexport interface DeriveResult {\n /** Keyed by `DeriveInput.label`; every input has a record. */\n records: Map<string, DerivedRecord>;\n /**\n * One status per source the run consulted. A source nobody asked for is\n * absent, and so is whichever of `github` and `gitlab` the origin remote does\n * not point at. Absent means not applicable here, never unavailable.\n */\n sources: Partial<Record<DeriveSource, SourceStatus>>;\n}\n\n/**\n * Which sources can state a field, in precedence order: the built-in table\n * for one of the six, `command` for a key of `commands`, nothing otherwise.\n * A built-in never reaches the command arm, whatever the table says.\n */\nexport function sourcesFor(\n field: DerivableField,\n commands?: Readonly<Record<string, DeriveCommand>>,\n): readonly DeriveSource[] {\n if (isBuiltinField(field)) return FIELD_SOURCES[field];\n if (commands !== undefined && Object.hasOwn(commands, field)) return [\"command\"];\n return [];\n}\n\n/** The sources a run consults: requested, and able to state a requested field. */\nexport function consultedSources(\n fields: readonly DerivableField[],\n sources: readonly DeriveSource[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): DeriveSource[] {\n const needed = new Set<DeriveSource>();\n for (const field of fields) {\n for (const s of sourcesFor(field, commands)) needed.add(s);\n }\n return sources.filter((s) => needed.has(s));\n}\n\n/**\n * Throw the exit-2 error for the first consulted source that could not\n * answer. `hint` is the command's own way out, appended after a semicolon.\n */\nexport function assertSourcesAvailable(\n sources: Partial<Record<DeriveSource, SourceStatus>>,\n hint?: string,\n): void {\n for (const name of Object.keys(sources) as DeriveSource[]) {\n const status = sources[name];\n if (status === undefined || status.available) continue;\n const reason = status.reason ?? \"it could not answer\";\n throw new DocmetaError(\n `${name} source unavailable: ${reason}${hint === undefined ? \"\" : `; ${hint}`}`,\n );\n }\n}\n\nexport async function deriveMetadata(\n inputs: readonly DeriveInput[],\n ctx: DeriveContext,\n): Promise<DeriveResult> {\n const consulted = new Set(consultedSources(ctx.fields, ctx.sources, ctx.commands));\n const sources: Partial<Record<DeriveSource, SourceStatus>> = {};\n\n // git: the walk every other source builds on.\n let git: Map<string, GitFacts> = new Map();\n if (consulted.has(\"git\")) {\n const result = await deriveFromGit(inputs, { cwd: ctx.cwd, now: ctx.now });\n sources.git = result.status;\n git = result.records;\n }\n\n // Repository root per input: git's answer where it gave one, the .git walk otherwise.\n const rootCache = new Map<string, string | null>();\n const rootOf = (absPath: string): string | null => {\n const dir = dirname(absPath);\n let root = rootCache.get(dir);\n if (root === undefined) {\n root = findGitRoot(dir);\n rootCache.set(dir, root);\n }\n return root;\n };\n const rootFor = (input: DeriveInput): string | null =>\n git.get(input.label)?.root ?? rootOf(input.absPath);\n\n // codeowners\n let owners: Map<string, DerivedValue | null> = new Map();\n if (consulted.has(\"codeowners\")) {\n const result = await deriveFromCodeowners(inputs, {\n explicit: ctx.codeowners,\n configDir: ctx.configDir,\n rootOf,\n });\n sources.codeowners = result.status;\n owners = result.records;\n }\n\n // github / gitlab: one client per repository root, or the injected seam\n // for all. Which of the two a root uses is the origin remote's call.\n const requested = REVIEW_SOURCES.filter((s) => consulted.has(s));\n let reviews: Map<string, ReviewFacts> = new Map();\n if (requested.length > 0) {\n if (!consulted.has(\"git\")) {\n for (const s of requested) {\n sources[s] = {\n available: false,\n reason: `the ${s} source needs the git source to find each document's commits; add git to sources`,\n };\n }\n } else if (sources.git?.available === false) {\n // Git already failed the run; every review lookup starts from a commit\n // git names, so spawning gh/glab now would be wasted calls before the\n // same exit 2.\n for (const s of requested) {\n sources[s] = {\n available: false,\n reason: `the git source could not answer, so the ${s} source cannot locate any commit`,\n };\n }\n } else {\n const result = await deriveReviewsByRoot(inputs, git, rootFor, ctx, requested);\n Object.assign(sources, result.status);\n reviews = result.records;\n }\n }\n\n // command: last, and only when nothing has failed yet. A configured\n // command is the one source that runs a program of the operator's own,\n // which may do more than report a value, so it is not spawned for a run\n // already destined for exit 2 — and the source that failed first is the\n // one whose reason `assertSourcesAvailable` reports.\n let commanded: Map<string, Record<string, DerivedValue | null>> = new Map();\n const doomed = Object.values(sources).some((s) => !s.available);\n if (consulted.has(\"command\") && ctx.commands !== undefined && !doomed) {\n // Only the entries for fields this run asked for, so a narrowed\n // `--fields` spawns nothing it does not need.\n const wanted = new Set(ctx.fields);\n const commands = Object.fromEntries(\n Object.entries(ctx.commands).filter(([field]) => wanted.has(field)),\n );\n if (Object.keys(commands).length > 0) {\n const result = await deriveFromCommands(inputs, commands, { cwd: ctx.configDir ?? ctx.cwd });\n sources.command = result.status;\n commanded = result.records;\n }\n }\n\n const records = new Map<string, DerivedRecord>();\n for (const input of inputs) {\n const fields: DerivedRecord[\"fields\"] = {};\n const g = git.get(input.label);\n const r = reviews.get(input.label);\n const c = commanded.get(input.label);\n for (const field of ctx.fields) {\n let value: DerivedValue | null = null;\n for (const source of sourcesFor(field, ctx.commands)) {\n if (!consulted.has(source)) continue;\n const candidate = valueFrom(source, field, g, r, owners.get(input.label), c);\n if (candidate !== null) {\n value = candidate;\n break;\n }\n }\n fields[field] = value;\n }\n records.set(input.label, { file: input.label, fields });\n }\n return { records, sources };\n}\n\nfunction valueFrom(\n source: DeriveSource,\n field: DerivableField,\n git: GitFacts | undefined,\n reviews: ReviewFacts | undefined,\n owner: DerivedValue | null | undefined,\n commanded: Readonly<Record<string, DerivedValue | null>> | undefined,\n): DerivedValue | null {\n switch (source) {\n case \"git\":\n if (git === undefined || !isBuiltinField(field) || field === \"owner\") return null;\n return git[field];\n case \"command\":\n return commanded?.[field] ?? null;\n case \"codeowners\":\n return field === \"owner\" ? (owner ?? null) : null;\n case \"github\":\n case \"gitlab\": {\n if (reviews === undefined) return null;\n if (field !== \"reviewed-by\" && field !== \"last-reviewed\") return null;\n // A fact answers for the source of the host it came from, and no other.\n const fact = reviews[field];\n return fact !== null && fact.source === source ? fact : null;\n }\n }\n}\n\n/**\n * Consult the review record for each repository root that holds an input.\n *\n * The root's origin remote picks the source: a GitHub origin uses `github`,\n * a GitLab origin `gitlab`, and only the one used is reported. When the\n * origin names a host whose source was not requested, that requested source\n * is reported unavailable with the host named and the fix spelled out. With\n * no origin at all, every requested review source is unavailable, because\n * nothing tells the two apart.\n */\nasync function deriveReviewsByRoot(\n inputs: readonly DeriveInput[],\n git: ReadonlyMap<string, GitFacts>,\n rootFor: (input: DeriveInput) => string | null,\n ctx: DeriveContext,\n requested: readonly ReviewSource[],\n): Promise<{ status: Partial<Record<ReviewSource, SourceStatus>>; records: Map<string, ReviewFacts> }> {\n const byRoot = new Map<string, DeriveInput[]>();\n for (const input of inputs) {\n const root = rootFor(input);\n if (root === null) continue;\n const bucket = byRoot.get(root) ?? [];\n bucket.push(input);\n byRoot.set(root, bucket);\n }\n const status: Partial<Record<ReviewSource, SourceStatus>> = {};\n const records = new Map<string, ReviewFacts>();\n const unavailable = (\n which: readonly ReviewSource[],\n reason: string,\n ): { status: Partial<Record<ReviewSource, SourceStatus>>; records: Map<string, ReviewFacts> } => {\n for (const s of which) status[s] = { available: false, reason };\n return { status, records: new Map() };\n };\n if (byRoot.size === 0) {\n return unavailable(requested, \"no git repository contains the documents\");\n }\n const cacheDir = resolve(ctx.configDir ?? ctx.cwd, REVIEW_CACHE_DIR);\n for (const [root, bucket] of byRoot) {\n const client: ReviewClient =\n ctx.reviews ??\n (await createReviewClient(root, { cwd: ctx.cwd, cache: ctx.cache, cacheDir, requested }));\n const identity = await client.detect();\n if (identity === null) {\n // No origin, or a host that names neither platform: the client's own\n // status says which, and names the fix.\n const s = await client.status();\n return unavailable(requested, s.reason ?? \"no origin remote to tell GitHub from GitLab\");\n }\n const source = identity.kind;\n if (!requested.includes(source)) {\n return unavailable(\n requested,\n `the origin remote is ${identity.host}, which is ${HOST_NAME[source]}; add ${source} to sources, or drop reviewed-by and last-reviewed from the managed fields`,\n );\n }\n const result = await deriveFromReviews(\n bucket.map((input) => ({\n label: input.label,\n sha: git.get(input.label)?.lastBodyCommit ?? null,\n })),\n client,\n );\n // One root that cannot answer makes the source unavailable for the run:\n // a half-derived review field would read as \"nobody approved\", which is\n // the false green the whole channel refuses.\n if (!result.status.available) {\n status[source] = result.status;\n return { status, records: new Map() };\n }\n status[source] = result.status;\n for (const [label, facts] of result.records) records.set(label, facts);\n }\n return { status, records };\n}\n\n","/**\n * Derive `owner` from a CODEOWNERS file.\n *\n * Unlike `.gitignore` (see `../gitignore.ts`), CODEOWNERS is matched here\n * rather than by asking a tool. There is no `git check-codeowners`, and the\n * language is the small end of gitignore: GitHub allows no `!` negation and no\n * character ranges, there is one file rather than a stack of nested ones, and\n * the precedence rule is \"last match wins\". That is expressible with\n * picomatch once each pattern is rewritten the way git reads it — a pattern\n * with no slash matches at any depth, a leading `/` anchors it, a trailing\n * `/` names a directory, and any match on a directory covers what is under it.\n *\n * GitLab adds sections. Every section applies, so the owners of a file are the\n * union of the last match in each section; a section may carry default owners\n * for rules that list none, `^[Name]` marks approval optional (the owners are\n * still owners), and `[Name][n]` sets the approvals required. GitHub has no\n * sections, which is the same thing as one unnamed section.\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { errorMessage } from \"../../../shared/errors.js\";\nimport type { DerivedValue, SourceStatus } from \"./types.js\";\n\n/** Where a CODEOWNERS file may live, in the order GitHub and GitLab look. */\nexport const CODEOWNERS_LOCATIONS = [\n \".github/CODEOWNERS\",\n \"CODEOWNERS\",\n \"docs/CODEOWNERS\",\n \".gitlab/CODEOWNERS\",\n] as const;\n\nexport interface CodeownersRule {\n pattern: string;\n owners: string[];\n line: number;\n /** The GitLab section the rule sits in; absent in the unnamed default section. */\n section?: string;\n}\n\nexport interface CodeownersSection {\n name: string;\n optional: boolean;\n approvals?: number;\n defaultOwners: string[];\n}\n\nexport interface CodeownersFile {\n path: string;\n /** As the run reports it: forward slashes, relative to the base. */\n label: string;\n rules: CodeownersRule[];\n sections: CodeownersSection[];\n}\n\n/**\n * The first existing location in `CODEOWNERS_LOCATIONS` under `root`, or the\n * explicit path resolved against `root`; null if none exists. An explicit\n * path that is missing is null rather than a fallback to the search, because\n * a config that names a file means that file.\n */\nexport function findCodeowners(root: string, explicit?: string): string | null {\n if (explicit !== undefined) {\n const path = resolve(root, explicit);\n return existsSync(path) ? path : null;\n }\n for (const loc of CODEOWNERS_LOCATIONS) {\n const path = resolve(root, ...loc.split(\"/\"));\n if (existsSync(path)) return path;\n }\n return null;\n}\n\n/** `[Name]`, `^[Name]`, `[Name][2]`, each optionally followed by default owners. */\nconst SECTION_HEADER = /^(\\^?)\\[([^\\]]+)\\](?:\\[(\\d+)\\])?(.*)$/;\n\n/** Tokens split on unescaped whitespace; `\\ ` stays inside its token. */\nconst TOKEN = /(?:\\\\.|[^\\s\\\\])+/g;\n\n/**\n * Parse CODEOWNERS text. Never throws: a line that cannot be read as a rule\n * or a section header (an unclosed `[Name`, say) is skipped, since the host\n * would skip it too and a derived value should not fail the run over it.\n */\nexport function parseCodeowners(\n text: string,\n path: string,\n label: string,\n): CodeownersFile {\n const rules: CodeownersRule[] = [];\n const sections: CodeownersSection[] = [];\n let current: CodeownersSection | undefined;\n\n const lines = text.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i += 1) {\n const raw = lines[i] ?? \"\";\n const line = raw.trim();\n if (line === \"\" || line.startsWith(\"#\")) continue;\n\n if (line.startsWith(\"[\") || line.startsWith(\"^[\")) {\n const m = SECTION_HEADER.exec(line);\n if (!m) continue;\n const [, caret, rawName, approvals, rest] = m;\n const name = (rawName ?? \"\").trim();\n if (name === \"\") continue;\n const owners = tokens(rest ?? \"\");\n // GitLab merges repeated headers of one section, case-insensitively.\n const existing = sections.find(\n (s) => s.name.toLowerCase() === name.toLowerCase(),\n );\n if (existing) {\n if (owners.length > 0) existing.defaultOwners = owners;\n current = existing;\n continue;\n }\n const section: CodeownersSection = {\n name,\n optional: caret === \"^\",\n ...(approvals !== undefined ? { approvals: Number(approvals) } : {}),\n defaultOwners: owners,\n };\n sections.push(section);\n current = section;\n continue;\n }\n\n const [first, ...owners] = tokens(line);\n if (first === undefined) continue;\n const pattern = unescapePattern(first);\n if (pattern === \"\" || pattern === \"/\") continue;\n rules.push({\n pattern,\n owners,\n line: i + 1,\n ...(current ? { section: current.name } : {}),\n });\n }\n return { path, label, rules, sections };\n}\n\nfunction tokens(s: string): string[] {\n return s.match(TOKEN) ?? [];\n}\n\n/**\n * `\\ ` is a literal space and `\\#` a literal hash at the start; every other\n * escape is left for picomatch, where `\\*` still means a literal star.\n */\nfunction unescapePattern(token: string): string {\n return token.replace(/\\\\ /g, \" \").replace(/^\\\\#/, \"#\");\n}\n\n/**\n * Owners of `relPath` (repository-relative, forward slashes) under `file`,\n * with the line of the last winning rule; null when no rule in any section\n * matches. Within a section the last matching rule wins outright, a winner\n * that lists no owners takes the section's default owners, and a winner with\n * neither means \"no owner\" — a match that clears the field rather than a\n * miss. Across sections the winners' owners are unioned in section order,\n * first appearance kept.\n */\nexport function ownersFor(\n file: CodeownersFile,\n relPath: string,\n): { owners: string[]; line: number } | null {\n const matchers = matchersFor(file);\n const defaults = new Map(file.sections.map((s) => [s.name, s.defaultOwners]));\n\n // Section order is first appearance; the unnamed default section is first.\n const order: (string | undefined)[] = [undefined, ...file.sections.map((s) => s.name)];\n const winners = new Map<string | undefined, CodeownersRule>();\n file.rules.forEach((rule, i) => {\n if (matchers[i]?.(relPath)) winners.set(rule.section, rule);\n });\n if (winners.size === 0) return null;\n\n // The evidence line is the last winner that named an owner, so it points\n // at a rule the reader can see owners on. A winner that names nobody (no\n // owners, no section default) sets the line only when no winner named\n // anyone, which is the \"no owner\" clearing case.\n const owners: string[] = [];\n let line = 0;\n let lineFromOwner = false;\n for (const section of order) {\n const rule = winners.get(section);\n if (!rule) continue;\n const chosen =\n rule.owners.length > 0\n ? rule.owners\n : (section === undefined ? undefined : defaults.get(section)) ?? [];\n if (chosen.length > 0) {\n line = rule.line;\n lineFromOwner = true;\n } else if (!lineFromOwner) {\n line = rule.line;\n }\n for (const o of chosen) if (!owners.includes(o)) owners.push(o);\n }\n return { owners, line };\n}\n\nconst matcherCache = new WeakMap<CodeownersFile, ((p: string) => boolean)[]>();\n\nfunction matchersFor(file: CodeownersFile): ((p: string) => boolean)[] {\n let matchers = matcherCache.get(file);\n if (!matchers) {\n matchers = file.rules.map((r) => picomatch(toGlobs(r.pattern), PICOMATCH));\n matcherCache.set(file, matchers);\n }\n return matchers;\n}\n\n/**\n * `dot` because CODEOWNERS covers `.github/` and friends as a matter of\n * course, and gitignore's `*` never skips dotfiles. `windows: false` pins\n * posix semantics on every platform: the paths handed in are already\n * forward-slashed, and letting picomatch treat `\\` as a separator on Windows\n * would silently change what a `\\*` escape in the file means there.\n */\nconst PICOMATCH = { dot: true, windows: false } as const;\n\n/**\n * Rewrite one CODEOWNERS pattern into the picomatch globs that read it the\n * way git does. A pattern with no slash (or only a trailing one) matches at\n * any depth, so it gets a globstar-and-slash prefix; a leading `/` or a slash\n * in the middle anchors it to the root. A match on a directory covers\n * everything under it, so a second glob with a slash-and-globstar suffix is\n * included when the last segment is a literal name that could be one; a\n * trailing `/` means *only* a directory, so the bare pattern is then left\n * out. A last segment with a wildcard gets no twin: GitHub reads `docs/*`\n * as the files directly in `docs/`, not `docs/build-app/troubleshooting.md`,\n * and `*.md` already reaches any depth through its globstar prefix.\n */\nfunction toGlobs(pattern: string): string[] {\n let p = pattern;\n const dirOnly = p.endsWith(\"/\");\n if (dirOnly) p = p.slice(0, -1);\n let anchored = false;\n if (p.startsWith(\"/\")) {\n anchored = true;\n p = p.slice(1);\n } else if (p.includes(\"/\") && !p.startsWith(\"**/\")) {\n anchored = true;\n }\n const base = anchored || p.startsWith(\"**/\") ? p : `**/${p}`;\n if (dirOnly) return [`${base}/**`];\n const last = p.slice(p.lastIndexOf(\"/\") + 1);\n return /[*?[]/.test(last) ? [base] : [base, `${base}/**`];\n}\n\nexport interface CodeownersSourceOptions {\n /** Explicit path from config `derive.codeowners`, resolved against `configDir`. */\n explicit?: string;\n configDir?: string;\n /** Repository root for an input's absolute path; null when outside a repository. */\n rootOf: (absPath: string) => string | null;\n}\n\nexport interface CodeownersSourceResult {\n status: SourceStatus;\n /** Keyed by label; an input outside any repository is absent. */\n records: Map<string, DerivedValue | null>;\n}\n\nconst NOT_FOUND_REASON = `no CODEOWNERS file found (looked for ${CODEOWNERS_LOCATIONS.join(\", \")})`;\n\n/**\n * Derive owners for every input that sits in a repository. Inputs are grouped\n * by root and each root resolves its own file — the explicit path when the\n * config names one, otherwise the first location found under that root.\n *\n * A root with no file yields null records, and so does a run where no root\n * has one: a repository that declares no owners is a fact, not a broken\n * source, so the status stays available and carries the search as a\n * `reason` for the caller to surface as a notice. Only an explicit\n * `derive.codeowners` path that does not exist is unavailable — a configured\n * file that is missing is the operator's error, and silently answering null\n * there would be the green gate over nothing that the channel refuses.\n */\nexport async function deriveFromCodeowners(\n inputs: readonly { label: string; absPath: string }[],\n opts: CodeownersSourceOptions,\n): Promise<CodeownersSourceResult> {\n const records = new Map<string, DerivedValue | null>();\n\n const explicitPath =\n opts.explicit === undefined\n ? undefined\n : resolve(opts.configDir ?? process.cwd(), opts.explicit);\n if (explicitPath !== undefined && !existsSync(explicitPath)) {\n return {\n status: { available: false, reason: `CODEOWNERS not found at ${explicitPath}` },\n records,\n };\n }\n\n const byRoot = new Map<string, { label: string; absPath: string }[]>();\n const rootCache = new Map<string, string | null>();\n for (const input of inputs) {\n // Keyed by directory: every file in one directory shares its repository.\n const dir = dirname(input.absPath);\n let root = rootCache.get(dir);\n if (root === undefined) {\n root = opts.rootOf(input.absPath);\n rootCache.set(dir, root);\n }\n if (root === null) continue;\n const bucket = byRoot.get(root);\n if (bucket) bucket.push(input);\n else byRoot.set(root, [input]);\n }\n\n let found = 0;\n const parsed = new Map<string, Promise<CodeownersFile>>();\n for (const [root, bucket] of byRoot) {\n const path = explicitPath ?? findCodeowners(root);\n if (path === null) {\n for (const input of bucket) records.set(input.label, null);\n continue;\n }\n found += 1;\n const label = toPosix(relative(opts.configDir ?? root, path));\n const key = `${path}\\0${label}`;\n let file = parsed.get(key);\n if (!file) {\n file = readFile(path, \"utf8\").then((text) =>\n parseCodeowners(text, path, label),\n );\n parsed.set(key, file);\n }\n let owners: CodeownersFile;\n try {\n owners = await file;\n } catch (err) {\n // It was there a moment ago: deleted since, or not a readable file at\n // all. A source that cannot answer says so. It never crashes the run,\n // and it never answers \"nobody owns this\".\n return {\n status: {\n available: false,\n reason: `CODEOWNERS at ${label} could not be read: ${errorMessage(err)}`,\n },\n records,\n };\n }\n for (const input of bucket) {\n const rel = toPosix(relative(root, input.absPath));\n const hit = ownersFor(owners, rel);\n records.set(\n input.label,\n hit === null\n ? null\n : {\n value: hit.owners,\n source: \"codeowners\",\n evidence: `${label}:${hit.line}`,\n },\n );\n }\n }\n\n if (byRoot.size === 0) {\n return {\n status: { available: false, reason: \"no git repository contains the documents\" },\n records,\n };\n }\n if (found === 0 && explicitPath === undefined) {\n return { status: { available: true, reason: NOT_FOUND_REASON }, records };\n }\n return { status: { available: true }, records };\n}\n\nfunction toPosix(p: string): string {\n return p.split(sep).join(\"/\");\n}\n","/**\n * The git source of the derived channel (proposal 0040): what history can\n * state about a document's birth, its last body change, who wrote it and who\n * reviewed it.\n *\n * Documents are grouped by the repository that contains them, as\n * `gitignore.ts` groups candidates, and each root is asked once. A root's\n * history is read in one of two forms that produce the same `FileHistory`:\n * per-file `git log --follow` for a small run, because `--follow` is what\n * carries `created` across a rename and it forbids more than one pathspec;\n * one whole-repository `git log --raw -M` walk otherwise, with renames\n * followed backwards here. The judge on top of either form is the same.\n *\n * A body change is a change outside the metadata block, so a frontmatter\n * sweep does not move `last-updated`. Blobs are compared by their bodies\n * with line endings normalised, because `core.autocrlf` rewrites a blob on\n * the way in and out of the index and that is not an edit.\n *\n * Availability is a verdict, not an exception (decision 6): git missing, no\n * repository, or a shallow checkout report `available: false` with the fix.\n */\nimport { constants as bufferConstants } from \"node:buffer\";\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { dirname, extname, relative, sep } from \"node:path\";\nimport { findGitRoot } from \"../../../shared/git-root.js\";\nimport { locateFrontmatter } from \"../../extractors/frontmatter.js\";\nimport {\n extractorByName,\n extractorForExtension,\n} from \"../../extractors/index.js\";\nimport type { MetadataExtractor } from \"../../types.js\";\nimport { toJsonText } from \"../json-text.js\";\nimport type { DeriveInput, DerivedValue, SourceStatus } from \"./types.js\";\n\n/** Facts git can state about one document. Every field is null when git answered but has no fact. */\nexport interface GitFacts {\n created: DerivedValue | null;\n \"last-updated\": DerivedValue | null;\n authors: DerivedValue | null;\n /** From `Reviewed-by` trailers only. */\n \"reviewed-by\": DerivedValue | null;\n /** From `Reviewed-by` trailers only. */\n \"last-reviewed\": DerivedValue | null;\n /** Full sha of the newest body-changing commit, for the review sources; null when uncommitted or none. */\n lastBodyCommit: string | null;\n /** Repository root the document lives in, absolute, native separators. */\n root: string;\n}\n\nexport interface GitSourceOptions {\n cwd: string;\n now: () => Date;\n /** Runs with more inputs per root than this take the bulk walk. Test seam; default 32. */\n bulkThreshold?: number;\n /**\n * Most bytes one git process may write to stdout before the root is\n * reported too large to read. Test seam; default `MAX_GIT_OUTPUT_BYTES`.\n */\n maxOutputBytes?: number;\n}\n\nexport interface GitSourceResult {\n status: SourceStatus;\n /** Keyed by `DeriveInput.label`. A document outside any repository is absent. */\n records: Map<string, GitFacts>;\n}\n\nconst DEFAULT_BULK_THRESHOLD = 32;\nconst NULL_SHA = \"0\".repeat(40);\n\n/**\n * The whole of one git process's stdout is held in memory and decoded in one\n * pass; streaming the log is out of scope for now. A history past this cap\n * is refused rather than decoded: 512 MiB, or V8's string limit where that\n * is lower, so the cap itself is what stops the run and not an\n * `ERR_STRING_TOO_LONG` from inside `Buffer#toString`.\n */\nconst MAX_GIT_OUTPUT_BYTES = Math.min(\n 512 * 1024 * 1024,\n bufferConstants.MAX_STRING_LENGTH,\n);\n\n/** A root whose history cannot be held in memory; caught by `deriveFromGit`. */\nclass HistoryTooLarge extends Error {}\n\n/**\n * `git cat-file --batch` exited non-zero: a corrupt object, a missing pack,\n * lock contention. An empty blob map would read every body as empty and\n * every history entry as unchanged, which is the false green the channel\n * refuses, so it is a failed root like a shallow clone.\n */\nclass BlobsUnreadable extends Error {\n constructor(readonly detail: string) {\n super(detail);\n }\n}\n\n/** One commit that touched a document, as either walk form reports it. */\ninterface FileHistory {\n sha: string;\n /** `%aI`: ISO 8601 in the author's own offset. */\n authorDate: string;\n authorName: string;\n authorEmail: string;\n /** `Co-authored-by` trailer values, `Name <email>` form. */\n coAuthors: string[];\n /** `Reviewed-by` trailer values, as written. */\n reviewedBy: string[];\n oldBlob: string | null;\n newBlob: string | null;\n pathAtCommit: string;\n}\n\n/**\n * Content outside the metadata block: for a fenced document the block\n * `[openStart, closeEnd)` is dropped, so a BOM ahead of it survives; anything\n * else is the whole content. Exported for the orchestrator and tests.\n */\nexport function bodyOf(content: string, fenced: boolean | undefined): string {\n if (fenced !== true) return content;\n const loc = locateFrontmatter(content);\n if (!loc) return content;\n return content.slice(0, loc.openStart) + content.slice(loc.closeEnd);\n}\n\n/**\n * Never throws for availability: git missing, no repository for any input,\n * a shallow clone, or a history too large to read report\n * `status.available: false` with a `reason` that names the fix, and an\n * empty map. One root that cannot answer makes the source unavailable for\n * the whole run, as `deriveReviewsByRoot` rules: a walk that answered for\n * some roots and silently dropped the rest would read as green for\n * documents it never looked at. An input outside any repository is not a\n * failing root; it is simply absent from the records.\n */\nexport async function deriveFromGit(\n inputs: readonly DeriveInput[],\n opts: GitSourceOptions,\n): Promise<GitSourceResult> {\n const records = new Map<string, GitFacts>();\n const byRoot = groupByRoot(inputs);\n if (byRoot.size === 0) {\n return {\n status: {\n available: false,\n reason: \"no git repository contains the documents\",\n },\n records,\n };\n }\n\n const threshold = opts.bulkThreshold ?? DEFAULT_BULK_THRESHOLD;\n const maxBytes = opts.maxOutputBytes ?? MAX_GIT_OUTPUT_BYTES;\n const reasons: string[] = [];\n for (const [root, bucket] of byRoot) {\n const run: GitRun = (args, stdin) => runGit(args, root, stdin, maxBytes);\n const shallow = await run([\"rev-parse\", \"--is-shallow-repository\"]);\n if (shallow.missing) {\n return {\n status: { available: false, reason: \"git is not on PATH\" },\n records: new Map(),\n };\n }\n if (shallow.code !== 0) {\n reasons.push(`git could not read the repository at ${root}`);\n continue;\n }\n if (text(shallow).trim() === \"true\") {\n reasons.push(\n `this checkout is shallow; use actions/checkout with fetch-depth: 0 (${root})`,\n );\n continue;\n }\n\n let histories: Map<string, FileHistory[]> | null;\n let blobs: Map<string, string>;\n try {\n histories =\n bucket.length <= threshold\n ? await perFileHistories(run, bucket)\n : await bulkHistories(run, bucket);\n if (histories === null) {\n reasons.push(`git could not read the history at ${root}`);\n continue;\n }\n blobs = await fetchBlobs(run, neededBlobs(histories));\n } catch (err) {\n if (err instanceof BlobsUnreadable) {\n reasons.push(`git cat-file could not read the history (${root}): ${err.detail}`);\n continue;\n }\n if (!(err instanceof HistoryTooLarge)) throw err;\n reasons.push(`git history is too large to read in one pass (${root})`);\n continue;\n }\n\n for (const entry of bucket) {\n const history = histories.get(entry.rel) ?? [];\n records.set(\n entry.input.label,\n judge(entry.input, root, history, blobs, opts.now),\n );\n }\n }\n\n if (reasons.length > 0) {\n return {\n status: { available: false, reason: reasons.join(\"; \") },\n records: new Map(),\n };\n }\n return { status: { available: true }, records };\n}\n\n// ---------------------------------------------------------------------------\n// Grouping\n\ninterface RootEntry {\n input: DeriveInput;\n /** Root-relative, forward slashes: how git names the path. */\n rel: string;\n}\n\nfunction groupByRoot(inputs: readonly DeriveInput[]): Map<string, RootEntry[]> {\n const rootOf = new Map<string, string | null>();\n const byRoot = new Map<string, RootEntry[]>();\n for (const input of inputs) {\n const dir = dirname(input.absPath);\n let root = rootOf.get(dir);\n if (root === undefined) {\n root = findGitRoot(dir);\n rootOf.set(dir, root);\n }\n if (root === null) continue;\n const rel = relative(root, input.absPath).split(sep).join(\"/\");\n const bucket = byRoot.get(root);\n if (bucket) bucket.push({ input, rel });\n else byRoot.set(root, [{ input, rel }]);\n }\n return byRoot;\n}\n\n// ---------------------------------------------------------------------------\n// History walks\n\n/**\n * Record format: one `\\x1e`-led header per commit, its fields `\\0`-separated,\n * trailer values `\\x1f`-separated. `--raw` lines follow each header. `-z` is\n * deliberately absent: it makes the record boundary ambiguous, where `\\x1e`\n * cannot appear in a sha, a date, or a raw line. `--no-abbrev` because\n * `--raw` shortens blob shas by default, and `cat-file` wants the full ones.\n * `unfold` because a trailer may wrap onto an indented continuation line,\n * and the header is read up to its first newline: folded, the rest of the\n * header would be taken for raw lines and the value split in two.\n */\nconst RECORD_FORMAT =\n \"--format=%x1e%H%x00%aI%x00%an%x00%ae%x00\" +\n \"%(trailers:key=Co-authored-by,valueonly,unfold,separator=%x1f)%x00\" +\n \"%(trailers:key=Reviewed-by,valueonly,unfold,separator=%x1f)\";\n\nconst LOG_ARGS = [\n \"-c\",\n \"core.quotePath=false\",\n \"log\",\n \"--raw\",\n \"-M\",\n \"--no-abbrev\",\n RECORD_FORMAT,\n];\n\n/** The per-file form: `--follow` carries the path across renames itself. */\nasync function perFileHistories(\n run: GitRun,\n bucket: RootEntry[],\n): Promise<Map<string, FileHistory[]> | null> {\n const histories = new Map<string, FileHistory[]>();\n for (const entry of bucket) {\n const out = await run([...LOG_ARGS, \"--follow\", \"--\", pathspec(entry.rel)]);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) {\n if (await isUnbornHead(run)) return histories;\n return null;\n }\n // `--follow` already walked the rename; `attribute` still applies so the\n // rename commit's own raw line is read the same way the bulk form reads it.\n const attributed = attribute(parseLog(text(out)), [entry.rel]);\n histories.set(entry.rel, attributed.get(entry.rel) ?? []);\n }\n return histories;\n}\n\n/** The bulk form: one walk, every path attributed and followed here. */\nasync function bulkHistories(\n run: GitRun,\n bucket: RootEntry[],\n): Promise<Map<string, FileHistory[]> | null> {\n const out = await run(LOG_ARGS);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) {\n if (await isUnbornHead(run)) return new Map();\n return null;\n }\n return attribute(\n parseLog(text(out)),\n bucket.map((e) => e.rel),\n );\n}\n\n/** A path with glob characters is named literally, as `gitignore.ts` does. */\nfunction pathspec(rel: string): string {\n return /[*?[\\]]/.test(rel) ? `:(literal)${rel}` : rel;\n}\n\n/** A repository with no commits yet has no history rather than a broken one. */\nasync function isUnbornHead(run: GitRun): Promise<boolean> {\n const out = await run([\"rev-parse\", \"--verify\", \"--quiet\", \"HEAD^{commit}\"]);\n return !out.missing && out.code !== 0;\n}\n\ninterface RawEntry {\n status: string;\n oldBlob: string;\n newBlob: string;\n oldPath: string;\n newPath: string;\n}\n\ninterface LogRecord {\n sha: string;\n authorDate: string;\n authorName: string;\n authorEmail: string;\n coAuthors: string[];\n reviewedBy: string[];\n raw: RawEntry[];\n}\n\nfunction parseLog(text: string): LogRecord[] {\n const records: LogRecord[] = [];\n for (const chunk of text.split(\"\\x1e\")) {\n if (chunk === \"\") continue;\n const nl = chunk.indexOf(\"\\n\");\n const header = nl === -1 ? chunk : chunk.slice(0, nl);\n const fields = header.split(\"\\0\");\n const sha = fields[0];\n if (sha === undefined || sha === \"\") continue;\n const raw: RawEntry[] = [];\n if (nl !== -1) {\n for (const line of chunk.slice(nl + 1).split(\"\\n\")) {\n const entry = parseRawLine(line);\n if (entry) raw.push(entry);\n }\n }\n records.push({\n sha,\n authorDate: fields[1] ?? \"\",\n authorName: fields[2] ?? \"\",\n authorEmail: fields[3] ?? \"\",\n coAuthors: splitTrailers(fields[4]),\n reviewedBy: splitTrailers(fields[5]),\n raw,\n });\n }\n return records;\n}\n\nfunction splitTrailers(field: string | undefined): string[] {\n if (field === undefined || field === \"\") return [];\n return field\n .split(\"\\x1f\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\");\n}\n\n/**\n * `:<oldmode> <newmode> <oldsha> <newsha> <status>\\t<path>`, or with two\n * paths after `R`/`C`. A path git still had to quote (a control character\n * or a backslash, even with `core.quotePath=false`) is C-unquoted.\n */\nfunction parseRawLine(line: string): RawEntry | null {\n if (!line.startsWith(\":\")) return null;\n const tab = line.indexOf(\"\\t\");\n if (tab === -1) return null;\n const meta = line.slice(1, tab).split(\" \");\n const oldBlob = meta[2];\n const newBlob = meta[3];\n const status = meta[4];\n if (oldBlob === undefined || newBlob === undefined || status === undefined) {\n return null;\n }\n const paths = line.slice(tab + 1).split(\"\\t\").map(unquotePath);\n const first = paths[0];\n if (first === undefined) return null;\n const second = paths[1];\n const renamed = status.startsWith(\"R\") || status.startsWith(\"C\");\n return {\n status,\n oldBlob,\n newBlob,\n oldPath: first,\n newPath: renamed && second !== undefined ? second : first,\n };\n}\n\nfunction unquotePath(p: string): string {\n if (p.length < 2 || !p.startsWith('\"') || !p.endsWith('\"')) return p;\n const inner = p.slice(1, -1);\n const bytes: number[] = [];\n for (let i = 0; i < inner.length; i += 1) {\n const ch = inner[i];\n if (ch !== \"\\\\\") {\n bytes.push(...Buffer.from(ch ?? \"\", \"utf8\"));\n continue;\n }\n const next = inner[i + 1];\n if (next === undefined) break;\n const octal = /^[0-7]{3}/.exec(inner.slice(i + 1));\n if (octal) {\n bytes.push(parseInt(octal[0], 8));\n i += 3;\n continue;\n }\n const simple: Record<string, number> = {\n a: 7, b: 8, t: 9, n: 10, v: 11, f: 12, r: 13, '\"': 34, \"\\\\\": 92,\n };\n const code = simple[next];\n if (code === undefined) bytes.push(...Buffer.from(next, \"utf8\"));\n else bytes.push(code);\n i += 1;\n }\n return Buffer.from(bytes).toString(\"utf8\");\n}\n\n/**\n * Attribute raw lines to the wanted paths, newest first, following a rename\n * backwards: after the commit that renamed `old` to `new`, the file is\n * looked for under `old`. A path deleted and later re-added is tracked\n * through the deletion, since the re-add is its newest history.\n */\nfunction attribute(\n records: LogRecord[],\n wanted: string[],\n): Map<string, FileHistory[]> {\n const histories = new Map<string, FileHistory[]>();\n // The path each wanted document is currently known by, walking backwards.\n const tracked = new Map<string, string>();\n for (const rel of wanted) {\n histories.set(rel, []);\n tracked.set(rel, rel);\n }\n for (const record of records) {\n if (record.raw.length === 0) continue;\n const byNewPath = new Map<string, RawEntry>();\n for (const entry of record.raw) byNewPath.set(entry.newPath, entry);\n for (const [rel, current] of tracked) {\n const entry = byNewPath.get(current);\n if (!entry) continue;\n histories.get(rel)?.push({\n sha: record.sha,\n authorDate: record.authorDate,\n authorName: record.authorName,\n authorEmail: record.authorEmail,\n coAuthors: record.coAuthors,\n reviewedBy: record.reviewedBy,\n oldBlob: entry.oldBlob === NULL_SHA ? null : entry.oldBlob,\n newBlob: entry.newBlob === NULL_SHA ? null : entry.newBlob,\n pathAtCommit: entry.newPath,\n });\n if (entry.oldPath !== entry.newPath) tracked.set(rel, entry.oldPath);\n }\n }\n return histories;\n}\n\n// ---------------------------------------------------------------------------\n// Blobs\n\nfunction neededBlobs(histories: Map<string, FileHistory[]>): Set<string> {\n const shas = new Set<string>();\n for (const history of histories.values()) {\n for (const h of history) {\n if (h.oldBlob !== null) shas.add(h.oldBlob);\n if (h.newBlob !== null) shas.add(h.newBlob);\n }\n }\n return shas;\n}\n\n/**\n * One `git cat-file --batch` per root, one sha per line on stdin. Output is\n * `<sha> blob <size>\\n<bytes>\\n` per object, correlated by the header's sha\n * rather than by order; a `<sha> missing` line yields nothing.\n */\nasync function fetchBlobs(\n run: GitRun,\n shas: Set<string>,\n): Promise<Map<string, string>> {\n const blobs = new Map<string, string>();\n if (shas.size === 0) return blobs;\n const out = await run([\"cat-file\", \"--batch\"], `${[...shas].join(\"\\n\")}\\n`);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) throw new BlobsUnreadable(`exit ${String(out.code)}`);\n const buf = out.raw;\n let cursor = 0;\n while (cursor < buf.length) {\n const nl = buf.indexOf(0x0a, cursor);\n if (nl === -1) break;\n const header = buf.toString(\"utf8\", cursor, nl).split(\" \");\n cursor = nl + 1;\n const sha = header[0];\n const kind = header[1];\n const size = Number(header[2]);\n if (sha === undefined || kind !== \"blob\" || !Number.isFinite(size)) {\n continue;\n }\n blobs.set(sha, buf.toString(\"utf8\", cursor, cursor + size));\n cursor += size + 1; // the trailing newline after the object\n }\n return blobs;\n}\n\n// ---------------------------------------------------------------------------\n// The judge\n\nconst git = (value: unknown, evidence: string): DerivedValue => ({\n value,\n source: \"git\",\n evidence,\n});\n\nfunction judge(\n input: DeriveInput,\n root: string,\n history: readonly FileHistory[],\n blobs: Map<string, string>,\n now: () => Date,\n): GitFacts {\n const fenced = input.extracted.fenced;\n const extractor = extractorFor(input);\n const blobBody = (sha: string | null): string | null =>\n sha === null ? null : bodyOf(blobs.get(sha) ?? \"\", fenced);\n const stampsOf = (sha: string | null): Record<string, unknown> => {\n if (sha === null) return {};\n const content = blobs.get(sha);\n return content === undefined ? {} : extractStamps(extractor, content, input.absPath);\n };\n\n // Oldest first, so authors read in order of first appearance.\n const bodyChanging = [...history]\n .reverse()\n .filter((h) => !sameBody(blobBody(h.newBlob), blobBody(h.oldBlob)));\n const oldest = history[history.length - 1];\n const newestBody = bodyChanging[bodyChanging.length - 1];\n const head = history[0];\n const headBlob = head === undefined ? null : head.newBlob;\n\n const created = oldest === undefined ? null : createdOf(oldest, stampsOf(oldest.newBlob));\n\n const workingChanged = !sameBody(\n bodyOf(input.content, fenced),\n headBlob === null ? null : blobBody(headBlob),\n );\n\n let lastUpdated: DerivedValue | null;\n let lastBodyCommit: string | null;\n if (workingChanged) {\n lastBodyCommit = null;\n const working = input.extracted.data[\"last-updated\"];\n const committed = stampsOf(headBlob)[\"last-updated\"];\n lastUpdated =\n working !== undefined && working !== null && !sameValue(working, committed)\n ? git(working, \"stamped in working tree\")\n : git(localDate(now()), \"uncommitted body change\");\n } else if (newestBody === undefined) {\n lastBodyCommit = null;\n lastUpdated = null;\n } else {\n lastBodyCommit = newestBody.sha;\n lastUpdated = lastUpdatedOf(\n newestBody,\n stampsOf(newestBody.newBlob),\n stampsOf(newestBody.oldBlob),\n );\n }\n\n const authors = bodyChanging.length === 0 ? null : authorsOf(bodyChanging);\n\n let reviewedBy: DerivedValue | null = null;\n let lastReviewed: DerivedValue | null = null;\n if (!workingChanged && newestBody !== undefined && newestBody.reviewedBy.length > 0) {\n const evidence = `Reviewed-by trailer in ${short(newestBody.sha)}`;\n reviewedBy = git(newestBody.reviewedBy.map(nameOf), evidence);\n lastReviewed = git(datePart(newestBody.authorDate), evidence);\n }\n\n return {\n created,\n \"last-updated\": lastUpdated,\n authors,\n \"reviewed-by\": reviewedBy,\n \"last-reviewed\": lastReviewed,\n lastBodyCommit,\n root,\n };\n}\n\nfunction createdOf(\n oldest: FileHistory,\n stamps: Record<string, unknown>,\n): DerivedValue {\n const stamp = stamps[\"created\"];\n if (stamp !== undefined && stamp !== null) {\n return git(stamp, `stamped in ${short(oldest.sha)}`);\n }\n const date = datePart(oldest.authorDate);\n return git(date, `added in ${short(oldest.sha)} (${date})`);\n}\n\nfunction lastUpdatedOf(\n commit: FileHistory,\n after: Record<string, unknown>,\n before: Record<string, unknown>,\n): DerivedValue {\n const stamp = after[\"last-updated\"];\n if (stamp !== undefined && stamp !== null && !sameValue(stamp, before[\"last-updated\"])) {\n return git(stamp, `stamped in ${short(commit.sha)}`);\n }\n const date = datePart(commit.authorDate);\n return git(date, `body changed in ${short(commit.sha)} (${date})`);\n}\n\n/**\n * Distinct people behind the body-changing commits, oldest first, each\n * commit's author ahead of its co-authors, deduplicated by lowercase email\n * (by lowercase name when a co-author trailer carries none). A name ending\n * `[bot]` is a machine and is left out.\n */\nfunction authorsOf(bodyChanging: readonly FileHistory[]): DerivedValue {\n const seen = new Set<string>();\n const names: string[] = [];\n const add = (name: string, email: string | null): void => {\n if (name === \"\" || name.endsWith(\"[bot]\")) return;\n const key = email === null || email === \"\" ? `name:${name.toLowerCase()}` : email.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n names.push(name);\n };\n for (const h of bodyChanging) {\n add(h.authorName, h.authorEmail);\n for (const co of h.coAuthors) add(nameOf(co), emailOf(co));\n }\n const n = bodyChanging.length;\n return git(names, `${n} body-changing ${n === 1 ? \"commit\" : \"commits\"}`);\n}\n\n// ---------------------------------------------------------------------------\n// Small helpers\n\nfunction extractorFor(input: DeriveInput): MetadataExtractor | undefined {\n return (\n extractorByName(input.extracted.format) ??\n extractorForExtension(extname(input.absPath))\n );\n}\n\n/** The stamps a blob carries; a blob that fails to parse carries none. */\nfunction extractStamps(\n extractor: MetadataExtractor | undefined,\n content: string,\n filePath: string,\n): Record<string, unknown> {\n if (!extractor) return {};\n try {\n return extractor.extract(content, filePath).data;\n } catch {\n return {};\n }\n}\n\n/**\n * Bodies compare with CRLF folded to LF: `core.autocrlf` rewrites line\n * endings between the working tree and the index, and that is not an edit.\n * An absent blob (a file being added, or one with no history) matches only\n * another absent blob.\n */\nfunction sameBody(a: string | null, b: string | null): boolean {\n if (a === null || b === null) return a === b;\n return a.replace(/\\r\\n/g, \"\\n\") === b.replace(/\\r\\n/g, \"\\n\");\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n return toJsonText(a) === toJsonText(b);\n}\n\nconst short = (sha: string): string => sha.slice(0, 7);\n\n/** The `YYYY-MM-DD` of a `%aI` string: the author's own day, no conversion. */\nconst datePart = (iso: string): string => iso.slice(0, 10);\n\nfunction localDate(d: Date): string {\n const pad = (n: number): string => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n}\n\n/** `Name <email>` → `Name`; a bare name is returned trimmed. */\nfunction nameOf(trailer: string): string {\n const lt = trailer.lastIndexOf(\"<\");\n return (lt === -1 ? trailer : trailer.slice(0, lt)).trim();\n}\n\nfunction emailOf(trailer: string): string | null {\n const m = /<([^>]*)>\\s*$/.exec(trailer);\n return m?.[1]?.trim() ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Process plumbing\n\ninterface GitOutput {\n /** Exit code; null when git was killed by a signal or never started. */\n code: number | null;\n /**\n * The bytes of stdout, undecoded: `cat-file` sizes are byte counts, and\n * the log is decoded only where it is read, through `text()`.\n */\n raw: Buffer;\n /** True when `git` itself could not be started (not on PATH). */\n missing: boolean;\n /** True when stdout passed the byte cap; `raw` is then empty. */\n tooLarge: boolean;\n}\n\n/** One git command in a fixed root, with the run's byte cap bound in. */\ntype GitRun = (args: string[], stdin?: string) => Promise<GitOutput>;\n\n/**\n * Decode stdout as UTF-8. The cap keeps the byte count under V8's string\n * limit, so a decode that still throws is treated the same way rather than\n * escaping as a crash.\n */\nfunction text(out: GitOutput): string {\n try {\n return out.raw.toString(\"utf8\");\n } catch {\n throw new HistoryTooLarge();\n }\n}\n\n/**\n * One git process from `cwd`, modelled on `checkIgnore` in gitignore.ts.\n * stdout is collected whole and capped at `maxBytes`: past the cap the\n * child is killed and the result says `tooLarge` instead of carrying the\n * bytes. Anything thrown while assembling the result rejects the promise\n * rather than escaping the 'close' handler as an uncaught exception.\n */\nfunction runGit(\n args: string[],\n cwd: string,\n stdin: string | undefined,\n maxBytes: number,\n): Promise<GitOutput> {\n return new Promise((settle, reject) => {\n let done = false;\n const finish = (out: GitOutput): void => {\n if (done) return;\n done = true;\n settle(out);\n };\n const fail = (err: unknown): void => {\n if (done) return;\n done = true;\n reject(err instanceof Error ? err : new Error(String(err)));\n };\n const failed = (missing: boolean): GitOutput => ({\n code: null,\n raw: Buffer.alloc(0),\n missing,\n tooLarge: false,\n });\n\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(\"git\", args, { cwd, windowsHide: true });\n } catch {\n finish(failed(true));\n return;\n }\n\n let chunks: Buffer[] = [];\n let total = 0;\n let tooLarge = false;\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (tooLarge) return;\n total += chunk.length;\n if (total > maxBytes) {\n tooLarge = true;\n chunks = [];\n child.kill();\n return;\n }\n chunks.push(chunk);\n });\n // Drain stderr so a chatty git cannot fill the pipe and stall.\n child.stderr.resume();\n // No binary on PATH lands here rather than throwing from spawn().\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n finish(failed(err.code === \"ENOENT\"));\n });\n // A dead child makes the pipe write fail; 'error'/'close' report that.\n child.stdin.on(\"error\", () => {});\n child.on(\"close\", (code) => {\n try {\n const raw = tooLarge ? Buffer.alloc(0) : Buffer.concat(chunks);\n finish({ code, raw, missing: false, tooLarge });\n } catch (err) {\n fail(err);\n }\n });\n\n if (stdin === undefined) child.stdin.end();\n else child.stdin.end(stdin);\n });\n}\n","/**\n * The one adapter between `derive:` as the config file spells it and the\n * derive context as the sources want it.\n *\n * The config is a user-facing document, so it says `timeout: 30`, in whole\n * seconds. Every source downstream measures in milliseconds, because that is\n * what `child_process` takes. Exactly one place should know both, and this is\n * it. It lived in `table.ts` first, which made the SQL projection the owner\n * of a unit conversion four commands need and only one of them is about\n * tables.\n */\nimport type { DeriveConfig } from \"../config.js\";\nimport type { DeriveCommand } from \"./types.js\";\n\n/** How long a configured command may run when its entry says nothing: 60 s. */\nexport const DEFAULT_COMMAND_TIMEOUT_MS = 60_000;\n\n/**\n * The `command` source's table as the derive context wants it, from the\n * config's spelling: `timeout` is in seconds there and `timeoutMs` here.\n * Undefined when the config configures no command, so a context built from\n * it consults the source for nothing.\n */\nexport function commandsOf(\n config?: DeriveConfig,\n): Readonly<Record<string, DeriveCommand>> | undefined {\n if (config?.commands === undefined) return undefined;\n const out: Record<string, DeriveCommand> = {};\n for (const [field, c] of Object.entries(config.commands)) {\n out[field] = {\n run: c.run,\n timeoutMs:\n c.timeout === undefined ? DEFAULT_COMMAND_TIMEOUT_MS : Math.round(c.timeout * 1000),\n };\n }\n return out;\n}\n","/**\n * The `derived` table (proposal 0040): what the evidence says each derivable\n * field should be, one row per file, as a read-only SQL view beside `docs`.\n *\n * `query` builds it when a statement names it, and a corpus check that names\n * it gets the same view — this module is what keeps the two from drifting.\n * It is a view over a backing table rather than a table, so that SQLite's own\n * `cannot modify derived because it is a view` refuses a write before any\n * effect gate has to: the value it holds is not stored anywhere, and the only\n * way to change it is to change the evidence. Both objects are transient: a\n * `--db` export drops them before the handle closes, so a frozen derived\n * value never outlives the run that computed it.\n *\n * The columns are the run's: the six built-in fields, then one per key of\n * `derive.commands` (proposal 0042), so a command-derived field is read\n * exactly as a built-in one is.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport type { DocmetaConfig } from \"../config.js\";\nimport { bindValue, quoteIdent, RESERVED } from \"../projection.js\";\nimport { commandsOf } from \"./config.js\";\nimport { assertSourcesAvailable, deriveMetadata } from \"./index.js\";\nimport {\n DERIVE_SOURCES,\n derivableFields,\n type DerivableField,\n type DeriveCommand,\n type DerivedRecord,\n type DeriveInput,\n} from \"./types.js\";\n\n/** The view's name, and the backing table the rows actually sit in. */\nexport const DERIVED_VIEW = \"derived\";\nexport const DERIVED_ROWS = \"_derived_rows\";\n\n/** The third table: the effective value per field, over `docs` and the rows. */\nexport const RESOLVED_VIEW = \"resolved\";\n\n/** The two columns `resolved` adds past the fields: which side, and why. */\nconst ORIGIN_COLUMN = \"_origin\";\nconst SOURCES_COLUMN = \"_sources\";\n\n/** The view's columns, in order: the path, every derivable field, the evidence. */\nexport function derivedColumns(commands?: Readonly<Record<string, DeriveCommand>>): string[] {\n return [\"_path\", ...derivableFields(commands), SOURCES_COLUMN];\n}\n\n/**\n * Does the statement name the `derived` table? The search wants `derived`\n * where a table goes — after FROM, JOIN, UPDATE, INTO, TABLE or VIEW, bare\n * or double-quoted — so that the word inside a string literal, a comment or\n * a column alias does not spawn git for nothing. A spelling this misses\n * (`main.derived`, a CTE that shadows it) is caught by the engine's own\n * `no such table: derived`, which `query` rescues with a lazy build.\n */\nexport function mentionsDerived(sql: string): boolean {\n return /\\b(?:from|join|update|into|table|view)\\s+(?:\"derived\"|derived\\b)/i.test(sql);\n}\n\n/**\n * The derivable fields a statement can read, out of `fields` — the run's\n * own list, see `derivableFields`: every one of them when it selects `*`, or\n * reads `_sources` or `_origin` (the evidence and the origin map span them\n * all), otherwise the field names\n * it spells out, quoted or not. `owner` is not `owners` and `created` is\n * not `recreated`, and the hyphen inside `last-updated` counts as part of\n * the name; a command key is matched as written, whatever it contains.\n * Over-triggering costs one source consulted for nothing; under-triggering\n * would leave a named column NULL, so a field that appears anywhere in the\n * text — a literal, a comment — is derived.\n */\nexport function fieldsForSql(sql: string, fields: readonly DerivableField[]): DerivableField[] {\n if (sql.includes(\"*\") || /\\b_(?:sources|origin)\\b/i.test(sql)) return [...fields];\n return fields.filter((field) =>\n new RegExp(`(?<![\\\\w-])${escapeRegExp(field)}(?![\\\\w-])`, \"i\").test(sql),\n );\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Create the backing table, load one row per record, and expose it as the\n * `derived` view. `columns` is the run's list (`derivedColumns`), and the\n * values are placed by it, so the view and the rows agree by construction.\n * Values go through `bindValue`, so a list is JSON text exactly as it is in\n * `docs`; `_sources` is the JSON object `{field: {source, evidence}}` over\n * the non-null fields.\n */\nexport function createDerivedView(\n db: DatabaseSync,\n records: ReadonlyMap<string, DerivedRecord>,\n columns: readonly string[],\n): void {\n const quoted = columns.map(quoteIdent);\n db.exec(\n `CREATE TABLE ${DERIVED_ROWS} (${quoted\n .map((c, i) => (i === 0 ? `${c} TEXT PRIMARY KEY` : `${c} TEXT`))\n .join(\", \")})`,\n );\n const insert = db.prepare(\n `INSERT INTO ${DERIVED_ROWS} VALUES (${quoted.map(() => \"?\").join(\", \")})`,\n );\n const fields = columns.slice(1, -1);\n db.exec(\"BEGIN\");\n // Committed or rolled back, never left open: the caller may keep using the\n // handle after a failed insert, and every later statement would otherwise\n // run inside the half-built transaction.\n let committed = false;\n try {\n for (const [label, record] of records) {\n const sources: Record<string, { source: string; evidence: string }> = {};\n const values = fields.map((field) => {\n const derived = record.fields[field];\n if (derived == null) return null;\n sources[field] = { source: derived.source, evidence: derived.evidence };\n return bindValue(derived.value);\n });\n insert.run(label, ...values, JSON.stringify(sources));\n }\n db.exec(\"COMMIT\");\n committed = true;\n } finally {\n if (!committed) db.exec(\"ROLLBACK\");\n }\n db.exec(`CREATE VIEW ${DERIVED_VIEW} AS SELECT * FROM ${DERIVED_ROWS}`);\n}\n\n/**\n * Every column `resolved` carries, in order: `_path`, the `docs` data columns,\n * then any derivable field `docs` does not already have, then `_origin` and\n * `_sources`. A docs column that is also a derivable field appears once, in\n * the position `docs` gives it, so the field list only ever adds.\n *\n * The system columns are skipped: `_path` is already first, and `_format`,\n * `_present` and `_data` are facts about the document rather than values a\n * source could state. A frontmatter key spelled `_origin` or `_sources` is\n * skipped for the same reason a reserved one is — the column is taken.\n */\nexport function resolvedColumns(\n docsColumns: readonly string[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): string[] {\n const columns = [\"_path\"];\n const seen = new Set<string>([\"_path\", ORIGIN_COLUMN, SOURCES_COLUMN]);\n for (const column of docsColumns) {\n if (seen.has(column) || RESERVED.has(column)) continue;\n seen.add(column);\n columns.push(column);\n }\n for (const field of derivableFields(commands)) {\n if (seen.has(field)) continue;\n seen.add(field);\n columns.push(field);\n }\n columns.push(ORIGIN_COLUMN, SOURCES_COLUMN);\n return columns;\n}\n\n/**\n * Does the statement name the `resolved` table? The twin of `mentionsDerived`,\n * with the same shape and the same reason: `resolved` where a table goes, so\n * that a column alias or the word inside `unresolved` does not build a view —\n * and, more to the point, does not spawn git behind it.\n */\nexport function mentionsResolved(sql: string): boolean {\n return /\\b(?:from|join|update|into|table|view)\\s+(?:\"resolved\"|resolved\\b)/i.test(sql);\n}\n\n/** One field name as a SQLite JSON path step: `$.\"last-updated\"`. */\nfunction jsonPath(field: string): string {\n // JSON.stringify quotes and escapes exactly the way SQLite's path parser\n // reads a quoted label — `\\\"` for a quote, `\\\\` for a backslash — and the\n // way the label was written into `_data` in the first place.\n return `$.${JSON.stringify(field)}`;\n}\n\n/** Any string as a SQL string literal (doubling internal apostrophes). */\nfunction sqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Create the `resolved` view: one row per `docs` row, holding the effective\n * value of every field — what the document asserts when it carries the key,\n * what the evidence derived otherwise — plus `_origin` saying which of the two\n * answered, and the derived row's `_sources` unchanged. Call after\n * `createDocsTable` and `createDerivedView`.\n *\n * **Presence is decided by `_data`, never by NULL.** A docs column is NULL\n * both when the key is absent and when the document writes `key: null`, and\n * those are opposite answers: an explicit null is an assertion, and the\n * derived value must not overwrite it. So each field asks\n * `json_type(_data, '$.\"field\"') IS NOT NULL`, which is true for a JSON null\n * and false for an absent key.\n *\n * `_origin` is `json_patch('{}', json_object(…))` over a CASE per field that\n * yields `'asserted'`, `'derived'`, or NULL. `json_object` alone would keep\n * the NULL members — a field neither side has would read as present with a\n * null origin — and RFC 7396 merge-patch, which `json_patch` implements, is\n * exactly the \"a null member deletes the key\" rule that drops them. One patch\n * call does the whole object, so the shape stays flat however many fields the\n * run carries.\n *\n * The join is a LEFT JOIN, so a file the derive run has no row for keeps its\n * asserted values with an all-`asserted` `_origin` and a NULL `_sources`.\n *\n * Read-only by construction: SQLite refuses a write to a view with no\n * INSTEAD OF trigger, and there is none. The effective value is not stored\n * anywhere, so the only way to change it is to change the document or the\n * evidence.\n *\n * Call it after `createDocsTable` and `createDerivedView`. SQLite accepts a\n * view over a table that does not exist yet and fails only at the first read,\n * as `no such table: main._derived_rows`, far from the call that got the\n * order wrong.\n */\nexport function createResolvedView(\n db: DatabaseSync,\n docsColumns: readonly string[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): void {\n const columns = resolvedColumns(docsColumns, commands);\n const fields = columns.slice(1, -2);\n const inDocs = new Set(docsColumns);\n const inDerived = new Set(derivableFields(commands));\n\n const selects = [`d.${quoteIdent(\"_path\")} AS ${quoteIdent(\"_path\")}`];\n const origin: string[] = [];\n for (const field of fields) {\n const path = sqlString(jsonPath(field));\n const asserted = `json_type(d.${quoteIdent(\"_data\")}, ${path}) IS NOT NULL`;\n // A field with no docs column can only be asserted by an inconsistent\n // table, but `_data` answers for it either way and costs nothing here.\n const assertedValue = inDocs.has(field)\n ? `d.${quoteIdent(field)}`\n : `d.${quoteIdent(\"_data\")} ->> ${path}`;\n if (inDerived.has(field)) {\n const derivedValue = `r.${quoteIdent(field)}`;\n selects.push(\n `CASE WHEN ${asserted} THEN ${assertedValue} ELSE ${derivedValue} END AS ${quoteIdent(field)}`,\n );\n origin.push(\n `${sqlString(field)}, CASE WHEN ${asserted} THEN 'asserted' WHEN ${derivedValue} IS NOT NULL THEN 'derived' END`,\n );\n } else {\n // A docs-only column: no source states it, so the document always wins.\n selects.push(`${assertedValue} AS ${quoteIdent(field)}`);\n origin.push(`${sqlString(field)}, CASE WHEN ${asserted} THEN 'asserted' END`);\n }\n }\n selects.push(\n `json_patch('{}', json_object(${origin.join(\", \")})) AS ${quoteIdent(ORIGIN_COLUMN)}`,\n );\n selects.push(`r.${quoteIdent(SOURCES_COLUMN)} AS ${quoteIdent(SOURCES_COLUMN)}`);\n\n db.exec(\n `CREATE VIEW ${RESOLVED_VIEW} AS SELECT ${selects.join(\", \")} FROM docs d LEFT JOIN ${DERIVED_ROWS} r USING (${quoteIdent(\"_path\")})`,\n );\n}\n\n/** Where a table build stands: the run's directories and its config. */\nexport interface DeriveTableContext {\n cwd: string;\n base: string;\n configDir?: string;\n config: DocmetaConfig | null;\n /** Whether the GitHub or GitLab review cache may answer; `--no-cache` clears it. */\n cache: boolean;\n /** The clock an uncommitted body change is dated by; default `new Date()`. */\n now?: () => Date;\n}\n\n/**\n * Derive the table's rows: `fields` — what the caller's statements can read,\n * see `fieldsForSql` — from the sources the config allows (all five when it\n * says nothing), with the review cache on. The view keeps every column, and\n * a field not derived is NULL in it; only a source some named field needs\n * is consulted, so a statement reading `owner` never spawns `gh`, and a\n * configured command runs only when its field is read. A requested source\n * that cannot answer is the run's error, never an empty column — the same\n * rule `validate` and `derive` follow — and `hint` is the caller's own way\n * out.\n */\nexport async function deriveForTable(\n inputs: readonly DeriveInput[],\n ctx: DeriveTableContext,\n hint: string,\n fields: readonly DerivableField[],\n): Promise<Map<string, DerivedRecord>> {\n const derive = ctx.config?.derive;\n const commands = commandsOf(derive);\n const result = await deriveMetadata(inputs, {\n cwd: ctx.cwd,\n base: ctx.base,\n ...(ctx.configDir !== undefined ? { configDir: ctx.configDir } : {}),\n sources: derive?.sources ?? [...DERIVE_SOURCES],\n fields,\n ...(derive?.codeowners !== undefined ? { codeowners: derive.codeowners } : {}),\n ...(commands !== undefined ? { commands } : {}),\n cache: ctx.cache,\n now: ctx.now ?? (() => new Date()),\n });\n assertSourcesAvailable(result.sources, hint);\n return result.records;\n}\n","/**\n * `validate` command core. Resolves targets, extracts metadata, resolves a\n * schema set per file, validates, and returns structured results. Kept free of\n * CLI/IO plumbing so it can be tested directly.\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport {\n loadExternalMetadata,\n mergeExternalMetadata,\n orphanEntries,\n orphanError,\n orphanJoins,\n externalMetadataPointer,\n EXTERNAL_DUPLICATE_SCHEMA,\n EXTERNAL_KEYWORD,\n EXTERNAL_OWNED_SCHEMA,\n} from \"../core/external-metadata.js\";\nimport { resolve, extname } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { warn } from \"../../shared/warn.js\";\nimport {\n DocmetaError,\n type BaselineSummary,\n type FieldError,\n type RunSummary,\n type ValidationResult,\n} from \"../types.js\";\nimport {\n DEFAULT_BASELINE_PATH,\n LEGACY_BASELINE_PATH,\n type FingerprintContext,\n applyBaseline,\n buildBaseline,\n countFingerprints,\n diffBaselines,\n readBaseline,\n writeBaselineFile,\n} from \"../core/baseline.js\";\nimport {\n extractorByName,\n extractorForExtension,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_LABEL,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport {\n resolveRunConfig,\n schemaTrustRoot,\n type ConfigNotice,\n} from \"../core/config.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport {\n collectSchemaPins,\n resolveSchemaSetWithSource,\n FILE_SCHEMA_KEY,\n type ResolvedSchemaSet,\n resolveElements,\n} from \"../core/resolve-schema.js\";\nimport { Validator } from \"../core/validator.js\";\nimport { schemaLoadOptions } from \"../core/schema-registry.js\";\nimport { runChecks, type CheckEntry } from \"../core/checks.js\";\nimport {\n assertSourcesAvailable,\n deriveMetadata,\n type DeriveResult,\n} from \"../core/derive/index.js\";\nimport { commandsOf } from \"../core/derive/config.js\";\nimport {\n fieldsForSql,\n mentionsDerived,\n mentionsResolved,\n} from \"../core/derive/table.js\";\nimport {\n compareDerived,\n derivableFields,\n DERIVE_SOURCES,\n staleFindings,\n type DerivedRecord,\n type DeriveInput,\n} from \"../core/derive/types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\nexport interface ValidateOptions {\n inputs: string[];\n cliSchemas?: string[];\n exts?: string[];\n exclude?: string[];\n /** `--as` format override (extractor name). */\n as?: string;\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n /**\n * `--collection <name>`, repeatable: run over the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with positional paths; `-` is allowed beside it.\n */\n collections?: string[];\n cwd?: string;\n /** Content for the `-` (stdin) input, injected by the CLI/tests. */\n stdinContent?: string;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /**\n * `--baseline [path]`: compare findings against a recorded baseline and fail\n * only on new ones. A string is a path relative to `cwd`; `true` means the\n * default path; `false` is `--no-baseline`, which suppresses a baseline the\n * config supplied. Absent means \"whatever the config says\".\n */\n baseline?: string | boolean;\n /**\n * `--write-baseline [path]`: record this run's findings as the baseline\n * instead of comparing against one. Wins over `baseline`.\n */\n writeBaseline?: string | boolean;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n /**\n * `--offline`: never fetch a remote schema. Absent leaves config `offline:`\n * in charge, which itself defaults to off.\n */\n offline?: boolean;\n /**\n * `--no-cache` (false): ask GitHub or GitLab again rather than reading the\n * review cache. It reaches the comparison and any check reading the\n * `derived` table; absent leaves the cache on.\n */\n cache?: boolean;\n /**\n * `--no-checks` (false): skip the config's named corpus checks for this\n * run. Absent leaves them on — they still only run when the resolved file\n * set is the config-resolved corpus (proposal 0026).\n */\n checks?: boolean;\n /**\n * `--no-derive` (false): skip comparing each managed field (`derive.fields`\n * in the config, proposal 0040) with what the evidence says. Absent leaves\n * the comparison on whenever `derive:` is configured — on scoped runs too,\n * since it is per file rather than a corpus rule.\n */\n derive?: boolean;\n /** The clock an uncommitted body change is dated by. Test seam; default `new Date()`. */\n now?: () => Date;\n}\n\nexport interface ValidateRun {\n results: ValidationResult[];\n summary: RunSummary;\n /**\n * Where the run stood: the working directory, the directory canonical paths\n * are measured from, and the directory `results[].file` labels are relative\n * to.\n *\n * Returned rather than kept private because a `ValidationResult.file` is only\n * meaningful *with* it. A reporter that has to name a file the same way from\n * anywhere — SARIF, whose `artifactLocation.uri` GitHub resolves against the\n * repository root — cannot reconstruct this after the fact, and guessing puts\n * it in the same false-green trap the baseline's canonical keys exist to\n * avoid.\n */\n frame: FingerprintContext;\n}\n\n/**\n * A violation docmeta raises itself rather than one Ajv produced.\n *\n * Two different failures land here and they are not the same thing: the\n * document's metadata block could not be parsed (`parse`), or a schema set\n * could not be resolved for it (`schema`). `keyword` is what tells them apart\n * downstream — the `schema` field stays `\"(parse)\"` for both, because it is the\n * documented literal machine consumers already match on.\n */\nfunction parseErrorResult(\n file: string,\n format: string,\n message: string,\n keyword: \"parse\" | \"schema\",\n): ValidationResult {\n const err: FieldError = {\n schema: \"(parse)\",\n instancePath: \"\",\n message,\n keyword,\n };\n return { file, format, ok: false, schemas: [], errors: [err] };\n}\n\n/** A resolved `--baseline` / `--write-baseline` / `baseline:` request. */\ninterface BaselineRequest {\n absPath: string;\n /** The path spelled as the user would type it, for messages. */\n label: string;\n write: boolean;\n}\n\n/**\n * Settle which baseline file (if any) governs this run, and where it lives.\n *\n * The one subtlety is the base directory. A path the user typed on the command\n * line is relative to where they are standing; a `baseline:` written in a config\n * file is relative to **the config**, because that is where the person editing\n * it can see the file. Resolving a configured path against `cwd` instead would\n * mean running from a subdirectory silently finds no baseline and reports the\n * entire backlog as new — the exact class of bug config discovery exists to fix.\n */\nfunction resolveBaselineRequest(\n opts: ValidateOptions,\n configured: string | undefined,\n configDir: string | undefined,\n cwd: string,\n): BaselineRequest | null {\n /** A path typed on the command line: relative to where the user is standing. */\n const named = (label: string): Omit<BaselineRequest, \"write\"> => ({\n absPath: resolve(cwd, label),\n label,\n });\n\n /**\n * The file this project's baseline lives in when no path was typed.\n *\n * A configured `baseline:` wins over the built-in default here, and that is\n * load-bearing rather than a nicety: read and write have to agree on one\n * file. A repo that points `baseline:` somewhere other than the default, then\n * runs a bare `--write-baseline`, would otherwise record into a second file\n * nothing ever reads — and the ratchet would silently do nothing at all.\n *\n * Both spellings resolve against the **config's** directory, not `cwd`. An\n * implied baseline is a property of the project, the same as the config that\n * governs it, so it has to be the same file wherever the command is run from.\n * Resolving it against `cwd` would break the ratchet the moment someone runs\n * from `docs/` — the subdirectory workflow config discovery exists to support\n * — and a later write from there would quietly give the project a second\n * baseline that nothing reads. An explicitly *typed* path stays relative to\n * where the user is standing, which is what a shell argument should mean.\n */\n const implied = (): Omit<BaselineRequest, \"write\"> => {\n const base = configDir ?? cwd;\n if (configured !== undefined) {\n return { absPath: resolve(base, configured), label: configured };\n }\n // A baseline recorded before the rename is still the project's baseline.\n // Only when the new name is absent, so a project that has moved is never\n // pulled back by a stale file it forgot to delete.\n const current = resolve(base, DEFAULT_BASELINE_PATH);\n const legacy = resolve(base, LEGACY_BASELINE_PATH);\n if (!existsSync(current) && existsSync(legacy)) {\n warn(\n `\"${LEGACY_BASELINE_PATH}\" is the pre-rename baseline file name. Rename it to \"${DEFAULT_BASELINE_PATH}\".`,\n );\n return { absPath: legacy, label: LEGACY_BASELINE_PATH };\n }\n return { absPath: current, label: DEFAULT_BASELINE_PATH };\n };\n\n const requested = (\n value: string | true,\n ): Omit<BaselineRequest, \"write\"> =>\n typeof value === \"string\" ? named(value) : implied();\n\n // Recording wins over comparing: `--write-baseline` must not depend on\n // whether the file it is about to replace could be read.\n if (opts.writeBaseline !== undefined && opts.writeBaseline !== false) {\n return { ...requested(opts.writeBaseline), write: true };\n }\n if (opts.baseline === false) return null; // --no-baseline\n if (opts.baseline !== undefined) {\n return { ...requested(opts.baseline), write: false };\n }\n if (configured) return { ...implied(), write: false };\n return null;\n}\n\n/**\n * Run `fn` at most once and hand every caller the same promise, rejection\n * included: a derivation that failed for the checks has failed for the\n * comparison too, and must not be retried against the same evidence.\n */\nfunction once<T>(fn: () => Promise<T>): () => Promise<T> {\n let pending: Promise<T> | undefined;\n return () => {\n pending ??= fn();\n return pending;\n };\n}\n\nexport async function runValidate(\n opts: ValidateOptions,\n): Promise<ValidateRun> {\n const cwd = opts.cwd ?? process.cwd();\n\n // Explicit CLI inputs win, else config `paths:`; `base` is whichever of the\n // two directories those inputs were written relative to.\n const {\n config,\n inputs,\n base,\n configDir,\n collections,\n declaredCollections,\n fromCollections,\n } =\n await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const usingStdin = inputs.includes(STDIN_TOKEN);\n\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to validate. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n // Pick an explicit extractor for `--as`, validating it up front.\n const forcedExtractor = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forcedExtractor) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Supported extensions: ${supportedExtensions().join(\", \")}.`,\n );\n }\n\n const exts =\n opts.exts ?? (forcedExtractor ? forcedExtractor.extensions : undefined);\n\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n // Only `--exclude`. A collection's `exclude:` governs *membership*, not the\n // walk of a path someone typed (0041 rule 3): the tool has no basis to pick\n // which collection's exclusions to honour once there are several.\n const exclude = opts.exclude ?? [];\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"validated\",\n });\n\n // Settled once per run, not per file: finding it is a filesystem walk, and\n // every file in one run shares the same repository.\n const trustRoot = schemaTrustRoot(cwd, configDir);\n\n // External metadata (0037), read once per run: a manifest the config names\n // that cannot be read is the run's problem, not a document's.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n });\n\n const validator = new Validator(\n schemaLoadOptions({\n // The config's directory when a config governs the run, so one project\n // keeps one cache no matter which directory the command was run from.\n root: configDir ?? cwd,\n // A relative file ref belongs to the run's directory, not the cache root.\n fileBase: cwd,\n ttlHours: config?.schemaCache?.ttlHours,\n offline: opts.offline ?? config?.offline,\n // Built from the rebased config, so a pinned local ref is keyed by the\n // same absolute spelling `resolveSchemaSet` will hand to `loadSchema`.\n pins: collectSchemaPins(config),\n }),\n );\n const results: ValidationResult[] = [];\n // Field-joined entries each document matched (0039), keyed by field then\n // value: the duplicate finding and the post-loop orphan check both need\n // to know which documents claimed which value.\n const joinHits = new Map<\n string,\n Map<string, { label: string; line?: number; file: string }[]>\n >();\n // Corpus checks (0026) run only when the resolved file set IS the\n // config-resolved corpus — an invariant, not a flag list: any CLI reshaping\n // of the input set (positional paths, stdin, --as/--ext, --exclude,\n // --no-gitignore) disqualifies the run, because a corpus rule computed over\n // half a corpus reports wrong answers. `--collection` is the same reshaping\n // by name (0041 rule 11): every unselected collection's view holds only what\n // the run happened to load, so a `FROM blog` check would pass by having\n // nothing to fail on. `-s/--schema` disqualifies too even though the file\n // set is unchanged: a CLI schema override reshapes the corpus *contract* —\n // cliSchemas outranks every override, so every file is judged against a set\n // the config never assigned it, and a check written against the configured\n // contract would be reporting on a corpus that does not exist outside this\n // run. Config `exclude:` and `respectGitignore:` do not disqualify — they\n // *define* the corpus; the CLI flags redefine the run.\n const scopedToCollections = (opts.collections?.length ?? 0) > 0;\n const scopedByFlags =\n opts.inputs.length > 0 ||\n // redundant with inputs.length (stdin is an input) — kept as belt-and-suspenders\n usingStdin ||\n opts.as !== undefined ||\n opts.exts !== undefined ||\n (opts.exclude !== undefined && opts.exclude.length > 0) ||\n opts.respectGitignore !== undefined ||\n (opts.cliSchemas?.length ?? 0) > 0;\n // Corpus checks need the whole corpus: a reshaping flag disqualifies, and so\n // does narrowing by name, because every unselected collection's view then\n // holds only what the run happened to load (0041 rule 11).\n const scoped = scopedByFlags || scopedToCollections;\n const configuredChecks = config?.checks ?? [];\n\n // A manifest entry naming a document this run did not load (0037 rule 4):\n // 0014's named-file-that-is-not-there, and 0026 §4's row outside the run.\n // Only when the run is a corpus — a positional path or a reshaping flag means\n // the operator chose to look at part of it, and entries for the rest are\n // expected rather than orphaned.\n //\n // `--collection` is not such a reshaping. It makes each named collection the\n // corpus (0041 rule 6): the run loaded all of every collection it named, so\n // an entry of one of those pointing at a document that is not there is a\n // stale entry, and a CI job narrowed to one collection would otherwise lose\n // the check it relies on. Entries of unselected collections are skipped.\n if (!scopedByFlags) {\n const covered = scopedToCollections ? collections.map((c) => c.name) : undefined;\n const orphans = orphanEntries(externalMetadata, files, base, covered);\n if (orphans.length > 0) throw orphanError(orphans);\n }\n const checksWillRun =\n configuredChecks.length > 0 && opts.checks !== false && !scoped;\n // Every successful extraction, kept for the corpus checks (0026): the\n // projection they run over is these entries, exactly as `query` holds them.\n // 0021 measured that holding a docs corpus in memory is not the cost that\n // matters — but the common no-checks path should not retain every file's\n // extraction, so the list fills only when the checks will actually run.\n const checkEntries: CheckEntry[] = [];\n // The derived channel (0040): with `derive:` configured and the flag\n // absent, every file read is an input to one derivation after the loop,\n // and its managed fields are then compared with what the sources say.\n // Stdin is never an input — there is no history behind it.\n const deriveConfig = config?.derive;\n // A `derive:` carrying only `sources` or `codeowners` shapes the reads and\n // manages nothing, so there is nothing to compare.\n const deriveWillRun =\n deriveConfig !== undefined &&\n deriveConfig.fields.length > 0 &&\n opts.derive !== false;\n // A corpus check naming the `derived` or `resolved` table needs the same\n // inputs, content included (the git source hashes it to spot an uncommitted\n // body), so the one list serves both — and fills only when something will\n // read it. Both names count: a check reading `resolved` alone in a repo\n // with no managed fields would otherwise keep no inputs, derive nothing,\n // and read every column NULL without saying so.\n const derivedChecks = checksWillRun\n ? configuredChecks.filter((c) => mentionsDerived(c.query) || mentionsResolved(c.query))\n : [];\n const checksNeedDerived = derivedChecks.length > 0;\n const deriveInputs: DeriveInput[] = [];\n const keepDeriveInputs = deriveWillRun || checksNeedDerived;\n // One derivation for the run, over the union of what either reader needs:\n // the managed fields the comparison judges, and the columns the checks\n // can read. Memoized so a check that names the table and a managed field\n // share the git walk (and the gh or glab round-trip) rather than each paying\n // for one. A source that cannot answer is the run's error either way — a\n // half-derived comparison would read as \"all current\", the false green\n // the channel refuses — and the hint names the reader that asked.\n // The configured commands (0042) are part of both: a command's field is\n // managed like a built-in one, and is a column the checks can read.\n const deriveCommands = commandsOf(deriveConfig);\n const deriveFields = new Set<string>(deriveWillRun ? deriveConfig.fields : []);\n const readable = derivableFields(deriveCommands);\n for (const c of derivedChecks) for (const f of fieldsForSql(c.query, readable)) deriveFields.add(f);\n const derivedOnce = once(async (): Promise<DeriveResult> => {\n const derived = await deriveMetadata(deriveInputs, {\n cwd,\n base,\n ...(configDir !== undefined ? { configDir } : {}),\n sources: deriveConfig?.sources ?? [...DERIVE_SOURCES],\n fields: [...deriveFields],\n ...(deriveConfig?.codeowners !== undefined\n ? { codeowners: deriveConfig.codeowners }\n : {}),\n ...(deriveCommands !== undefined ? { commands: deriveCommands } : {}),\n cache: opts.cache ?? true,\n now: opts.now ?? (() => new Date()),\n });\n assertSourcesAvailable(\n derived.sources,\n deriveWillRun\n ? \"pass --no-derive to skip the comparison, or narrow derive.sources\"\n : \"narrow derive.sources in manni.config.yaml\",\n );\n // A source that answered, with a caveat worth one line: a repository\n // with no CODEOWNERS file derives null owners rather than failing.\n for (const [name, status] of Object.entries(derived.sources)) {\n if (status.available && status.reason !== undefined) {\n opts.onNotice?.(`${name}: ${status.reason}`);\n }\n }\n return derived;\n });\n\n const processOne = async (\n label: string,\n content: string,\n extension: string,\n ): Promise<void> => {\n const extractor =\n forcedExtractor ?? extractorForExtension(extension);\n if (!extractor) {\n throw new DocmetaError(\n `Unsupported file type \"${extension}\" for \"${label}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n\n const members = membersFor(label);\n let extracted;\n try {\n extracted = extractor.extract(content, label, {\n elements: resolveElements(label, config, members),\n });\n } catch (err) {\n // A `DocmetaError` out of an extractor is operational, not a bad\n // document — it aborts the run rather than counting as a file failure.\n if (err instanceof DocmetaError) throw err;\n results.push(\n parseErrorResult(label, extractor.name, errorMessage(err), \"parse\"),\n );\n return;\n }\n // The external-metadata merge sits between extraction and everything downstream,\n // so schema resolution, validation, and the corpus checks all see the one\n // object the document and its manifest entry make together.\n // `merged.extracted` keeps the document's own `lineFor`/`colFor`: a\n // manifest key is not in the document, so those answer `undefined` for it\n // and `merged.locate` answers instead. Rebound rather than shadowed, so\n // every read below — resolution, validation, the collision loop — sees\n // the one merged object.\n //\n // The derived comparison is the one reader that takes the document's\n // OWN extraction, from before the merge: a managed key can never be\n // manifest-owned (`loadConfig` refuses the overlap), so the asserted\n // value is the document's, and `lineFor` must answer for its own lines.\n if (keepDeriveInputs && label !== STDIN_LABEL) {\n deriveInputs.push({ label, absPath: resolve(base, label), content, extracted });\n }\n const merged = mergeExternalMetadata(label, extracted, externalMetadata, members, base);\n extracted = merged.extracted;\n for (const j of merged.joins) {\n const byValue =\n joinHits.get(j.field) ??\n new Map<string, { label: string; line?: number; file: string }[]>();\n const line = extracted.lineFor(j.field);\n const hits = byValue.get(j.value) ?? [];\n hits.push({ label, file: j.file, ...(line != null ? { line } : {}) });\n byValue.set(j.value, hits);\n joinHits.set(j.field, byValue);\n }\n if (checksWillRun) checkEntries.push({ label, extracted });\n\n let resolved: ResolvedSchemaSet;\n try {\n resolved = resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: extracted.data[FILE_SCHEMA_KEY],\n cliSchemas: opts.cliSchemas,\n config,\n memberOf: members,\n // A document's own `$schema` is measured from the run's directory, the\n // same base `loadSchema` will read it from, and contained to the\n // repository the run is standing in.\n fileBase: cwd,\n trustRoot,\n onNotice: opts.onNotice,\n });\n } catch (err) {\n results.push(\n parseErrorResult(label, extractor.name, errorMessage(err), \"schema\"),\n );\n return;\n }\n\n const schemaSet = resolved.schemas;\n let errors: FieldError[];\n try {\n errors = await validator.validate(\n extracted.data,\n schemaSet,\n extracted.lineFor,\n extracted.colFor,\n merged.locate,\n );\n } catch (err) {\n // A schema the *document* chose failing to load — unparseable, missing,\n // integrity mismatch — is that document's failure, and is filed as one.\n // Letting it escape meant a single contributed file naming any non-JSON\n // path in the repo aborted the whole run: exit 2, and nothing reported\n // about any file, including the ones that were fine.\n //\n // Every other source stays operational on purpose. A schema the operator\n // configured is not one document's problem; it invalidates the run, and\n // reporting it per-file would repeat the same error once per document\n // while implying the documents were at fault.\n if (!(err instanceof DocmetaError) || resolved.source !== \"document\") {\n throw err;\n }\n results.push(\n parseErrorResult(label, extractor.name, err.message, \"schema\"),\n );\n return;\n }\n // A document carrying a key a manifest owns (0020 across files: neither\n // channel wins, and the discarded value would be exactly the one nobody\n // checked). Filed against the document at the key's own line.\n for (const { key, file, collection } of merged.collisions) {\n const line = extracted.lineFor(key);\n errors.push({\n schema: EXTERNAL_OWNED_SCHEMA,\n keyword: EXTERNAL_KEYWORD,\n subject: key,\n instancePath: externalMetadataPointer(key),\n message: `\"${key}\" is owned by manifest ${file} (collection ${collection}); remove it from the document`,\n ...(line != null ? { line } : {}),\n });\n }\n results.push({\n file: label,\n format: extractor.name,\n ok: errors.length === 0,\n schemas: schemaSet,\n errors,\n });\n };\n\n if (usingStdin) {\n const content = opts.stdinContent ?? \"\";\n if (!forcedExtractor) {\n throw new DocmetaError(\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\",\n );\n }\n await processOne(STDIN_LABEL, content, forcedExtractor.extensions[0] ?? \"\");\n }\n\n for (const file of files) {\n const content = await readFile(resolve(base, file), \"utf8\");\n await processOne(file, content, extname(file));\n }\n\n // Two documents carrying one join value (0039): one entry matched both,\n // and the manifest cannot tell them apart. A finding on each, at the\n // field's own line, whether or not the run is scoped — it is about the\n // documents loaded, not the corpus. Then, on a corpus run, a field entry\n // nothing matched is the same orphan a path entry is.\n if (externalMetadata) {\n const byLabel = new Map(results.map((r) => [r.file, r]));\n const matched = new Map<string, Set<string>>();\n for (const [field, byValue] of joinHits) {\n matched.set(field, new Set(byValue.keys()));\n for (const [value, hits] of byValue) {\n if (hits.length < 2) continue;\n for (const hit of hits) {\n const others = hits\n .filter((h) => h.label !== hit.label)\n .map((h) => h.label)\n .join(\", \");\n const result = byLabel.get(hit.label);\n if (!result) continue;\n result.errors.push({\n schema: EXTERNAL_DUPLICATE_SCHEMA,\n keyword: EXTERNAL_KEYWORD,\n subject: value,\n instancePath: externalMetadataPointer(field),\n message: `${hits.length} documents carry ${field} \"${value}\"; ${hit.file} cannot tell them apart (${others})`,\n ...(hit.line != null ? { line: hit.line } : {}),\n });\n result.ok = false;\n }\n }\n }\n // Same corpus invariant as the path-entry orphans above, and the same\n // reading of `--collection`: a named collection is a corpus of its own.\n if (!scopedByFlags) {\n const covered = scopedToCollections ? collections.map((c) => c.name) : undefined;\n const orphans = orphanJoins(externalMetadata, matched, covered);\n if (orphans.length > 0) throw orphanError(orphans);\n }\n }\n\n // Corpus checks (0026), after the per-file loop and before the baseline so\n // their findings ride the same ratchet the schemas get. The disqualifying\n // conditions live with `scoped`, computed before the loop above.\n if (configuredChecks.length > 0 && opts.checks !== false) {\n if (scoped) {\n // Name the reason when it is `--collection`: \"scoped\" alone reads as a\n // stray positional path, and the operator who narrowed the run by name\n // is the one most likely to expect the checks to have run.\n opts.onNotice?.(\n scopedToCollections\n ? `corpus checks skipped: run is scoped to collections ${collections\n .map((c) => c.name)\n .join(\", \")}`\n : \"corpus checks skipped: run is scoped\",\n );\n } else {\n const findings = await runChecks(configuredChecks, checkEntries, {\n // Every declared collection is a view (0041 rule 7), holding the\n // members this run loaded — decided by the same path arithmetic\n // `membersFor` uses, so a check and a `manni meta query` over the same\n // corpus see the same collections.\n collections: declaredCollections,\n ...(configDir !== undefined ? { configDir } : {}),\n base,\n // A check that names the `derived` table (0040) gets the same view\n // `query` builds, from the run's one derivation — which already\n // covers every field the checks can read, so the list handed back\n // here is not needed. Built only when asked for, because building\n // it spawns git.\n derive: async () => (await derivedOnce()).records,\n // Its columns include the configured commands' keys (0042), which a\n // check's context cannot read from a config since 0041.\n ...(deriveCommands !== undefined ? { commands: deriveCommands } : {}),\n });\n const byFile = new Map(results.map((r) => [r.file, r]));\n for (const [file, errs] of findings) {\n // Unreachable while runChecks vets every path against the loaded set,\n // which is a subset of `results` by construction — but a missed merge\n // must be a loud failure, not findings silently dropped.\n const result = byFile.get(file);\n if (!result) {\n throw new DocmetaError(\n `check findings for \"${file}\" have no validation result to attach to.`,\n );\n }\n result.errors.push(...errs);\n result.ok = false;\n }\n }\n }\n\n // The derived comparison (0040): what each document asserts for its\n // managed fields against what the sources say. Per file, so it runs on\n // scoped runs too, and before the baseline so a stale stamp rides the same\n // ratchet every other finding does. Reads only the configured fields from\n // the run's one derivation, which may hold more for the checks' sake.\n if (deriveWillRun && deriveInputs.length > 0) {\n const derived = await derivedOnce();\n const byFile = new Map(results.map((r) => [r.file, r]));\n for (const input of deriveInputs) {\n const record: DerivedRecord | undefined = derived.records.get(input.label);\n const result = byFile.get(input.label);\n if (!record || !result) continue;\n const findings = staleFindings(\n deriveConfig.fields.map((field) =>\n compareDerived(field, input.extracted.data[field], record.fields[field]),\n ),\n input.extracted.lineFor,\n );\n if (findings.length === 0) continue;\n result.errors.push(...findings);\n result.ok = false;\n }\n }\n\n // Fingerprints must not depend on where the command was run from, so a\n // local file schema ref is measured against the config's directory.\n const frame: FingerprintContext = { cwd, base: configDir ?? cwd, runBase: base };\n\n const { results: reported, baseline } = await settleBaseline(\n results,\n resolveBaselineRequest(opts, config?.baseline, configDir, cwd),\n frame,\n );\n\n const failed = reported.filter((r) => !r.ok).length;\n const summary: RunSummary = {\n files: reported.length,\n passed: reported.length - failed,\n failed,\n errors: reported.reduce((n, r) => n + r.errors.length, 0),\n // Omitted when nothing was skipped: there is nothing to audit, and the\n // JSON summary stays as it was for every run in a clean repo.\n ...(gitignoreSkipped > 0 ? { gitignoreSkipped } : {}),\n ...(baseline ? { baseline } : {}),\n };\n\n return { results: reported, summary, frame };\n}\n\n/**\n * Apply — or record — the baseline, and describe what it did.\n *\n * On a write, the freshly recorded baseline is then applied to the same\n * results, so `--write-baseline` reports the files it recorded as clean and\n * exits 0 without the exit code needing a special case anywhere.\n *\n * `<stdin>` is the one exception, and deliberately so: it is not a path anyone\n * can look up on the next run, so it is never recorded, never matches, and its\n * findings still fail the run. Reporting it clean would announce success for a\n * violation that was neither fixed nor baselined.\n */\nasync function settleBaseline(\n results: ValidationResult[],\n request: BaselineRequest | null,\n ctx: FingerprintContext,\n): Promise<{ results: ValidationResult[]; baseline?: BaselineSummary }> {\n if (!request) return { results };\n\n const previous = await readBaseline(request.absPath, request.label);\n\n if (request.write) {\n // `<stdin>` is not a path anyone can look up on the next run, so recording\n // it would only leave an entry that can never match again.\n const recordable = results.filter((r) => r.file !== STDIN_LABEL);\n const next = buildBaseline(recordable, pkg.version, ctx);\n const { added, removed } = diffBaselines(previous, next);\n await writeBaselineFile(request.absPath, next, request.label);\n const applied = applyBaseline(results, next, ctx);\n return {\n results: applied.results,\n baseline: {\n path: request.label,\n written: true,\n recorded: countFingerprints(next),\n suppressed: applied.suppressed,\n stale: applied.stale,\n added,\n removed,\n },\n };\n }\n\n if (!previous) {\n throw new DocmetaError(\n `Baseline \"${request.label}\" not found. Record one with \\`manni meta validate --write-baseline\\`, or drop --baseline.`,\n );\n }\n\n const applied = applyBaseline(results, previous, ctx);\n return {\n results: applied.results,\n baseline: {\n path: request.label,\n written: false,\n recorded: applied.recorded,\n suppressed: applied.suppressed,\n stale: applied.stale,\n },\n };\n}\n","/**\n * The validation baseline — a ratchet.\n *\n * A baseline records today's violations so a run can fail on *new* ones only.\n * That is what lets a team make a field `required` on a Monday instead of after\n * a 1,200-file cleanup: the standard tightens immediately, the backlog is\n * recorded, and nothing regresses past the recorded state.\n *\n * A violation is identified by a fingerprint over the parts of it that are\n * machine-stable. See `fingerprint` for what is deliberately excluded and why.\n */\nimport { createHash } from \"node:crypto\";\nimport { readFile } from \"node:fs/promises\";\nimport { relative, resolve } from \"node:path\";\nimport { DocmetaError, type FieldError, type ValidationResult } from \"../types.js\";\nimport { stripBom } from \"./json-text.js\";\nimport { classifyRef } from \"./schema-registry.js\";\nimport { writeFileAtomic } from \"./write-file.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\n/** Where `--baseline` / `--write-baseline` / `baseline:` point when unspecified. */\nexport const DEFAULT_BASELINE_PATH = \".manni-baseline.json\";\n\n/**\n * The default before the rename. A baseline is committed, so an existing one\n * is still read when the new name is absent — with a warning, because two\n * defaults is one too many to keep.\n */\nexport const LEGACY_BASELINE_PATH = \".docmeta-baseline.json\";\n\n/** The only file format this version understands. */\nexport const BASELINE_VERSION = 1;\n\n/** Exactly what `fingerprint` emits: 16 lowercase hex characters. */\nconst FINGERPRINT_RE = /^[0-9a-f]{16}$/;\n\nexport interface Baseline {\n version: number;\n /** docmeta version that produced the file, for diagnosis only. */\n generatedWith: string;\n /** File path (as reported in results) -> sorted violation fingerprints. */\n entries: Record<string, string[]>;\n}\n\n/** The parts of a violation a fingerprint is built from. */\nexport type Fingerprintable = Pick<\n FieldError,\n \"schema\" | \"instancePath\" | \"keyword\" | \"subject\"\n>;\n\n/** What a schema reference is measured against when it names a local file. */\nexport interface FingerprintContext {\n /** Working directory a relative file ref was written against. */\n cwd: string;\n /** Directory canonical paths are expressed relative to: the config's, else `cwd`. */\n base: string;\n /**\n * Directory a `ValidationResult.file` label is relative to. Usually `base`,\n * but a run that took positional paths resolves them against `cwd` instead,\n * so the two genuinely differ. Defaults to `base` when omitted.\n */\n runBase?: string;\n}\n\n/**\n * The key a file's entry is stored under.\n *\n * Result labels are relative to whatever the run resolved against, so the same\n * page is `docs/legacy.md` from the repo root and `legacy.md` from inside\n * `docs/`. A baseline is a committed, shared artifact, so its keys have to name\n * the file the same way from anywhere — otherwise the lookup misses and every\n * baselined finding reads as new, without the fingerprints ever being compared.\n */\nexport function canonicalFilePath(\n file: string,\n ctx?: FingerprintContext,\n): string {\n if (!ctx) return file;\n const from = ctx.runBase ?? ctx.base;\n return relative(ctx.base, resolve(from, file)).replace(/\\\\/g, \"/\");\n}\n\n/**\n * A schema reference reduced to a form that does not depend on where the\n * command was run from.\n *\n * The ref is part of a violation's identity, and config discovery rewrites a\n * config's **local file** refs to absolute paths whenever the config directory\n * is not the working directory. Left alone, that would give one fingerprint set\n * when CI runs from the repo root and a different, machine-specific one when a\n * developer runs from `docs/` — the whole baselined backlog reading as new for\n * exactly the subdirectory workflow config discovery exists to support.\n *\n * Built-in ids and URLs are already stable and pass through untouched. A local\n * file ref becomes its path relative to `base`, with posix separators so a\n * baseline recorded on Windows matches one recorded on Linux.\n *\n * Only the *fingerprint input* is canonicalized. Reports and schema loading\n * keep using the ref exactly as the user wrote it.\n */\nexport function canonicalSchemaRef(\n ref: string,\n ctx?: FingerprintContext,\n): string {\n if (!ctx) return ref;\n if (classifyRef(ref).kind !== \"file\") return ref;\n // `resolve` is a no-op on an already-absolute ref, which is the rebased case.\n const abs = resolve(ctx.cwd, ref);\n return relative(ctx.base, abs).replace(/\\\\/g, \"/\");\n}\n\n/**\n * A violation's stable identity: 16 hex characters of\n * `sha256(schema NUL instancePath NUL keyword NUL subject)`.\n *\n * Deliberately excludes:\n *\n * - **the line number** — adding one key to frontmatter shifts every line below\n * it, and a fingerprint that moved with it would present a pure reordering as\n * a wall of new findings;\n * - **the message prose** — Ajv generates it, so any Ajv release that rewords a\n * message would invalidate every affected entry in every consuming repo at\n * once, presenting as \"docmeta broke our build\";\n * - **the file path** — it is already the entry key, so hashing it again buys\n * nothing.\n *\n * 64 bits against a realistic per-file population of tens of violations is\n * overwhelming headroom, and a collision costs one forgiven violation rather\n * than a corrupt file. The NUL separators are what keep `(\"ab\", undefined)` and\n * `(\"a\", \"b\")` apart.\n *\n * Note the sharp edge in the *included* half: the schema **ref string** is part\n * of the identity, so re-pointing a schema from `google:okf:0.1` to a URL\n * serving the same bytes changes every fingerprint. That is correct — docmeta\n * cannot tell it is the same contract — but it is surprising, and the remedy is\n * a re-record.\n */\nexport function fingerprint(\n e: Fingerprintable,\n ctx?: FingerprintContext,\n): string {\n const parts = [\n canonicalSchemaRef(e.schema, ctx),\n e.instancePath,\n e.keyword,\n e.subject ?? \"\",\n ];\n return createHash(\"sha256\").update(parts.join(\"\\0\")).digest(\"hex\").slice(0, 16);\n}\n\n/** Sorted keys and sorted fingerprints, so the file diffs and merges legibly. */\nexport function serializeBaseline(baseline: Baseline): string {\n // Null-prototype for the same reason `parseBaseline` uses one: a file key of\n // `__proto__` assigned into a plain object literal would set the prototype\n // and drop the entry, so a parse/serialize round-trip would lose it silently.\n const entries = Object.create(null) as Record<string, string[]>;\n for (const file of Object.keys(baseline.entries).sort()) {\n entries[file] = [...(baseline.entries[file] ?? [])].sort();\n }\n return `${JSON.stringify(\n {\n version: baseline.version,\n generatedWith: baseline.generatedWith,\n entries,\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction bad(source: string, detail: string): never {\n throw new DocmetaError(`Baseline \"${source}\": ${detail}`);\n}\n\n/** Parse baseline JSON. `source` is the path as the user would type it. */\nexport function parseBaseline(text: string, source: string): Baseline {\n let raw: unknown;\n try {\n // A baseline is a committed file an editor may have re-saved. Nothing here\n // hashes it, so this is purely the parsing concession. See `stripBom`.\n raw = JSON.parse(stripBom(text));\n } catch (err) {\n bad(source, `invalid JSON: ${errorMessage(err)}`);\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n bad(source, \"top level must be an object.\");\n }\n const obj = raw as Record<string, unknown>;\n\n if (obj.version !== BASELINE_VERSION) {\n bad(\n source,\n `unsupported version ${JSON.stringify(obj.version)} (this manni writes version ${BASELINE_VERSION}). Re-record it with \\`manni meta validate --write-baseline\\`.`,\n );\n }\n\n const generatedWith =\n typeof obj.generatedWith === \"string\" ? obj.generatedWith : \"\";\n\n const rawEntries = obj.entries;\n if (\n typeof rawEntries !== \"object\" ||\n rawEntries === null ||\n Array.isArray(rawEntries)\n ) {\n bad(source, '\"entries\" must be an object mapping file paths to fingerprints.');\n }\n\n // Null-prototype, so a file key of `__proto__` is stored as an ordinary entry\n // rather than triggering the inherited setter — which would replace this\n // object's prototype and silently drop the entry. Every other malformation\n // here is rejected loudly; this one would not even be visible.\n const entries = Object.create(null) as Record<string, string[]>;\n for (const [file, value] of Object.entries(\n rawEntries as Record<string, unknown>,\n )) {\n if (!Array.isArray(value) || value.some((v) => typeof v !== \"string\")) {\n bad(source, `entries[\"${file}\"] must be a list of fingerprint strings.`);\n }\n // A fingerprint that is not the shape this code writes can never match a\n // real violation, so a typo in a hand-edited baseline would otherwise\n // present as \"that finding came back\" with nothing to explain it. Reject it\n // where the user can still see which entry is wrong.\n const malformed = (value as string[]).find((v) => !FINGERPRINT_RE.test(v));\n if (malformed !== undefined) {\n bad(\n source,\n `entries[\"${file}\"] contains ${JSON.stringify(malformed)}, which is not a fingerprint (16 lowercase hex characters).`,\n );\n }\n entries[file] = value as string[];\n }\n\n return { version: BASELINE_VERSION, generatedWith, entries };\n}\n\n/** Read a baseline from disk. Returns null when the file does not exist. */\nexport async function readBaseline(\n absPath: string,\n source: string,\n): Promise<Baseline | null> {\n let text: string;\n try {\n text = await readFile(absPath, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw new DocmetaError(\n `Baseline \"${source}\" could not be read: ${errorMessage(err)}`,\n );\n }\n return parseBaseline(text, source);\n}\n\n/**\n * Write the baseline atomically.\n *\n * The baseline is a committed artifact the whole team's gate reads, and a\n * truncated write is not merely lost work: the next run cannot parse it and\n * exits 2 until someone re-records. `writeFileAtomic` gives the same\n * temp-file-plus-rename guarantee `fill` relies on when it edits sources.\n *\n * Failures are wrapped the same way `readBaseline` wraps its own, so a missing\n * parent directory or a read-only checkout names the baseline and reads as an\n * operational error rather than surfacing a bare `ENOENT` through the CLI's\n * \"Unexpected error\" branch.\n */\nexport async function writeBaselineFile(\n absPath: string,\n baseline: Baseline,\n source: string,\n): Promise<void> {\n try {\n await writeFileAtomic(absPath, serializeBaseline(baseline));\n } catch (err) {\n throw new DocmetaError(\n `Baseline \"${source}\" could not be written: ${errorMessage(err)}`,\n );\n }\n}\n\n/** Record every finding in `results` as a baseline. Clean files are omitted. */\nexport function buildBaseline(\n results: ValidationResult[],\n generatedWith: string,\n ctx?: FingerprintContext,\n): Baseline {\n // Null-prototype, matching `parseBaseline` and `serializeBaseline` — and here\n // it prevents a crash rather than a lost entry. `__proto__` is the famous\n // collision but not the reachable one; `toString` is a legal filename. A file\n // that is *clean* gets no entry, so `applyBaseline`'s lookup would find the\n // inherited method instead of `undefined`, pass the `!known` guard because a\n // function is truthy, and then die in `new Set(known)` with \"function is not\n // iterable\".\n const entries = Object.create(null) as Record<string, string[]>;\n for (const r of results) {\n if (r.errors.length === 0) continue;\n // Two identical violations in one file are one fingerprint; storing the\n // duplicate would only make the count meaningless.\n const prints = [...new Set(r.errors.map((e) => fingerprint(e, ctx)))].sort();\n entries[canonicalFilePath(r.file, ctx)] = prints;\n }\n return { version: BASELINE_VERSION, generatedWith, entries };\n}\n\nexport interface AppliedBaseline {\n /** Results with baselined findings removed and `ok`/`baselined` updated. */\n results: ValidationResult[];\n /** Fingerprints the baseline holds **for the files this run checked**. */\n recorded: number;\n /** Findings suppressed because the baseline already had them. */\n suppressed: number;\n /** Recorded fingerprints for checked files that no longer occur. */\n stale: number;\n}\n\n/**\n * Subtract a baseline from a run's results.\n *\n * `recorded` and `stale` count only the files this run actually checked. The\n * alternative — counting the whole file — would make `manni meta validate one.md\n * --baseline` announce that hundreds of entries \"no longer occur\", and the\n * advice that follows (`--write-baseline` to prune) would then destroy them.\n */\nexport function applyBaseline(\n results: ValidationResult[],\n baseline: Baseline,\n ctx?: FingerprintContext,\n): AppliedBaseline {\n let recorded = 0;\n let suppressed = 0;\n let stale = 0;\n\n const applied = results.map((r) => {\n const known = baseline.entries[canonicalFilePath(r.file, ctx)];\n if (!known) return r; // no entry: a new or renamed file, everything is new\n const recordedHere = new Set(known);\n recorded += recordedHere.size;\n\n const seen = new Set<string>();\n const fresh: FieldError[] = [];\n for (const e of r.errors) {\n const print = fingerprint(e, ctx);\n if (recordedHere.has(print)) {\n seen.add(print);\n suppressed += 1;\n } else {\n fresh.push(e);\n }\n }\n stale += recordedHere.size - seen.size;\n\n const baselined = r.errors.length - fresh.length;\n return {\n ...r,\n ok: fresh.length === 0,\n errors: fresh,\n ...(baselined > 0 ? { baselined } : {}),\n };\n });\n\n return { results: applied, recorded, suppressed, stale };\n}\n\n/**\n * Count fingerprints added and dropped between two baselines.\n *\n * The `removed` half is the load-bearing one: an accidental `--write-baseline`\n * on a narrowed glob or a mistyped `--exclude` silently forgives everything it\n * did not see, and this number is the only thing that makes that visible in a\n * CI log.\n */\nexport function diffBaselines(\n previous: Baseline | null,\n next: Baseline,\n): { added: number; removed: number } {\n const flatten = (b: Baseline | null): Set<string> => {\n const out = new Set<string>();\n if (!b) return out;\n for (const [file, prints] of Object.entries(b.entries)) {\n for (const p of prints) out.add(`${file}\\0${p}`);\n }\n return out;\n };\n const before = flatten(previous);\n const after = flatten(next);\n let added = 0;\n let removed = 0;\n for (const k of after) if (!before.has(k)) added += 1;\n for (const k of before) if (!after.has(k)) removed += 1;\n return { added, removed };\n}\n\n/** Total fingerprints held in a baseline, across every file. */\nexport function countFingerprints(baseline: Baseline): number {\n let n = 0;\n for (const prints of Object.values(baseline.entries)) n += prints.length;\n return n;\n}\n","/**\n * Named corpus checks (proposal 0026): SQL from the config's `checks:` list,\n * run over the same `docs` projection `query` builds, whose result rows are\n * **findings** rather than a table.\n *\n * The column convention is the whole mapping: `path` (required) names the file\n * a finding attaches to, `line` its 1-based source line, `key` the metadata\n * field at fault (it becomes the `instancePath`, and with it part of the\n * finding's baseline identity), `message` the prose. A row that follows it\n * becomes an ordinary `FieldError` — `schema: \"check:<name>\"`, `keyword:\n * \"check\"` — and every downstream surface (pretty, github, SARIF, JUnit, the\n * baseline ratchet) works unchanged.\n */\nimport { DocmetaError, type FieldError } from \"../types.js\";\nimport { CHECK_NAME, type CheckConfig } from \"./config.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\nimport {\n assertSingleStatement,\n collectNamedParameters,\n corpusDataColumns,\n createDocsTable,\n loadSqlite,\n registerLineFor,\n stripLeadingTrivia,\n type ProjectionEntry,\n} from \"./projection.js\";\nimport {\n collectCollections,\n createCollectionViews,\n type CollectionParams,\n} from \"./collections.js\";\nimport {\n createDerivedView,\n createResolvedView,\n derivedColumns,\n fieldsForSql,\n mentionsDerived,\n mentionsResolved,\n} from \"./derive/table.js\";\nimport {\n derivableFields,\n type DerivableField,\n type DeriveCommand,\n type DerivedRecord,\n} from \"./derive/types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\n/** One loaded file a check may attach findings to. */\nexport type CheckEntry = ProjectionEntry;\n\n/** The `keyword` every check finding carries: no Ajv keyword produced it. */\nexport const CHECK_KEYWORD = \"check\";\n\n/**\n * The `schema` ref a check's findings carry — and their baseline identity.\n *\n * The grammar is asserted here as well as in the config parser: a\n * programmatic `CheckConfig` never passes through `parseChecks`, and a\n * path-shaped name (`../evil`, `slugs.json`) would classify as a file ref and\n * fingerprint cwd-relative — the identity bug `CHECK_NAME` exists to prevent.\n */\nexport function checkSchemaRef(name: string): string {\n if (!CHECK_NAME.test(name) || name.toLowerCase().endsWith(\".json\")) {\n throw new DocmetaError(\n `check name \"${name}\" must match [a-z0-9][a-z0-9._-]* and not end in \".json\" — the name is part of each finding's identity (check:<name>).`,\n );\n }\n return `check:${name}`;\n}\n\n/** The columns the convention consumes; everything else feeds the message. */\nconst CONVENTION_COLUMNS = new Set([\"path\", \"line\", \"key\", \"message\"]);\n\n/**\n * Map one check's result rows to findings, keyed by file path.\n *\n * `loaded` is the set of paths this run holds extractions for. A row naming\n * any other path is a broken check, not a finding: fabricating a result for a\n * file the run never read would corrupt the summary, so it refuses (exit 2)\n * with the check named — the same class as SQL that does not prepare. On the\n * `query --check` path no set is passed: the SELECT is the user's own, its\n * `path` column is taken at its word (`<stdin>` included — proposal 0026\n * § stress test 7), and only a non-string path refuses.\n */\nexport function rowsToFindings(\n name: string,\n columns: readonly string[],\n rows: readonly Record<string, unknown>[],\n loaded?: ReadonlySet<string>,\n): Map<string, FieldError[]> {\n if (!columns.includes(\"path\")) {\n throw new DocmetaError(\n `check \"${name}\": the result has no \\`path\\` column. A check's SELECT names its findings through the column convention: \\`path\\` (required), and optionally \\`line\\`, \\`key\\`, and \\`message\\`; any other column is folded into the message.`,\n );\n }\n const findings = new Map<string, FieldError[]>();\n const extras = columns.filter((c) => !CONVENTION_COLUMNS.has(c));\n for (const row of rows) {\n const path = row.path;\n if (typeof path !== \"string\" || (loaded !== undefined && !loaded.has(path))) {\n throw new DocmetaError(\n `check \"${name}\": a result row names ${JSON.stringify(path)}, which this run did not load — a finding must attach to a file of the corpus. Fix the check's \\`path\\` column.`,\n );\n }\n const key = typeof row.key === \"string\" && row.key !== \"\" ? row.key : undefined;\n const line = asLine(row.line);\n const message =\n typeof row.message === \"string\" && row.message !== \"\"\n ? row.message\n : synthesizeMessage(extras, row);\n const err: FieldError = {\n schema: checkSchemaRef(name),\n keyword: CHECK_KEYWORD,\n // RFC 6901 escaping, or a key containing `/` or `~` would build a\n // pointer that parses as a different (nested) location.\n instancePath: key === undefined ? \"\" : `/${escapePointerSegment(key)}`,\n message,\n ...(line === undefined ? {} : { line }),\n };\n const bucket = findings.get(path);\n if (bucket) bucket.push(err);\n else findings.set(path, [err]);\n }\n return findings;\n}\n\n/** A `line` cell, when it is the 1-based positive integer the contract means. */\nfunction asLine(value: unknown): number | undefined {\n const n =\n typeof value === \"bigint\" ? Number(value) : typeof value === \"number\" ? value : undefined;\n return n !== undefined && Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\n/**\n * The fallback prose when a check declares no `message`: `col=value` over the\n * remaining columns, so a lazy `SELECT _path AS path, slug FROM …` is still\n * usable — not so it is a good idea; write a message. A NULL cell says\n * nothing, so it is omitted rather than rendered as a literal `null`; when\n * every remaining cell is NULL the generic fallback stands.\n */\nfunction synthesizeMessage(\n extras: readonly string[],\n row: Record<string, unknown>,\n): string {\n const pairs = extras.flatMap((c) => {\n const value = row[c];\n if (value === null || value === undefined) return [];\n // SQL cells are string | number | bigint (a BLOB cannot arise from the\n // projection's text/numeric columns); the JSON fallback keeps a future\n // surprise printable rather than \"[object Object]\".\n const text =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"bigint\"\n ? String(value)\n : JSON.stringify(value);\n return [`${c}=${text}`];\n });\n return pairs.length > 0 ? pairs.join(\", \") : \"check matched\";\n}\n\n/**\n * Run every configured check over the corpus and merge their findings.\n *\n * The projection is the one `query` builds — same columns, same value\n * conventions — plus `lineFor(path, key)` so a check can carry a source line.\n * A check whose SQL cannot prepare, or whose rows break the column\n * convention, aborts the run with the check named: a broken rule is an\n * operational error, never a finding or a silent skip.\n */\n/**\n * The run context a check projection may need beyond the entries themselves:\n * the declared collections that become views, and the two directories\n * membership is arithmetic between (proposal 0041 rules 7 and 10). No\n * resolution inputs: a check's `FROM authors` means \"the files the authors\n * collection selects\", which is what the config says, and deciding it costs\n * nothing but string arithmetic. The shape IS `CollectionParams`: it is handed\n * to `collectCollections` verbatim, and an intersection is what keeps the two\n * from drifting apart field by field.\n *\n * `derive` is the one addition (proposal 0040): how to get the rows behind\n * the `derived` and `resolved` tables when a check names either. A function\n * rather than the rows,\n * because building them spawns git, and a check that never names the table\n * must not pay for it. It is handed the fields the checks can read, so a\n * caller deriving from scratch consults only the sources those need; a\n * caller that already derived more may hand back what it has. Absent, a\n * check naming the table is refused.\n */\nexport type CheckRunContext = CollectionParams & {\n derive?: (\n fields: readonly DerivableField[],\n ) => Promise<ReadonlyMap<string, DerivedRecord>>;\n /**\n * The configured commands (proposal 0042), whose keys are columns of the\n * `derived` table beside the built-ins. Handed over rather than read from a\n * config, because since proposal 0041 a check's context carries none.\n */\n commands?: Readonly<Record<string, DeriveCommand>>;\n};\n\nexport async function runChecks(\n checks: readonly CheckConfig[],\n entries: readonly CheckEntry[],\n ctx: CheckRunContext = {},\n): Promise<Map<string, FieldError[]>> {\n const merged = new Map<string, FieldError[]>();\n if (checks.length === 0) return merged;\n\n const { DatabaseSync } = await loadSqlite();\n const db = new DatabaseSync(\":memory:\");\n try {\n // The one column list both `docs` and `resolved` are built from: the\n // view's asserted side reads those columns by name, so a second call\n // could not be allowed to disagree with the table's.\n const dataColumns = corpusDataColumns(entries);\n createDocsTable(db, entries, dataColumns);\n registerLineFor(db, entries);\n createCollectionViews(db, collectCollections(entries, ctx));\n // The derived channel's tables (0040), when any check names one: the same\n // views `query` builds, over the union of the fields those checks can\n // read. Either name builds both — `resolved` is `docs` joined to the same\n // rows — so a check reading the effective value costs the same one\n // derivation. Before `query_only`, since building them loads a table.\n const wantsDerived = checks.filter(\n (c) => mentionsDerived(c.query) || mentionsResolved(c.query),\n );\n if (wantsDerived.length > 0) {\n if (ctx.derive === undefined) {\n throw new DocmetaError(\n `check \"${wantsDerived[0]?.name ?? \"\"}\": the SQL names the derived or resolved table, but this run cannot derive. Run it through \\`manni meta validate\\`, or drop the reference.`,\n );\n }\n // The run's columns: the built-ins and the configured command keys\n // (0042), handed over by the caller that read the config.\n const commands = ctx.commands;\n const readable = derivableFields(commands);\n const fields = new Set<DerivableField>();\n for (const c of wantsDerived) for (const f of fieldsForSql(c.query, readable)) fields.add(f);\n createDerivedView(db, await ctx.derive([...fields]), derivedColumns(commands));\n createResolvedView(db, dataColumns, commands);\n }\n // Checks are SELECT-only by design — 0021's original discipline, which\n // 0022 lifted for `query` because writes became query's *feature*, judged\n // by its effect gate. Checks have no such gate: without this, an UPDATE\n // in one check mutates the shared projection every later check computes\n // over, and a DELETE/DROP is misdiagnosed downstream. Set after the\n // table and views are built, before any check's SQL runs.\n db.exec(\"PRAGMA query_only = 1\");\n const loaded = new Set(entries.map((e) => e.label));\n\n for (const check of checks) {\n // ATTACH and VACUUM write files of their own, which `query_only`\n // does not fully prevent (ATTACH creates the attached file; VACUUM\n // INTO creates its target before the engine refuses) — the same two\n // statements `query` refuses by name.\n const head = stripLeadingTrivia(check.query);\n if (/^(attach|vacuum)\\b/i.test(head)) {\n throw new DocmetaError(\n `check \"${check.name}\": ${head.split(/\\s/, 1)[0]?.toUpperCase() ?? \"that statement\"} is refused: it can write outside the docs table.`,\n );\n }\n // Checks bind nothing, so any named parameter would silently bind\n // NULL, match nothing, and green the gate forever — the false-green\n // shape the query-side guard refuses with a bind; here the remedy is\n // to inline the value.\n let tokens: string[];\n try {\n tokens = collectNamedParameters(check.query);\n } catch (err) {\n // The scan's own refusal (one name under two prefixes), check named.\n throw new DocmetaError(\n `check \"${check.name}\": ${errorMessage(err)}`,\n );\n }\n if (tokens.length > 0) {\n throw new DocmetaError(\n `check \"${check.name}\": the SQL references ${tokens.join(\", \")}, but checks bind no parameters — an unbound name binds NULL and matches nothing, so the gate would pass on a typo. Inline the value in the SQL.`,\n );\n }\n let columns: string[];\n let rows: Record<string, unknown>[];\n try {\n assertSingleStatement(check.query);\n const stmt = db.prepare(check.query);\n columns = stmt.columns().map((c) => c.name);\n rows = stmt.all();\n } catch (err) {\n const message = errorMessage(err);\n throw new DocmetaError(\n message.includes(\"attempt to write a readonly database\")\n ? `check \"${check.name}\": ${message} — checks are read-only by design; a check is a SELECT over the projection. Edit the corpus with \\`manni meta query\\` instead.`\n : `check \"${check.name}\": ${message}`,\n );\n }\n for (const [path, errs] of rowsToFindings(\n check.name,\n columns,\n rows,\n loaded,\n )) {\n const bucket = merged.get(path);\n if (bucket) bucket.push(...errs);\n else merged.set(path, errs);\n }\n }\n } finally {\n db.close();\n }\n return merged;\n}\n","/**\n * `get` command core. Prints one or more metadata field values from each file.\n * Input handling (positional paths, globs, directories, `-` for stdin, and\n * config `paths:` fallback) mirrors `validate` so the two commands behave\n * identically.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { loadExternalMetadata, mergeExternalMetadata } from \"../core/external-metadata.js\";\nimport { resolve, extname } from \"node:path\";\nimport { resolveElements } from \"../core/resolve-schema.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport { DocmetaError } from \"../types.js\";\nimport {\n extractorByName,\n extractorForExtension,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_LABEL,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport {\n resolveRunConfig,\n type ConfigNotice,\n type DocmetaConfig,\n} from \"../core/config.js\";\nimport {\n assertSourcesAvailable,\n deriveMetadata,\n} from \"../core/derive/index.js\";\nimport { commandsOf } from \"../core/derive/config.js\";\nimport {\n DERIVE_SOURCES,\n isBuiltinField,\n type DerivableField,\n type DeriveCommand,\n type DerivedRecord,\n type DerivedValue,\n type DeriveInput,\n} from \"../core/derive/types.js\";\n\nexport interface GetOptions {\n fields: string[];\n inputs: string[];\n as?: string;\n exclude?: string[];\n exts?: string[];\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n /**\n * `--collection <name>`, repeatable: run over the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with positional paths; `-` is allowed beside it.\n */\n collections?: string[];\n cwd?: string;\n /** Content for the `-` (stdin) input, injected by the CLI/tests. */\n stdinContent?: string;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n /**\n * `--offline`, accepted for surface parity with `validate` and `fill`.\n *\n * It has **no effect here**, and that is a property of the command rather\n * than an omission: `get` prints extracted field values and never resolves or\n * loads a schema, so it has no network dependency to suppress. Accepting it\n * keeps one flag set across the three commands, so a script can pass\n * `--offline` uniformly without knowing which subcommand needs it.\n */\n offline?: boolean;\n /**\n * `--no-cache` (false): ask GitHub or GitLab again rather than reading the\n * review cache. Only `--derived` consults it, and only for `reviewed-by`\n * and `last-reviewed`; absent leaves the cache on.\n */\n cache?: boolean;\n /**\n * Whether to resolve each requested field against the evidence — git\n * history, CODEOWNERS, the review record, a configured command (proposals\n * 0040, 0042). **On unless explicitly `false`** (proposal 0043): a read\n * says what the value is and where it came from, and `--no-derived` is the\n * way back to what the document alone stores.\n *\n * Only the requested fields a source can state are derived, so a field no\n * source claims consults nothing and spawns nothing. Stdin is included in\n * the run and simply derives nothing: a piped document has no path, so no\n * source can speak for it, and that is an answer rather than an error.\n */\n derived?: boolean;\n /** The clock an uncommitted body change is dated by. Test seam; default `new Date()`. */\n now?: () => Date;\n}\n\nexport interface GetFileResult {\n file: string;\n present: boolean;\n values: Record<string, unknown>;\n /**\n * The evidence per requested field. A derivable field is always a key\n * here: a `DerivedValue` when a source answered, `null` when every\n * consulted source had nothing to say (a file with no commits, a path no\n * CODEOWNERS rule matches). A requested field that is **not** derivable is\n * absent from the record. Absent altogether under `--no-derived`, when no\n * requested field is derivable, and on a file that did not parse.\n */\n derived?: Record<string, DerivedValue | null>;\n /**\n * The effective value per requested field (proposal 0043): the document's\n * when it **carries the key**, the derived one otherwise, and absent when\n * neither side has it. Presence is `Object.hasOwn`, not truthiness, so a\n * document writing `owner: null` has asserted a value and no derived one\n * replaces it — the same rule the `resolved` SQL view implements.\n *\n * Shaped exactly like `values`: one entry per requested field, `undefined`\n * where nothing resolved, which JSON drops. Absent under `--no-derived`,\n * and on a file that did not parse.\n */\n resolved?: Record<string, unknown>;\n /**\n * Which side answered, for the fields that resolved to something. A field\n * neither the document nor any source has is absent, which is how a reader\n * tells \"unset\" from \"unset, but derivable\". Absent under `--no-derived`,\n * and on a file that did not parse.\n */\n origin?: Record<string, \"asserted\" | \"derived\">;\n /**\n * Why this file yielded no values, when it yielded none for a reason.\n *\n * Set only when the document's metadata block could not be read at all — the\n * same throw `validate` turns into a `(parse)` finding. Absent on every file\n * that parsed, including one with no metadata block and one where every\n * requested field was unset: those are answers, and this is the absence of\n * one. A run carrying any `error` exits 1.\n */\n error?: string;\n}\n\nexport async function runGet(opts: GetOptions): Promise<GetFileResult[]> {\n const cwd = opts.cwd ?? process.cwd();\n if (opts.fields.length === 0) {\n throw new DocmetaError(\"Specify at least one field to get.\");\n }\n\n // Explicit CLI inputs win, else config `paths:`; `base` is whichever of the\n // two directories those inputs were written relative to.\n const { config, inputs, base, configDir, collections, fromCollections } =\n await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n const usingStdin = inputs.includes(STDIN_TOKEN);\n\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to read. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n const forced = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forced) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Supported extensions: ${supportedExtensions().join(\", \")}.`,\n );\n }\n\n const exts = opts.exts ?? (forced ? forced.extensions : undefined);\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n // Only `--exclude`: a collection's `exclude:` governs membership, not the\n // walk of a path someone typed (0041 rule 3).\n const exclude = opts.exclude ?? [];\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"read\",\n });\n\n const out: GetFileResult[] = [];\n // External metadata (0037), read once per run.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n });\n\n // The derived channel (0040): the requested fields a source can state,\n // and one input per parsed file — the document's OWN extraction, since a\n // managed key is never manifest-owned and the git source reads its lines.\n // A field is derivable when a built-in source claims it, or when the\n // config runs a command for it (0042).\n const commands: Readonly<Record<string, DeriveCommand>> = commandsOf(config?.derive) ?? {};\n // Derivation is on unless the user said `--no-derived` (proposal 0043).\n const deriving = opts.derived !== false;\n const derivableFields: DerivableField[] = deriving\n ? opts.fields.filter((f) => isBuiltinField(f) || Object.hasOwn(commands, f))\n : [];\n const deriveInputs: DeriveInput[] = [];\n // Which requested fields each parsed file **carries**, keyed by label. It\n // is the resolution rule's whole input, and it is collected here because\n // only `readOne` holds the extracted data.\n const carried = new Map<string, Record<string, boolean>>();\n\n const readOne = (label: string, content: string, extension: string): void => {\n const extractor = forced ?? extractorForExtension(extension);\n if (!extractor) {\n throw new DocmetaError(\n `Unsupported file type \"${extension}\" for \"${label}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n const members = membersFor(label);\n let extracted;\n try {\n const own = extractor.extract(content, label, {\n elements: resolveElements(label, config, members),\n });\n if (deriving && label !== STDIN_LABEL) {\n deriveInputs.push({\n label,\n absPath: resolve(base, label),\n content,\n extracted: own,\n });\n }\n extracted = mergeExternalMetadata(label, own, externalMetadata, members, base).extracted;\n } catch (err) {\n // A `DocmetaError` is already operational and already carries a message\n // written for a person — rethrow it untouched, exactly as `validate`\n // does with the same call.\n if (err instanceof DocmetaError) throw err;\n // Anything else is a document that will not parse, which is a fact about\n // the document and not about the run. It is recorded against the file and\n // the walk continues, the same call `validate` turns into a `(parse)`\n // finding. Promoting it to an operational error put it on the wrong side\n // of the 0/1/2 contract and, worse, made one malformed file hide the\n // values of every other file in the directory.\n //\n // `err` is `unknown` and an extractor is not obliged to throw an `Error`,\n // so the reason is narrowed rather than cast: `(err as Error).message`\n // would record `undefined` and lose the reason entirely.\n const reason = err instanceof Error ? err.message : String(err);\n out.push({ file: label, present: false, values: {}, error: reason });\n return;\n }\n const values: Record<string, unknown> = {};\n const carries: Record<string, boolean> = {};\n for (const f of opts.fields) {\n values[f] = resolveField(extracted.data, f);\n carries[f] = carriesField(extracted.data, f);\n }\n carried.set(label, carries);\n out.push({ file: label, present: extracted.present, values });\n };\n\n if (usingStdin) {\n if (!forced) {\n throw new DocmetaError(\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\",\n );\n }\n readOne(STDIN_LABEL, opts.stdinContent ?? \"\", forced.extensions[0] ?? \"\");\n }\n\n for (const file of files) {\n const content = await readFile(resolve(base, file), \"utf8\");\n readOne(file, content, extname(file));\n }\n\n if (deriving) {\n await attachResolved(out, deriveInputs, {\n fields: opts.fields,\n derivable: derivableFields,\n carried,\n run: {\n cwd,\n base,\n configDir,\n config,\n cache: opts.cache ?? true,\n now: opts.now ?? (() => new Date()),\n },\n });\n }\n\n return out;\n}\n\n/**\n * One derivation for the run, then three records on every parsed file: the\n * evidence (`derived`), the effective value (`resolved`), and which side\n * answered (`origin`).\n *\n * Nothing is derived when no requested field is derivable, or when every\n * input is stdin — no source is consulted and no process is spawned, and\n * each file still gets its records, because the document is then the only\n * side there is and every field it carries resolves to `asserted`. A\n * consulted source that cannot answer is the run's error, with the way out.\n *\n * The resolution rule is one line, and it is the same one the `resolved` SQL\n * view implements: the document's value when the document **carries the\n * key**, the derived one otherwise. Carrying is `Object.hasOwn` (see\n * `carriesField`), so `owner: null` is an assertion and outranks CODEOWNERS.\n */\nasync function attachResolved(\n out: GetFileResult[],\n inputs: readonly DeriveInput[],\n opts: {\n /** Every requested field, in the order the user named them. */\n fields: readonly string[];\n /** The subset a source can state; only these are derived. */\n derivable: readonly DerivableField[];\n /** Which requested fields each parsed file carries, by label. */\n carried: ReadonlyMap<string, Record<string, boolean>>;\n run: {\n cwd: string;\n base: string;\n configDir: string | undefined;\n config: DocmetaConfig | null;\n cache: boolean;\n now: () => Date;\n };\n },\n): Promise<void> {\n const { run } = opts;\n const derive = run.config?.derive;\n const commands = commandsOf(derive);\n const records: ReadonlyMap<string, DerivedRecord> =\n opts.derivable.length === 0 || inputs.length === 0\n ? new Map<string, DerivedRecord>()\n : await (async () => {\n const result = await deriveMetadata(inputs, {\n cwd: run.cwd,\n base: run.base,\n ...(run.configDir !== undefined ? { configDir: run.configDir } : {}),\n sources: derive?.sources ?? [...DERIVE_SOURCES],\n fields: opts.derivable,\n ...(derive?.codeowners !== undefined\n ? { codeowners: derive.codeowners }\n : {}),\n ...(commands !== undefined ? { commands } : {}),\n cache: run.cache,\n now: run.now,\n });\n assertSourcesAvailable(\n result.sources,\n \"pass --no-derived, or narrow derive.sources\",\n );\n return result.records;\n })();\n for (const r of out) {\n if (r.error !== undefined) continue;\n const record = records.get(r.file);\n const derived: Record<string, DerivedValue | null> = {};\n for (const field of opts.derivable) {\n derived[field] = record?.fields[field] ?? null;\n }\n const carries = opts.carried.get(r.file) ?? {};\n const resolved: Record<string, unknown> = {};\n const origin: Record<string, \"asserted\" | \"derived\"> = {};\n for (const field of opts.fields) {\n const evidence = derived[field];\n if (carries[field] === true) {\n resolved[field] = r.values[field];\n origin[field] = \"asserted\";\n } else if (evidence != null) {\n resolved[field] = evidence.value;\n origin[field] = \"derived\";\n } else {\n // Neither side has it. Shaped like `values`, which also carries the\n // key with `undefined` rather than dropping it, so a caller iterating\n // the requested fields sees the same key set on both records.\n resolved[field] = undefined;\n }\n }\n // Only when a requested field is derivable. With none there is no\n // evidence to report, and `{}` would read as \"derived, and nothing\n // answered\".\n if (opts.derivable.length > 0) r.derived = derived;\n r.resolved = resolved;\n r.origin = origin;\n }\n}\n\n/**\n * Resolve a single field reference against extracted metadata.\n *\n * A reference starting with `/` is a JSON Pointer (RFC 6901) — the same\n * convention the validator and reporters already use for nested error paths,\n * so a pointer copied from a validation error works verbatim. Any other\n * reference is dot-notation (`author.name`, `tags.0`). Pointers also escape\n * keys that contain literal dots or slashes (`/odd.key`, `/a~1b` for `a/b`).\n *\n * Returns `undefined` when any segment is missing or descends into a scalar.\n * A bare top-level key (no `/`, no `.`) resolves to a single segment, so the\n * historical `get title` behavior is unchanged.\n *\n * **A key that literally contains a dot is tried as a fallback**, after descent\n * fails. Element-derived metadata makes those ordinary — `article.title`,\n * `prolog.author`, `ms.date` — and without this, `get article.title` returned\n * an *empty* result rather than an error, which is a silent wrong answer.\n * Descent still wins wherever it resolves, so a document with a genuine\n * `author: { name: … }` object answers `author.name` exactly as it always has;\n * the fallback only fires where the old behavior was to give up.\n */\nfunction resolveField(data: Record<string, unknown>, field: string): unknown {\n const segments = field.startsWith(\"/\")\n ? parseJsonPointer(field)\n : field.split(\".\");\n const descended = descend(data, segments);\n if (descended !== undefined) return descended;\n if (\n !field.startsWith(\"/\") &&\n field.includes(\".\") &&\n Object.prototype.hasOwnProperty.call(data, field)\n ) {\n return data[field];\n }\n return undefined;\n}\n\n/**\n * Does the document **carry** this field? `resolveField`'s twin, deciding\n * presence rather than value, and it follows exactly the same three routes:\n * JSON Pointer, dot-notation descent, then the literal dotted key.\n *\n * The difference is the last step. `resolveField` reports a miss as\n * `undefined`, which a key written `owner:` — present, valued null — cannot\n * be told apart from. So the final segment is an own-property test rather\n * than a read, and an asserted null answers `true`. For a bare top-level\n * field this is `Object.hasOwn(data, field)`, which is the rule the\n * `resolved` SQL view spells `json_type(_data, '$.\"field\"') IS NOT NULL`.\n */\nfunction carriesField(data: Record<string, unknown>, field: string): boolean {\n const segments = field.startsWith(\"/\")\n ? parseJsonPointer(field)\n : field.split(\".\");\n if (carriesPath(data, segments)) return true;\n return (\n !field.startsWith(\"/\") &&\n field.includes(\".\") &&\n Object.prototype.hasOwnProperty.call(data, field)\n );\n}\n\n/** Whether `segments` names an existing member of `data`. */\nfunction carriesPath(data: Record<string, unknown>, segments: string[]): boolean {\n const last = segments.at(-1);\n if (last === undefined) return true;\n const parent =\n segments.length === 1 ? data : descend(data, segments.slice(0, -1));\n if (Array.isArray(parent)) {\n return /^\\d+$/.test(last) && Number(last) < parent.length;\n }\n if (parent !== null && typeof parent === \"object\") {\n return Object.prototype.hasOwnProperty.call(parent, last);\n }\n return false;\n}\n\n/** Walk `segments` into `data`, or `undefined` at the first miss. */\nfunction descend(data: Record<string, unknown>, segments: string[]): unknown {\n let current: unknown = data;\n for (const segment of segments) {\n if (Array.isArray(current)) {\n if (!/^\\d+$/.test(segment)) return undefined;\n current = current[Number(segment)];\n } else if (current !== null && typeof current === \"object\") {\n // Own-property check only: never resolve inherited members like\n // `toString` or `__proto__` — those are \"missing\", not values.\n if (!Object.prototype.hasOwnProperty.call(current, segment)) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\n/** Decode a JSON Pointer into path segments, unescaping `~1`→`/` and `~0`→`~`. */\nfunction parseJsonPointer(pointer: string): string[] {\n return pointer\n .split(\"/\")\n .slice(1)\n .map((s) => s.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n}\n","/**\n * `schemas` command core. Reports built-in schemas and supported input formats,\n * vendors a remote schema into the repository, and infers a coverage report\n * (plus a draft schema) from the metadata a docset already carries.\n */\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile } from \"node:fs/promises\";\nimport { loadExternalMetadata, mergeExternalMetadata } from \"../core/external-metadata.js\";\nimport { dirname, extname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport { parseDocument, parse as parseYaml, stringify } from \"yaml\";\nimport { resolveElements } from \"../core/resolve-schema.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport { DocmetaError } from \"../types.js\";\nimport {\n fetchSchemaBytes,\n listBuiltins,\n type BuiltinInfo,\n} from \"../core/schema-registry.js\";\nimport {\n extractorByName,\n extractorForExtension,\n listFormats,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport { isoDateValue } from \"../extractors/date-value.js\";\nimport { integrityOf } from \"../core/integrity.js\";\nimport { gitIgnored } from \"../core/gitignore.js\";\nimport {\n META_SECTION,\n parseConfig,\n parseConfigValue,\n loadConfig,\n resolveRunConfig,\n type ConfigNotice,\n type SchemaEntry,\n} from \"../core/config.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_LABEL,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport { toJsonText } from \"../core/json-text.js\";\nimport { writeFileAtomic } from \"../core/write-file.js\";\n\nexport interface SchemasInfo {\n builtins: BuiltinInfo[];\n formats: {\n name: string;\n extensions: string[];\n implemented: boolean;\n /** Whether `manni meta fill` can write metadata back to this format. */\n writable: boolean;\n }[];\n}\n\nexport function getSchemasInfo(): SchemasInfo {\n return { builtins: listBuiltins(), formats: listFormats() };\n}\n\n/**\n * Where a vendored schema lands by default.\n *\n * **Not** `.docmeta/`, which is gitignored wholesale and holds the schema and\n * proposal caches. A vendored schema is the opposite kind of artifact: it has\n * to be committed, because being in the consuming repository's own history is\n * the entire point of vendoring.\n */\nexport const DEFAULT_VENDOR_DIR = \"./schema\";\n\n/**\n * The config file `vendor` creates when a repository has none: the family\n * file, with the entries under the metadata tool's own key.\n */\nexport const DEFAULT_CONFIG_NAME = \"manni.config.yaml\";\n\nexport interface VendorOptions {\n /** The `http(s)` URL to download. */\n url: string;\n /** Directory for the vendored copy, relative to `cwd`. Default `./schema`. */\n dir?: string;\n /** `-c/--config`. Absent discovers a config, or creates one in `cwd`. */\n configPath?: string;\n cwd?: string;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /** Fetch timeout, in ms. Defaults to the registry's. */\n timeoutMs?: number;\n /** Response size cap, in bytes. Defaults to the registry's. */\n maxBytes?: number;\n}\n\nexport interface VendorResult {\n /** The URL that was downloaded. */\n url: string;\n /** The vendored file, relative to `cwd`, posix-style. */\n file: string;\n /** The pin recorded for it. */\n integrity: string;\n /** Size of the vendored copy, in bytes. */\n bytes: number;\n /** The config that was written, relative to `cwd`, posix-style. */\n config: string;\n /** Whether that config had to be created. */\n configCreated: boolean;\n /** Whether an existing `schemas:` entry was replaced rather than appended. */\n replaced: boolean;\n /** Whether the downloaded bytes were identical to the copy already on disk. */\n unchanged: boolean;\n}\n\n/** A path spelled the way git and a config both want it: relative, posix. */\nexport function posixRelative(from: string, to: string): string {\n return relative(from, to).split(sep).join(\"/\");\n}\n\n/**\n * The filename for a vendored schema, derived from the URL's last path segment.\n *\n * Sanitized rather than trusted: the segment reaches the filesystem, so\n * anything that is not an ordinary filename character is replaced, and a\n * leading dot is prefixed away so the copy cannot land as a hidden file that\n * directory walks skip.\n */\nexport function vendorFileName(url: string): string {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new DocmetaError(`\"${url}\" is not a valid URL.`);\n }\n const segments = parsed.pathname.split(\"/\").filter(Boolean);\n const last = segments[segments.length - 1] ?? \"\";\n // `new URL` carries a malformed escape like `%zz` through untouched — the\n // WHATWG parser does not validate percent-encoding — so the segment reaches\n // here and `decodeURIComponent` throws `URIError`, which is not a\n // `DocmetaError` and escaped as an unhandled stack trace. Decoding is only a\n // nicety: the result is sanitized to `[A-Za-z0-9._-]` regardless, so an\n // undecodable segment is used as written.\n let decoded: string;\n try {\n decoded = decodeURIComponent(last);\n } catch {\n decoded = last;\n }\n let name = decoded.replace(/[^A-Za-z0-9._-]/g, \"-\");\n // No usable segment at all (`https://host/`): fall back to the host, which is\n // at least recognizable in a diff.\n if (name === \"\" || /^\\.+$/.test(name)) {\n name = parsed.hostname.replace(/[^A-Za-z0-9._-]/g, \"-\");\n }\n if (name.startsWith(\".\")) name = `schema${name}`;\n if (!name.toLowerCase().endsWith(\".json\")) name += \".json\";\n return name;\n}\n\n/**\n * Refuse a target `.gitignore` covers.\n *\n * The highest-value guard in this command. A vendored schema that git ignores\n * validates perfectly on the machine that downloaded it and is simply *absent*\n * on CI, where the failure arrives as a missing schema file in a repository\n * nobody changed.\n *\n * Three states, all of them enumerated. Git says the path is ignored — refuse,\n * naming whichever of the directory or the file matched, since the fix differs.\n * Git says it is not — proceed. Git cannot answer at all (no repository here,\n * no `git` on `PATH`) — proceed, but say so: refusing every non-repository\n * would make the command unusable in an extracted tarball, and staying silent\n * would claim a check that never ran.\n */\nexport async function assertNotIgnored(\n absFile: string,\n absDir: string,\n cwd: string,\n onNotice: ((message: string) => void) | undefined,\n text: IgnoreGuardText = VENDOR_IGNORE_TEXT,\n): Promise<void> {\n const relFile = posixRelative(cwd, absFile);\n const relDir = posixRelative(cwd, absDir);\n const candidates = [relFile];\n // \"\" is cwd itself, and a path outside cwd is not something git can be asked\n // about relative to here.\n if (relDir !== \"\" && !relDir.startsWith(\"..\")) candidates.push(relDir);\n\n const answer = await gitIgnored(candidates, cwd);\n if (!answer.available) {\n onNotice?.(text.unchecked(relDir || \".\"));\n return;\n }\n\n const ignoredDir = answer.ignored.has(relDir);\n const ignoredFile = answer.ignored.has(relFile);\n if (!ignoredDir && !ignoredFile) return;\n\n // Name the broadest thing git actually flagged. Both spellings are asked\n // about because a directory-only pattern (`vendor/`) does not match the bare\n // path `vendor` while the directory does not yet exist on disk — git can only\n // answer for the file underneath it. Which of the two matched is therefore a\n // fact about the pattern's shape, not about which rule the user should edit,\n // so the remedy names both routes rather than guessing.\n throw new DocmetaError(text.refusal(ignoredDir ? relDir : relFile));\n}\n\n/**\n * The two messages the guard above needs, so the *mechanic* is shared and the\n * *wording* is not.\n *\n * `vendor` and `infer --out` refuse for the same structural reason — a file git\n * ignores is present locally and absent in CI — but the remedy differs (`--dir`\n * versus `--out`), and a message naming the wrong flag sends the reader to the\n * wrong place. Parameterizing beat writing a second copy of the three-state\n * logic, which is where the subtle half of this check lives.\n */\nexport interface IgnoreGuardText {\n /** Git says the path is ignored. `target` is whichever spelling matched. */\n refusal(target: string): string;\n /** Git could not answer at all. `where` is the directory, or \".\". */\n unchecked(where: string): string;\n}\n\nconst VENDOR_IGNORE_TEXT: IgnoreGuardText = {\n refusal: (target) =>\n `Refusing to vendor into \"${target}\": git reports it as ignored. A vendored schema has to be committed — an ignored copy validates on this machine and is simply missing in CI, where the failure reads as a schema nobody changed. Vendor into a directory your repository tracks (\\`--dir\\`, default \\`${DEFAULT_VENDOR_DIR}\\`), or drop the .gitignore rule covering this path.`,\n unchecked: (where) =>\n `could not check .gitignore for \"${where}\" (no repository here, or no git on PATH). A vendored schema must be committed — make sure this path is tracked.`,\n};\n\nconst DRAFT_IGNORE_TEXT: IgnoreGuardText = {\n refusal: (target) =>\n `Refusing to write the draft schema into \"${target}\": git reports it as ignored. A generated schema you cannot commit validates on this machine and is simply absent in CI, where the failure reads as a schema nobody changed. Pass an --out path your repository tracks, or drop the .gitignore rule covering this one.`,\n unchecked: (where) =>\n `could not check .gitignore for \"${where}\" (no repository here, or no git on PATH). A draft schema has to be committed to be worth anything in CI — make sure this path is tracked.`,\n};\n\n/**\n * Fold the vendored entry into a `schemas:` list.\n *\n * Replaces rather than appends whenever the list already speaks about this\n * schema, in any of the three spellings it can take: the bare URL a\n * pre-vendoring config carried, an earlier vendored entry naming the same\n * `source`, or an entry already pointing at the same `ref`. Appending instead\n * would leave the URL live beside its own local copy, so the run would still\n * depend on the host being up — the exact failure vendoring removes.\n */\nfunction foldEntry(\n entries: SchemaEntry[],\n next: { ref: string; source: string; integrity: string },\n): { entries: SchemaEntry[]; replaced: boolean; displacedSource?: string } {\n const speaksAbout = (entry: SchemaEntry): boolean =>\n typeof entry === \"string\"\n ? entry === next.source || entry === next.ref\n : entry.ref === next.ref || entry.source === next.source;\n\n const index = entries.findIndex(speaksAbout);\n if (index === -1) return { entries: [...entries, next], replaced: false };\n\n // Matched on `ref` while naming a *different* origin. Two hosts serving\n // different schemas whose URLs end in the same segment both default to the\n // same filename, so this replaces one pinned contract with another and the\n // \"already exists and is not ours\" guard reads it as a re-vendor. Doing it is\n // right — the command was asked to — but the caller reports it, because a\n // pinned entry silently changing meaning is not something to find out from a\n // diff later.\n const displacedSource = entries\n .filter(speaksAbout)\n .map((entry) => (typeof entry === \"string\" ? undefined : entry.source))\n .find((source) => source !== undefined && source !== next.source);\n // Every match collapses into the one entry, not just the first. A config\n // carrying both the bare URL and an earlier vendored ref would otherwise keep\n // the one that was not replaced — leaving the list disagreeing with itself\n // about whether the schema is pinned.\n return {\n entries: entries.flatMap((entry, i) =>\n i === index ? [next] : speaksAbout(entry) ? [] : [entry],\n ),\n replaced: true,\n ...(displacedSource !== undefined ? { displacedSource } : {}),\n };\n}\n\n/**\n * Serialize the updated config, preserving everything else in the file.\n *\n * `parseDocument` keeps comments and key order, so a config someone documented\n * comes back documented — including one that is nothing *but* comments, which\n * is why an empty file is not special-cased here. Only `schemas:` is rewritten;\n * comments written *inside* the old `schemas:` list are the one thing that does\n * not survive, because the list itself is replaced.\n *\n * `section` is where the config sits in the file: under `meta:` in the family\n * file, at the top level of a pre-family one. A new file is always the family\n * shape.\n */\nfunction renderConfig(\n existing: string | null,\n entries: SchemaEntry[],\n section: string | undefined,\n): string {\n // No file at all is the one case with nothing to preserve.\n if (existing === null) {\n return stringify({ [META_SECTION]: { schemas: entries } });\n }\n const doc = parseDocument(existing);\n doc.setIn(section === undefined ? [\"schemas\"] : [section, \"schemas\"], entries);\n return doc.toString();\n}\n\n/**\n * Read back what `renderConfig` produced, the way `loadConfig` would. A\n * config the tool itself cannot read is worse than a failed vendor, and this\n * is the last moment it can be caught before it reaches disk.\n */\nfunction reparseConfig(text: string, source: string, section: string | undefined): void {\n if (section === undefined) {\n parseConfig(text, source);\n return;\n }\n const doc = parseYaml(text) as Record<string, unknown>;\n parseConfigValue(doc[section], source, section);\n}\n\n/**\n * Download a remote schema into the repository and pin it.\n *\n * The order of operations is the contract: everything that can refuse does so\n * *before* the network call or the write, so a refused run leaves the working\n * tree exactly as it found it.\n */\nexport async function runVendorSchema(\n opts: VendorOptions,\n): Promise<VendorResult> {\n const cwd = opts.cwd ?? process.cwd();\n const url = opts.url;\n\n if (!/^https?:\\/\\//i.test(url)) {\n throw new DocmetaError(\n `\\`manni meta schemas vendor\\` takes an http(s) URL to download; \"${url}\" is ${/^[a-z0-9][a-z0-9._-]*:/i.test(url) && !url.includes(\"/\") ? \"a built-in id, which is already bundled\" : \"a local reference, which is already in your repository\"}.`,\n );\n }\n\n // Load first, so a malformed or missing config fails before anything is\n // downloaded or written.\n const loaded = await loadConfig(opts.configPath, cwd);\n const configPath = loaded?.path ?? resolve(cwd, DEFAULT_CONFIG_NAME);\n const configDir = loaded?.dir ?? cwd;\n\n const absDir = resolve(cwd, opts.dir ?? DEFAULT_VENDOR_DIR);\n const absFile = join(absDir, vendorFileName(url));\n\n await assertNotIgnored(absFile, absDir, cwd, opts.onNotice);\n\n // The ref is written into the config, so it is relative to the **config**,\n // not to wherever the command was run from — that is what makes it resolve\n // the same way from a subdirectory, from the repo root, and in CI.\n const fromConfig = posixRelative(configDir, absFile);\n const ref =\n isAbsolute(fromConfig) || fromConfig === \"\"\n ? absFile\n : fromConfig.startsWith(\".\")\n ? fromConfig\n : `./${fromConfig}`;\n\n const { bytes } = await fetchSchemaBytes(url, {\n ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),\n ...(opts.maxBytes !== undefined ? { maxBytes: opts.maxBytes } : {}),\n });\n const integrity = integrityOf(bytes);\n\n const entries = loaded?.config.schemas ?? [];\n const folded = foldEntry(entries, { ref, source: url, integrity });\n if (folded.displacedSource !== undefined) {\n opts.onNotice?.(\n `\"${ref}\" was vendored from ${folded.displacedSource}; replacing it with ${url}.`,\n );\n }\n\n // Whether this path is already ours. Three states: nothing there, our own\n // earlier copy (a re-vendor, which is the update path), or a file that\n // belongs to something else — which must not be silently overwritten just\n // because two schemas share a last URL segment.\n let unchanged = false;\n if (existsSync(absFile)) {\n const current = await readFile(absFile);\n unchanged = bytes.equals(current);\n if (!unchanged && !folded.replaced) {\n throw new DocmetaError(\n `\"${posixRelative(cwd, absFile)}\" already exists and is not the copy this config points at, so vendoring ${url} here would overwrite it. Vendor into a different directory with --dir, or remove that file first.`,\n );\n }\n }\n\n await mkdir(absDir, { recursive: true });\n await writeFileAtomic(absFile, bytes);\n\n const existing = loaded ? await readFile(configPath, \"utf8\") : null;\n // A new file is the family shape, so its section is `meta:` too.\n const section = loaded ? loaded.section : META_SECTION;\n const text = renderConfig(existing, folded.entries, section);\n // Parse what is about to be written rather than trusting the serializer.\n reparseConfig(text, posixRelative(cwd, configPath) || DEFAULT_CONFIG_NAME, section);\n await writeFileAtomic(configPath, text);\n\n return {\n url,\n file: posixRelative(cwd, absFile),\n integrity,\n bytes: bytes.byteLength,\n config: posixRelative(cwd, configPath),\n configCreated: loaded === null,\n replaced: folded.replaced,\n unchanged,\n };\n}\n\n// ---------------------------------------------------------------------------\n// `manni meta schemas infer` (0010)\n//\n// Purely statistical and **offline**: no provider, no network, no schema\n// resolution. It counts the metadata keys a docset already carries, so the\n// question \"should I require this field?\" has an answer before anyone edits a\n// schema. The coverage report is the product; the draft schema is a by-product.\n//\n// Deliberate limits, stated here rather than discovered later:\n//\n// - **Top-level keys only.** Coverage of `author` is the standard-level\n// question; `author.name` is a schema-authoring detail, and reporting both\n// would bury the first under the second on any docset with nested metadata.\n// - **`-` (stdin) is accepted** for input-model parity, and yields a one-file\n// report. Not useful, not wrong: excluding it would be the exceptional case\n// needing an argument, and every other path-taking command takes it.\n// - **`--min-coverage` defaults to 0.** A default that hid the long tail would\n// hide exactly the \"3% is one team's convention, not a standard\" signal the\n// report exists to surface.\n// ---------------------------------------------------------------------------\n\n/** Draft schemas are written against the same dialect the built-ins use. */\nconst DRAFT_DIALECT = \"https://json-schema.org/draft/2020-12/schema\";\n\n/**\n * Enum thresholds — **both** must hold (0010 stress test 4).\n *\n * The absolute cap alone would turn a 10-file repo with 7 hand-written `type`\n * values into a 7-value vocabulary; the ratio alone would turn a 30-file repo\n * of unique titles into a 30-value enum for prose.\n *\n * The ratio is measured against the files that **carry the key**, not against\n * every file scanned. Against the corpus, a key present in 5 files of 1,000\n * with 5 distinct values — every single occurrence unique, which is what free\n * text looks like — passes both thresholds and gets an enum of exactly those\n * five. The sixth value anyone writes is then rejected by a schema generated\n * from their own docset, which is the opposite of a draft that \"constrains only\n * what it observed\". Against occurrences the same key needs 5 <= 0.25 and is\n * correctly refused: whether a vocabulary exists is a question about this key's\n * own values, and corpus size has no bearing on it.\n */\nconst ENUM_MAX_DISTINCT = 20;\nconst ENUM_MAX_DISTINCT_RATIO = 0.05;\n\n/**\n * How many distinct values are tracked per key before counting stops.\n *\n * Only the report's `distinct` column is affected, and it says so via\n * `distinctCapped`. The enum decision is unaffected: a key past this cap is\n * orders of magnitude past `ENUM_MAX_DISTINCT` already.\n */\nconst DISTINCT_CAP = 1000;\n\n/** Outlier locations kept per non-dominant type, so one bad key cannot blow up memory. */\nconst OUTLIER_SAMPLE_CAP = 20;\n\nexport interface InferOptions {\n /** Positional inputs: files, directories, globs, and `-` for stdin. */\n inputs: string[];\n as?: string;\n exclude?: string[];\n exts?: string[];\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n /**\n * `--collection <name>`, repeatable: run over the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with positional paths; `-` is allowed beside it.\n */\n collections?: string[];\n cwd?: string;\n /** Content for the `-` (stdin) input, injected by the CLI/tests. */\n stdinContent?: string;\n /** `--out`: write the draft schema here, relative to `cwd`. */\n out?: string;\n /** `--min-coverage`: hide keys below this percentage. 0–100, default 0. */\n minCoverage?: number;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /**\n * `--offline`, accepted for surface parity with the other input-taking\n * commands.\n *\n * It has **no effect here**, and — as on `get` — that is a property of the\n * command rather than an omission: `infer` counts keys that are already\n * structured, resolves no schema and loads no provider, so there is no fetch\n * for it to suppress. 0010 stress test 2 asserts that unconditionally.\n * Accepting the flag keeps one flag set across the commands, so a script can\n * pass `--offline` uniformly without knowing which subcommand needs it.\n */\n offline?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n}\n\n/** One observed type and how many files carried the key at that type. */\nexport interface InferTypeCount {\n type: string;\n count: number;\n}\n\n/** A file whose value for a key is not the dominant type. */\nexport interface InferOutlier {\n file: string;\n /** 1-based source line, when the extractor knows one. */\n line?: number;\n type: string;\n}\n\nexport interface InferKeyReport {\n key: string;\n /** Files carrying this key. */\n present: number;\n /** `present` as a percentage of every file scanned, 0–100. */\n coverage: number;\n /** Observed types with counts, most common first. */\n types: InferTypeCount[];\n /** The type the draft encodes. Never a union — see stress test 3. */\n dominantType: string;\n /** Files at some other type, with locations. Capped; see `outlierCount`. */\n outliers: InferOutlier[];\n /** Every non-dominant occurrence, including any beyond `outliers`. */\n outlierCount: number;\n /** Distinct values seen, across all types. */\n distinct: number;\n /** Whether `distinct` stopped counting at `DISTINCT_CAP`. */\n distinctCapped: boolean;\n /** The candidate vocabulary, when both enum thresholds hold. */\n enumValues?: unknown[];\n /** The most common value, for the report's sample column. */\n sample?: unknown;\n /** `date`, `date-time`, or `uri` when every observed string matched one. */\n format?: string;\n}\n\nexport interface InferResult {\n /** Every file read, including those with no metadata block. */\n filesScanned: number;\n /**\n * Files with no metadata block at all. Reported on its own line rather than\n * folded into a denominator: these pass a require-nothing schema and fail the\n * moment any key becomes required, which is the surprise worth naming.\n */\n filesWithoutMetadata: number;\n /** Files whose metadata block could not be parsed, with the reason. */\n unreadable: { file: string; message: string }[];\n /** Keys at or above `--min-coverage`, most-covered first. */\n keys: InferKeyReport[];\n /** Keys `--min-coverage` removed from `keys`. */\n hiddenByMinCoverage: number;\n /** The draft schema. Always produced; `--out` decides whether it is written. */\n draft: Record<string, unknown>;\n /** Where the draft was written, posix-relative to `cwd`. Absent without `--out`. */\n out?: string;\n /** Candidate documents `.gitignore` removed from the walk. */\n gitignoreSkipped: number;\n}\n\n/** Everything accumulated for one top-level key while scanning. */\ninterface KeyStats {\n present: number;\n /** type -> files seen at that type. */\n types: Map<string, number>;\n /** type -> where they were, capped at OUTLIER_SAMPLE_CAP each. */\n locations: Map<string, InferOutlier[]>;\n /** JSON of the value -> the value, its count, and its type. */\n values: Map<string, { value: unknown; count: number; type: string }>;\n distinctCapped: boolean;\n /** Whether an empty string was ever the value. Gates `minLength: 1`. */\n sawEmptyString: boolean;\n}\n\n/**\n * The JSON Schema type name for a runtime value.\n *\n * Integers are **not** split out from `number`. JSON Schema's `number` already\n * accepts them, and separating the two would report a key written `2` in some\n * files and `2.5` in others as having outliers it does not have.\n *\n * A `Date` reaches here only from TOML frontmatter, whose parser materializes\n * timestamps. It is reported as `string`, because that is how every other\n * frontmatter flavor carries a date and the draft describes the metadata\n * standard rather than one parser's object graph.\n */\nfunction jsonTypeOf(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n if (value instanceof Date) return \"string\";\n switch (typeof value) {\n case \"string\":\n return \"string\";\n case \"number\":\n case \"bigint\":\n return \"number\";\n case \"boolean\":\n return \"boolean\";\n default:\n return \"object\";\n }\n}\n\nconst FORMAT_TESTS: [string, RegExp][] = [\n [\"date\", /^\\d{4}-\\d{2}-\\d{2}$/],\n [\"date-time\", /^\\d{4}-\\d{2}-\\d{2}[Tt ]\\d{2}:\\d{2}/],\n [\"uri\", /^[a-z][a-z0-9+.-]*:\\/\\//i],\n];\n\n/**\n * A format annotation for the report's types column — `string (date)`.\n *\n * Report only. It is **not** written into the draft: whether `2026-04-01` is\n * *required* to be a date, or merely what everyone happened to write, is a\n * policy call, and the draft's rule is to encode only the shape it observed\n * (stress test 1). Skipped entirely once distinct counting was capped, since a\n * claim about \"every value\" cannot be made from a truncated sample.\n */\nfunction formatOf(stats: KeyStats, dominantType: string): string | undefined {\n if (dominantType !== \"string\" || stats.distinctCapped) return undefined;\n const strings = [...stats.values.values()]\n .filter((v) => v.type === \"string\")\n .map((v) => String(v.value));\n if (strings.length === 0) return undefined;\n for (const [name, re] of FORMAT_TESTS) {\n if (strings.every((s) => re.test(s))) return name;\n }\n return undefined;\n}\n\nfunction emptyStats(): KeyStats {\n return {\n present: 0,\n types: new Map(),\n locations: new Map(),\n values: new Map(),\n distinctCapped: false,\n sawEmptyString: false,\n };\n}\n\nfunction recordValue(\n stats: KeyStats,\n label: string,\n value: unknown,\n line: number | undefined,\n): void {\n const type = jsonTypeOf(value);\n stats.present += 1;\n stats.types.set(type, (stats.types.get(type) ?? 0) + 1);\n\n const where = stats.locations.get(type) ?? [];\n if (where.length < OUTLIER_SAMPLE_CAP) {\n where.push({ file: label, type, ...(line !== undefined ? { line } : {}) });\n }\n stats.locations.set(type, where);\n\n const normalized = isoDateValue(value);\n if (normalized === \"\") stats.sawEmptyString = true;\n\n // Objects and arrays are keyed by their JSON too, so a repeated `tags: []`\n // counts once. They are never enum candidates, so the only cost is an\n // accurate `distinct` column.\n // `toJsonText`, not `JSON.stringify`, so the `?? \"undefined\"` stays visibly\n // reachable: a hand-written value can stringify to nothing. See there.\n const key = toJsonText(normalized) ?? \"undefined\";\n const seen = stats.values.get(key);\n if (seen) {\n seen.count += 1;\n } else if (stats.values.size < DISTINCT_CAP) {\n stats.values.set(key, { value: normalized, count: 1, type });\n } else {\n stats.distinctCapped = true;\n }\n}\n\n/** The type most files used, ties broken by name so output is deterministic. */\nfunction dominantTypeOf(stats: KeyStats): string {\n return [...stats.types.entries()].sort(\n (a, b) => b[1] - a[1] || a[0].localeCompare(b[0]),\n )[0]?.[0] ?? \"string\";\n}\n\n/**\n * Propose a vocabulary, or don't.\n *\n * Candidates are the values at the **dominant** type only. Including an\n * outlier's value would write the typo into the contract — the same failure\n * `dominantTypeOf` exists to avoid, one level down.\n */\nfunction enumFor(\n stats: KeyStats,\n dominantType: string,\n): unknown[] | undefined {\n // A vocabulary is a set of scalars. An enum of objects or arrays compares by\n // deep equality and is never what someone adopting a standard meant.\n if (![\"string\", \"number\", \"boolean\"].includes(dominantType)) return undefined;\n if (stats.distinctCapped) return undefined;\n\n const candidates = [...stats.values.values()].filter(\n (v) => v.type === dominantType,\n );\n if (candidates.length === 0) return undefined;\n if (candidates.length > ENUM_MAX_DISTINCT) return undefined;\n // Against occurrences of this key, not against the corpus — see the constant.\n if (candidates.length > stats.present * ENUM_MAX_DISTINCT_RATIO) {\n return undefined;\n }\n\n return candidates\n .sort(\n (a, b) =>\n b.count - a.count ||\n JSON.stringify(a.value).localeCompare(JSON.stringify(b.value)),\n )\n .map((v) => v.value);\n}\n\n/** `sawEmptyString` is a scan detail, not part of the public report. */\ntype ReportWithEmptyFlag = InferKeyReport & { sawEmptyString: boolean };\n\n/** One key's `properties` entry: the dominant type, and nothing about policy. */\nfunction draftPropertyFor(report: ReportWithEmptyFlag): Record<string, unknown> {\n const property: Record<string, unknown> = { type: report.dominantType };\n if (report.enumValues) {\n property.enum = report.enumValues;\n } else if (report.dominantType === \"string\" && !report.sawEmptyString) {\n // Observed, not assumed: nobody in this docset wrote an empty string, so\n // requiring a non-empty one when the key *is* present rejects the\n // fat-fingered `title:` without demanding anybody supply a title.\n property.minLength = 1;\n }\n return property;\n}\n\nexport async function runInferSchema(\n opts: InferOptions,\n): Promise<InferResult> {\n const cwd = opts.cwd ?? process.cwd();\n\n const minCoverage = opts.minCoverage ?? 0;\n if (!Number.isFinite(minCoverage) || minCoverage < 0 || minCoverage > 100) {\n throw new DocmetaError(\n `--min-coverage must be a percentage between 0 and 100, got ${minCoverage}.`,\n );\n }\n\n const { config, inputs, base, configDir, collections, fromCollections } =\n await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n const usingStdin = inputs.includes(STDIN_TOKEN);\n // External metadata (0037): an inferred schema describes the merged corpus.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n });\n\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to scan. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n const forced = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forced) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Supported extensions: ${supportedExtensions().join(\", \")}.`,\n );\n }\n if (usingStdin && !forced) {\n throw new DocmetaError(\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\",\n );\n }\n\n // Every refusal happens **before** the scan, so a refused run leaves the\n // working tree exactly as it found it — the ordering `vendor` established.\n let absOut: string | undefined;\n if (opts.out !== undefined) {\n absOut = resolve(cwd, opts.out);\n await assertNotIgnored(\n absOut,\n dirname(absOut),\n cwd,\n opts.onNotice,\n DRAFT_IGNORE_TEXT,\n );\n if (existsSync(absOut)) {\n throw new DocmetaError(\n `\"${posixRelative(cwd, absOut) || opts.out}\" already exists, and \\`schemas infer\\` will not overwrite it. The draft is a starting point you then edit, so clobbering it would throw away the edits. Pass a different --out path, or remove that file first.`,\n );\n }\n }\n\n const exts = opts.exts ?? (forced ? forced.extensions : undefined);\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n // Only `--exclude`: a collection's `exclude:` governs membership, not the\n // walk of a path someone typed (0041 rule 3).\n const exclude = opts.exclude ?? [];\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"scanned\",\n });\n\n const stats = new Map<string, KeyStats>();\n const unreadable: { file: string; message: string }[] = [];\n let filesScanned = 0;\n let filesWithoutMetadata = 0;\n\n const scanOne = (label: string, content: string, extension: string): void => {\n const extractor = forced ?? extractorForExtension(extension);\n if (!extractor) {\n throw new DocmetaError(\n `Unsupported file type \"${extension}\" for \"${label}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n filesScanned += 1;\n const members = membersFor(label);\n let extracted;\n try {\n extracted = mergeExternalMetadata(\n label,\n extractor.extract(content, label, {\n elements: resolveElements(label, config, members),\n }),\n externalMetadata,\n members,\n base,\n ).extracted;\n } catch (err) {\n // One malformed block must not end the scan: the coverage question is\n // about the rest of the docset, and the bad file is itself a finding.\n unreadable.push({\n file: label,\n message: err instanceof Error ? err.message : String(err),\n });\n return;\n }\n if (!extracted.present) {\n filesWithoutMetadata += 1;\n return;\n }\n // Top-level keys only — see the note at the head of this section.\n for (const [key, value] of Object.entries(extracted.data)) {\n const stat = stats.get(key) ?? emptyStats();\n recordValue(stat, label, value, extracted.lineFor(key));\n stats.set(key, stat);\n }\n };\n\n if (usingStdin && forced) {\n scanOne(STDIN_LABEL, opts.stdinContent ?? \"\", forced.extensions[0] ?? \"\");\n }\n for (const file of files) {\n const content = await readFile(resolve(base, file), \"utf8\");\n scanOne(file, content, extname(file));\n }\n\n for (const u of unreadable) {\n opts.onNotice?.(`could not read metadata from \"${u.file}\": ${u.message}`);\n }\n\n const all: ReportWithEmptyFlag[] = [...stats.entries()].map(([key, stat]) => {\n const dominantType = dominantTypeOf(stat);\n const enumValues = enumFor(stat, dominantType);\n const format = formatOf(stat, dominantType);\n const outliers = [...stat.locations.entries()]\n .filter(([type]) => type !== dominantType)\n .flatMap(([, where]) => where);\n const outlierCount = [...stat.types.entries()]\n .filter(([type]) => type !== dominantType)\n .reduce((sum, [, count]) => sum + count, 0);\n // From the dominant type only. Ranked across every type, a clustered\n // *outlier* outranks unique dominant values: 50 distinct string titles and\n // three files writing `title: 42` put `42` in the sample column, because it\n // is the one value with a count above 1. The row then reported\n // `string ×50, number ×3` and offered a number as the representative value,\n // three lines above naming those same files as the outliers.\n const sample = [...stat.values.values()]\n .filter((v) => v.type === dominantType)\n .sort((a, b) => b.count - a.count)[0]?.value;\n return {\n key,\n present: stat.present,\n coverage: filesScanned === 0 ? 0 : (stat.present / filesScanned) * 100,\n types: [...stat.types.entries()]\n .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))\n .map(([type, count]) => ({ type, count })),\n dominantType,\n outliers,\n outlierCount,\n distinct: stat.values.size,\n distinctCapped: stat.distinctCapped,\n ...(enumValues ? { enumValues } : {}),\n ...(sample !== undefined ? { sample } : {}),\n ...(format !== undefined ? { format } : {}),\n sawEmptyString: stat.sawEmptyString,\n };\n });\n\n const kept = all\n .filter((k) => k.coverage >= minCoverage)\n .sort((a, b) => b.coverage - a.coverage || a.key.localeCompare(b.key));\n\n // Alphabetical in the draft, not coverage order: this file is committed and\n // hand-edited, and a stable key order keeps its diffs readable.\n const properties: Record<string, unknown> = {};\n for (const report of [...kept].sort((a, b) => a.key.localeCompare(b.key))) {\n properties[report.key] = draftPropertyFor(report);\n }\n\n const draft: Record<string, unknown> = {\n $schema: DRAFT_DIALECT,\n $comment:\n \"Generated by `manni meta schemas infer`. Nothing is required, deliberately: what your docset happens to contain is not the same as what your standard should demand. Promote keys into a `required` list yourself, one at a time, behind a baseline.\",\n type: \"object\",\n properties,\n };\n\n // Public reports carry no scan bookkeeping.\n const keys: InferKeyReport[] = kept.map(({ sawEmptyString: _drop, ...rest }) => rest);\n\n if (absOut !== undefined) {\n await mkdir(dirname(absOut), { recursive: true });\n await writeFileAtomic(absOut, `${JSON.stringify(draft, null, 2)}\\n`);\n }\n\n return {\n filesScanned,\n filesWithoutMetadata,\n unreadable,\n keys,\n hiddenByMinCoverage: all.length - kept.length,\n draft,\n ...(absOut !== undefined ? { out: posixRelative(cwd, absOut) } : {}),\n gitignoreSkipped,\n };\n}\n","/**\n * `query` command core. Runs one SQL statement over an in-memory SQLite\n * database built per run from the metadata extracted from every input file.\n * Input handling (positional paths, globs, directories, `-` for stdin, and\n * config `paths:` fallback) mirrors `get` so the two commands behave\n * identically. Proposal 0021 is the design record.\n */\nimport { randomBytes } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, open, readFile, rename, rm } from \"node:fs/promises\";\nimport type { CollectionConfig } from \"../../shared/collections.js\";\nimport {\n loadExternalMetadata,\n mergeExternalMetadata,\n type ExternalMetadataIndex,\n} from \"../core/external-metadata.js\";\nimport { dirname, isAbsolute, resolve, extname, sep } from \"node:path\";\nimport {\n FILE_SCHEMA_KEY,\n overrideGlobs,\n collectSchemaPins,\n resolveElements,\n resolveSchemaSetWithSource,\n} from \"../core/resolve-schema.js\";\nimport { detectJsonIndent, stripBom, toJsonText } from \"../core/json-text.js\";\nimport { integrityOf } from \"../core/integrity.js\";\nimport {\n assertNotIgnored,\n posixRelative,\n type IgnoreGuardText,\n} from \"./schemas.js\";\nimport { writeFileAtomic } from \"../core/write-file.js\";\nimport { stripFrontmatter } from \"../extractors/frontmatter-write.js\";\nimport { deepEqual } from \"../extractors/patch-util.js\";\nimport {\n DocmetaError,\n type ExtractedMetadata,\n type MetadataExtractor,\n type MetadataPatch,\n} from \"../types.js\";\nimport {\n extractorByName,\n extractorForExtension,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_TOKEN,\n STDIN_LABEL,\n} from \"../core/load-files.js\";\nimport {\n resolveRunConfig,\n schemaTrustRoot,\n type ConfigNotice,\n type DocmetaConfig,\n type SchemaTrustRoot,\n} from \"../core/config.js\";\nimport {\n RESERVED,\n SYSTEM_COLUMNS,\n assertSingleStatement,\n bindValue,\n collectNamedParameters,\n corpusDataColumns,\n createDocsTable,\n loadSqlite,\n registerLineFor,\n skipComment,\n skipStringOrIdent,\n startsComment,\n startsStringOrIdent,\n stripLeadingTrivia,\n type SqlValue,\n} from \"../core/projection.js\";\nimport {\n collectCollections,\n collectionNames,\n memberOf,\n retainMembers,\n createCollectionViews,\n} from \"../core/collections.js\";\nimport { commandsOf } from \"../core/derive/config.js\";\nimport {\n createDerivedView,\n createResolvedView,\n DERIVED_ROWS,\n DERIVED_VIEW,\n derivedColumns,\n deriveForTable,\n fieldsForSql,\n mentionsDerived,\n mentionsResolved,\n RESOLVED_VIEW,\n} from \"../core/derive/table.js\";\nimport { derivableFields, type DeriveInput } from \"../core/derive/types.js\";\nimport type { FingerprintContext } from \"../core/baseline.js\";\nimport { stringFormatNames, validatesFormat } from \"../core/validator.js\";\nimport {\n classifyRef,\n isPublishedBuiltinUrl,\n loadSchema,\n publishedBuiltins,\n type SchemaPin,\n} from \"../core/schema-registry.js\";\nimport { parseDocument, isMap, isSeq, isScalar } from \"yaml\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\nexport interface QueryOptions {\n /**\n * One SQL statement. The table is `docs`; see the system columns below.\n * May be empty when `db` is set — export without querying.\n */\n sql: string;\n /**\n * `--db`: also write the built database to this file, for any SQLite\n * front-end (sqlite3, Datasette, duckdb) to open afterwards. The file is a\n * regenerated artifact: an existing SQLite file at the path is overwritten,\n * anything else is refused.\n */\n db?: string;\n inputs: string[];\n as?: string;\n exclude?: string[];\n exts?: string[];\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n /**\n * `--collection <name>`, repeatable: run over the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with positional paths; `-` is allowed beside it.\n */\n collections?: string[];\n cwd?: string;\n /** Content for the `-` (stdin) input, injected by the CLI/tests. */\n stdinContent?: string;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n /**\n * `--offline`, accepted for surface parity with the other commands. DDL\n * statements do resolve the corpus's schema set (0024), but only from disk\n * and the bundled built-ins — a URL ref refuses with \"vendor it first\"\n * before anything could fetch — so there is still no network dependency to\n * suppress.\n */\n offline?: boolean;\n /**\n * `--no-cache` (false): ask GitHub or GitLab again rather than reading the\n * review cache. Only a statement naming the `derived` table consults it,\n * and only for `reviewed-by` and `last-reviewed`; absent leaves it on.\n */\n cache?: boolean;\n /**\n * `--dry-run`: preview the statement's per-file changes — the diff it\n * would make, files untouched. Without it a mutating statement applies,\n * matching `fill`'s convention (proposal 0025; 0022 recorded the original\n * preview-by-default surface this revises).\n */\n dryRun?: boolean;\n /**\n * Values for the statement's named parameters (`$name`, `:name`, `@name`),\n * keyed by bare name (a `$`/`:`/`@` prefix on a key is tolerated). Each\n * value passes through the same `bindValue` the projection loader uses —\n * booleans become 1/0, arrays and objects JSON text — so a bound parameter\n * compares against a stored cell under exactly the encoding the cell got\n * (proposal 0029). A parameter the SQL references with no entry here\n * refuses: unbound would silently bind NULL and match nothing.\n */\n params?: Record<string, unknown>;\n /**\n * `-s/--schema`, repeatable: the schema set the run's DDL evolves — CLI\n * precedence for the DDL planner *only* (proposal 0030). The per-file\n * resolution walk is skipped and the deduped refs are the set; every guard\n * inside the set (single local file for ADD, sole declarer for\n * DROP/RENAME, builtin fork, URL refusal, the trust boundary) runs\n * unchanged. Collection views keep following the config's resolution. A\n * run whose statement produces no DDL effect refuses before anything is\n * applied — a flag that would silently mean nothing must refuse.\n */\n schemas?: string[];\n /** The clock an uncommitted body change is dated by. Test seam; default `new Date()`. */\n now?: () => Date;\n}\n\n/**\n * One thing a statement changed, in file-space terms. Cell-level kinds carry\n * a `key` (a set, a deletion via `SET k = NULL` / `ALTER DROP COLUMN`, or a\n * key rename); file-level kinds carry the whole event (`cleared` — the block\n * stripped by DELETE; `created` — a file INSERT made; `renamed` — a `_path`\n * move). Exactly one kind per object.\n */\nexport type QueryChange = { file: string; written: boolean } & (\n | { key: string; from: unknown; to: unknown }\n | { key: string; from: unknown; deleted: true }\n | { key: string; renamedFrom: string; to: unknown }\n | { cleared: true; from: Record<string, unknown> }\n | { created: true; to: Record<string, unknown> }\n | { renamed: string }\n | {\n /** A DDL statement edited the schema itself (0024): `file` is the\n * schema written — an in-place edit, or the fork of a builtin. */\n schema: true;\n op: \"add\" | \"drop\" | \"rename\";\n key: string;\n renamedTo?: string;\n type?: string;\n /** 0028: a declared type equal to a format name carries the format. */\n format?: string;\n /** 0028: a `CHECK (k IN (…))` on the added column carries the enum. */\n enum?: (string | number)[];\n required?: boolean;\n forkedFrom?: string;\n }\n | {\n /** A DDL side effect on the governing config file: a fork repoints the\n * `schemas:` entry (`key: \"schemas\"`), an in-place edit of a pinned\n * schema refreshes its pin (`key: \"integrity\"`). Disclosed as a change\n * because the preview must name every file `--write` will touch. */\n config: true;\n key: string;\n from: unknown;\n to: unknown;\n }\n);\n\nexport interface QueryRun {\n /** Result column names, in SELECT order — present even for zero rows. */\n columns: string[];\n rows: Record<string, unknown>[];\n /** Set when `db` was written: where, and how big the table is. */\n db?: { path: string; files: number; columns: number };\n /**\n * Present when the statement was a metadata edit: every cell it changed\n * (empty when a mutating statement matched nothing). Absent on reads.\n */\n changes?: QueryChange[];\n /**\n * Where the run stood, in the same shape `ValidateRun.frame` carries — the\n * path-normalization frame SARIF and JUnit need before they can name a file\n * the way the repository does (proposal 0026). Constructed from the run's\n * `cwd`, its config directory, and the directory file labels resolve\n * against; absent only when a caller built a `QueryRun` by hand.\n */\n frame?: FingerprintContext;\n}\n\nexport async function runQuery(opts: QueryOptions): Promise<QueryRun> {\n const cwd = opts.cwd ?? process.cwd();\n const sql = opts.sql.trim();\n if (sql === \"\" && opts.db === undefined) {\n throw new DocmetaError(\"Specify SQL to run.\");\n }\n if (sql === \"\") {\n // Export-only run. Options that speak to a statement would be silently\n // ignored past this point (runSql returns before either is consulted),\n // and an ignored option is the false green 0029's rule exists to\n // refuse. Guarded here in the core, not only in the CLI gates, so a\n // library caller gets the same refusal the flags get.\n if (opts.schemas !== undefined && opts.schemas.length > 0) {\n throw new DocmetaError(\n \"`schemas` names the schema set DDL evolves, and an export-only run (no SQL) runs no statement. Pass the SQL, or drop `schemas`.\",\n );\n }\n if (opts.params !== undefined && Object.keys(opts.params).length > 0) {\n throw new DocmetaError(\n \"`params` binds named parameters in a statement, and an export-only run (no SQL) references none. Pass the SQL, or drop `params`.\",\n );\n }\n }\n if (sql !== \"\") assertSingleStatement(sql);\n\n // The false-green guard (proposal 0029): the engine throws on an extra\n // bound parameter, but a referenced parameter with nothing bound silently\n // binds NULL and matches nothing — a zero-row `--check` from a typo is a\n // passing CI gate. Refused here, before any file is read.\n const boundParams = bindParams(opts.params);\n if (sql !== \"\") {\n // Own keys only: `\"toString\" in {}` is true, so an `in` test would read\n // $toString (or $constructor, $__proto__) as bound and let it bind NULL —\n // the exact false green this guard refuses.\n const unbound = collectNamedParameters(sql).filter(\n (token) => !Object.hasOwn(boundParams, token.slice(1)),\n );\n if (unbound.length > 0) {\n const list = unbound.join(\", \");\n throw new DocmetaError(\n `The statement references ${list} with nothing bound — an unbound parameter binds NULL and matches nothing. Bind ${\n unbound.length === 1 ? \"it\" : \"each\"\n } with --param ${unbound[0]?.slice(1) ?? \"name\"}=<value> (or \\`params\\` in the API).`,\n );\n }\n }\n\n // Explicit CLI inputs win, else config `paths:`; `base` is whichever of the\n // two directories those inputs were written relative to.\n const {\n config,\n inputs,\n base,\n configDir,\n configPath,\n configSection,\n collections,\n declaredCollections,\n fromCollections,\n } = await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const usingStdin = inputs.includes(STDIN_TOKEN);\n\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to read. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n const forced = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forced) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Supported extensions: ${supportedExtensions().join(\", \")}.`,\n );\n }\n\n const exts = opts.exts ?? (forced ? forced.extensions : undefined);\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n // Only `--exclude`: a collection's `exclude:` governs membership, not the\n // walk of a path someone typed (0041 rule 3).\n const exclude = opts.exclude ?? [];\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"queried\",\n });\n\n const entries: QueryEntry[] = [];\n // External metadata (0037), read once per run and merged into every row.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n });\n\n const readOne = (label: string, content: string, extension: string): void => {\n const extractor = forced ?? extractorForExtension(extension);\n if (!extractor) {\n throw new DocmetaError(\n `Unsupported file type \"${extension}\" for \"${label}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n const members = membersFor(label);\n const own = extractor.extract(content, label, {\n elements: resolveElements(label, config, members),\n });\n const extracted = mergeExternalMetadata(label, own, externalMetadata, members, base).extracted;\n entries.push({ label, extracted, extractor, own, content });\n };\n\n if (usingStdin) {\n if (!forced) {\n throw new DocmetaError(\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\",\n );\n }\n // Unreachable while every registered extractor has at least one extension,\n // but a bare \"\" fallback here would surface as `Unsupported file type \"\"`\n // with the --as format name nowhere in it.\n const ext = forced.extensions[0];\n if (ext === undefined) {\n throw new DocmetaError(\n `Format \"${forced.name}\" registers no file extension to read stdin as.`,\n );\n }\n readOne(STDIN_LABEL, opts.stdinContent ?? \"\", ext);\n }\n\n for (const file of files) {\n const content = await readFile(resolve(base, file), \"utf8\");\n readOne(file, content, extname(file));\n }\n\n // The export path resolves like every positional the user typed: from\n // where they are standing, not from the config's directory.\n const db =\n opts.db === undefined\n ? undefined\n : { resolved: resolve(cwd, opts.db), display: opts.db };\n const run = await runSql(sql, entries, {\n target: db,\n params: boundParams,\n ...(opts.schemas !== undefined && opts.schemas.length > 0\n ? { cliSchemas: opts.schemas }\n : {}),\n write: !opts.dryRun,\n cache: opts.cache ?? true,\n ...(opts.now !== undefined ? { now: opts.now } : {}),\n base,\n config,\n cwd,\n configDir,\n configPath,\n configSection,\n trustRoot: schemaTrustRoot(cwd, configDir),\n externalMetadata,\n collections,\n declaredCollections,\n memberships: membersFor,\n managed: new Set(config?.derive?.fields ?? []),\n onNotice: opts.onNotice,\n });\n // The same frame `runValidate` returns, built from query's own run context:\n // fingerprints and canonical paths must not depend on where the command was\n // run from (proposal 0026 § stress test 6).\n return { ...run, frame: { cwd, base: configDir ?? cwd, runBase: base } };\n}\n\ninterface QueryEntry {\n label: string;\n extracted: ExtractedMetadata;\n /** The extractor that read it — a write goes back through the same one. */\n extractor: MetadataExtractor;\n /**\n * The document's OWN extraction, from before the external-metadata merge,\n * and the text it came from: what the `derived` table (0040) is computed\n * over. A managed key is never manifest-owned, and the git source hashes\n * the body.\n */\n own: ExtractedMetadata;\n content: string;\n}\n\n/**\n * `QueryOptions.params`, normalized for the engine: bare-name keys (a\n * `$`/`:`/`@` prefix is tolerated, since `node:sqlite` binds either spelling)\n * and SQL-space values via the projection's own `bindValue`.\n */\nfunction bindParams(\n params: Record<string, unknown> | undefined,\n): Record<string, SqlValue> {\n // Null prototype, so a `__proto__` key is an ordinary own entry (it passes\n // the name grammar) instead of a prototype mutation the engine never sees.\n const out: Record<string, SqlValue> = Object.create(null) as Record<\n string,\n SqlValue\n >;\n for (const [key, value] of Object.entries(params ?? {})) {\n const name = key.startsWith(\"$\") || key.startsWith(\":\") || key.startsWith(\"@\")\n ? key.slice(1)\n : key;\n out[name] = bindValue(value);\n }\n return out;\n}\n\ninterface RunContext {\n target?: { resolved: string; display: string };\n /** Named-parameter binds, bare-name keys, already through `bindValue`. */\n params: Record<string, SqlValue>;\n /**\n * `-s` refs: the DDL planner's set, in place of the per-file walk (0030).\n * INVARIANT: set only when non-empty — `runQuery` threads it only then —\n * so `!== undefined` is the one guard every consumer uses.\n */\n cliSchemas?: string[];\n write: boolean;\n /** Whether the review cache may answer a `derived` build; `--no-cache` clears it. */\n cache: boolean;\n /** The clock an uncommitted body change is dated by; default `new Date()`. */\n now?: () => Date;\n /** Directory file labels resolve against (see `resolveRunConfig`). */\n base: string;\n config: DocmetaConfig | null;\n /** The run's working directory — schema refs resolve from here. */\n cwd: string;\n /** Directory holding the governing config file, when one exists. */\n configDir?: string;\n /** Absolute path of the governing config file, when one exists. */\n configPath?: string;\n /**\n * The key that config sits under — `meta` in a family file, absent in a\n * legacy per-tool file. Only the DDL config rewrite needs it, and it needs\n * it badly: `schemas:` is one level down in a family file.\n */\n configSection?: string;\n /** The boundary a schema read or write may not escape (proposal 0015). */\n trustRoot: SchemaTrustRoot;\n /** External metadata of the run (proposal 0037); null when none are configured. */\n externalMetadata: ExternalMetadataIndex | null;\n /** The collections the run covers (proposal 0041); `[]` with no config. */\n collections: readonly CollectionConfig[];\n /**\n * Every collection the config declares, selected or not. The views are built\n * from this list (0041 rule 11), so a statement naming a collection\n * `--collection` left out still answers instead of failing to compile.\n */\n declaredCollections: readonly CollectionConfig[];\n /** The collections one label belongs to - `memberOf` bound to this run. */\n memberships: (label: string) => readonly string[];\n /**\n * The managed fields (`derive.fields`, proposal 0040): readable in every\n * row, writable by `manni meta derive` alone. Empty when none are configured.\n */\n managed: ReadonlySet<string>;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n}\n\n/**\n * Only two byte patterns may be overwritten by `--db`: a SQLite database\n * (docmeta's own artifact, or anyone else's — both are regenerable-shaped)\n * and an empty file. Anything else at the path is somebody's data.\n */\nasync function prepareDbTarget(resolved: string, display: string): Promise<void> {\n let handle;\n try {\n handle = await open(resolved, \"r\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return;\n throw err;\n }\n try {\n const { bytesRead, buffer } = await handle.read(\n Buffer.alloc(16),\n 0,\n 16,\n 0,\n );\n const magic = Buffer.from(\"SQLite format 3\\0\", \"latin1\");\n const isSqlite = bytesRead === 16 && buffer.equals(magic);\n if (bytesRead !== 0 && !isSqlite) {\n throw new DocmetaError(\n `\"${display}\" exists and is not a SQLite database; refusing to overwrite it.`,\n );\n }\n } finally {\n await handle.close();\n }\n await rm(resolved);\n}\n\n/**\n * Internal signal for the lazy view build: the statement referenced a\n * configured collection whose view is not created yet. Never escapes\n * `runSql` — its retry catch either rebuilds once or is not reached.\n */\nclass MissingCollectionView extends Error {}\n\n/**\n * The same signal for the derived channel's two tables (0040): the statement\n * named `derived` or `resolved`, neither view is built yet, and building them\n * is worth one git walk. One class for both, because one build makes both.\n */\nclass MissingDerivedTable extends Error {}\n\n/**\n * Wrap an engine error from the user's statement — prepare-time or\n * execution-time — into the operational refusal the CLI reports. Three cases\n * get a remedy: an INSERT/rename onto a loaded `_path` (the projection's\n * primary key catches it before any disk check can), a write through a\n * collection view (0027) — SQLite's own refusal, completed with the\n * write-through-docs spelling — and a write to the `derived` or `resolved`\n * view (0040), neither of which has anything behind it to write to.\n * `resolved` gets a remedy of its own because it has two sides: a value the\n * document should state is a write to `docs`, and one the evidence should\n * state is a derive run. The view-name capture is\n * non-greedy up to the literal tail: a collection name may contain spaces,\n * which \\S+ would truncate into a remedy naming a view that does not exist.\n */\nfunction refuseSqlError(err: unknown): never {\n const message = errorMessage(err);\n if (message.includes(\"UNIQUE constraint failed: docs._path\")) {\n throw new DocmetaError(\"That _path already exists in the corpus.\");\n }\n const viewWrite = /cannot modify (.+?) because it is a view/.exec(message);\n const viewName = viewWrite?.[1];\n if (viewName !== undefined) {\n if (viewName.toLowerCase() === DERIVED_VIEW) {\n throw new DocmetaError(\n `SQL error: ${message}; a collection or the derived table is read-only — the derived table is recomputed from the evidence on every run. Change the evidence, or stamp it into the documents with manni meta derive.`,\n );\n }\n if (viewName.toLowerCase() === RESOLVED_VIEW) {\n throw new DocmetaError(\n `SQL error: ${message}; the resolved table is read-only — it is \\`docs\\` and the evidence joined, so write to docs, or stamp the evidence with manni meta derive.`,\n );\n }\n throw new DocmetaError(\n `SQL error: ${message}; a collection or the derived table is read-only — write through docs: UPDATE docs … WHERE _path IN (SELECT _path FROM \"${viewName.replaceAll('\"', '\"\"')}\").`,\n );\n }\n throw new DocmetaError(`SQL error: ${message}`);\n}\n\n/**\n * Build the `docs` table — in memory, or at the export target — run the\n * user's statement over it (none, when only exporting), and judge what the\n * statement *did*: reads return rows; metadata edits become per-file changes,\n * previewed or (with `write`) applied through the extractors' writers.\n */\nasync function runSql(\n sql: string,\n entries: QueryEntry[],\n ctx: RunContext,\n): Promise<QueryRun> {\n const target = ctx.target;\n // Data columns: the corpus's key union, plus a SET/INSERT target no file has\n // yet — that is how a corpus-new key is created. The scan is tolerant and\n // only ever *adds* empty columns: anything it misses fails exactly as before\n // (\"no such column\"), and a false positive is an all-NULL column nothing\n // diffs.\n const dataColumns = corpusDataColumns(\n entries,\n sql === \"\"\n ? []\n : [...collectSetTargets(sql), ...collectInsertTargets(sql)],\n );\n\n const { DatabaseSync } = await loadSqlite();\n if (target) {\n // SQLite creates the file but never its directories — `.docmeta/` on a\n // fresh checkout is exactly the path that does not exist yet.\n await mkdir(dirname(target.resolved), { recursive: true });\n await prepareDbTarget(target.resolved, target.display);\n }\n let db: InstanceType<typeof DatabaseSync>;\n try {\n db = new DatabaseSync(target ? target.resolved : \":memory:\");\n } catch (err) {\n throw new DocmetaError(\n `Cannot open \"${target?.display ?? \":memory:\"}\": ${errorMessage(err)}`,\n );\n }\n const dbInfo = target\n ? {\n path: target.display,\n files: entries.length,\n columns: SYSTEM_COLUMNS.length + dataColumns.length,\n }\n : undefined;\n // Whether the derived table was built this run. Held in an object, and\n // declared here rather than beside `buildDerived`, because the `finally`\n // below reads it to drop the table from a `--db` export — and a bare\n // `let` set inside a closure narrows to `false` at that read.\n const derivedTable = { built: false };\n try {\n createDocsTable(db, entries, dataColumns);\n // Collections (0041 rule 7): one view per declared collection, holding the\n // members the run loaded — built LAZILY on the normal path, because a\n // statement that never names a collection should pay nothing for the\n // membership arithmetic and the view SQL. The build happens on demand\n // (below, when the engine reports the collection's table as missing) —\n // with one eager exception: a `--db` export must carry the views (0027 §\n // stress test 5), empty-SQL export-only runs included.\n // Annotated `boolean`: assignments happen inside `buildViews`, which\n // narrowing does not track — an inferred `false` reads every later\n // `!viewsBuilt` as always-true.\n let viewsBuilt: boolean = false;\n const buildViews = (): void => {\n // Idempotent, because the eager triggers overlap: a `--db` export and\n // the catalog pre-trigger may both ask for the same build.\n if (viewsBuilt) return;\n createCollectionViews(\n db,\n collectCollections(entries, {\n collections: ctx.declaredCollections,\n ...(ctx.configDir !== undefined ? { configDir: ctx.configDir } : {}),\n base: ctx.base,\n }),\n );\n viewsBuilt = true;\n };\n if (target) buildViews();\n // The derived channel's tables (0040), `derived` and `resolved`: built\n // only when the statement names one of them, because building them spawns\n // git (and, with the github or gitlab source, gh or glab). One build makes\n // both — `resolved` is the join of `docs` with the same rows — so naming\n // either pays the walk once and a statement joining the two pays it once\n // too. Eager when the text names one as a table, and lazily on the\n // engine's `no such table: derived` / `: resolved` as the backstop for a\n // spelling the text search misses. Only the fields the statement can read are\n // derived, so only the sources those need are consulted; the view\n // keeps every column, NULL where nothing was derived. Stdin has no\n // history and no row. Transient in a `--db` export: the value is not\n // stored anywhere, and an export that froze it would be the stale stamp\n // the channel exists to catch, so both objects are dropped before the\n // handle closes (see the `finally` below).\n const buildDerived = async (): Promise<void> => {\n if (derivedTable.built) return;\n const inputs: DeriveInput[] = entries\n .filter((e) => e.label !== STDIN_LABEL)\n .map((e) => ({\n label: e.label,\n absPath: resolve(ctx.base, e.label),\n content: e.content,\n extracted: e.own,\n }));\n // The run's columns: the built-ins and the configured command keys\n // (0042), so a statement reading a command's field runs the command.\n const commands = commandsOf(ctx.config?.derive);\n const records = await deriveForTable(\n inputs,\n {\n cwd: ctx.cwd,\n base: ctx.base,\n ...(ctx.configDir !== undefined ? { configDir: ctx.configDir } : {}),\n config: ctx.config,\n cache: ctx.cache,\n ...(ctx.now !== undefined ? { now: ctx.now } : {}),\n },\n \"narrow derive.sources in manni.config.yaml\",\n fieldsForSql(sql, derivableFields(commands)),\n );\n createDerivedView(db, records, derivedColumns(commands));\n // `resolved` (0040) is the join of the two, so it is built from the\n // same `dataColumns` `createDocsTable` was given — the view's asserted\n // side reads those columns by name, and a list recomputed here could\n // disagree with the table's (a SET target the scan added has a column\n // in `docs` and must have one in `resolved`).\n createResolvedView(db, dataColumns, commands);\n derivedTable.built = true;\n };\n if (sql === \"\") {\n return { columns: [], rows: [], ...(dbInfo ? { db: dbInfo } : {}) };\n }\n if (mentionsDerived(sql) || mentionsResolved(sql)) await buildDerived();\n\n // ATTACH and VACUUM INTO write files of their own, outside the table the\n // effect gate below watches — the only statements refused by name. The\n // check runs on the first real token: `/* c */ ATTACH …` must not slip\n // past a first-character regex on the strength of a comment.\n //\n // Deliberately NOT `PRAGMA query_only`: writes to the projection are the\n // feature since 0022 (the effect gate below is the guard), and the\n // snapshot reads share this handle. The residue is confined to a `--db`\n // export — a statement may add its own tables or indexes to that file,\n // which is a regenerable artifact by declared contract.\n const head = stripLeadingTrivia(sql);\n if (/^(attach|vacuum)\\b/i.test(head)) {\n throw new DocmetaError(\n `${head.split(/\\s/, 1)[0]?.toUpperCase() ?? \"That statement\"} is refused: it can write outside the docs table.`,\n );\n }\n\n // Fail-safe eager build for catalog-observing statements — and any\n // statement that plausibly names a collection. A sqlite_master /\n // sqlite_schema read, a PRAGMA, and CREATE/DROP/ALTER never raise\n // `no such table` for a missing view, so the lazy retry below cannot\n // rescue them: without this they would observe a catalog with no views\n // (empty listings, table_info silence, CREATE silently shadowing a\n // collection name) where the always-eager build listed, answered, or\n // refused. The substring search deliberately OVER-triggers: a collection\n // name inside a string literal or comment costs one always-correct eager\n // build, while under-triggering is exactly this silent-miss bug class.\n // The retry stays as the backstop for the one spelling a raw-text search\n // cannot see — a name whose quoted-identifier spelling doubles a quote\n // character inside it.\n const lower = sql.toLowerCase();\n const observesCatalog =\n lower.includes(\"sqlite_master\") ||\n lower.includes(\"sqlite_schema\") ||\n lower.includes(\"pragma\") ||\n /^(create|drop|alter)\\b/i.test(head) ||\n collectionNames(ctx.declaredCollections).some((n) =>\n lower.includes(n.toLowerCase()),\n );\n if (observesCatalog) buildViews();\n\n // 0024: `SET k = NULL` is the removal spelling, so the literal `k: null`\n // gets a function instead — `explicit_null()` returns a per-run random\n // sentinel no real content can collide with and nothing can type.\n const sentinel = `manni:null:${randomBytes(16).toString(\"hex\")}`;\n db.function(\"explicit_null\", () => sentinel);\n // 0026: the statement may name the source line a key sits on.\n registerLineFor(db, entries);\n\n // 0022: the statement runs freely against this disposable projection and\n // is judged by its effects, not its syntax. A read leaves no diff. The\n // column snapshot (0024) is what makes DDL an effect too.\n //\n // One closure, so the lazy view build below can re-run it intact. The\n // ordering invariant: prepare first — compiling is effect-free, so a\n // lazy-view miss on the first attempt costs one compile and never a\n // full-corpus snapshot — then the baseline snapshots, then execution:\n // the baseline must precede the statement's effects. The snapshots\n // themselves are all docs-scoped (`SELECT * FROM docs`,\n // `PRAGMA table_info(docs)`, the catalog row named `docs`) and cannot\n // see views, so a rebuild between attempts changes nothing they record.\n const runOnce = async (): Promise<QueryRun> => {\n let stmt: ReturnType<typeof db.prepare>;\n let columns: string[];\n try {\n stmt = db.prepare(sql);\n columns = stmt.columns().map((c) => c.name);\n } catch (err) {\n const message = errorMessage(err);\n // Lazy collection views: the first time a statement names a configured\n // collection, its view does not exist yet and the engine reports the\n // table as missing (case-folded — SQLite resolves table names\n // case-insensitively). Signal the build-and-retry; on the retry\n // `viewsBuilt` is true, so a second failure surfaces normally below.\n const missing = missingTableName(message);\n if (\n missing !== undefined &&\n !viewsBuilt &&\n namesConfiguredCollection(missing, ctx.declaredCollections)\n ) {\n // INVARIANT: this signal may only ever be raised from this\n // prepare-time catch. `no such table` is a compile error — probed\n // unreachable from execution on node:sqlite — and a retry thrown\n // after execution began would re-run `stmt.all` and double-apply\n // whatever DML the first run already did.\n throw new MissingCollectionView();\n }\n // The same backstop for the derived channel's tables (0040), for the\n // one spelling the raw-text search cannot see. Either name signals the\n // one build that makes both. Same invariant: raised only from this\n // prepare-time catch.\n const missingBare = missing?.replace(/^(main|temp)\\./i, \"\").toLowerCase();\n if (\n !derivedTable.built &&\n (missingBare === DERIVED_VIEW || missingBare === RESOLVED_VIEW)\n ) {\n throw new MissingDerivedTable();\n }\n refuseSqlError(err);\n }\n const before = snapshotRows(db);\n const colBefore = snapshotColumns(db);\n // 0028: table_info cannot see a CHECK, so the stored CREATE TABLE text is\n // snapshotted alongside the column shapes and consulted for adds only.\n const catalogBefore = snapshotCatalogSql(db);\n let rows: Record<string, unknown>[];\n try {\n // The single user-SQL call site (proposal 0029): binding here is why\n // parameters work uniformly across reads, `--check` gates, and DML.\n // Passed unconditionally — probed on node:sqlite, `all({})` behaves\n // identically to `all()` for statements with and without parameters,\n // and the unbound-reference guard already refused any statement whose\n // named parameters this object does not cover.\n // node:sqlite types rows as unknown[]; each row is a name->value record.\n rows = stmt.all(ctx.params);\n } catch (err) {\n refuseSqlError(err);\n }\n let after: Map<string, Record<string, unknown>>;\n try {\n after = snapshotRows(db);\n } catch {\n // The table itself is gone. \"Delete the table definition\" is the\n // accident-shaped spelling of two real statements; name them both.\n throw new DocmetaError(\n \"DROP TABLE is refused. DELETE FROM docs WHERE … strips metadata from files; ALTER TABLE docs DROP COLUMN retires one key from the schema and every file.\",\n );\n }\n const diff = diffProjection(before, after);\n const schemaOps = columnDiffOps(\n colBefore,\n snapshotColumns(db),\n before,\n after,\n catalogBefore,\n snapshotCatalogSql(db),\n );\n // 0030: -s speaks only to the DDL planner, and DDL is judged by its\n // effects — so \"no schema-evolving effects\" is knowable only here,\n // after execution. The placement is load-bearing: the refusal must\n // land on the plan side of the all-or-nothing line, BEFORE\n // buildChanges and applyChanges, so a DML statement under -s never\n // writes files and then errors (the applies-then-refuses trap the\n // -f csv review found). Two truths in the wording: \"no\n // schema-evolving effects\" rather than \"no DDL\" (a CREATE INDEX into\n // a --db export is DDL the planner deliberately ignores), and the\n // --db residue named when it exists — the export target was written\n // before the statement ran and holds whatever the statement did.\n if (ctx.cliSchemas !== undefined && schemaOps.length === 0) {\n throw new DocmetaError(\n `-s names the schema set DDL evolves; this statement produced no schema-evolving effects (ALTER TABLE docs …), so the flag would silently mean nothing.${\n target\n ? \" No file or schema writes were applied; the --db export was still written and reflects the statement.\"\n : \" Nothing was applied.\"\n } Drop -s, or evolve the schema with ALTER TABLE docs.`,\n );\n }\n // Structural, not textual: a read always yields result columns, DML and\n // DDL (without RETURNING) never do — so `WITH … UPDATE …` classifies\n // correctly even when it matches zero rows. The residual: RETURNING DML\n // that matches nothing reads as an empty result, which is what it shows.\n const mutatingIntent = columns.length === 0;\n const hasEffects =\n diff.cells.length > 0 ||\n diff.clearedRows.length > 0 ||\n diff.createdRows.size > 0 ||\n diff.renamedFiles.length > 0 ||\n schemaOps.length > 0;\n if (!hasEffects && !mutatingIntent) {\n return { columns, rows, ...(dbInfo ? { db: dbInfo } : {}) };\n }\n\n // DDL edits the schema itself (0024); its plan carries both the schema\n // change records and — for a builtin fork — the reference repoints.\n assertDefaultsMatchDeclaredTypes(schemaOps, diff.cells);\n const schemaPlan =\n schemaOps.length > 0\n ? await planSchemaMutation(schemaOps, entries, ctx)\n : undefined;\n const renameHints = schemaOps.flatMap((op) =>\n op.op === \"rename\" && op.renamedTo !== undefined\n ? [{ from: op.key, to: op.renamedTo }]\n : [],\n );\n // 0028: a BOOLEAN add's backfill writes real booleans to the files — the\n // projection's 1/0 encoding is bind-layer, not file-layer.\n const booleanAdds = new Set(\n schemaOps.flatMap((op) =>\n op.op === \"add\" && op.type === \"boolean\" ? [op.key] : [],\n ),\n );\n const changes = [\n ...(schemaPlan?.changes ?? []),\n ...buildChanges(diff, entries, sentinel, ctx, renameHints, booleanAdds),\n ];\n if (ctx.write) await applyChanges(changes, entries, ctx, schemaPlan);\n return { columns, rows, changes, ...(dbInfo ? { db: dbInfo } : {}) };\n };\n\n try {\n return await runOnce();\n } catch (err) {\n if (err instanceof MissingDerivedTable) {\n // The prepare named `derived` or `resolved` with no view yet: derive,\n // build both, and re-run the closure — the same one-retry shape as the\n // collections below, for the same reasons.\n await buildDerived();\n return await runOnce();\n }\n if (!(err instanceof MissingCollectionView)) throw err;\n // The first prepare named a collection with no view yet: build them\n // all and re-run the closure — prepare, snapshots, execution,\n // judgment. The first attempt died compiling, so nothing ran and\n // nothing was snapshotted; re-running the whole closure keeps one code\n // path with the baseline still taken before the (only) execution. A\n // write through the fresh view reaches the ordinary \"cannot modify X\n // because it is a view\" remedy on this retry; any other second failure\n // surfaces as usual.\n buildViews();\n return await runOnce();\n }\n } finally {\n // A `--db` export must not carry the derived channel's tables: they are\n // recomputed from the evidence on every run, and a file that froze one\n // would hand a later reader a stale value with no evidence behind it. In\n // memory the whole database goes with the handle, so only the export\n // needs the drop. `resolved` goes first: it reads the backing table, and\n // an export must never carry a view over a table it no longer has.\n if (target && derivedTable.built) {\n db.exec(\n `DROP VIEW IF EXISTS ${RESOLVED_VIEW}; DROP VIEW IF EXISTS ${DERIVED_VIEW}; DROP TABLE IF EXISTS ${DERIVED_ROWS}`,\n );\n }\n db.close();\n }\n}\n\n/**\n * The name after `no such table: ` in an engine message — sliced rather than\n * regexed, because a collection name may legally contain a newline, which a\n * `.`-based capture cannot span.\n */\nfunction missingTableName(message: string): string | undefined {\n const prefix = \"no such table: \";\n const at = message.indexOf(prefix);\n return at === -1 ? undefined : message.slice(at + prefix.length);\n}\n\n/**\n * Does the engine's missing-table name refer to a configured collection?\n * Case-folded, because SQLite resolves table names case-insensitively (see\n * `collectionNames` for why JS's looser fold is safe here); a `main.`/`temp.`\n * qualifier the engine may echo for a qualified reference is tolerated too.\n */\nfunction namesConfiguredCollection(\n missing: string,\n collections: readonly CollectionConfig[],\n): boolean {\n const candidates = [missing, missing.replace(/^(main|temp)\\./i, \"\")];\n return collectionNames(collections).some((n) =>\n candidates.some((c) => c.toLowerCase() === n.toLowerCase()),\n );\n}\n\n/** The one sliver of the `node:sqlite` surface the snapshots need. */\ninterface Queryable {\n prepare(sql: string): { all(): unknown[] };\n}\n\n/** Every row of the projection, keyed by `_path`. */\nfunction snapshotRows(db: Queryable): Map<string, Record<string, unknown>> {\n const rows = db.prepare(\"SELECT * FROM docs\").all() as Record<\n string,\n unknown\n >[];\n return new Map(rows.map((r) => [String(r._path), r]));\n}\n\n/** Exported with `assertDefaultsMatchDeclaredTypes`, not via the API index. */\nexport interface CellEffect {\n file: string;\n key: string;\n /** SQL-space value the statement left behind. */\n to: unknown;\n}\n\ninterface ProjectionDiff {\n cells: CellEffect[];\n /** Rows the statement removed — DELETE, meaning: strip the block. */\n clearedRows: string[];\n /** Rows the statement added — INSERT, meaning: create the file. */\n createdRows: Map<string, Record<string, unknown>>;\n /** Rows whose only change is `_path` — a file move. */\n renamedFiles: { from: string; to: string }[];\n}\n\n/**\n * What the statement did, judged by effects (0024). Common rows diff cell by\n * cell; a removed row is a DELETE (strip), an added row an INSERT (create),\n * and a removed/added pair identical in everything but `_path` is a rename.\n * Mixing a rename with cell edits in one statement refuses — each deserves\n * its own preview. Non-`_path` system columns stay read-only.\n */\nfunction diffProjection(\n before: Map<string, Record<string, unknown>>,\n after: Map<string, Record<string, unknown>>,\n): ProjectionDiff {\n const allRemoved = [...before.keys()].filter((p) => !after.has(p)).sort();\n const allAdded = [...after.keys()].filter((p) => !before.has(p)).sort();\n\n // Greedy pairing in sorted order, tracked in sets rather than spliced out\n // of the arrays — same outcome, no quadratic index churn on a bulk rename.\n const renamedFiles: { from: string; to: string }[] = [];\n const pairedFrom = new Set<string>();\n const pairedTo = new Set<string>();\n for (const from of allRemoved) {\n const was = before.get(from);\n if (!was) continue;\n const to = allAdded.find((p) => {\n if (pairedTo.has(p)) return false;\n const now = after.get(p);\n return now !== undefined && rowsEqualExceptPath(was, now);\n });\n if (to === undefined) continue;\n renamedFiles.push({ from, to });\n pairedFrom.add(from);\n pairedTo.add(to);\n }\n const removed = allRemoved.filter((p) => !pairedFrom.has(p));\n const added = allAdded.filter((p) => !pairedTo.has(p));\n if (removed.length > 0 && added.length > 0) {\n // Leftover unpaired adds and removes together can only mean a `_path`\n // change combined with cell edits — no single-statement DML produces\n // both a genuine strip and a genuine create.\n throw new DocmetaError(\n \"The statement changed _path and other cells together; rename and edit separately, so each has its own preview.\",\n );\n }\n\n const cells: CellEffect[] = [];\n for (const [path, was] of before) {\n const now = after.get(path);\n if (!now) continue; // removed — handled as a cleared row\n // The union of both sides: a column ALTER ADD introduced exists only in\n // `now`, and with a DEFAULT it backfills every row — a real change a\n // before-keys-only scan would silently miss.\n for (const key of new Set([...Object.keys(was), ...Object.keys(now)])) {\n if (Object.is(was[key], now[key])) continue;\n if (RESERVED.has(key)) {\n throw new DocmetaError(\n `The statement changed system column \"${key}\" for \"${path}\"; system columns are read-only.`,\n );\n }\n cells.push({ file: path, key, to: now[key] });\n }\n }\n cells.sort((a, b) =>\n a.file === b.file ? a.key.localeCompare(b.key) : a.file.localeCompare(b.file),\n );\n return {\n cells,\n clearedRows: removed,\n createdRows: new Map(\n added.map((p) => [p, after.get(p) ?? {}] as const),\n ),\n renamedFiles: renamedFiles.sort((a, b) => a.from.localeCompare(b.from)),\n };\n}\n\n/** Row equality over every column except `_path` — the rename signature. */\nfunction rowsEqualExceptPath(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): boolean {\n for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) {\n if (key === \"_path\") continue;\n if (!Object.is(a[key], b[key])) return false;\n }\n return true;\n}\n\n/** Declared shape of one projection column, from `PRAGMA table_info`. */\nfunction snapshotColumns(\n db: Queryable,\n): Map<string, { type: string; notnull: number }> {\n const rows = db.prepare(\"PRAGMA table_info(docs)\").all() as {\n name: string;\n type: string;\n notnull: number;\n }[];\n // The cast trusts node:sqlite's documented row shape; this catches the day\n // a Node release renames a pragma column, instead of mistyping silently.\n if (rows.length > 0 && typeof rows[0]?.name !== \"string\") {\n throw new DocmetaError(\n \"PRAGMA table_info returned an unexpected row shape; this node:sqlite build is not one manni understands.\",\n );\n }\n return new Map(rows.map((r) => [r.name, { type: r.type, notnull: r.notnull }]));\n}\n\n/** Exported with `assertDefaultsMatchDeclaredTypes`, not via the API index. */\nexport interface SchemaOp {\n op: \"add\" | \"drop\" | \"rename\";\n key: string;\n renamedTo?: string;\n type?: string;\n /** 0028: the format a declared type equal to a format name carries. */\n format?: string;\n /** 0028: the members of a `CHECK (k IN (…))` on the added column. */\n enum?: (string | number)[];\n required?: boolean;\n}\n\n/** The stored `CREATE TABLE docs` text — the only place a CHECK lives. */\nfunction snapshotCatalogSql(db: Queryable): string {\n const rows = db\n .prepare(\n \"SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'docs'\",\n )\n .all() as { sql: unknown }[];\n const sql = rows[0]?.sql;\n return typeof sql === \"string\" ? sql : \"\";\n}\n\n/**\n * DDL, read as an effect: the column set changed. A removed/added pair whose\n * per-row values are identical is a column rename; the rest are drops and\n * adds, an add carrying its declared type and NOT NULL as schema intent.\n *\n * The catalog text (0028) is consulted **only for adds** — `ADD COLUMN`\n * appends the column def verbatim to docmeta-authored CREATE TABLE text, so\n * the suffix delta is extractable without parsing the user's statement. DROP\n * and RENAME rewrite the stored text mid-string and never consult it.\n */\nfunction columnDiffOps(\n before: Map<string, { type: string; notnull: number }>,\n after: Map<string, { type: string; notnull: number }>,\n rowsBefore: Map<string, Record<string, unknown>>,\n rowsAfter: Map<string, Record<string, unknown>>,\n catalogBefore: string,\n catalogAfter: string,\n): SchemaOp[] {\n const removed = [...before.keys()].filter((c) => !after.has(c));\n const added = [...after.keys()].filter((c) => !before.has(c));\n const ops: SchemaOp[] = [];\n // Same set-tracked pairing as diffProjection's file renames — one idiom for\n // both rename detectors, though DDL grammar bounds these arrays at one.\n const pairedFrom = new Set<string>();\n const pairedTo = new Set<string>();\n for (const from of removed) {\n // The size guard keeps an empty corpus from vacuously pairing every drop\n // with every add — unreachable through one ALTER today, stated anyway.\n const to = added.find(\n (a) =>\n !pairedTo.has(a) &&\n rowsBefore.size > 0 &&\n [...rowsBefore.keys()].every((path) =>\n Object.is(rowsBefore.get(path)?.[from], rowsAfter.get(path)?.[a]),\n ),\n );\n if (!to) continue;\n ops.push({ op: \"rename\", key: from, renamedTo: to });\n pairedFrom.add(from);\n pairedTo.add(to);\n }\n for (const key of removed.filter((k) => !pairedFrom.has(k))) {\n ops.push({ op: \"drop\", key });\n }\n for (const key of added.filter((k) => !pairedTo.has(k))) {\n const decl = after.get(key);\n const mapped = mapDeclaredType(decl?.type ?? \"\");\n const members = enumForAddedColumn(catalogBefore, catalogAfter, key, mapped);\n ops.push({\n op: \"add\",\n key,\n ...(mapped?.type !== undefined ? { type: mapped.type } : {}),\n ...(mapped?.format !== undefined ? { format: mapped.format } : {}),\n ...(members !== undefined ? { enum: members } : {}),\n required: decl?.notnull === 1,\n });\n }\n return ops;\n}\n\n/** What a declared column type means for the schema property it will build. */\ninterface DeclaredMapping {\n type: string;\n format?: string;\n}\n\n/**\n * SQLite declared type → JSON Schema mapping. 0024 stopped at SQLite's own\n * affinity rules; 0028 puts the format match **before** them — ordering is\n * load-bearing, or `/INT/` eats `json-POINTER` (0028 § stress test 3):\n *\n * 1. a type case-insensitively equal to a format name the validator enforces\n * (derived from the ajv-formats registration, so upgrades arrive free)\n * maps to `{type: \"string\", format: <name>}`;\n * 2. the closed alias pair `DATETIME`/`TIMESTAMP` → `format: date-time`;\n * 3. `BOOLEAN`/`BOOL` → `{type: \"boolean\"}`;\n * 4. the affinity regexes, exactly as before.\n */\nfunction mapDeclaredType(declared: string): DeclaredMapping | undefined {\n const lower = declared.toLowerCase();\n if (stringFormatNames().has(lower)) return { type: \"string\", format: lower };\n if (lower === \"datetime\" || lower === \"timestamp\") {\n return { type: \"string\", format: \"date-time\" };\n }\n if (lower === \"boolean\" || lower === \"bool\") return { type: \"boolean\" };\n if (/INT/i.test(declared)) return { type: \"integer\" };\n if (/CHAR|CLOB|TEXT/i.test(declared)) return { type: \"string\" };\n if (/REAL|FLOA|DOUB|NUMERIC|DEC/i.test(declared)) return { type: \"number\" };\n return undefined;\n}\n\n/**\n * The column definition `ADD COLUMN` appended to the stored CREATE TABLE\n * text: the after-text is the before-text with `, <def>` inserted before the\n * final `)` (verified against the engine — 0028 § stress test 2). Undefined\n * when the delta is not that shape.\n */\nfunction appendedColumnDef(before: string, after: string): string | undefined {\n const cut = before.lastIndexOf(\")\");\n if (cut === -1 || cut !== before.length - 1 || !after.endsWith(\")\")) {\n return undefined;\n }\n const prefix = before.slice(0, cut);\n if (!after.startsWith(prefix)) return undefined;\n const appended = after.slice(prefix.length, -1);\n const comma = /^\\s*,\\s*/.exec(appended);\n return comma ? appended.slice(comma[0].length) : undefined;\n}\n\n/** Index of the first non-whitespace character of `text` at or after `from`. */\nfunction skipWs(text: string, from: number): number {\n let i = from;\n while (i < text.length && /\\s/.test(text[i] ?? \"\")) i++;\n return i;\n}\n\n/**\n * Index of a `CHECK` keyword at or after `from`, outside quoted regions and\n * comments. The comment branch matters because SQLite stores an ADD COLUMN's\n * definition verbatim, comments included — a CHECK spelled inside one must\n * not satisfy the count guard or trip the one-shape refusal.\n */\nfunction indexOfCheck(text: string, from: number): number {\n let i = from;\n while (i < text.length) {\n const ch = text[i];\n if (startsStringOrIdent(text, i)) {\n i = skipStringOrIdent(text, i);\n } else if (startsComment(text, i)) {\n i = skipComment(text, i);\n } else if (ch !== undefined && /[A-Za-z_]/.test(ch)) {\n const m = /^[A-Za-z_][A-Za-z0-9_]*/.exec(text.slice(i));\n const word = m?.[0] ?? \"\";\n if (word.toUpperCase() === \"CHECK\") return i;\n i += Math.max(word.length, 1);\n } else {\n i++;\n }\n }\n return -1;\n}\n\n/**\n * Index just past `(…)` starting at `open` — paren-aware, and skipping every\n * string/identifier form, brackets included: `[a)b]` is a legal identifier\n * whose `)` must not close the group early. Comments too: a paren inside a\n * block or line comment must not move the depth. (The enum member grammar's\n * own whitespace walks stay strict on purpose — a comment between literals\n * refuses loudly per the one-shape contract, which is the designed outcome,\n * not a miscount.)\n */\nfunction matchingParenEnd(text: string, open: number): number {\n let depth = 0;\n let i = open;\n while (i < text.length) {\n const ch = text[i];\n if (startsStringOrIdent(text, i)) {\n i = skipStringOrIdent(text, i);\n continue;\n }\n if (startsComment(text, i)) {\n i = skipComment(text, i);\n continue;\n }\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) return i + 1;\n }\n i++;\n }\n return -1;\n}\n\n/**\n * `enum` members for an added column, read from the catalog delta — the\n * second recorded consultation of syntax (after ATTACH/VACUUM's\n * refusal-by-name), scoped to stay small (0028 § stress test 2). The grammar\n * accepted is exactly one shape: `CHECK (<the-new-column> IN (<literals>))`\n * with the literals all strings or all numbers, agreeing with the declared\n * type. Everything else refuses, naming the shape and the hand-edit\n * alternative — a constraint silently dropped from the schema would be worse\n * than either.\n */\nfunction enumForAddedColumn(\n catalogBefore: string,\n catalogAfter: string,\n key: string,\n mapped: DeclaredMapping | undefined,\n): (string | number)[] | undefined {\n // The variable annotation (not just the return position) is what lets\n // control-flow analysis treat a `refuseShape()` call as terminating.\n const refuseShape: () => never = () => {\n throw new DocmetaError(\n `The CHECK on \"${key}\" is not the one shape DDL maps: \\`CHECK (${key} IN (…))\\` with all-string or all-number literals becomes \\`enum\\`. Anything else — an expression, another column, AND — is a hand edit to the schema file.`,\n );\n };\n const def = appendedColumnDef(catalogBefore, catalogAfter);\n if (def === undefined) {\n // Unreachable through ALTER ADD against docmeta-authored text today;\n // stated anyway so an engine that rewrites the catalog differently\n // refuses loudly instead of silently dropping a CHECK the user wrote.\n const count = (text: string): number => {\n let n = 0;\n for (let i = indexOfCheck(text, 0); i !== -1; i = indexOfCheck(text, i + 5)) {\n n++;\n }\n return n;\n };\n if (count(catalogAfter) > count(catalogBefore)) refuseShape();\n return undefined;\n }\n const checkAt = indexOfCheck(def, 0);\n if (checkAt === -1) return undefined;\n\n const i = skipWs(def, checkAt + \"CHECK\".length);\n if (def[i] !== \"(\") refuseShape();\n const end = matchingParenEnd(def, i);\n if (end === -1) refuseShape();\n // A second CHECK anywhere in the def is not the supported shape.\n if (indexOfCheck(def, end) !== -1) refuseShape();\n const inner = def.slice(i + 1, end - 1);\n\n // `<the-new-column> IN ( <literals> )`, and nothing else.\n let j = skipWs(inner, 0);\n const col = readIdentifier(inner, j);\n if (!col || col.value.toLowerCase() !== key.toLowerCase()) refuseShape();\n j = skipWs(inner, col.end);\n const kw = /^[A-Za-z]+/.exec(inner.slice(j));\n if (kw?.[0]?.toUpperCase() !== \"IN\") refuseShape();\n j = skipWs(inner, j + 2);\n if (inner[j] !== \"(\") refuseShape();\n const listEnd = matchingParenEnd(inner, j);\n if (listEnd === -1 || skipWs(inner, listEnd) !== inner.length) refuseShape();\n const list = inner.slice(j + 1, listEnd - 1);\n\n const members: (string | number)[] = [];\n let sawString = false;\n let sawNumber = false;\n let k = skipWs(list, 0);\n for (;;) {\n if (list[k] === \"'\") {\n const close = skipStringOrIdent(list, k);\n if (list[close - 1] !== \"'\" || close <= k + 1) refuseShape();\n members.push(list.slice(k + 1, close - 1).replaceAll(\"''\", \"'\"));\n sawString = true;\n k = close;\n } else {\n const m = /^[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?/.exec(\n list.slice(k),\n );\n if (!m) refuseShape();\n members.push(Number(m[0]));\n sawNumber = true;\n k += m[0].length;\n }\n k = skipWs(list, k);\n if (k >= list.length) break;\n if (list[k] !== \",\") refuseShape();\n k = skipWs(list, k + 1);\n }\n if (members.length === 0) refuseShape();\n if (sawString && sawNumber) {\n // Homogeneity is part of the grammar, not a rule invented later.\n throw new DocmetaError(\n `The CHECK on \"${key}\" mixes string and number literals; an IN list maps to \\`enum\\` only as all strings or all numbers.`,\n );\n }\n if (mapped !== undefined) {\n const disagree = sawString\n ? mapped.type !== \"string\"\n : mapped.type === \"integer\"\n ? members.some((v) => typeof v === \"number\" && !Number.isInteger(v))\n : mapped.type !== \"number\";\n if (disagree) {\n throw new DocmetaError(\n `The CHECK on \"${key}\" lists ${sawString ? \"string\" : \"number\"} literals, but the declared type maps to ${mapped.type} — the members' JSON types must agree with the declared type, the same reconciliation the DEFAULT guard applies.`,\n );\n }\n }\n return members;\n}\n\n/**\n * The declared type and the DEFAULT are two halves of one statement, and\n * SQLite will happily store a default its own declaration cannot hold\n * (`INTEGER … DEFAULT 'high'` stores TEXT). Left unchecked, that writes a\n * schema requiring a type every backfilled file immediately violates — the\n * exact inverse of the ratchet staying green. Refused before any plan exists.\n *\n * Exported for the guard's own tests: `mapDeclaredType` always pairs a\n * format with a type today, but `SchemaOp` declares them independent, and\n * the format check below must hold for a format-only op too.\n */\nexport function assertDefaultsMatchDeclaredTypes(\n ops: SchemaOp[],\n cells: CellEffect[],\n): void {\n // JSON.stringify throws on bigint — a refusal must never crash while\n // trying to describe the value it is refusing.\n const show = (v: unknown): string =>\n typeof v === \"bigint\" ? `${String(v)}n` : (toJsonText(v) ?? \"undefined\");\n for (const op of ops) {\n // Adds only — and NOT gated on a declared type: an op with no mapped\n // type has nothing for the `ok` chain below to refuse (it falls through\n // to true), while the format check must still run.\n if (op.op !== \"add\") continue;\n for (const cell of cells) {\n if (cell.key !== op.key || cell.to === null || cell.to === undefined) {\n continue;\n }\n const to = cell.to;\n const ok =\n op.type === \"integer\"\n ? typeof to === \"bigint\" ||\n (typeof to === \"number\" && Number.isInteger(to))\n : op.type === \"number\"\n ? typeof to === \"number\" || typeof to === \"bigint\"\n : op.type === \"string\"\n ? typeof to === \"string\"\n : op.type === \"boolean\"\n ? // The reconciliation accepts only the SQL spellings 0, 1,\n // true, false — all of which the engine stores as 0/1.\n to === 0 || to === 1 || to === 0n || to === 1n\n : true;\n if (!ok) {\n throw new DocmetaError(\n op.type === \"boolean\"\n ? `ALTER declares \"${op.key}\" as boolean, but the DEFAULT backfills ${show(to)} — only 0, 1, true, or false reconcile with a boolean column.`\n : // `!ok` is unreachable with no declared type (the chain falls\n // through to true), so the fallback text never actually prints.\n `ALTER declares \"${op.key}\" as ${op.type ?? \"its declared type\"}, but the DEFAULT backfills ${show(to)} — the corpus would fail the schema it just gained. Match the DEFAULT to the declared type.`,\n );\n }\n // 0028 stress 4: `DATE DEFAULT 'yesterday'` sails through the engine\n // and through the broad-type check above; the format is validated with\n // the same ajv-formats machinery `validate` enforces it with, before\n // any plan exists. (Enums need no twin: SQLite itself refuses an ADD\n // whose DEFAULT violates its own CHECK.)\n if (\n op.format !== undefined &&\n typeof to === \"string\" &&\n !validatesFormat(op.format, to)\n ) {\n throw new DocmetaError(\n `ALTER declares \"${op.key}\" as format ${op.format}, but the DEFAULT backfills ${show(to)} — the corpus would fail the schema it just gained. Match the DEFAULT to the format.`,\n );\n }\n }\n }\n}\n\ninterface SchemaWrite {\n path: string;\n content: string;\n /**\n * Bytes the plan read from this path; apply refuses if they moved since —\n * the same contract corpus files get. Absent means the plan requires the\n * path to not exist (a fork target).\n */\n expected?: string;\n}\n\ninterface SchemaPlan {\n changes: QueryChange[];\n writes: SchemaWrite[];\n /**\n * ADD writes the schema after the corpus, so a mid-apply failure leaves\n * extra keys under an unchanged schema (still green) instead of a new\n * requirement without its backfill (red). DROP/RENAME write schema-first\n * for the mirror-image reason: files keep a key the schema merely no longer\n * declares.\n */\n schemaLast: boolean;\n}\n\n/** One schema of the resolved set, loaded exactly once. */\ntype SetMember =\n | {\n /** The ref exactly as the set spells it — what repoints must match. */\n ref: string;\n kind: \"file\";\n /** Resolved from the run's cwd, the same base `loadSchema` uses. */\n abs: string;\n /** The exact text read, for indent/EOL fidelity and pin hashing. */\n text: string;\n schema: Record<string, unknown>;\n }\n | {\n ref: string;\n kind: \"builtin\";\n /** The bundled id — the ref itself, or a published URL's alias. */\n builtinId: string;\n schema: Record<string, unknown>;\n };\n\n/** `properties`, when it is the object the mutation machinery can touch. */\nfunction propsOf(\n schema: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const p = schema.properties;\n return p !== null && typeof p === \"object\" && !Array.isArray(p)\n ? (p as Record<string, unknown>)\n : undefined;\n}\n\n/** Does this schema constrain `key` — by declaring it, or by requiring it? */\nfunction constrains(member: SetMember, key: string): boolean {\n const props = propsOf(member.schema);\n if (props && key in props) return true;\n const required = member.schema.required;\n return Array.isArray(required) && required.some((r) => r === key);\n}\n\nconst FORK_IGNORE_TEXT: IgnoreGuardText = {\n refusal: (target) =>\n `Refusing to fork into \"${target}\": git reports it as ignored. The forked schema must be committed — an ignored copy validates on this machine and is simply missing in CI, where the failure reads as a schema nobody changed. Drop the .gitignore rule covering this path, or evolve a tracked local schema instead.`,\n unchecked: (where) =>\n `could not check .gitignore for \"${where}\" (no repository here, or no git on PATH). The forked schema must be committed — make sure this path is tracked.`,\n};\n\n/** Preserve the reference text's line endings in a freshly serialized body. */\nfunction matchEol(reference: string, text: string): string {\n return reference.includes(\"\\r\\n\") ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\n\n/** A path the way reports spell it: relative to the run's base, posix. */\nfunction displayPath(ctx: RunContext, abs: string): string {\n const rel = posixRelative(ctx.base, abs);\n return rel === \"\" || rel.startsWith(\"..\") ? abs : rel;\n}\n\n/** Refuse a schema write outside the boundary every schema *read* honors. */\nfunction assertSchemaWriteWithin(ctx: RunContext, abs: string): void {\n const within = posixRelative(ctx.trustRoot.dir, abs);\n if (within !== \"\" && !within.startsWith(\"..\") && !isAbsolute(within)) return;\n throw new DocmetaError(\n `The resolved schema \"${abs}\" lives outside ${ctx.trustRoot.dir}; DDL edits schemas inside the repository. Evolve it where it lives, or vendor a copy in.`,\n );\n}\n\n/**\n * Canonical identity of a local schema path: absolute, case-folded on win32 —\n * where `./Schemas/House.json` and `schemas/house.json` name one file — and\n * case-preserved on POSIX, where two casings really are two files.\n */\nfunction foldPath(p: string): string {\n const abs = resolve(p);\n return process.platform === \"win32\" ? abs.toLowerCase() : abs;\n}\n\n/**\n * The config's file-ref pins keyed by canonical path rather than ref text.\n * `collectSchemaPins` keys carry the config's (possibly rebased) spelling; a\n * `-s` ref typed even slightly differently — `schemas/x.json` for\n * `./schemas/x.json` — must still find its pin, or pre-edit verification\n * silently skips and the un-refreshed pin refuses every later run.\n *\n * `ctx.cwd` is the right base for these keys: `resolveRunConfig` passes every\n * loaded config through `rebaseConfigSchemaRefs`, which rewrites file refs to\n * ABSOLUTE paths whenever configDir differs from cwd (where `resolve` is the\n * identity) and leaves them cwd-relative-correct when the two coincide —\n * pinned by the configDir ≠ cwd test in query-ddl.test.ts.\n */\nfunction filePinsByPath(ctx: RunContext): Map<string, SchemaPin> {\n const byPath = new Map<string, SchemaPin>();\n for (const [ref, pin] of collectSchemaPins(ctx.config)) {\n if (classifyRef(ref).kind !== \"file\") continue;\n byPath.set(foldPath(resolve(ctx.cwd, ref)), pin);\n }\n return byPath;\n}\n\n/**\n * Load every schema in the set, through the same conventions the rest of the\n * pipeline reads them with: refs resolve from the run's cwd (the\n * `LoadSchemaOptions.fileBase` contract), text is BOM-stripped before parsing\n * only, integrity pins are verified against the exact bytes, and a published\n * built-in URL is the built-in it aliases. Any plain URL refuses: DDL cannot\n * inspect (let alone edit) a schema a server owns, and sibling-conflict\n * checks below need to see the whole set.\n */\nasync function loadSetMembers(\n refs: readonly string[],\n ctx: RunContext,\n): Promise<SetMember[]> {\n const pins = filePinsByPath(ctx);\n const members: SetMember[] = [];\n // Identity-level dedupe on top of the resolver's textual one: two -s\n // spellings of one file (`./x.json` vs `x.json`, case variants on win32)\n // must load one member, or ADD refuses naming one file twice and DROP\n // hands out an unfollowable \"evolve them separately\". Builtins dedupe by\n // id for the same reason — the raw id and its published URL are one schema.\n const seenFiles = new Set<string>();\n const seenBuiltins = new Set<string>();\n for (const ref of refs) {\n const { kind } = classifyRef(ref);\n if (kind === \"url\" && !isPublishedBuiltinUrl(ref)) {\n throw new DocmetaError(\n `\"${ref}\" in the resolved schema set is a URL — DDL edits local schemas only. Vendor it first (manni meta schemas vendor), then evolve the local copy.`,\n );\n }\n if (kind === \"builtin\" || kind === \"url\") {\n const builtinId =\n kind === \"url\"\n ? (publishedBuiltins().find((b) => b.url === ref || b.legacyUrl === ref)?.id ?? ref)\n : ref;\n if (seenBuiltins.has(builtinId)) continue;\n seenBuiltins.add(builtinId);\n members.push({\n ref,\n kind: \"builtin\",\n builtinId,\n schema: await loadSchema(builtinId),\n });\n continue;\n }\n const abs = resolve(ctx.cwd, ref);\n const canon = foldPath(abs);\n if (seenFiles.has(canon)) continue;\n seenFiles.add(canon);\n let text: string;\n try {\n text = await readFile(abs, \"utf8\");\n } catch {\n throw new DocmetaError(\n `Schema file not found: \"${ref}\" (looked at ${abs}).`,\n );\n }\n const pin = pins.get(canon);\n if (pin?.integrity !== undefined) {\n if (integrityOf(Buffer.from(text, \"utf8\")) !== pin.integrity) {\n throw new DocmetaError(\n `Schema \"${ref}\" does not match its recorded integrity; its contents have moved since it was vendored. Re-vendor it before evolving it.`,\n );\n }\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(stripBom(text));\n } catch {\n throw new DocmetaError(\n `Schema \"${ref}\" is not valid JSON, so DDL cannot read it. Fix the file first.`,\n );\n }\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new DocmetaError(\n `Schema \"${ref}\" is not an object schema; DDL edits \\`properties\\` and \\`required\\`, which only an object schema carries.`,\n );\n }\n members.push({\n ref,\n kind: \"file\",\n abs,\n text,\n schema: parsed as Record<string, unknown>,\n });\n }\n return members;\n}\n\n/**\n * 0024's DDL pipeline: resolve the run's single schema set, pick the target,\n * and plan the mutation — an in-place edit for a hand-maintained local file,\n * a fork (plus reference repoints) for an immutable builtin. Every refusal\n * here costs nothing: no file has been touched.\n */\nasync function planSchemaMutation(\n ops: SchemaOp[],\n entries: QueryEntry[],\n ctx: RunContext,\n): Promise<SchemaPlan> {\n // One action per statement is SQLite's own ALTER grammar; a second op here\n // would mean the effect diff misread the projection.\n const [op, ...extraOps] = ops;\n if (!op) return { changes: [], writes: [], schemaLast: false };\n if (extraOps.length > 0) {\n throw new DocmetaError(\n \"One DDL action per statement; this statement produced several column effects, which DDL cannot attribute to one schema edit.\",\n );\n }\n if (entries.length === 0) {\n // Two rationales for one refusal: without -s the set comes from the\n // corpus, so no corpus means no set; with -s the set is known, but the\n // backfill and the corpus-satisfies-the-evolved-set reconciliation\n // still run over the loaded files (review of #139, finding 9).\n throw new DocmetaError(\n ctx.cliSchemas !== undefined\n ? \"DDL needs at least one loaded file: the statement's backfill and the check that the corpus satisfies the evolved set both run over the loaded files, and this run matched none.\"\n : \"DDL needs at least one loaded file: the schema it edits is the one the corpus resolves, and this run matched no files.\",\n );\n }\n\n // One schema set for the whole run, or nothing mutates. Resolution runs\n // with the same trust boundary as validate — a document may not name a\n // schema outside the repository, least of all as a write target.\n //\n // 0030: -s replaces the walk outright — the deduped CLI refs ARE the set\n // (source \"cli\"), unanimous by construction, so neither the split refusal\n // nor the default-set refusal below can arise. Everything after the set is\n // chosen — member loading, trust, every ownership guard — is one shared\n // path: -s picks the contract, never what the contract says.\n let refs: string[] | undefined;\n const sources = new Set<string>();\n const groupIndexes = new Set<number>();\n let splitLabel: string | undefined;\n if (ctx.cliSchemas !== undefined) {\n // One implementation of CLI-ref handling across commands: the resolver's\n // own cli branch (textual dedupe, source \"cli\"), called exactly once for\n // the run — never per file; the counter seam in resolution-walk.test.ts\n // pins that. `filePath` feeds only override matching, which the cli\n // branch never reaches. The path-canonical dedupe file members also need\n // lives in `loadSetMembers`, where refs are resolved anyway — the\n // resolver's dedupe stays textual by design for validate.\n refs = resolveSchemaSetWithSource({\n filePath: \"\",\n cliSchemas: ctx.cliSchemas,\n config: ctx.config,\n fileBase: ctx.cwd,\n trustRoot: ctx.trustRoot,\n }).schemas;\n } else {\n for (const e of entries) {\n let resolved;\n try {\n resolved = resolveSchemaSetWithSource({\n filePath: e.label,\n fileSchema: e.extracted.data[FILE_SCHEMA_KEY],\n config: ctx.config,\n memberOf: ctx.memberships(e.label),\n fileBase: ctx.cwd,\n trustRoot: ctx.trustRoot,\n onNotice: ctx.onNotice,\n });\n } catch (err) {\n // `coerceFileSchema` throws a plain Error; either way the file that\n // carried the bad `$schema` is the one fact the user needs.\n throw new DocmetaError(`\"${e.label}\": ${errorMessage(err)}`);\n }\n sources.add(resolved.source);\n if (resolved.overrideIndex !== undefined) {\n groupIndexes.add(resolved.overrideIndex);\n }\n if (refs === undefined) {\n refs = resolved.schemas;\n } else if (\n // Order-insensitive, like seqResolvesToRunSet below: a document that\n // lists the same refs in another order names the same contract.\n splitLabel === undefined &&\n JSON.stringify([...refs].sort()) !==\n JSON.stringify([...resolved.schemas].sort())\n ) {\n // The walk finishes before refusing, so the refusal can name every\n // override group the run spans, not only the first two it met.\n splitLabel = e.label;\n }\n }\n }\n if (splitLabel !== undefined) {\n // With named override groups (0027) the remedy is finally spellable:\n // list each group by name with its glob, so \"one group's files\" is a\n // copy-pastable next step rather than a concept.\n const overrides = ctx.config?.overrides ?? [];\n const named = [...groupIndexes]\n .sort((a, b) => a - b)\n .flatMap((i) => {\n const o = overrides[i];\n if (o?.collection === undefined) return [];\n // The globs come from the declaration now (0041): the override names a\n // collection, and the collection is where its `paths:` live.\n const declared = ctx.collections.find((c) => c.name === o.collection);\n return [\n `${o.collection} (${overrideGlobs(declared?.paths).join(\", \")})`,\n ];\n });\n const last = named[named.length - 1];\n // 0030: -s makes the set unanimous by construction, so it is the third\n // remedy — the direct one — in both spellings of this refusal.\n const remedy =\n named.length >= 2 && last !== undefined\n ? `The run spans ${[named.slice(0, -1).join(\", \"), last].join(\" and \")}; re-run over one group's files, or pass -s <schema> to name the contract directly.`\n : \"Scope the run to one override group, or pass -s <schema> to name the contract directly.\";\n throw new DocmetaError(\n `DDL needs the corpus to resolve to one schema set, and this run's is split (\"${splitLabel}\" resolves differently). ${remedy}`,\n );\n }\n if (!refs || sources.has(\"default\")) {\n throw new DocmetaError(\n \"DDL edits the resolved schema, and this corpus runs on the built-in default set. Name a schema to evolve — in the config's `schemas:`, an override group, or the files' own `$schema`. For data-only edits the UPDATE spellings cover every case: `SET k = v` (backfill via `WHERE k IS NULL`), `SET k = NULL` to remove a key, and paired SETs to rename one.\",\n );\n }\n\n const members = await loadSetMembers(refs, ctx);\n const fileMembers = members.flatMap((m) => (m.kind === \"file\" ? [m] : []));\n const builtinMembers = members.flatMap((m) =>\n m.kind === \"builtin\" ? [m] : [],\n );\n\n // The target: for ADD the single local file (else the builtin, forked); for\n // DROP/RENAME the one schema that constrains the key. \"One\" is load-bearing\n // both ways — a second declarer, or a sibling that still requires a dropped\n // key, would leave the corpus failing a schema this statement never named.\n let target: SetMember;\n if (op.op === \"add\") {\n if (fileMembers.length > 1) {\n throw new DocmetaError(\n `The resolved set names ${String(fileMembers.length)} local schema files (${fileMembers.map((m) => m.ref).join(\", \")}) — DDL cannot tell which one to evolve. Scope the run to an override group that names one, set the files' \\`$schema\\` to the schema to evolve, or pass -s <schema> to name it directly.`,\n );\n }\n // The same ambiguity rule as several local files: with no local file\n // and several builtins, \"the one to fork\" would be decided by flag or\n // list order — a silent pick where every sibling refusal names its\n // reasons (review of #139, finding 6).\n if (fileMembers.length === 0 && builtinMembers.length > 1) {\n throw new DocmetaError(\n `The resolved set names ${String(builtinMembers.length)} built-ins (${builtinMembers.map((m) => m.builtinId).join(\", \")}) and no local schema file — DDL cannot tell which one to fork. Name one with -s, or evolve a local schema.`,\n );\n }\n const chosen = fileMembers[0] ?? builtinMembers[0];\n if (!chosen) {\n throw new DocmetaError(\n `No local schema or built-in in the resolved set takes this DDL.`,\n );\n }\n target = chosen;\n const targetProps = propsOf(target.schema);\n if (target.schema.properties !== undefined && targetProps === undefined) {\n throw new DocmetaError(\n `Schema \"${target.ref}\": its \"properties\" is not an object, so DDL cannot edit it.`,\n );\n }\n if (targetProps && op.key in targetProps) {\n throw new DocmetaError(\n `\"${op.key}\" is already declared in ${target.ref}; ALTER ADD would overwrite its subschema, constraints included. Edit the schema file directly to change an existing property.`,\n );\n }\n for (const m of members) {\n if (m !== target && constrains(m, op.key)) {\n throw new DocmetaError(\n `\"${op.key}\" is already declared by ${m.ref} in the same schema set; adding it to ${target.ref} would put two contracts on one key. Evolve ${m.ref} instead, or scope the run to a set with one owner of the key.`,\n );\n }\n }\n } else {\n // Destructuring narrows without a third guard: `sole` absent IS the\n // zero-declarers case, and `rest` non-empty is the shared-key refusal.\n const [sole, ...rest] = members.filter((m) => constrains(m, op.key));\n if (!sole) {\n throw new DocmetaError(\n `No schema in the resolved set declares \"${op.key}\".`,\n );\n }\n if (rest.length > 0) {\n throw new DocmetaError(\n `\"${op.key}\" is constrained by ${String(rest.length + 1)} schemas in the set (${[sole, ...rest].map((m) => m.ref).join(\", \")}); a DDL statement edits one schema. Evolve them separately.`,\n );\n }\n target = sole;\n if (op.op === \"rename\") {\n const to = op.renamedTo ?? op.key;\n for (const m of members) {\n if (constrains(m, to)) {\n throw new DocmetaError(\n `\"${to}\" is already declared${m === target ? \"\" : ` by ${m.ref}`} in the schema set; renaming \"${op.key}\" onto it would overwrite that declaration. Pick another name, or evolve that schema first.`,\n );\n }\n }\n }\n }\n\n const writes: SchemaWrite[] = [];\n const changes: QueryChange[] = [];\n const configEdit: ConfigEditRequest = {};\n\n let baseObject: Record<string, unknown>;\n let schemaAbs: string;\n /** Indent and EOL come from the file being edited; a fork starts fresh. */\n let styleReference: string;\n let schemaExpected: string | undefined;\n let forkedFrom: string | undefined;\n if (target.kind === \"file\") {\n schemaAbs = target.abs;\n baseObject = target.schema;\n styleReference = target.text;\n schemaExpected = target.text;\n assertSchemaWriteWithin(ctx, schemaAbs);\n } else {\n // A builtin is immutable by invariant — fork it beside the config and\n // repoint every reference: the config entry, and any in-file `$schema`.\n forkedFrom = target.builtinId;\n const [, name, ver] = target.builtinId.split(\":\");\n // Segments reach the filesystem; every shipped id is [a-z0-9._-] but the\n // filename must not trust that a future one stays so.\n const safe = (s: string): string => s.replace(/[^A-Za-z0-9._-]/g, \"-\");\n const forkName = `${safe(name ?? \"schema\")}-${safe(ver ?? \"0\")}.local.json`;\n schemaAbs = resolve(ctx.configDir ?? ctx.cwd, \"schemas\", forkName);\n assertSchemaWriteWithin(ctx, schemaAbs);\n if (existsSync(schemaAbs)) {\n throw new DocmetaError(\n `\"${displayPath(ctx, schemaAbs)}\" already exists; refusing to overwrite it with a fork of ${target.builtinId}.`,\n );\n }\n await assertNotIgnored(\n schemaAbs,\n dirname(schemaAbs),\n ctx.cwd,\n ctx.onNotice,\n FORK_IGNORE_TEXT,\n );\n baseObject = { ...target.schema, $id: `${target.builtinId}+local` };\n styleReference = \"\\n\";\n // Repoints match refs that NAME THE BUILTIN — the raw id or its\n // published URL — not the spelling the run's set happened to use. A\n // cli-named set has no reason to agree textually with the config or\n // the files, and the exact-string match orphaned every fork whose\n // corpus spelled the builtin differently (review of #139, finding 1).\n const forkOf = target.builtinId;\n const builtinIdOf = (r: string): string | undefined => {\n const { kind } = classifyRef(r);\n if (kind === \"builtin\") return r;\n if (kind === \"url\" && isPublishedBuiltinUrl(r)) {\n return publishedBuiltins().find((b) => b.url === r || b.legacyUrl === r)?.id;\n }\n return undefined;\n };\n const namesFork = (r: unknown): boolean =>\n typeof r === \"string\" && builtinIdOf(r) === forkOf;\n if (ctx.configPath !== undefined && ctx.configDir !== undefined) {\n const rel = posixRelative(ctx.configDir, schemaAbs);\n configEdit.repoint = {\n oldRef: target.ref,\n newRef: rel.startsWith(\".\") ? rel : `./${rel}`,\n // The resolved-set path keeps its whole-set gate; a cli-named set\n // can never satisfy it, so it matches by builtin identity instead.\n ...(ctx.cliSchemas !== undefined ? { matchRef: namesFork } : {}),\n };\n }\n const docRel = posixRelative(ctx.cwd, schemaAbs);\n const newRefForDocs = docRel.startsWith(\".\") ? docRel : `./${docRel}`;\n for (const e of entries) {\n const fileSchema = e.extracted.data[FILE_SCHEMA_KEY];\n if (namesFork(fileSchema)) {\n changes.push({\n file: e.label,\n key: FILE_SCHEMA_KEY,\n from: fileSchema,\n to: newRefForDocs,\n written: false,\n });\n } else if (Array.isArray(fileSchema)) {\n // The documented list spelling repoints element-wise; the rest of\n // the list is not this statement's business.\n const list = fileSchema.filter(\n (r): r is string => typeof r === \"string\",\n );\n if (list.length === fileSchema.length && list.some(namesFork)) {\n changes.push({\n file: e.label,\n key: FILE_SCHEMA_KEY,\n from: fileSchema,\n to: list.map((r) => (namesFork(r) ? newRefForDocs : r)),\n written: false,\n });\n }\n }\n }\n }\n // Doc-side repoints planned so far — the fork block is the only writer of\n // `changes` up to here, so this is the count the orphan check below needs.\n const docRepoints = changes.length;\n\n // BOM-strip before sniffing: the regex anchors at the string head, and a\n // BOM'd file would silently fall back to two-space and be reformatted.\n const indent = detectJsonIndent(stripBom(styleReference));\n const mutated = mutateSchemaObject(baseObject, op);\n const content = matchEol(\n styleReference,\n `${JSON.stringify(mutated, null, indent)}\\n`,\n );\n changes.unshift({\n file: displayPath(ctx, schemaAbs),\n schema: true,\n op: op.op,\n key: op.key,\n ...(op.renamedTo !== undefined ? { renamedTo: op.renamedTo } : {}),\n ...(op.type !== undefined ? { type: op.type } : {}),\n ...(op.format !== undefined ? { format: op.format } : {}),\n ...(op.enum !== undefined ? { enum: op.enum } : {}),\n ...(op.required ? { required: true } : {}),\n ...(forkedFrom !== undefined ? { forkedFrom } : {}),\n written: false,\n });\n writes.push({\n path: schemaAbs,\n content,\n ...(schemaExpected !== undefined ? { expected: schemaExpected } : {}),\n });\n\n // An in-place edit of a pinned schema carries its pin along: the pin is a\n // promise about the bytes, and the bytes just changed on purpose. Looked\n // up by canonical path, like the verification in `loadSetMembers` — the\n // -s spelling must never decide whether a pin is found.\n if (target.kind === \"file\") {\n const pin = filePinsByPath(ctx).get(foldPath(target.abs));\n if (pin?.integrity !== undefined) {\n configEdit.integrity = {\n path: target.abs,\n value: integrityOf(Buffer.from(content, \"utf8\")),\n };\n }\n }\n\n let configRepointed = false;\n if (configEdit.repoint || configEdit.integrity) {\n const edited = await planConfigEdit(ctx, configEdit, refs);\n changes.push(...edited.changes);\n if (edited.write) writes.push(edited.write);\n configRepointed = edited.repointed;\n if (\n configEdit.repoint &&\n !edited.repointed &&\n (sources.has(\"config\") || sources.has(\"override\"))\n ) {\n throw new DocmetaError(\n `The run resolved ${configEdit.repoint.oldRef} through the config, but no \\`schemas:\\` entry in it matches — refusing to fork with a reference that cannot be repointed.`,\n );\n }\n }\n // A cli-named fork that nothing would resolve afterwards is an orphan:\n // the statement reports success while validate keeps resolving the\n // un-evolved builtin. Refused with nothing written — the mirror of the\n // config-source no-repoint refusal above (review of #139, finding 1).\n if (\n ctx.cliSchemas !== undefined &&\n forkedFrom !== undefined &&\n !configRepointed &&\n docRepoints === 0\n ) {\n throw new DocmetaError(\n `The fork of ${forkedFrom} would be orphaned: nothing in this corpus resolves it — no config \\`schemas:\\` entry and no loaded file's \\`$schema\\` names the builtin, so nothing would validate against \"${displayPath(ctx, schemaAbs)}\" after the run. No schema or file writes were applied${\n ctx.target === undefined\n ? \"\"\n : \"; the --db export was still written and reflects the statement\"\n }. Add the schema to the config (or the files' \\`$schema\\`) first, then evolve it.`,\n );\n }\n\n return { changes, writes, schemaLast: op.op === \"add\" };\n}\n\n/** Apply one DDL op to a schema object, touching properties/required only. */\nfunction mutateSchemaObject(\n schema: Record<string, unknown>,\n op: SchemaOp,\n): Record<string, unknown> {\n const without = (\n obj: Record<string, unknown>,\n key: string,\n ): Record<string, unknown> =>\n Object.fromEntries(Object.entries(obj).filter(([k]) => k !== key));\n let props = { ...(propsOf(schema) ?? {}) };\n // Spec-invalid non-string entries are dropped rather than carried: every\n // comparison below is against a string key, so they could only persist as\n // junk this rewrite pretended not to see.\n let required = Array.isArray(schema.required)\n ? (schema.required as unknown[]).filter(\n (r): r is string => typeof r === \"string\",\n )\n : [];\n switch (op.op) {\n case \"add\":\n props[op.key] = {\n ...(op.type !== undefined ? { type: op.type } : {}),\n ...(op.format !== undefined ? { format: op.format } : {}),\n ...(op.enum !== undefined ? { enum: op.enum } : {}),\n };\n if (op.required && !required.includes(op.key)) required.push(op.key);\n break;\n case \"drop\":\n props = without(props, op.key);\n required = required.filter((r) => r !== op.key);\n break;\n case \"rename\": {\n const to = op.renamedTo ?? op.key;\n const moved = props[op.key];\n props = without(props, op.key);\n // A required-only key (no `properties` entry — legal, if odd) renames\n // to a required-only key: the guard keeps the faithful shape rather\n // than fabricating an empty subschema the author never declared.\n if (moved !== undefined) props[to] = moved;\n required = required.map((r) => (r === op.key ? to : r));\n break;\n }\n }\n // Set-or-remove explicitly: a spread of the original schema would carry the\n // old `required` back in whenever the new list is empty.\n const out: Record<string, unknown> = { ...schema, properties: props };\n if (required.length > 0) out.required = required;\n else delete out.required;\n return out;\n}\n\ninterface ConfigEditRequest {\n /**\n * A builtin fork: point the entry that named the builtin at the fork.\n * With `matchRef` (a cli-named fork), every entry the predicate accepts is\n * repointed wherever it appears; without it, only entries spelled exactly\n * `oldRef` inside a sequence that resolves to the run's whole set are.\n */\n repoint?: {\n oldRef: string;\n newRef: string;\n matchRef?: (raw: string) => boolean;\n };\n /**\n * An in-place edit of a pinned schema: the pin over the new bytes. `path`\n * is the schema's absolute path — entries match by resolved path, so the\n * config's spelling and the run's never have to agree textually.\n */\n integrity?: { path: string; value: string };\n}\n\n/**\n * Plan an edit to the governing config — the file discovery actually loaded,\n * at `ctx.configPath` — through the YAML Document API, so every comment and\n * untouched line survives. Both spellings of a `schemas:` entry are handled:\n * the bare string, and the `{ref, source, integrity}` mapping.\n *\n * A repoint touches only the sequences that resolve to the run's schema set.\n * An override group with a different set is somebody else's contract; the\n * single-set guard proved it governs none of this run's files, and rewriting\n * it would change validation for files this statement never loaded.\n */\nasync function planConfigEdit(\n ctx: RunContext,\n edit: ConfigEditRequest,\n runRefs: readonly string[],\n): Promise<{ write?: SchemaWrite; changes: QueryChange[]; repointed: boolean }> {\n const { configPath, configDir } = ctx;\n if (configPath === undefined || configDir === undefined) {\n return { changes: [], repointed: false };\n }\n const text = await readFile(configPath, \"utf8\");\n // BOM-strip like every other parse of file text; `expected`/`matchEol`\n // below still see the raw bytes, which is what freshness and EOL are about.\n const doc = parseDocument(stripBom(text));\n const display = displayPath(ctx, configPath);\n\n const rawRefOf = (item: unknown): string | undefined => {\n if (isScalar(item) && typeof item.value === \"string\") return item.value;\n if (isMap(item)) {\n const ref = item.get(\"ref\");\n if (typeof ref === \"string\") return ref;\n }\n return undefined;\n };\n // The YAML holds refs as written; the run's set holds them rebased. Spell\n // the raw ones the same way before comparing.\n const rebaseRaw = (raw: string): string =>\n classifyRef(raw).kind === \"file\" && !isAbsolute(raw)\n ? resolve(configDir, raw)\n : raw;\n // Both sides through the same rebase: `runRefs` is raw whenever the config\n // sat in the working directory (rebasing was the identity there).\n const wantSet = runRefs.map(rebaseRaw).sort().join(\"\\n\");\n const seqResolvesToRunSet = (node: unknown): boolean => {\n if (!isSeq(node)) return false;\n const refs = node.items\n .map(rawRefOf)\n .flatMap((r) => (r === undefined ? [] : [rebaseRaw(r)]));\n return refs.length === node.items.length &&\n [...refs].sort().join(\"\\n\") === wantSet;\n };\n\n const repoint = (node: unknown): number => {\n if (!edit.repoint || !isSeq(node)) return 0;\n const spec = edit.repoint;\n // `matchRef` (a cli-named fork) matches entries by builtin identity in\n // every sequence: an entry naming the forked builtin is this statement's\n // business wherever it lives. The whole-set gate stays for the\n // resolved-set path, where rewriting another group's sequence would\n // change validation for files the statement never loaded.\n if (spec.matchRef === undefined && !seqResolvesToRunSet(node)) return 0;\n const wants = (raw: string): boolean =>\n spec.matchRef ? spec.matchRef(raw) : raw === spec.oldRef;\n let n = 0;\n for (const item of node.items) {\n const raw = rawRefOf(item);\n if (raw === undefined || !wants(raw)) continue;\n if (isScalar(item)) {\n item.value = spec.newRef;\n n += 1;\n } else if (isMap(item)) {\n item.set(\"ref\", spec.newRef);\n n += 1;\n }\n }\n return n;\n };\n // Where the tool's keys live in this file. A family `manni.config.yaml`\n // holds them under `meta:`; a legacy per-tool file *is* the section, so its\n // keys are at the top level. Reading the top level unconditionally finds\n // nothing in the family shape, which is the documented default since\n // proposal 0033 — every fork and every pin refresh then refused with\n // \"no `schemas:` entry in it matches\" against a config that plainly has one.\n // The suite missed it because every fixture was a legacy file until 0041.\n const root = ctx.configSection === undefined ? doc : doc.get(ctx.configSection, true);\n const keyOf = (key: string): unknown =>\n root === doc ? doc.get(key, true) : isMap(root) ? root.get(key, true) : undefined;\n\n const topSeq = keyOf(\"schemas\");\n let repointCount = repoint(topSeq);\n const overrides = keyOf(\"overrides\");\n if (isSeq(overrides)) {\n for (const entry of overrides.items) {\n if (isMap(entry)) repointCount += repoint(entry.get(\"schemas\", true));\n }\n }\n const repointed = repointCount > 0;\n\n let pinFrom: unknown;\n let pinned = false;\n if (edit.integrity && isSeq(topSeq)) {\n // Pins live on top-level mapping entries only — that is where\n // `collectSchemaPins` reads them from. Matching is by resolved path (a\n // raw config ref is config-relative), so no spelling has to agree.\n const wantPath = foldPath(edit.integrity.path);\n for (const item of topSeq.items) {\n if (!isMap(item)) continue;\n const raw = rawRefOf(item);\n if (raw === undefined || classifyRef(raw).kind !== \"file\") continue;\n const abs = isAbsolute(raw) ? raw : resolve(configDir, raw);\n if (foldPath(abs) !== wantPath) continue;\n pinFrom = item.get(\"integrity\");\n item.set(\"integrity\", edit.integrity.value);\n pinned = true;\n }\n }\n\n const changes: QueryChange[] = [];\n if (repointed && edit.repoint) {\n changes.push({\n file: display,\n config: true,\n key: \"schemas\",\n from: edit.repoint.oldRef,\n to: edit.repoint.newRef,\n written: false,\n });\n }\n if (pinned && edit.integrity) {\n changes.push({\n file: display,\n config: true,\n key: \"integrity\",\n from: pinFrom,\n to: edit.integrity.value,\n written: false,\n });\n }\n if (!repointed && !pinned) return { changes: [], repointed };\n return {\n write: {\n path: configPath,\n content: matchEol(text, doc.toString({ lineWidth: 0 })),\n expected: text,\n },\n changes,\n repointed,\n };\n}\n\ntype FileType = \"boolean\" | \"number\" | \"bigint\" | \"string\" | \"array\" | \"object\";\n\nfunction fileTypeOf(value: unknown): FileType | undefined {\n if (value === null || value === undefined) return undefined;\n if (Array.isArray(value)) return \"array\";\n const t = typeof value;\n if (t === \"boolean\" || t === \"number\" || t === \"bigint\" || t === \"string\") {\n return t;\n }\n return t === \"object\" ? \"object\" : undefined;\n}\n\n/**\n * File-space changes from the projection diff — 0022's inverse map plus\n * 0024's file-level kinds. Type precedence for a restored cell: the file's\n * own original type, then the column's dominant type, then storage as-is.\n * Failures refuse by file and key rather than guess.\n */\nfunction buildChanges(\n diff: ProjectionDiff,\n entries: QueryEntry[],\n sentinel: string,\n ctx: RunContext,\n renameHints: readonly { from: string; to: string }[] = [],\n /** Keys a DDL add declared boolean: their backfill restores as booleans. */\n booleanAdds: ReadonlySet<string> = new Set(),\n): QueryChange[] {\n const effects = diff.cells;\n const originals = new Map(entries.map((e) => [e.label, e.extracted.data]));\n const meta = new Map(entries.map((e) => [e.label, e.extracted]));\n const dominant = new Map<string, FileType | undefined>();\n const dominantFor = (key: string): FileType | undefined => {\n if (dominant.has(key)) return dominant.get(key);\n const counts = new Map<FileType, number>();\n for (const e of entries) {\n const t = fileTypeOf(e.extracted.data[key]);\n if (t) counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n let best: FileType | undefined;\n let bestN = 0;\n let tied = false;\n for (const [t, n] of counts) {\n if (n > bestN) [best, bestN, tied] = [t, n, false];\n else if (n === bestN) tied = true;\n }\n const result = tied ? undefined : best;\n dominant.set(key, result);\n return result;\n };\n\n const restoreValue = (\n file: string,\n key: string,\n to: unknown,\n targetType: FileType | undefined,\n ): unknown => {\n // The variable annotation (not just the return position) is what lets\n // control-flow analysis treat a `refuse(...)` call as terminating.\n const refuse: (why: string) => never = (why) => {\n throw new DocmetaError(`\"${key}\" in ${file}: ${why}`);\n };\n // JSON.stringify throws on bigint — a refusal must never crash while\n // trying to describe the value it is refusing.\n const show = (v: unknown): string =>\n typeof v === \"bigint\" ? `${String(v)}n` : (toJsonText(v) ?? \"undefined\");\n if (to instanceof Uint8Array) refuse(\"a BLOB cannot be written back\");\n if (to === null || targetType === undefined) return to;\n switch (targetType) {\n case \"boolean\":\n // A SQL expression can come back as bigint; 1n is as boolean as 1.\n if (to === 1 || to === 1n) return true;\n if (to === 0 || to === 0n) return false;\n refuse(`${show(to)} is not a boolean`);\n case \"array\":\n case \"object\": {\n if (typeof to !== \"string\") {\n refuse(`${show(to)} is not JSON text for a ${targetType}`);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(to);\n } catch {\n refuse(`the new value is not valid JSON for a ${targetType}`);\n }\n const kind = Array.isArray(parsed) ? \"array\" : typeof parsed;\n if (kind !== targetType) {\n refuse(`the new value is ${kind}, and the key holds ${targetType}`);\n }\n return parsed;\n }\n case \"number\":\n case \"bigint\":\n if (typeof to !== \"number\" && typeof to !== \"bigint\") {\n refuse(`${show(to)} is not a number`);\n }\n return to;\n case \"string\":\n if (typeof to !== \"string\") {\n refuse(`${show(to)} is not a string; quote it in the statement`);\n }\n return to;\n }\n return to;\n };\n\n // Key-rename pairing pre-pass (per file): a deletion of `a` and a creation\n // of `b` whose SQL value equals `bindValue(original a)` is a rename, and it\n // carries the original file value verbatim — an array must never round-trip\n // through its JSON-text projection (0024 § stress test 1).\n type Pair = { key: string; renamedFrom: string; to: unknown };\n const consumedDeletes = new Set<CellEffect>();\n const pairForCreate = new Map<CellEffect, Pair>();\n const byFile = new Map<string, CellEffect[]>();\n for (const e of effects) {\n const list = byFile.get(e.file) ?? [];\n list.push(e);\n byFile.set(e.file, list);\n }\n // A DDL column rename is authoritative before any value matching: the pair\n // comes from the column diff, so it carries an explicit-null value the\n // generic pass below cannot see (a NULL cell is a deletion, not an add).\n for (const hint of renameHints) {\n for (const [file, list] of byFile) {\n const data = originals.get(file) ?? {};\n if (data[hint.from] === undefined) continue;\n const del = list.find(\n (e) =>\n e.key === hint.from &&\n (e.to === null || e.to === undefined) &&\n !consumedDeletes.has(e),\n );\n const add = list.find(\n (e) => e.key === hint.to && !pairForCreate.has(e),\n );\n if (!del || !add) continue;\n consumedDeletes.add(del);\n pairForCreate.set(add, {\n key: hint.to,\n renamedFrom: hint.from,\n to: data[hint.from],\n });\n }\n }\n for (const [file, list] of byFile) {\n const data = originals.get(file) ?? {};\n const dels = list.filter(\n (e) =>\n (e.to === null || e.to === undefined) &&\n data[e.key] !== undefined &&\n !consumedDeletes.has(e),\n );\n const adds = list.filter(\n (e) => data[e.key] === undefined && e.to != null && e.to !== sentinel,\n );\n for (const d of dels) {\n const bound = bindValue(data[d.key]);\n const match = adds.find(\n (a) => !pairForCreate.has(a) && Object.is(a.to, bound),\n );\n if (!match) continue;\n consumedDeletes.add(d);\n pairForCreate.set(match, {\n key: match.key,\n renamedFrom: d.key,\n to: data[d.key],\n });\n }\n }\n\n const changes: QueryChange[] = [];\n for (const effect of effects) {\n const { file, key, to } = effect;\n if (consumedDeletes.has(effect)) continue;\n const pair = pairForCreate.get(effect);\n if (pair) {\n changes.push({ file, ...pair, written: false });\n continue;\n }\n const original = originals.get(file)?.[key];\n // `explicit_null()` bypasses the type map by design: the statement asked\n // for the literal, whatever type the key held.\n if (to === sentinel) {\n changes.push({ file, key, from: original, to: null, written: false });\n continue;\n }\n // Deletion: `SET k = NULL` (0024's standard spelling) or a dropped\n // column. Deleting a key the file never had is a no-op, not a change.\n if (to === null || to === undefined) {\n if (original !== undefined) {\n changes.push({ file, key, from: original, deleted: true, written: false });\n }\n continue;\n }\n // A boolean DDL add is authoritative for a key no file had: without the\n // hint the backfill's 1/0 would land in the files as numbers (0028).\n const targetType =\n fileTypeOf(original) ??\n (booleanAdds.has(key) ? \"boolean\" : dominantFor(key));\n // `from` stays `undefined` for a key the file never had — JSON output\n // omits it — which keeps \"absent\" distinguishable from an explicit null.\n changes.push({\n file,\n key,\n from: original,\n to: restoreValue(file, key, to, targetType),\n written: false,\n });\n }\n\n // DELETE: a removed row strips the block. A file that had none is a no-op.\n const extractorOf = new Map(entries.map((e) => [e.label, e.extractor]));\n for (const file of diff.clearedRows) {\n const extracted = meta.get(file);\n if (!extracted?.present) continue;\n // Refused at plan time, not discovered at apply: this extraction did not\n // come from a fenced block — element-backed metadata, or an RST/AsciiDoc\n // file read through its native-header fallback — so there is nothing\n // whose removal leaves the document whole, and the preview must never\n // promise a strip the writer refuses. Per-file truth, not extractor\n // capability: the same RST extractor answers both ways.\n if (extracted.fenced !== true) {\n const name = extractorOf.get(file)?.name ?? extracted.format;\n throw new DocmetaError(\n `\"${file}\": the ${name} format has no front matter block to strip.`,\n );\n }\n changes.push({ file, cleared: true, from: extracted.data, written: false });\n }\n\n // INSERT: an added row creates a file.\n for (const [file, row] of diff.createdRows) {\n // An *omitted* _path never reaches here — the PRIMARY KEY's NOT NULL\n // rejects it in SQLite. What does arrive and still refuses: the empty\n // string (NOT NULL admits it) and a BLOB (TEXT affinity never coerces\n // blobs), neither of which names a file.\n if (typeof row._path !== \"string\" || row._path === \"\") {\n throw new DocmetaError(\"INSERT requires a non-empty _path.\");\n }\n for (const sys of SYSTEM_COLUMNS) {\n if (sys !== \"_path\" && row[sys] != null) {\n throw new DocmetaError(\n `INSERT may not set system column \"${sys}\".`,\n );\n }\n }\n validateNewPath(file, ctx.base);\n // Refused at plan time so the preview never promises a file the writer\n // cannot build — the same courtesy every other refusal here extends.\n if (!extractorForExtension(extname(file))?.apply) {\n throw new DocmetaError(\n `\"${file}\": no writable format for that extension.`,\n );\n }\n if (existsSync(resolve(ctx.base, file))) {\n throw new DocmetaError(\n `\"${file}\" already exists; INSERT creates new files only.`,\n );\n }\n const to: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (RESERVED.has(key) || value === null || value === undefined) continue;\n to[key] =\n value === sentinel\n ? null\n : restoreValue(file, key, value, dominantFor(key));\n }\n changes.push({ file, created: true, to, written: false });\n }\n\n // A `_path` move renames the file.\n for (const { from, to } of diff.renamedFiles) {\n validateNewPath(to, ctx.base);\n if (extname(to).toLowerCase() !== extname(from).toLowerCase()) {\n throw new DocmetaError(\n `\"${from}\" -> \"${to}\": a rename may not change the extension.`,\n );\n }\n if (existsSync(resolve(ctx.base, to))) {\n throw new DocmetaError(\n `\"${to}\" already exists; the rename would overwrite it.`,\n );\n }\n changes.push({ file: from, renamed: to, written: false });\n }\n\n refuseExternalMetadataWrites(changes, entries, ctx);\n refuseManagedWrites(changes, entries, ctx);\n return changes;\n}\n\n/**\n * Only `derive` writes a managed field (0040): that is what makes the stamp\n * trustworthy, so every other writer refuses it by name, at plan time, the\n * way a manifest-owned key is refused. Every change kind that would touch\n * one: a set (or a `SET k = NULL` deletion), a rename onto or away from it,\n * an INSERT that carries it, and a DELETE that would strip a document's\n * block along with the stamp in it.\n */\nfunction refuseManagedWrites(\n changes: readonly QueryChange[],\n entries: readonly QueryEntry[],\n ctx: RunContext,\n): void {\n if (ctx.managed.size === 0) return;\n const refuse = (key: string): never => {\n throw new DocmetaError(\n `\"${key}\" is managed by derive; run manni meta derive instead.`,\n );\n };\n const data = new Map(entries.map((e) => [e.label, e.extracted.data]));\n for (const c of changes) {\n if (\"schema\" in c || \"config\" in c || \"renamed\" in c) continue;\n const keys =\n \"cleared\" in c\n ? Object.keys(data.get(c.file) ?? {})\n : \"created\" in c\n ? Object.keys(c.to)\n : \"renamedFrom\" in c\n ? [c.key, c.renamedFrom]\n : [c.key];\n for (const key of keys) if (ctx.managed.has(key)) refuse(key);\n }\n}\n\n/** A path an INSERT or rename may target: relative, contained, no traversal. */\nfunction validateNewPath(p: string, base: string): void {\n const refuse = (why: string): never => {\n throw new DocmetaError(`\"${p}\" is not a usable path: ${why}.`);\n };\n if (isAbsolute(p)) refuse(\"it is absolute\");\n if (p.split(/[\\\\/]/).some((segment) => segment === \"..\")) {\n refuse(\"it traverses upward\");\n }\n const abs = resolve(base, p);\n // Named before the escape check: `.` resolves to the base itself, and\n // \"escapes the corpus\" would be a baffling description of that.\n if (abs === resolve(base)) refuse(\"it points at the corpus root, not a file\");\n if (!abs.startsWith(resolve(base) + sep)) refuse(\"it escapes the corpus\");\n}\n\n/**\n * All-or-nothing apply: phase one computes every file's new content — any\n * refusal (unwritable format, a corpus that moved underneath the run, or the\n * writer's own re-parse verification) aborts before a single byte lands;\n * phase two writes atomically. A half-applied bulk edit would leave the\n * corpus in a state no statement describes.\n */\n\n/**\n * The first increment of external metadata is read-only (0037 rule 6): a write to a\n * key a manifest owns has exactly one honest destination, the manifest, and\n * writing it into the document instead would be the thing 0018 forbids. So\n * every change kind that would touch an owned key refuses at plan time, by\n * name, the way an RST native header does — and a document a manifest names\n * cannot be renamed out from under its entry.\n */\nfunction refuseExternalMetadataWrites(\n changes: readonly QueryChange[],\n entries: readonly QueryEntry[],\n ctx: RunContext,\n): void {\n const index = ctx.externalMetadata;\n if (!index) return;\n // One manifest is enough to refuse, and naming the first owner is the whole\n // message: a key owned by two collections' manifests is a run-time error\n // long before a write reaches here (0041 rule 5).\n const owned = (key: string): string | undefined =>\n index.owners.get(key)?.[0]?.file;\n const refuse = (file: string, key: string, owner: string): never => {\n throw new DocmetaError(\n `\"${file}\": \"${key}\" is owned by manifest ${owner}; edit the manifest instead.`,\n );\n };\n const data = new Map(entries.map((e) => [e.label, e.extracted.data]));\n for (const c of changes) {\n if (\"schema\" in c || \"config\" in c) continue;\n if (\"cleared\" in c) {\n // `data` is the *merged* object, so this refuses whenever the document\n // is manifest-covered — a manifest supplies a key for it, or it carries\n // an owned key itself — not only on a collision. Clearing a covered\n // document would leave its manifest entry an orphan, which the next\n // corpus run reports as exit 2; refusing here says so up front.\n for (const key of Object.keys(data.get(c.file) ?? {})) {\n const owner = owned(key);\n if (owner !== undefined) refuse(c.file, key, owner);\n }\n continue;\n }\n if (\"created\" in c) {\n for (const key of Object.keys(c.to)) {\n const owner = owned(key);\n if (owner !== undefined) refuse(c.file, key, owner);\n }\n continue;\n }\n if (\"renamed\" in c) {\n const entry = index.byPath.get(resolve(ctx.base, c.file));\n if (entry !== undefined && entry.size > 0) {\n const manifest = [...entry.values()][0]?.file ?? \"manifest\";\n throw new DocmetaError(\n `\"${c.file}\": manifest ${manifest} names it; rename the manifest entry first.`,\n );\n }\n continue;\n }\n const keys = \"renamedFrom\" in c ? [c.key, c.renamedFrom] : [c.key];\n for (const key of keys) {\n const owner = owned(key);\n if (owner !== undefined) refuse(c.file, key, owner);\n // The join field of a document that matched a field entry (0039):\n // changing it orphans the entry, which the next corpus run reports.\n // A rename, by contrast, is exactly what a field join permits.\n const byValue = index.byField.get(key);\n if (byValue === undefined) continue;\n const raw = data.get(c.file)?.[key];\n const value =\n typeof raw === \"string\"\n ? raw\n : typeof raw === \"number\" || typeof raw === \"boolean\"\n ? String(raw)\n : undefined;\n const entry = value === undefined ? undefined : byValue.get(value);\n if (entry !== undefined) {\n const manifest = entry.values().next().value?.file ?? \"manifest\";\n throw new DocmetaError(\n `\"${c.file}\": \"${key}\" is the field manifest ${manifest} joins on, and this document has an entry; change the manifest first.`,\n );\n }\n }\n }\n}\n\nasync function applyChanges(\n changes: QueryChange[],\n entries: QueryEntry[],\n ctx: RunContext,\n schemaPlan?: SchemaPlan,\n): Promise<void> {\n const schemaWrites = schemaPlan?.writes ?? [];\n if (changes.length === 0 && schemaWrites.length === 0) return;\n const byLabel = new Map(entries.map((e) => [e.label, e]));\n interface FileOps {\n patch: MetadataPatch;\n deletions: string[];\n cleared?: boolean;\n created?: Record<string, unknown>;\n renamedTo?: string;\n }\n const grouped = new Map<string, FileOps>();\n for (const c of changes) {\n if (c.file === STDIN_LABEL) {\n throw new DocmetaError(\n \"A write cannot touch <stdin>: there is no file behind it.\",\n );\n }\n if (\"schema\" in c || \"config\" in c) continue; // satisfied by schemaWrites\n const group = grouped.get(c.file) ?? { patch: {}, deletions: [] };\n if (\"cleared\" in c) group.cleared = true;\n else if (\"created\" in c) group.created = c.to;\n else if (\"renamed\" in c) group.renamedTo = c.renamed;\n else if (\"deleted\" in c) group.deletions.push(c.key);\n else if (\"renamedFrom\" in c) {\n group.patch[c.key] = c.to;\n group.deletions.push(c.renamedFrom);\n } else group.patch[c.key] = c.to;\n grouped.set(c.file, group);\n }\n\n const pendingWrites: { path: string; content: string; ensureDir?: boolean }[] =\n [];\n const pendingRenames: { from: string; to: string }[] = [];\n for (const [label, ops] of grouped) {\n const path = resolve(ctx.base, label);\n\n if (ops.renamedTo !== undefined) {\n if (!existsSync(path)) {\n throw new DocmetaError(\n `\"${label}\" is gone from disk since it was read; re-run the query.`,\n );\n }\n // The destination gets the same appeared-since-the-plan re-check the\n // created files do: rename(2) overwrites silently on POSIX.\n const toDisk = resolve(ctx.base, ops.renamedTo);\n if (existsSync(toDisk)) {\n throw new DocmetaError(\n `\"${ops.renamedTo}\" appeared on disk since the plan; re-run the query.`,\n );\n }\n pendingRenames.push({ from: path, to: toDisk });\n continue;\n }\n\n if (ops.created !== undefined) {\n const extractor = extractorForExtension(extname(label));\n if (!extractor?.apply) {\n throw new DocmetaError(\n `\"${label}\": no writable format for that extension.`,\n );\n }\n // Same moved-underneath contract the schema writes get: a file that\n // materialized here since the plan is somebody's data, not a target.\n if (existsSync(path)) {\n throw new DocmetaError(\n `\"${label}\" appeared on disk since the plan; re-run the query.`,\n );\n }\n pendingWrites.push({\n path,\n content: extractor.apply(\"\", ops.created, {\n filePath: label,\n // The new file's memberships, from its path alone. An INSERT has to\n // write through the element set a read of that file would use.\n elements: resolveElements(label, ctx.config, ctx.memberships(label)),\n }),\n ensureDir: true,\n });\n continue;\n }\n\n const entry = byLabel.get(label);\n if (!entry) throw new DocmetaError(`No loaded entry for \"${label}\".`);\n const content = await readFile(path, \"utf8\");\n // The change was computed against load-time data; if the file moved\n // since, applying it would encode a state nobody previewed.\n const members = ctx.memberships(label);\n const current = mergeExternalMetadata(\n label,\n entry.extractor.extract(content, label, {\n elements: resolveElements(label, ctx.config, members),\n }),\n ctx.externalMetadata,\n members,\n ctx.base,\n ).extracted;\n\n if (ops.cleared) {\n if (!deepEqual(current.data, entry.extracted.data)) {\n throw new DocmetaError(\n `\"${label}\" changed on disk since it was read; re-run the query.`,\n );\n }\n const stripped = stripFrontmatter(content);\n if (stripped === content) {\n // No fenced block to remove — element-backed metadata, or a native\n // header the fence writer does not own. Effect-judged, no name list.\n throw new DocmetaError(\n `\"${label}\": the ${entry.extractor.name} format has no front matter block to strip.`,\n );\n }\n pendingWrites.push({ path, content: stripped });\n continue;\n }\n\n if (!entry.extractor.apply) {\n throw new DocmetaError(\n `\"${label}\": the ${entry.extractor.name} format is read-only.`,\n );\n }\n for (const key of [...Object.keys(ops.patch), ...ops.deletions]) {\n if (!deepEqual(current.data[key], entry.extracted.data[key])) {\n throw new DocmetaError(\n `\"${label}\" changed on disk since it was read (\"${key}\" moved); re-run the query.`,\n );\n }\n }\n const applied = entry.extractor.apply(content, ops.patch, {\n filePath: label,\n // The memberships the read above used. Without them a collection-scoped\n // element the read found has nowhere to be written.\n elements: resolveElements(label, ctx.config, members),\n deletions: ops.deletions,\n });\n if (ops.deletions.length > 0) {\n // `deletions` is advisory in the ApplyOptions contract — a writer that\n // cannot remove a key ignores it. Certainty comes from reading back.\n const check = mergeExternalMetadata(\n label,\n entry.extractor.extract(applied, label, {\n elements: resolveElements(label, ctx.config, members),\n }),\n ctx.externalMetadata,\n members,\n ctx.base,\n ).extracted;\n for (const key of ops.deletions) {\n if (check.data[key] !== undefined) {\n throw new DocmetaError(\n `\"${label}\": the ${entry.extractor.name} writer cannot delete \"${key}\".`,\n );\n }\n }\n }\n pendingWrites.push({ path, content: applied });\n }\n // Phase two opens by re-checking the plan-time schema/config reads — the\n // same moved-underneath refusal corpus files got in phase one. Nothing has\n // landed yet, so a refusal here still leaves every file untouched.\n for (const w of schemaWrites) {\n const display = displayPath(ctx, w.path);\n if (w.expected === undefined) {\n if (existsSync(w.path)) {\n throw new DocmetaError(\n `\"${display}\" appeared on disk since the plan; re-run the query.`,\n );\n }\n continue;\n }\n let now: string | undefined;\n try {\n now = await readFile(w.path, \"utf8\");\n } catch {\n now = undefined;\n }\n if (now !== w.expected) {\n throw new DocmetaError(\n `\"${display}\" changed on disk since it was read; re-run the query.`,\n );\n }\n }\n // Parent directories once each, and only where one can be missing: a\n // fork's schemas/ dir, an INSERT into a new subtree, a rename into one.\n // Files that were read from disk this run prove their directories exist.\n const dirs = new Set<string>();\n for (const w of schemaWrites) dirs.add(dirname(w.path));\n for (const r of pendingRenames) dirs.add(dirname(r.to));\n for (const p of pendingWrites) {\n if (p.ensureDir) dirs.add(dirname(p.path));\n }\n for (const d of dirs) await mkdir(d, { recursive: true });\n\n // ADD writes the schema after the corpus so a mid-apply failure leaves\n // extra keys under an unchanged schema (green); DROP/RENAME write it first\n // so files at worst keep a key the schema no longer declares.\n const writeSchema = async (): Promise<void> => {\n for (const w of schemaWrites) await writeFileAtomic(w.path, w.content);\n };\n const schemaLast = schemaPlan?.schemaLast ?? false;\n if (!schemaLast) await writeSchema();\n // Content before moves: a statement may rename one file while editing\n // others, and writes are the failure-prone step (disk full, permissions).\n // With renames last, a write failure leaves every file under its old name\n // with some new values — the statement re-runs to convergence — instead of\n // a completed rename whose \"already exists\" guard blocks the re-run.\n for (const p of pendingWrites) await writeFileAtomic(p.path, p.content);\n for (const r of pendingRenames) {\n try {\n await rename(r.from, r.to);\n } catch (err) {\n // EXDEV and friends arrive as raw fs errors; name the move and keep\n // the operational exit code instead of an \"Unexpected error\" trace.\n throw new DocmetaError(\n `Cannot move \"${r.from}\" to \"${r.to}\": ${errorMessage(err)}`,\n );\n }\n }\n if (schemaLast) await writeSchema();\n for (const c of changes) c.written = true;\n}\n\n/**\n * Column names a statement SETs, so the table can be widened before it runs.\n * Tolerant by design: it walks strings and comments with the same rules as\n * the semicolon scan, and bails out at anything unexpected — a miss merely\n * leaves today's \"no such column\" error in place.\n *\n * Exported for the scanner parity suite, not via the API index.\n */\nexport function collectSetTargets(sql: string): string[] {\n const targets: string[] = [];\n let i = 0;\n const n = sql.length;\n const isWord = (ch: string | undefined): boolean =>\n ch !== undefined && /[A-Za-z0-9_]/.test(ch);\n while (i < n) {\n const ch = sql[i];\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n } else if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n } else if (\n (ch === \"s\" || ch === \"S\") &&\n /^set$/i.test(sql.slice(i, i + 3)) &&\n !isWord(sql[i - 1]) &&\n !isWord(sql[i + 3])\n ) {\n i += 3;\n // Assignment list: identifier `=` expression, comma-separated, ending\n // at a top-level WHERE/FROM/RETURNING or the end of the statement.\n for (;;) {\n while (i < n && /\\s/.test(sql[i] ?? \"\")) i++;\n const name = readIdentifier(sql, i);\n if (!name) return targets;\n targets.push(name.value);\n i = name.end;\n while (i < n && /\\s/.test(sql[i] ?? \"\")) i++;\n if (sql[i] !== \"=\") return targets;\n const next = skipExpression(sql, i + 1);\n if (next.terminator !== \",\") return targets;\n i = next.end + 1;\n }\n } else {\n i++;\n }\n }\n return targets;\n}\n\n/**\n * Column names an INSERT's column list carries, so a corpus-new key can be\n * introduced by creation too. Same tolerance contract as `collectSetTargets`.\n *\n * Exported for the scanner parity suite, not via the API index.\n */\nexport function collectInsertTargets(sql: string): string[] {\n const head = stripLeadingTrivia(sql);\n if (!/^(insert|replace)\\b/i.test(head)) return [];\n const open = head.indexOf(\"(\");\n if (open === -1) return [];\n const targets: string[] = [];\n let i = open + 1;\n for (;;) {\n while (i < head.length && /\\s/.test(head[i] ?? \"\")) i++;\n const id = readIdentifier(head, i);\n if (!id) return targets;\n targets.push(id.value);\n i = id.end;\n while (i < head.length && /\\s/.test(head[i] ?? \"\")) i++;\n if (head[i] === \",\") {\n i++;\n continue;\n }\n return targets;\n }\n}\n\nfunction readIdentifier(\n sql: string,\n from: number,\n): { value: string; end: number } | undefined {\n const ch = sql[from];\n if (ch === '\"' || ch === \"`\") {\n const end = skipStringOrIdent(sql, from);\n const raw = sql.slice(from + 1, end - 1);\n return { value: raw.replaceAll(ch + ch, ch), end };\n }\n if (ch === \"[\") {\n // The bracket skip's unterminated-at-EOF return (length + 1) is what\n // keeps `end - 1` the content boundary HERE. The quote path above has no\n // such contract: unterminated, the skip returns length, and `end - 1`\n // drops the final character — long-standing behavior, unchanged.\n const end = skipStringOrIdent(sql, from);\n return { value: sql.slice(from + 1, end - 1), end };\n }\n const m = /^[A-Za-z_][A-Za-z0-9_]*/.exec(sql.slice(from));\n return m ? { value: m[0], end: from + m[0].length } : undefined;\n}\n\n/**\n * Skip one SET-clause expression. Ends at a top-level `,` (another\n * assignment) or a top-level WHERE/FROM/RETURNING keyword or end-of-string.\n */\nfunction skipExpression(\n sql: string,\n from: number,\n): { end: number; terminator: \",\" | \"end\" } {\n let depth = 0;\n let i = from;\n const n = sql.length;\n while (i < n) {\n const ch = sql[i];\n // Every string/identifier form, brackets included — a bracket identifier\n // may contain the `,`/`(`/`)` this scan otherwise acts on. Comments too:\n // `SET k = /* a, b */ 1` must not read the comment's comma as a\n // target separator.\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n continue;\n }\n if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n continue;\n }\n if (ch === \"(\") depth++;\n else if (ch === \")\") depth--;\n else if (depth === 0) {\n if (ch === \",\") return { end: i, terminator: \",\" };\n if (/^(where|from|returning)\\b/i.test(sql.slice(i, i + 10)) &&\n !/[A-Za-z0-9_]/.test(sql[i - 1] ?? \"\")) {\n return { end: i, terminator: \"end\" };\n }\n }\n i++;\n }\n return { end: i, terminator: \"end\" };\n}\n\n// `quoteIdent`, `bindValue`, `assertSingleStatement`, and `loadSqlite` moved\n// to ../core/projection.ts (proposal 0026), where the named checks share them.\n","/**\n * `fill` — infer missing or invalid metadata and write back the values it is\n * confident about.\n *\n * The gate order matters, and it is deliberate: **confidence is the last check,\n * not the only one.** A self-reported score is a weak, uncalibrated signal, so\n * three mechanical checks run first and cannot be overridden by a high score:\n *\n * 1. The proposal must satisfy the target property's own subschema — enforced\n * by the envelope schema inside `completeValidatedJSON`, before `fill` sees\n * the response at all.\n * 2. It must name a property that was actually a candidate; the envelope's\n * `additionalProperties: false` makes inventing keys impossible.\n * 3. After merging, the document must still validate. Anything that would\n * leave the page failing its own schema is reverted.\n *\n * Only then does the confidence threshold apply. Confidence itself is\n * report-only — it is never written into the document.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { loadExternalMetadata, mergeExternalMetadata } from \"../core/external-metadata.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport { resolve, extname, join } from \"node:path\";\nimport {\n completeValidatedJSON,\n makeProvider,\n resolveProviderIdentityAsync,\n DEFAULT_MODELS,\n JsonCache,\n buildCacheKey,\n sha256,\n pricingFor,\n costOfUsage,\n InferenceError,\n type InferenceProvider,\n type ProviderName,\n type ProviderSelector,\n type ProviderSpec,\n type TokenUsage,\n} from \"@hawkeyexl/inference\";\nimport { DocmetaError, type FieldError, type MetadataPatch } from \"../types.js\";\nimport { resolveRunConfig, schemaTrustRoot } from \"../core/config.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport {\n extractorByName,\n extractorForExtension,\n listFormats,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport {\n collectSchemaPins,\n resolveSchemaSetWithSource,\n type ResolvedSchemaSet,\n FILE_SCHEMA_KEY,\n resolveElements,\n} from \"../core/resolve-schema.js\";\nimport { loadSchema, schemaLoadOptions } from \"../core/schema-registry.js\";\nimport { Validator, compileWithFormats } from \"../core/validator.js\";\nimport { toJsonText } from \"../core/json-text.js\";\nimport { writeFileAtomic } from \"../core/write-file.js\";\nimport {\n FILL_PROMPT_VERSION,\n FILL_SYSTEM_PROMPT,\n buildEnvelopeSchema,\n buildUserPrompt,\n splitBody,\n mergeProposals,\n DEFAULT_CHUNK_CHARS,\n} from \"./fill-prompt.js\";\nimport type {\n Candidate,\n FillFileResult,\n FillOptions,\n FillRun,\n FilledField,\n Proposal,\n ProposalSet,\n} from \"./fill-types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\nexport type {\n Candidate,\n FillFileResult,\n FillOptions,\n FillRun,\n FillSummary,\n FilledField,\n Proposal,\n SkipReason,\n} from \"./fill-types.js\";\n\nconst DEFAULT_THRESHOLD = 0.7;\nconst DEFAULT_CONCURRENCY = 4;\n/**\n * `auto` detects the highest-priority provider this machine can actually use —\n * an Anthropic key, then an OpenAI key, then the Claude CLI, then a local model\n * that needs no credentials at all. Defaulting to a named provider instead meant\n * `manni meta fill` failed outright for anyone who did not happen to hold that\n * vendor's key.\n */\nconst DEFAULT_PROVIDER = \"auto\";\nconst CACHE_DIR = \".manni/meta/cache\";\n\n/**\n * Whether a provider error reads like \"the prompt did not fit\".\n *\n * Deliberately loose, and deliberately a *safety net* rather than the mechanism:\n * chunking is bounded by docmeta's own budget, and this only catches the case\n * where that budget was still too generous for the model in play. No provider\n * exposes its input limit ahead of time, and four providers word the failure\n * four ways, so matching on wording is the only option — a miss costs a per-file\n * error the user can act on, not a corrupted document.\n */\nfunction looksLikeOverflow(message: string): boolean {\n // `exceeds`, not `exceed`, and that one letter is load-bearing. Review\n // suggested dropping it because it would match \"rate limit exceeded\" and\n // \"quota exceeded\" — which matters, since the response to an overflow is to\n // halve the budget, and halving *doubles* the call count. Answering a rate\n // limit with twice the requests would be a real fault.\n //\n // But it does not match them: \"exceeded\" does not contain \"exceeds\". Checked\n // against both, plus \"429 Too Many Requests\" — none match. Dropping it lost a\n // genuine overflow instead: \"Your input exceeds the maximum allowed length\"\n // matched before and would not after. Kept deliberately, and written down so\n // the next reader does not re-derive the wrong half of this.\n return /context|too long|too large|token limit|maximum.*tokens|exceeds/i.test(\n message,\n );\n}\n\n/**\n * Add one call's usage to a running total.\n *\n * A chunked document costs several calls, so caching the last one's usage would\n * understate the file by roughly the number of chunks. Nothing reads it back\n * today, which is exactly why it is worth keeping honest now rather than after\n * something does.\n */\nfunction addUsage(\n total: TokenUsage | undefined,\n next: TokenUsage | undefined,\n): TokenUsage | undefined {\n if (next === undefined) return total;\n if (total === undefined) return next;\n return {\n ...total,\n inputTokens: total.inputTokens + next.inputTokens,\n outputTokens: total.outputTokens + next.outputTokens,\n };\n}\n\n/** What the cache stores: the raw, *pre-gating* proposal for one file. */\ninterface CachedProposal {\n proposals: ProposalSet;\n usage?: TokenUsage;\n}\n\nexport async function runFill(opts: FillOptions): Promise<FillRun> {\n const cwd = opts.cwd ?? process.cwd();\n // Explicit CLI inputs win, else config `paths:`; `base` is whichever of the\n // two directories those inputs were written relative to.\n const { config, inputs, base, configDir, collections, fromCollections } =\n await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n // How every schema in this run is loaded: the cross-run cache and\n // `--offline`. `fill` calls `loadSchema` directly as well as through the\n // validator, so both have to be handed the same settings.\n const schemaOptions = schemaLoadOptions({\n root: configDir ?? cwd,\n // A relative file ref belongs to the run's directory, not the cache root.\n fileBase: cwd,\n ttlHours: config?.schemaCache?.ttlHours,\n offline: opts.offline ?? config?.offline,\n pins: collectSchemaPins(config),\n });\n // Settled once per run, not per file: finding it is a filesystem walk, and\n // every file in one run shares the same repository.\n const trustRoot = schemaTrustRoot(cwd, configDir);\n const usingStdin = inputs.includes(STDIN_TOKEN);\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to fill. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n const forcedExtractor = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forcedExtractor) {\n // `--as` takes an extractor name (\"markdown\"), so list names — listing\n // extensions here would point the user at the wrong kind of value.\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Known formats: ${listFormats()\n .map((f) => f.name)\n .join(\", \")}.`,\n );\n }\n if (usingStdin && !forcedExtractor) {\n throw new DocmetaError(\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\",\n );\n }\n\n // The CLI range-checks its flags, but runFill is also a public API and is\n // called directly from config values, so it validates rather than trusting.\n // A NaN threshold would silently skip every field; a fractional concurrency\n // would be silently truncated by Array.from's ToLength coercion.\n const threshold = requireNumber(\n opts.confidence ?? config?.fill?.confidenceThreshold ?? DEFAULT_THRESHOLD,\n \"confidence\",\n { min: 0, max: 1 },\n );\n const concurrency = requireNumber(\n opts.concurrency ?? config?.fill?.concurrency ?? DEFAULT_CONCURRENCY,\n \"concurrency\",\n { min: 1, max: 64, integer: true },\n );\n const maxTurns = opts.maxTurns ?? config?.fill?.maxTurns;\n if (maxTurns !== undefined) {\n requireNumber(maxTurns, \"maxTurns\", {\n min: 1,\n max: Number.MAX_SAFE_INTEGER,\n integer: true,\n });\n }\n const chunkBudget = requireNumber(\n opts.chunkChars ?? config?.fill?.chunkChars ?? DEFAULT_CHUNK_CHARS,\n \"chunkChars\",\n { min: 1, max: Number.MAX_SAFE_INTEGER, integer: true },\n );\n const dryRun = Boolean(opts.dryRun);\n const only = opts.fields != null ? new Set(opts.fields) : undefined;\n /** The managed fields (0040): read everywhere, written only by `derive`. */\n const managed = new Set<string>(config?.derive?.fields ?? []);\n\n const requestedProvider = (opts.provider ??\n config?.fill?.provider ??\n DEFAULT_PROVIDER) as ProviderSelector;\n // `--local` with no explicit provider *is* the choice: resolve to the local\n // one directly rather than letting detection pick a hosted provider and then\n // refusing it. Detection would otherwise announce `auto-selected \"openai\"`\n // immediately before the refusal, which reads as though it had been used.\n // An explicit `--provider` is left alone so a contradictory pair still errors\n // by name rather than being quietly overridden.\n const providerName: ProviderSelector =\n opts.local === true && requestedProvider === \"auto\"\n ? \"llama-cpp\"\n : requestedProvider;\n const model = opts.model ?? config?.fill?.model;\n const spec = { provider: providerName, model: model ?? null };\n\n // Check the name up front, and regardless of whether a provider was injected:\n // it costs nothing, and construction is lazy, so a typo would otherwise exit 0\n // on any run where no file happened to need inference.\n assertKnownProvider(providerName);\n assertModelHasProvider(providerName, model);\n if (opts.local === true) assertLocalProvider(providerName);\n\n // Resolve targets BEFORE identity. Under `auto`, resolving identity probes the\n // environment, the Claude CLI and the local runtime, and that last probe is\n // slow on a machine holding no credentials — so a mistyped glob would spend\n // seconds detecting a provider it is never going to use before failing. The\n // work is wasted in exactly the case where the user most wants a fast answer.\n //\n // Identity is still resolved unconditionally below, so an `--allow-empty` run\n // that legitimately matches nothing still reports which provider it would have\n // used.\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n const fillExts = opts.exts ?? forcedExtractor?.extensions;\n // Only `--exclude`: a collection's `exclude:` governs membership, not the\n // walk of a path someone typed (0041 rule 3).\n const fillExclude = opts.exclude ?? [];\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts: fillExts,\n exclude: fillExclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude: fillExclude,\n exts: fillExts,\n gitignoreSkipped,\n action: \"filled\",\n });\n\n // Identity comes from the spec, not a constructed provider, so a fully cached\n // run needs no API key at all. Under `auto` this is also where detection runs\n // — it probes the environment, the Claude CLI and the local runtime, but never\n // authenticates, so the no-key property survives.\n //\n // The two branches are kept apart rather than merged behind a cast: an\n // injected provider's `provider()` is a free-form string, and only the\n // resolved path yields a name `makeProvider` can be trusted with.\n let identity: { provider: string; model: string };\n let construct: () => InferenceProvider;\n\n if (opts.inferenceProvider) {\n const injected = opts.inferenceProvider;\n identity = { provider: injected.provider(), model: injected.modelName() };\n construct = () => injected;\n } else {\n const resolved = await resolveIdentity(spec);\n // `--local` under `auto` can only be enforced here: detection is what picks\n // the provider, so the check has to sit after it rather than on the spec.\n if (opts.local === true) assertLocalProvider(resolved.provider);\n identity = resolved;\n // Build from the RESOLVED identity, never the spec we started with: under\n // `auto` that spec still says \"auto\", and the synchronous `makeProvider`\n // rightly refuses to guess. Detection has already run, so the concrete name\n // is known — which keeps construction synchronous and lazy, and that is what\n // lets a fully cached run finish without a key.\n const concrete: ProviderSpec = {\n ...spec,\n provider: resolved.provider,\n model: resolved.model,\n };\n construct = () => makeProvider(concrete);\n }\n\n let provider: InferenceProvider | undefined;\n const getProvider = (): InferenceProvider => {\n if (!provider) {\n try {\n provider = construct();\n } catch (err) {\n // Missing API key / unknown provider is operational, not per-file.\n throw new DocmetaError(\n err instanceof InferenceError\n ? err.message\n : `Could not construct the \"${providerName}\" provider: ${errorMessage(err)}`,\n );\n }\n }\n return provider;\n };\n\n const cache =\n opts.cache === false\n ? undefined\n : new JsonCache<CachedProposal>(join(cwd, CACHE_DIR), true, \"manni\");\n const pricing = pricingFor(identity.model);\n\n const validator = new Validator(schemaOptions);\n let costUsd = 0;\n let cachedCount = 0;\n let turnsSpent = false;\n let turnsUsed = 0;\n let inFlight = 0;\n\n /**\n * Whether the call cap is spent.\n *\n * Counts **calls, not files**: chunking a long document costs several, and a\n * cap that counted files would silently under-count exactly the pages that\n * cost the most. Checked before each call rather than each file for the same\n * reason.\n */\n const turnsExhausted = (): boolean =>\n maxTurns != null && turnsUsed + inFlight >= maxTurns;\n\n // External metadata (0037), read once per run. Merged so the schema sees\n // one object; an owned key is never a fill candidate, since the manifest\n // is the only place it may be written and fill does not write manifests.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n });\n\n const processOne = async (\n label: string,\n content: string,\n extension: string,\n ): Promise<FillFileResult> => {\n const extractor = forcedExtractor ?? extractorForExtension(extension);\n if (!extractor) {\n return errorResult(\n label,\n \"unknown\",\n `Unsupported file type \"${extension}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n if (typeof extractor.apply !== \"function\") {\n return errorResult(\n label,\n extractor.name,\n `The \"${extractor.name}\" format is read-only; manni meta fill cannot write metadata back to it.`,\n );\n }\n\n // Resolved once per file. It walks every `overrides:` entry and dedupes,\n // and the three call sites below — extract, the write pre-flight, and the\n // write itself — all want the same answer for the same file.\n // The collections this file belongs to, computed once per file: the merge\n // and both resolution calls below ask the same question of it.\n const members = membersFor(label);\n const elements = resolveElements(label, config, members);\n\n let extracted;\n let merged;\n try {\n merged = mergeExternalMetadata(\n label,\n extractor.extract(content, label, { elements }),\n externalMetadata,\n members,\n base,\n );\n extracted = merged.extracted;\n } catch (err) {\n return errorResult(label, extractor.name, errorMessage(err));\n }\n\n let resolved: ResolvedSchemaSet;\n try {\n resolved = resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: extracted.data[FILE_SCHEMA_KEY],\n cliSchemas: opts.cliSchemas,\n config,\n memberOf: members,\n // Same trust boundary as `validate`: `fill` writes metadata back into\n // the document, so a schema a document chose for itself decides what\n // gets written — if anything, a stronger reason to guard it.\n fileBase: cwd,\n trustRoot,\n onNotice: opts.onNotice,\n });\n } catch (err) {\n return errorResult(label, extractor.name, errorMessage(err));\n }\n\n const schemaSet = resolved.schemas;\n let schemas: Record<string, unknown>[];\n let existingErrors;\n try {\n schemas = await Promise.all(\n schemaSet.map((ref) => loadSchema(ref, schemaOptions)),\n );\n existingErrors = await validator.validate(\n extracted.data,\n schemaSet,\n extracted.lineFor,\n extracted.colFor,\n merged.locate,\n );\n } catch (err) {\n // Same rule as `validate`: a schema the *document* chose failing to load\n // is that document's failure and is reported as one, so one file cannot\n // abort the run. Every other source stays operational, because a schema\n // the operator configured invalidates every file, not just this one.\n if (!(err instanceof DocmetaError) || resolved.source !== \"document\") {\n throw err;\n }\n return errorResult(label, extractor.name, err.message);\n }\n const proposed = collectCandidates(\n schemas,\n extracted.data,\n existingErrors,\n only,\n );\n // A managed field (0040) is never a candidate: only `derive` writes it,\n // and a model's guess at a date git already knows would be exactly the\n // stamp the channel exists to make trustworthy. Reported rather than\n // dropped, so the omission is visible and a required one still fails\n // the run — the fix being `manni meta derive`, not a better model.\n const managedSkips: FilledField[] = proposed\n .filter((c) => managed.has(c.key))\n .map((c) => ({\n field: `/${c.key}`,\n required: c.required,\n confidence: 0,\n reasoning: \"managed by derive\",\n written: false,\n skipReason: \"managed\",\n }));\n const candidates = proposed.filter((c) => !managed.has(c.key));\n // Readable, loudly unwritable (0037 rule 6): a candidate a manifest owns\n // could only be satisfied by editing the manifest, which fill does not\n // do — and writing it into the document would be the one thing 0018\n // forbids. Refused for the file rather than skipped, so a missing private\n // key is never quietly left missing.\n // One owner is enough to refuse, and naming the first is the whole\n // message: a key two of this file's collections own is a run-time error\n // (0041 rule 5) long before fill picks candidates.\n const ownedCandidates = externalMetadata\n ? candidates.flatMap((c) => {\n const owner = externalMetadata.owners.get(c.key)?.[0];\n return owner === undefined ? [] : [{ key: c.key, file: owner.file }];\n })\n : [];\n const firstOwned = ownedCandidates[0];\n if (firstOwned) {\n return errorResult(\n label,\n extractor.name,\n `\"${firstOwned.key}\" is owned by manifest ${firstOwned.file}; manni meta fill cannot write a manifest key. Add it to the manifest instead.`,\n schemaSet,\n );\n }\n if (candidates.length === 0) {\n return {\n file: label,\n format: extractor.name,\n schemas: schemaSet,\n fields: managedSkips,\n changed: false,\n ...(opts.includeContent ? { content } : {}),\n };\n }\n\n // Probe writability with an empty patch *before* paying for inference.\n // rst/asciidoc accept `apply` but reject documents that use their native\n // metadata syntax, and finding that out afterwards means the call is\n // billed for a file that could never have been written.\n try {\n extractor.apply(content, {}, { filePath: label, elements });\n } catch (err) {\n return errorResult(label, extractor.name, errorMessage(err), schemaSet);\n }\n\n // ---- Propose (cache first) -------------------------------------------\n const cacheKey = buildCacheKey([\n identity.provider,\n identity.model,\n `fill-v${FILL_PROMPT_VERSION}`,\n // The chunk budget decides how the document was split, and so which\n // proposals came back. Without it two runs at different budgets share a\n // key and the second silently replays the first — and the halve-and-retry\n // path above makes that a real collision, not a hypothetical one.\n `chunk-${chunkBudget}`,\n schemaSet.join(\",\"),\n candidates.map((c) => c.key).join(\",\"),\n sha256(content),\n ]);\n const hit = cache?.get(cacheKey);\n\n let proposals: ProposalSet;\n if (hit) {\n cachedCount++;\n proposals = hit.proposals;\n } else {\n if (turnsExhausted()) {\n turnsSpent = true;\n return errorResult(\n label,\n extractor.name,\n \"Skipped: --max-turns reached before this file was processed.\",\n schemaSet,\n );\n }\n const envelope = buildEnvelopeSchema(candidates, collectDefs(schemas));\n // The library's own Ajv has no ajv-formats, so a lifted subschema with\n // `format: \"date-time\"` would fail to compile. Compile it ourselves — and\n // keep the failure per-file, since an unresolvable `$ref` in one schema\n // must not abort a whole directory walk.\n let validate;\n try {\n validate = compileWithFormats(envelope);\n } catch (err) {\n return errorResult(\n label,\n extractor.name,\n `Could not build a proposal schema from ${schemaSet.join(\", \")}: ${errorMessage(err)}`,\n schemaSet,\n );\n }\n // The whole file goes out, in as many calls as the chunk budget takes.\n // An overflow means the budget was too generous for this model — there is\n // no way to ask a model its input limit ahead of time — so halve it once\n // and retry rather than failing a file for being long.\n let chunkChars = chunkBudget;\n let attempt = 0;\n let sets: ProposalSet[] | undefined;\n let usageTotal: TokenUsage | undefined;\n let partsRead: { read: number; total: number } | undefined;\n let failure: string | undefined;\n while (attempt < 2 && sets === undefined) {\n attempt++;\n const chunks = splitBody(content, chunkChars);\n const collected: ProposalSet[] = [];\n let overflowed = false;\n let cutShort = false;\n for (const [i, chunk] of chunks.entries()) {\n if (turnsExhausted()) {\n turnsSpent = true;\n // Stopping mid-document is not a partial success. Proposals merged\n // from the chunks that did run would describe part of the page\n // while reading as though they described all of it — the silent\n // truncation this change exists to remove, reintroduced by another\n // route. Report the file as not processed instead.\n cutShort = true;\n break;\n }\n inFlight++;\n let run;\n try {\n run = await completeValidatedJSON<ProposalSet>({\n provider: getProvider(),\n system: FILL_SYSTEM_PROMPT,\n user: buildUserPrompt({\n filePath: label,\n existing: extracted.data,\n candidates,\n body: chunk,\n ...(chunks.length > 1\n ? { part: { index: i + 1, total: chunks.length } }\n : {}),\n }),\n schema: envelope,\n validate,\n });\n costUsd += costOfUsage(run.usage, pricing);\n turnsUsed++;\n } finally {\n inFlight--;\n }\n if (run.error != null && looksLikeOverflow(run.error)) {\n overflowed = true;\n failure = run.error;\n break;\n }\n if (run.error != null || run.result == null) {\n failure = run.error ?? \"The model returned no proposal.\";\n break;\n }\n usageTotal = addUsage(usageTotal, run.usage);\n collected.push(run.result);\n }\n if (overflowed && attempt < 2) {\n // The calls this attempt already made stay counted against\n // `--max-turns`. They were made — the provider billed them — so\n // rolling them back would make the cap describe something other than\n // what happened. It does mean a document that triggers the retry\n // costs more turns than its final chunk count suggests.\n //\n // The cached *usage* is reset, though, because it describes the\n // document rather than the run: leaving the abandoned attempt's\n // tokens in would double-count the content both attempts covered.\n usageTotal = undefined;\n chunkChars = Math.max(1, Math.floor(chunkChars / 2));\n continue;\n }\n if (cutShort) {\n return errorResult(\n label,\n extractor.name,\n `Skipped: --max-turns reached ${chunks.length > 1 ? `part-way through this document (${collected.length} of ${chunks.length} parts read)` : \"before this file was processed\"}.`,\n schemaSet,\n );\n }\n // Only a document read end to end is usable. Anything short of that —\n // a transient provider error on chunk 3, or an overflow that survived\n // the one retry — would otherwise be merged and written as though it\n // described the whole page, which is the silent truncation this change\n // exists to remove. `cutShort` catches the turn-cap route above; this\n // catches the rest.\n partsRead = { read: collected.length, total: chunks.length };\n if (collected.length < chunks.length) break;\n sets = collected;\n }\n\n if (sets === undefined || sets.length === 0) {\n return errorResult(\n label,\n extractor.name,\n failure ?? \"The model returned no proposal.\",\n schemaSet,\n );\n }\n /* c8 ignore next 3 -- the loop only assigns a complete set. */\n if (partsRead !== undefined && partsRead.read < partsRead.total) {\n throw new DocmetaError(\"Internal error: incomplete proposal set.\");\n }\n proposals = mergeProposals(sets);\n cache?.set(cacheKey, { proposals, ...(usageTotal ? { usage: usageTotal } : {}) });\n }\n\n // ---- Gate -------------------------------------------------------------\n const fields = [...managedSkips, ...gate(candidates, proposals, threshold)];\n\n // ---- Re-validate, and revert anything that makes the page worse -------\n const accepted = fields.filter((f) => f.written);\n if (accepted.length > 0) {\n const merged = { ...extracted.data, ...patchOf(accepted) };\n const after = await validator.validate(\n merged,\n schemaSet,\n extracted.lineFor,\n extracted.colFor,\n );\n const broken = new Set(\n after.map((e) => topKey(e.instancePath)).filter((k) => k !== \"\"),\n );\n for (const f of accepted) {\n if (broken.has(keyOf(f))) {\n f.written = false;\n f.skipReason = \"schema-mismatch\";\n delete f.value;\n }\n }\n }\n\n const writable = fields.filter((f) => f.written);\n if (writable.length === 0) {\n return {\n file: label,\n format: extractor.name,\n schemas: schemaSet,\n fields,\n changed: false,\n ...(opts.includeContent ? { content } : {}),\n };\n }\n\n let next: string;\n try {\n next = extractor.apply(content, patchOf(writable), {\n filePath: label,\n elements,\n });\n } catch (err) {\n return errorResult(\n label,\n extractor.name,\n errorMessage(err),\n schemaSet,\n fields,\n );\n }\n\n const changed = next !== content;\n if (changed && !dryRun && label !== \"<stdin>\") {\n await writeFileAtomic(resolve(base, label), next);\n }\n return {\n file: label,\n format: extractor.name,\n schemas: schemaSet,\n fields,\n changed,\n ...(opts.includeContent ? { content: next } : {}),\n };\n };\n\n // ---- Drive ---------------------------------------------------------------\n const results: FillFileResult[] = [];\n if (usingStdin) {\n results.push(\n await processOne(\n \"<stdin>\",\n opts.stdinContent ?? \"\",\n forcedExtractor?.extensions[0] ?? \"\",\n ),\n );\n }\n\n // Files are inferred in parallel — one network round trip each would make a\n // large retrofit unusable in series — but collected by index so the report is\n // deterministic regardless of completion order.\n const fileResults = await mapConcurrent(files, concurrency, async (file) => {\n const content = await readFile(resolve(base, file), \"utf8\");\n return processOne(file, content, extname(file));\n });\n results.push(...fileResults);\n\n return {\n results,\n summary: summarize(results, costUsd, cachedCount),\n threshold,\n dryRun,\n provider: identity.provider,\n model: identity.model,\n turnsSpent,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Candidates\n// ---------------------------------------------------------------------------\n\n/** First pointer segment of an Ajv instancePath (\"/tags/0\" -> \"tags\"). */\nfunction topKey(instancePath: string): string {\n if (instancePath === \"\") return \"\";\n const seg = instancePath.slice(1).split(\"/\")[0] ?? \"\";\n return seg.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\nconst keyOf = (f: FilledField): string => f.field.slice(1);\n\nfunction patchOf(fields: FilledField[]): MetadataPatch {\n const patch: MetadataPatch = {};\n for (const f of fields) patch[keyOf(f)] = f.value;\n return patch;\n}\n\n/**\n * A property is a candidate when it is absent from the metadata, or present but\n * invalid.\n *\n * \"Missing\" is derived from the schema objects rather than from validation\n * errors on purpose: Ajv reports a `required` violation with an empty\n * `instancePath` and names the property only inside the message text, so\n * recovering the key would mean parsing prose.\n *\n * When several schemas in the set define the same property, their subschemas\n * are **merged**, not raced. Picking one — the first named, say — would make the\n * proposal depend on flag order: stack a vocabulary that pins `type` to an enum\n * with OKF, which accepts any non-empty string, and whichever came first would\n * decide whether the model ever saw the enum. Since `validate` always runs every\n * schema, a value that only satisfies one of them was never writable anyway.\n */\nexport function collectCandidates(\n schemas: Record<string, unknown>[],\n data: Record<string, unknown>,\n errors: FieldError[],\n only?: Set<string>,\n): Candidate[] {\n const invalid = new Set(\n errors.map((e) => topKey(e.instancePath)).filter((k) => k !== \"\"),\n );\n const required = new Set<string>();\n for (const schema of schemas) {\n if (Array.isArray(schema.required)) {\n for (const r of schema.required) if (typeof r === \"string\") required.add(r);\n }\n }\n\n // Two schemas may define `#/$defs/Slug` differently, and the envelope has room\n // for only one of each name. Renaming the losers keeps each lifted subschema\n // pointing at its own definition.\n const { renames } = plannedFor(schemas);\n\n const seen = new Map<string, Candidate>();\n for (const [index, schema] of schemas.entries()) {\n const properties = schema.properties;\n if (typeof properties !== \"object\" || properties === null) continue;\n const renamed = renames.get(index);\n for (const [key, raw] of Object.entries(\n properties as Record<string, unknown>,\n )) {\n // `$schema` is docmeta's schema wiring, not document metadata.\n if (key === FILE_SCHEMA_KEY) continue;\n if (only && !only.has(key)) continue;\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) continue;\n\n const present = Object.prototype.hasOwnProperty.call(data, key);\n if (present && !invalid.has(key)) continue; // already valid — leave it alone\n\n const sub = renamed\n ? withRenamedRefs(raw as Record<string, unknown>, renamed)\n : (raw as Record<string, unknown>);\n const already = seen.get(key);\n if (already) {\n already.subschema = mergeSubschemas(already.subschema, sub);\n continue;\n }\n seen.set(key, {\n key,\n subschema: sub,\n required: required.has(key),\n present,\n });\n }\n }\n return [...seen.values()];\n}\n\n/**\n * Combine two subschemas for one property into a single schema that satisfies\n * both, via `allOf`.\n *\n * `allOf` rather than a structural merge because it is the only combination that\n * is correct for every keyword pair without knowing what the keywords mean: two\n * `enum`s intersect, two `minLength`s take the maximum, two `pattern`s must both\n * match. Ajv already resolves all of that, and the envelope schema built around\n * the result is compiled by Ajv before any proposal is accepted.\n *\n * Two things are done on top of the bare wrapper. Identical branches are dropped,\n * so the common \"both schemas say `{type: \"string\"}`\" case still lifts a plain\n * subschema. And the `description`s are combined and carried to the outside,\n * because that is where `fill-prompt` looks when it tells the model what the\n * property is for. Keeping only one of them would leave the prompt — and so the\n * proposal — dependent on schema order, which is the whole point of merging; the\n * combined text is deduplicated and sorted so it reads the same either way.\n */\nfunction mergeSubschemas(\n a: Record<string, unknown>,\n b: Record<string, unknown>,\n): Record<string, unknown> {\n const branches: Record<string, unknown>[] = [];\n for (const part of [...branchesOf(a), ...branchesOf(b)]) {\n if (!branches.some((seen) => canonical(seen) === canonical(part))) {\n branches.push(part);\n }\n }\n const joined = joinDescriptions([...describedBy(a), ...describedBy(b)]);\n const description = joined === \"\" ? undefined : joined;\n\n const [first] = branches;\n if (branches.length === 1 && first !== undefined) {\n return description === undefined || first.description === description\n ? first\n : { ...first, description };\n }\n return {\n ...(description !== undefined ? { description } : {}),\n allOf: branches,\n };\n}\n\n/** How descriptions from different schemas are strung together for the prompt. */\nconst DESCRIPTION_JOIN = \" \";\n\n/** Deduplicate, drop blanks, and order by text so the result is order-free. */\nfunction joinDescriptions(parts: string[]): string {\n return [...new Set(parts.map((p) => p.trim()))]\n .filter((p) => p !== \"\")\n .sort()\n .join(DESCRIPTION_JOIN);\n}\n\n/**\n * Every distinct sentence describing a subschema, including the ones on the\n * branches of an `allOf`.\n *\n * A wrapper this module built already carries exactly the join of its branches'\n * descriptions, so re-collecting it would fold the joined text back in as a\n * phrase of its own and make a third merge repeat itself. An author's wrapper\n * carries prose that is nowhere else, which is why the two are told apart by\n * comparison rather than by assuming the wrapper is ours.\n */\nfunction describedBy(schema: Record<string, unknown>): string[] {\n const own =\n typeof schema.description === \"string\" ? schema.description : undefined;\n const branches = branchesOf(schema);\n if (branches.length === 1 && branches[0] === schema) {\n return own === undefined ? [] : [own];\n }\n const nested = branches.flatMap(describedBy);\n if (own !== undefined && own !== joinDescriptions(nested)) nested.push(own);\n return nested;\n}\n\n/**\n * A JSON *object*, in the sense JSON Schema uses the word: `null` and arrays\n * are `typeof \"object\"` too and neither is a schema.\n *\n * A predicate rather than the inline test plus a cast, because the cast was the\n * only thing carrying `object` across to `Record<string, unknown>` and nothing\n * checked that it still matched the test beside it.\n */\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The branches a subschema contributes to a merge — its own `allOf` entries if\n * it is a wrapper, otherwise itself. An author-written `{description, allOf}` is\n * unfolded on the same terms as one of ours; `describedBy` is what keeps its\n * description from being lost in the process.\n *\n * The unwrapping is deliberately narrow: an author-written schema may carry\n * `allOf` *alongside* other keywords, and flattening that would drop them.\n */\nfunction branchesOf(schema: Record<string, unknown>): Record<string, unknown>[] {\n const keys = Object.keys(schema);\n const isWrapper =\n Array.isArray(schema.allOf) &&\n keys.every((k) => k === \"allOf\" || k === \"description\");\n if (!isWrapper) return [schema];\n return (schema.allOf as unknown[]).flatMap((branch) => {\n if (isJsonObject(branch)) {\n return [branch];\n }\n // JSON Schema allows a boolean where a schema belongs. `true` constrains\n // nothing and disappears into the merge; `false` accepts nothing, and\n // dropping it would quietly turn a property nothing can satisfy into one\n // `fill` proposes for. `{not: {}}` says \"never valid\" in object form.\n return branch === false ? [{ not: {} }] : [];\n });\n}\n\n/** Key-order-independent serialization, so equal branches compare equal. */\nfunction canonical(value: unknown): string {\n if (Array.isArray(value)) return `[${value.map(canonical).join(\",\")}]`;\n if (typeof value === \"object\" && value !== null) {\n const entries = Object.entries(value as Record<string, unknown>)\n .sort(([x], [y]) => (x < y ? -1 : x > y ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${canonical(v)}`);\n return `{${entries.join(\",\")}}`;\n }\n // A schema parsed from JSON holds nothing `JSON.stringify` refuses, but\n // `collectCandidates` is public API and a hand-written JS object can pass an\n // `undefined`, a function, or a symbol. Tagging by type keeps those apart from\n // each other and from `null`, which is a legitimate schema value.\n //\n // `toJsonText`, not `JSON.stringify`, only so the declared type admits the\n // `undefined` this fallback exists for — see there.\n return toJsonText(value) ?? `(${typeof value})`;\n}\n\nconst DEF_BLOCKS = [\"$defs\", \"definitions\"] as const;\ntype DefBlock = (typeof DEF_BLOCKS)[number];\n\ninterface DefsPlan {\n defs: Record<DefBlock, Record<string, unknown>>;\n /** Schema index -> `\"<block>/<name>\"` -> the name that schema's defs got. */\n renames: Map<number, Map<string, string>>;\n}\n\n/**\n * Decide what the envelope's `$defs`/`definitions` blocks hold, and which\n * schemas need their `$ref`s pointed somewhere else to get there.\n *\n * The envelope is one document, so the two blocks are flat namespaces that every\n * schema in the set shares. Names collide: `Slug` in a house schema and `Slug` in\n * a vocabulary are unrelated definitions, and letting the first one win would\n * silently validate half the set against the wrong rule. A colliding definition\n * therefore gets its own name, and everything that pointed at it — the lifted\n * subschemas *and* the other definitions of the same schema — is rewritten to\n * match. That second part is why names are allocated for the whole set before\n * anything is rewritten: a definition may point at one that is renamed later in\n * the walk, and a pointer left behind resolves to another schema's rule.\n *\n * Definitions two schemas write identically share a slot, since there is nothing\n * to tell apart and a copy would only make the envelope noisier. That is settled\n * on the text alone, so it is offered only to definitions that resolve to\n * nothing else: `{$ref: \"#/$defs/Inner\"}` reads the same in both schemas while\n * meaning whatever each one's `Inner` says.\n *\n * The two blocks are kept **separate**: draft-07 schemas (which `dialectOf` in\n * validator.ts explicitly supports) write `$ref: \"#/definitions/X\"`, and folding\n * those entries into `$defs` would leave the pointer dangling.\n */\nfunction planDefs(schemas: Record<string, unknown>[]): DefsPlan {\n const defs: Record<DefBlock, Record<string, unknown>> = {\n $defs: {},\n definitions: {},\n };\n const renames = new Map<number, Map<string, string>>();\n const placed: { index: number; block: DefBlock; emitted: string }[] = [];\n\n for (const [index, schema] of schemas.entries()) {\n for (const block of DEF_BLOCKS) {\n const entries = schema[block];\n if (typeof entries !== \"object\" || entries === null) continue;\n for (const [name, value] of Object.entries(\n entries as Record<string, unknown>,\n )) {\n const taken = defs[block];\n if (!(name in taken)) {\n taken[name] = value;\n placed.push({ index, block, emitted: name });\n continue;\n }\n if (!pointsInward(value) && canonical(taken[name]) === canonical(value)) {\n continue;\n }\n\n let emitted = `${name}__${index}`;\n while (emitted in taken) emitted += \"_\";\n taken[emitted] = value;\n placed.push({ index, block, emitted });\n let map = renames.get(index);\n if (!map) {\n map = new Map();\n renames.set(index, map);\n }\n map.set(`${block}/${name}`, emitted);\n }\n }\n }\n\n // Now that every name is settled, point each definition at the ones belonging\n // to the schema it came from.\n for (const { index, block, emitted } of placed) {\n const map = renames.get(index);\n if (map) defs[block][emitted] = withRenamedRefs(defs[block][emitted], map);\n }\n return { defs, renames };\n}\n\n/**\n * Every keyword that can send a definition back into its own document.\n * `$dynamicRef` (2020-12) and `$recursiveRef` (2019-09) resolve against the\n * schema they were written in just as `$ref` does, so a definition using one is\n * no more interchangeable between schemas than a `$ref` chain is.\n */\nconst INWARD_REFS = new Set([\"$ref\", \"$dynamicRef\", \"$recursiveRef\"]);\n\n/** Whether a definition depends on some other part of its own document. */\nfunction pointsInward(node: unknown): boolean {\n if (Array.isArray(node)) return node.some(pointsInward);\n if (typeof node !== \"object\" || node === null) return false;\n return Object.entries(node).some(([key, value]) =>\n INWARD_REFS.has(key) && typeof value === \"string\"\n ? value.startsWith(\"#\")\n : pointsInward(value),\n );\n}\n\n/**\n * Carry `$defs`/`definitions` across so a lifted subschema's `$ref` resolves.\n *\n * Memoized on the array itself: `collectCandidates` needs the same plan to know\n * which refs to rewrite, and both are handed the one array `processOne` built\n * for the file.\n */\nexport function collectDefs(schemas: Record<string, unknown>[]): {\n $defs: Record<string, unknown>;\n definitions: Record<string, unknown>;\n} {\n return plannedFor(schemas).defs;\n}\n\nconst planCache = new WeakMap<Record<string, unknown>[], DefsPlan>();\n\nfunction plannedFor(schemas: Record<string, unknown>[]): DefsPlan {\n let plan = planCache.get(schemas);\n if (!plan) {\n plan = planDefs(schemas);\n planCache.set(schemas, plan);\n }\n return plan;\n}\n\n/**\n * Deep-copy a subschema with its local `$ref`s repointed at the names its\n * definitions were emitted under. Only called for schemas that actually lost a\n * name collision, so the ordinary case keeps the original object.\n */\nfunction withRenamedRefs<T>(node: T, renames: Map<string, string>): T {\n if (Array.isArray(node)) {\n // `Array.isArray` narrows a generic to `T & any[]`, so the mapped result is\n // `any[]` and the cast below would launder it. Restate the element type as\n // `unknown` first: the recursion accepts it, and the only assertion left is\n // the `as T` that was always there.\n const items: unknown[] = node;\n return items.map((item) => withRenamedRefs(item, renames)) as T;\n }\n if (typeof node !== \"object\" || node === null) return node;\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(node)) {\n out[key] =\n key === \"$ref\" && typeof value === \"string\"\n ? renameRef(value, renames)\n : withRenamedRefs(value, renames);\n }\n return out as T;\n}\n\n/**\n * Repoint one local pointer: `#/$defs/Slug` and `#/$defs/Slug/properties/x` both\n * follow the rename of `Slug`. Anything else — an absolute URI, a `$id`-relative\n * ref, a pointer into some other part of the document — is left alone.\n */\nfunction renameRef(ref: string, renames: Map<string, string>): string {\n const match = /^#\\/(\\$defs|definitions)\\/([^/]+)(\\/.*)?$/.exec(ref);\n const block = match?.[1];\n const name = match?.[2];\n if (block === undefined || name === undefined) return ref;\n const emitted = renames.get(`${block}/${unescapePointer(name)}`);\n if (emitted === undefined) return ref;\n return `#/${block}/${escapePointer(emitted)}${match?.[3] ?? \"\"}`;\n}\n\nconst unescapePointer = (segment: string): string =>\n segment.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\nconst escapePointer = (name: string): string =>\n name.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n\n// ---------------------------------------------------------------------------\n// The gate\n// ---------------------------------------------------------------------------\n\nfunction gate(\n candidates: Candidate[],\n proposals: ProposalSet,\n threshold: number,\n): FilledField[] {\n return candidates.map((c): FilledField => {\n const proposal: Proposal | undefined = proposals[c.key];\n if (proposal == null) {\n return {\n field: `/${c.key}`,\n required: c.required,\n confidence: 0,\n reasoning: \"\",\n written: false,\n skipReason: \"no-proposal\",\n };\n }\n const passes = proposal.confidence >= threshold;\n return {\n field: `/${c.key}`,\n required: c.required,\n confidence: proposal.confidence,\n reasoning: proposal.reasoning,\n written: passes,\n ...(passes ? { value: proposal.value } : { skipReason: \"low-confidence\" as const }),\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Plumbing\n// ---------------------------------------------------------------------------\n\n/**\n * `schemas` is passed once resolution has succeeded, so a JSON consumer can\n * tell \"the schema set was never resolved\" from \"it resolved and then writing\n * was refused\" — the two need different follow-up.\n */\nfunction errorResult(\n file: string,\n format: string,\n message: string,\n schemas: string[] = [],\n fields: FilledField[] = [],\n): FillFileResult {\n return { file, format, schemas, fields, changed: false, error: message };\n}\n\n/**\n * Range-check a numeric option. Every comparison against NaN is false, so the\n * finite check has to be explicit or garbage passes silently.\n */\nfunction requireNumber(\n value: number,\n name: string,\n bounds: { min: number; max: number; integer?: boolean },\n): number {\n const { min, max, integer } = bounds;\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < min || value > max) {\n throw new DocmetaError(\n `fill: \"${name}\" must be a number between ${min} and ${max}, got ${String(value)}.`,\n );\n }\n if (integer === true && !Number.isInteger(value)) {\n throw new DocmetaError(\n `fill: \"${name}\" must be a whole number, got ${String(value)}.`,\n );\n }\n return value;\n}\n\n/**\n * Provider names the inference layer accepts, taken from the library rather\n * than copied. A hardcoded list here silently went stale when `llama-cpp` was\n * added upstream; deriving it means a new provider works the day it ships.\n */\nconst PROVIDERS = new Set<string>([...Object.keys(DEFAULT_MODELS), \"auto\"]);\n\n/**\n * Refuse a provider that would send content off the machine.\n *\n * `claude-cli` is the one that has to be named. The binary runs locally, so it\n * reads as local; the inference does not, so it is not. It sits third in the\n * detection order, which makes it exactly the fallback `--local` would\n * otherwise pick up by accident — the flag would keep working and stop meaning\n * anything.\n */\nfunction assertLocalProvider(name: string): void {\n if (name === \"llama-cpp\" || name === \"mock\") return;\n if (name === \"auto\") return; // narrowed below, once detection has run\n throw new DocmetaError(\n name === \"claude-cli\"\n ? `--local cannot use \"claude-cli\": the CLI runs on this machine but its inference does not. Use --provider llama-cpp.`\n : `--local cannot use \"${name}\", which sends document content to a hosted API. Use --provider llama-cpp, or drop --local.`,\n );\n}\n\nfunction assertKnownProvider(name: string): void {\n if (PROVIDERS.has(name)) return;\n throw new DocmetaError(\n `Unknown provider \"${name}\". Available: ${[...PROVIDERS].join(\", \")}.`,\n );\n}\n\n/**\n * A model name belongs to exactly one provider, so it cannot be handed to\n * whichever provider detection picks: `--model gpt-4o-mini` on a machine with an\n * Anthropic key selected anthropic and then 404'd mid-run, after file discovery\n * had already been paid for.\n *\n * The library enforces this too. It is repeated here to name the flags rather\n * than the API fields, since that is what the user typed.\n *\n * `name` is the EFFECTIVE provider, so a `fill.provider` in config satisfies\n * this just as `--provider` does; only an unresolved `auto` is ambiguous.\n */\nfunction assertModelHasProvider(\n name: ProviderSelector,\n model: string | undefined,\n): void {\n if (name !== \"auto\" || model == null) return;\n throw new DocmetaError(\n `Model \"${model}\" was given without a provider: a model name does not say ` +\n `which provider owns it. Set --provider or fill.provider to one of ` +\n `${Object.keys(DEFAULT_MODELS).join(\", \")}, or drop the model to take the ` +\n `detected provider's default.`,\n );\n}\n\nasync function resolveIdentity(spec: {\n provider: ProviderSelector;\n model: string | null;\n}): Promise<{ provider: ProviderName; model: string }> {\n try {\n return await resolveProviderIdentityAsync(spec);\n } catch (err) {\n // Detection failing with nothing available is operational, not per-file:\n // the aggregate message names every provider it tried and why each was out.\n throw new DocmetaError(\n err instanceof InferenceError\n ? err.message\n : `Could not resolve provider \"${spec.provider}\": ${errorMessage(err)}`,\n );\n }\n}\n\nfunction summarize(\n results: FillFileResult[],\n costUsd: number,\n cached: number,\n): FillRun[\"summary\"] {\n let written = 0;\n let skipped = 0;\n let requiredSkipped = 0;\n for (const r of results) {\n for (const f of r.fields) {\n if (f.written) written++;\n else {\n skipped++;\n if (f.required) requiredSkipped++;\n }\n }\n }\n return {\n files: results.length,\n changed: results.filter((r) => r.changed).length,\n written,\n skipped,\n requiredSkipped,\n errors: results.filter((r) => r.error != null).length,\n costUsd,\n cached,\n };\n}\n\n/** Bounded worker pool that preserves input order in its output. */\nasync function mapConcurrent<T, R>(\n items: T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const out = new Array<R>(items.length);\n let next = 0;\n const workers = Array.from(\n { length: Math.max(1, Math.min(limit, items.length)) },\n async () => {\n for (;;) {\n const i = next++;\n const item = items[i];\n if (i >= items.length || item === undefined) return;\n out[i] = await fn(item);\n }\n },\n );\n await Promise.all(workers);\n return out;\n}\n","/**\n * Prompt and schema construction for `fill`.\n *\n * The central idea is the **envelope schema**: rather than asking the model for\n * free-form values and checking them afterwards, each candidate property's own\n * subschema is lifted verbatim out of the document schema and wrapped in a\n * `{ value, confidence, reasoning }` object. The provider is then constrained to\n * emit something that already satisfies the user's schema, and the response is\n * validated against it before `fill` ever sees it. A malformed `date-time` or a\n * number where a string belongs never reaches the confidence gate at all — which\n * is what lets confidence be the *last* check rather than the only one.\n */\nimport type { Candidate, ProposalSet } from \"./fill-types.js\";\n\n/**\n * Part of the cache key: bump whenever the prompt wording or the envelope\n * schema construction changes, so stale proposals are not replayed.\n */\nexport const FILL_PROMPT_VERSION = 3;\n\n/**\n * Characters of document sent per inference call.\n *\n * This was the point at which the document stopped being read: anything past it\n * was replaced with `[body truncated]`, so a long reference page was described\n * from its introduction and its own conclusion was never seen. Same number, but\n * it now bounds a *chunk* — the whole file is sent, in as many calls as it takes.\n *\n * It is docmeta's budget rather than the model's because no per-model input\n * context size is discoverable: the inference catalog publishes `uri`,\n * `sizeBytes`, `license` and tier, and its `maxTokens` is an *output* cap. So\n * overflow cannot be predicted, only hit — which is why the caller treats a\n * provider overflow as a signal to shrink this and retry, rather than trying to\n * compute the right value up front.\n */\nexport const DEFAULT_CHUNK_CHARS = 12000;\n\n/**\n * Split a document into chunks of at most `chunkChars`.\n *\n * Splits on a line boundary when there is one inside the budget, so a chunk\n * rarely ends mid-sentence; a single line longer than the budget is cut anyway,\n * because a minified file has no boundary to prefer. Concatenating the result\n * reproduces the input exactly — the test asserts that, because \"the whole file\n * is sent\" is the entire point of the change.\n */\nexport function splitBody(body: string, chunkChars: number): string[] {\n if (body.length <= chunkChars) return [body];\n const chunks: string[] = [];\n let at = 0;\n while (at < body.length) {\n const end = Math.min(at + chunkChars, body.length);\n let cut = end;\n if (end < body.length) {\n const nl = body.lastIndexOf(\"\\n\", end - 1);\n // Only honour the boundary if it makes progress; otherwise the line is\n // longer than the budget and there is nothing to prefer.\n if (nl > at) cut = nl + 1;\n }\n chunks.push(body.slice(at, cut));\n at = cut;\n }\n return chunks;\n}\n\n/**\n * Combine per-chunk proposals, keeping the most confident value for each key.\n *\n * Confidence is already the accept/reject axis — `gate()` compares each\n * proposal against the threshold — so choosing between two proposals spends the\n * same currency once more rather than introducing a second one. (It is a\n * threshold, not a ranking: this is the first place two proposals are compared\n * against each other.) A value found in a page's conclusion therefore competes\n * on equal terms with one guessed from its introduction, which is the whole\n * point of reading past the first chunk. Ties keep the earlier chunk —\n * arbitrary, but stable across runs.\n */\nexport function mergeProposals(sets: ProposalSet[]): ProposalSet {\n const merged: ProposalSet = {};\n for (const set of sets) {\n for (const [key, proposal] of Object.entries(set)) {\n const held = merged[key];\n if (held === undefined || proposal.confidence > held.confidence) {\n merged[key] = proposal;\n }\n }\n }\n return merged;\n}\n\nexport const FILL_SYSTEM_PROMPT = [\n \"You infer document metadata from the document itself.\",\n \"\",\n \"You are given a page's existing metadata, the JSON Schema properties that are\",\n \"missing or currently invalid, and the page body. Propose a value for each\",\n \"property you can determine from the page.\",\n \"\",\n \"Rules:\",\n \"- Base every value on evidence in the page. Never invent facts, URLs, dates,\",\n \" authors, or identifiers that the page does not support.\",\n \"- Omit a property entirely rather than guessing at it. A missing property is a\",\n \" normal, expected outcome.\",\n \"- Report an honest confidence between 0 and 1 that the value is correct and\",\n \" that a careful human reviewer would agree with it. Do not inflate it.\",\n \" Reserve values above 0.9 for values the page states plainly.\",\n \"- Keep `reasoning` to one sentence naming the evidence you used.\",\n \"- Match each property's described purpose, not just its type.\",\n].join(\"\\n\");\n\n/** JSON Schema for one proposal, wrapping the target property's own subschema. */\nfunction proposalSchema(candidate: Candidate): Record<string, unknown> {\n const described =\n typeof candidate.subschema.description === \"string\"\n ? candidate.subschema.description\n : undefined;\n return {\n type: \"object\",\n additionalProperties: false,\n required: [\"value\", \"confidence\", \"reasoning\"],\n description: described\n ? `Proposed value for \"${candidate.key}\": ${described}`\n : `Proposed value for \"${candidate.key}\".`,\n properties: {\n value: candidate.subschema,\n confidence: {\n type: \"number\",\n minimum: 0,\n maximum: 1,\n description:\n \"Honest self-reported confidence that this value is correct. Do not inflate.\",\n },\n reasoning: {\n type: \"string\",\n description: \"One sentence naming the evidence in the page.\",\n },\n },\n };\n}\n\n/**\n * Build the response schema for one file. Every candidate is optional so the\n * model can decline; `additionalProperties: false` means it cannot invent keys.\n * `$defs` from the source schemas are carried along so any `$ref` inside a\n * lifted subschema still resolves.\n */\nexport function buildEnvelopeSchema(\n candidates: Candidate[],\n defs: { $defs: Record<string, unknown>; definitions: Record<string, unknown> },\n): Record<string, unknown> {\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n type: \"object\",\n additionalProperties: false,\n // Both blocks are reproduced under their original names so a lifted\n // subschema's `$ref` — `#/$defs/X` on 2020-12, `#/definitions/X` on\n // draft-07 — still resolves against the envelope root.\n ...(Object.keys(defs.$defs).length > 0 ? { $defs: defs.$defs } : {}),\n ...(Object.keys(defs.definitions).length > 0\n ? { definitions: defs.definitions }\n : {}),\n properties: Object.fromEntries(\n candidates.map((c) => [c.key, proposalSchema(c)]),\n ),\n };\n}\n\nexport function buildUserPrompt(params: {\n filePath: string;\n existing: Record<string, unknown>;\n candidates: Candidate[];\n body: string;\n /** Set when the document was split, so the model knows it sees a slice. */\n part?: { index: number; total: number };\n}): string {\n const { filePath, existing, candidates, body, part } = params;\n const wanted = candidates.map((c) => {\n const description =\n typeof c.subschema.description === \"string\"\n ? ` — ${c.subschema.description}`\n : \"\";\n const why = c.present\n ? \"currently invalid, propose a replacement\"\n : \"missing\";\n return `- ${c.key} (${why})${description}`;\n });\n\n return [\n `# File`,\n filePath,\n \"\",\n \"# Existing metadata\",\n Object.keys(existing).length > 0\n ? JSON.stringify(existing, null, 2)\n : \"(none)\",\n \"\",\n \"# Properties to propose\",\n ...wanted,\n \"\",\n part === undefined\n ? \"# Page body\"\n : `# Page body (part ${part.index} of ${part.total})`,\n body,\n ].join(\"\\n\");\n}\n","/**\n * `derive` — stamp the managed stewardship fields into each document from\n * evidence: git history, CODEOWNERS, and the review record on GitHub or GitLab.\n *\n * The shape is `fill`'s (load, extract, decide, write through the extractor)\n * with the deciding step replaced by the derived channel: every requested\n * field is compared with what the sources say, and a field that is `stale`\n * or `unset` is written. `current` and `unknown` fields are left alone. Under\n * `--check` nothing is written and every stale or unset field becomes a\n * finding, which is how CI turns a forgotten stamp into a red run.\n *\n * Three refusals are operational (exit 2) rather than per-file, because each\n * leaves the run with no honest verdict: stdin, which has no history behind\n * it; a field or source the channel does not know; and a consulted source\n * that cannot answer, since a skipped source would let a stale stamp read as\n * current — the false green the whole channel exists to end.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { extname, resolve } from \"node:path\";\nimport {\n DocmetaError,\n type FieldError,\n type MetadataExtractor,\n type MetadataPatch,\n} from \"../types.js\";\nimport { manifestOwning, resolveRunConfig, type ConfigNotice } from \"../core/config.js\";\nimport type { FingerprintContext } from \"../core/baseline.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport {\n extractorByName,\n extractorForExtension,\n listFormats,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport { resolveElements } from \"../core/resolve-schema.js\";\nimport { writeFileAtomic } from \"../core/write-file.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { assertSourcesAvailable, deriveMetadata } from \"../core/derive/index.js\";\nimport { commandsOf } from \"../core/derive/config.js\";\nimport {\n compareDerived,\n DERIVABLE_FIELDS,\n DERIVE_SOURCES,\n isBuiltinField,\n isDeriveSource,\n staleFindings,\n type DerivableField,\n type DeriveCommand,\n type DerivedField,\n type DeriveInput,\n type DeriveSource,\n type ReviewClient,\n type SourceStatus,\n} from \"../core/derive/types.js\";\n\nexport interface DeriveOptions {\n inputs: string[];\n /**\n * `--collection <name>`, repeatable: stamp only the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with paths.\n */\n collections?: string[];\n /** `--fields`: the managed fields to stamp this run; config `derive.fields` otherwise. */\n fields?: string[];\n /** `--sources`: the sources to consult; config `derive.sources`, else all four. */\n sources?: string[];\n /** `--dry-run`: report what would change and write nothing. */\n dryRun?: boolean;\n /** `--check`: implies `dryRun`; stale and unset fields are findings. */\n check?: boolean;\n /** Use the on-disk GitHub or GitLab review cache. Default true. */\n cache?: boolean;\n /** `--as` format override (extractor name). */\n as?: string;\n exts?: string[];\n exclude?: string[];\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n cwd?: string;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n /** The clock an uncommitted body change is dated by. Test seam; default `new Date()`. */\n now?: () => Date;\n /** The review client, for every repository in the run. Test seam; default `gh` / `glab`. */\n reviews?: ReviewClient;\n}\n\nexport interface DeriveFileResult {\n file: string;\n /** Extractor/format used; `unknown` when none matched the file. */\n format: string;\n /** One entry per requested field, in the requested order. Empty on `error`. */\n fields: DerivedField[];\n /**\n * Whether writing the stale and unset fields changed the document, or\n * would have but for `dryRun`. Computed from the writer's output, so a\n * patch the format serializes to the same bytes is not a change.\n */\n changed: boolean;\n /** Why the file could not be derived or written; the run goes on without it. */\n error?: string;\n /**\n * Under `check`, the findings for this file: one per stale or unset field,\n * at the field's line, plus one for an `error`. Absent otherwise.\n */\n findings?: FieldError[];\n}\n\nexport interface DeriveSummary {\n files: number;\n /** Files whose document changed, or would have under `dryRun`. */\n changed: number;\n /** Fields whose write reached the disk: always 0 under `dryRun` and `check`. */\n written: number;\n stale: number;\n unset: number;\n unknown: number;\n errors: number;\n}\n\nexport interface DeriveRun {\n results: DeriveFileResult[];\n summary: DeriveSummary;\n dryRun: boolean;\n check: boolean;\n /** One status per source the run consulted; a source nobody asked for is absent. */\n sources: Partial<Record<DeriveSource, SourceStatus>>;\n /** Where the run stood, for the SARIF reporter under `check`. See `ValidateRun.frame`. */\n frame: FingerprintContext;\n}\n\n/** The hint `assertSourcesAvailable` appends: this command's own way out. */\nconst SOURCE_HINT = \"narrow --sources or --fields\";\n\nexport async function runDerive(opts: DeriveOptions): Promise<DeriveRun> {\n const cwd = opts.cwd ?? process.cwd();\n const { config, inputs, base, configDir, collections, declaredCollections, fromCollections } =\n await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined ? { collections: opts.collections } : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n // Refused before any file is read: every other command takes `-`\n // as one more input, but a piped document has no commits, no path a\n // CODEOWNERS rule could match, and no pull request. There is nothing to\n // derive from, so the answer would be \"unknown\" for every field — and a\n // run that cannot answer is exit 2, not a quiet no-op.\n if (inputs.includes(STDIN_TOKEN)) {\n throw new DocmetaError(\"cannot derive <stdin>: no history behind it\");\n }\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to derive. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n // The configured commands (0042): a key of theirs is as derivable as a\n // built-in field, and the source runs them where the config lives.\n const commands = commandsOf(config?.derive);\n const fields = resolveFields(opts.fields, config?.derive?.fields, commands);\n // `loadConfig` refuses a `derive.fields` entry a manifest owns; the same\n // rule holds for `--fields`, which bypasses the config. Every declared\n // collection counts, not only the selected ones, and the config's `keys:`\n // list is the whole claim, so no manifest is loaded.\n for (const field of fields) {\n const owner = manifestOwning(field, declaredCollections);\n if (owner !== undefined) {\n throw new DocmetaError(\n `\"${field}\" is owned by the manifest ${owner.file} on collection ${owner.name}; a managed field has one authority, and a manifest key already has one.`,\n );\n }\n }\n const sources = resolveSources(opts.sources, config?.derive?.sources);\n const check = Boolean(opts.check);\n // `--check` judges and exits; it never writes.\n const dryRun = Boolean(opts.dryRun) || check;\n\n const forcedExtractor = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forcedExtractor) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Known formats: ${listFormats()\n .map((f) => f.name)\n .join(\", \")}.`,\n );\n }\n\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n const exts = opts.exts ?? forcedExtractor?.extensions;\n // Only `--exclude`: a collection's `exclude:` governs membership, not the\n // walk of a path someone typed (0041 rule 3).\n const exclude = opts.exclude ?? [];\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: narrow the walk to actual members, or a collection's `exclude:`\n // would shape its SQL view and not what a bare run stamps. Skipped for\n // typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs,\n usingStdin: false,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"derived\",\n });\n\n // ---- Load and extract ----------------------------------------------------\n // A document that will not parse is that file's error, not the run's: the\n // rest of the corpus still gets its stamps. Only the parseable ones go to\n // the sources.\n interface Loaded {\n label: string;\n absPath: string;\n content: string;\n format: string;\n elements: string[];\n extracted: DeriveInput[\"extracted\"];\n apply: MetadataExtractor[\"apply\"];\n }\n const loaded = new Map<string, Loaded>();\n const errors = new Map<string, { format: string; message: string }>();\n for (const label of files) {\n const absPath = resolve(base, label);\n const extractor = forcedExtractor ?? extractorForExtension(extname(label));\n if (!extractor) {\n errors.set(label, {\n format: \"unknown\",\n message: `Unsupported file type \"${extname(label)}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n });\n continue;\n }\n const content = await readFile(absPath, \"utf8\");\n const elements = resolveElements(label, config, membersFor(label));\n try {\n loaded.set(label, {\n label,\n absPath,\n content,\n format: extractor.name,\n elements,\n extracted: extractor.extract(content, label, { elements }),\n apply: extractor.apply,\n });\n } catch (err) {\n errors.set(label, { format: extractor.name, message: errorMessage(err) });\n }\n }\n\n // ---- Derive --------------------------------------------------------------\n const derived = await deriveMetadata([...loaded.values()], {\n cwd,\n base,\n configDir,\n sources,\n fields,\n codeowners: config?.derive?.codeowners,\n commands,\n cache: opts.cache ?? true,\n now: opts.now ?? (() => new Date()),\n reviews: opts.reviews,\n });\n assertSourcesAvailable(derived.sources, SOURCE_HINT);\n // A source that answered, with a caveat worth one line: a repository with\n // no CODEOWNERS file derives null owners rather than failing.\n for (const [name, status] of Object.entries(derived.sources)) {\n if (status.available && status.reason !== undefined) {\n opts.onNotice?.(`${name}: ${status.reason}`);\n }\n }\n\n // ---- Compare, and write ----------------------------------------------------\n const results: DeriveFileResult[] = [];\n for (const label of files) {\n const failure = errors.get(label);\n if (failure) {\n results.push(errorResult(label, failure.format, failure.message, check));\n continue;\n }\n const doc = loaded.get(label);\n /* c8 ignore next -- every file is in exactly one of the two maps. */\n if (!doc) continue;\n\n const record = derived.records.get(label);\n const compared = fields.map((field) =>\n compareDerived(field, doc.extracted.data[field], record?.fields[field]),\n );\n const pending = compared.filter((f) => f.status === \"stale\" || f.status === \"unset\");\n // `changed` is what the writer would do, not what the comparison found:\n // as in `fill`, the patch is applied and the result compared with the\n // document, so a field is `written` only when bytes went to disk. Under\n // `dryRun` the same patch is computed and nothing is written.\n let changed = false;\n if (pending.length > 0) {\n // Same writer `fill` and `query` use, so a format they cannot write is\n // refused here the same way — and refused loudly, as this file's error,\n // rather than by leaving a stale stamp in place with exit 0. Under\n // `check` a read-only format still gets its findings, since nothing was\n // going to be written anyway.\n if (typeof doc.apply !== \"function\") {\n if (!dryRun) {\n results.push(\n errorResult(\n label,\n doc.format,\n `The \"${doc.format}\" format is read-only; manni meta derive cannot write metadata back to it.`,\n check,\n compared,\n ),\n );\n continue;\n }\n changed = true;\n } else {\n const patch: MetadataPatch = {};\n for (const f of pending) patch[f.field] = f.derived;\n let next: string;\n try {\n next = doc.apply(doc.content, patch, { filePath: label, elements: doc.elements });\n } catch (err) {\n results.push(errorResult(label, doc.format, errorMessage(err), check, compared));\n continue;\n }\n changed = next !== doc.content;\n if (changed && !dryRun) {\n await writeFileAtomic(doc.absPath, next);\n for (const f of pending) f.written = true;\n }\n }\n }\n\n results.push({\n file: label,\n format: doc.format,\n fields: compared,\n changed,\n ...(check ? { findings: staleFindings(compared, doc.extracted.lineFor) } : {}),\n });\n }\n\n return {\n results,\n summary: summarize(results),\n dryRun,\n check,\n sources: derived.sources,\n frame: { cwd, base: configDir ?? cwd, runBase: base },\n };\n}\n\n/**\n * The fields this run stamps: `--fields`, else config `derive.fields`.\n * Validated here as well as in the config parser, because `--fields` is typed\n * by a person and `runDerive` is public API.\n */\nfunction resolveFields(\n flag: string[] | undefined,\n configured: readonly DerivableField[] | undefined,\n commands: Readonly<Record<string, DeriveCommand>> | undefined,\n): DerivableField[] {\n const names = flag ?? configured;\n if (names === undefined || names.length === 0) {\n throw new DocmetaError(\n \"nothing to derive: set derive.fields in manni.config.yaml or pass --fields\",\n );\n }\n const out: DerivableField[] = [];\n for (const name of names) {\n if (!isBuiltinField(name) && !(commands !== undefined && Object.hasOwn(commands, name))) {\n throw new DocmetaError(\n `\"${name}\" is not derivable; derivable fields are ${DERIVABLE_FIELDS.join(\", \")}, or any key with an entry in derive.commands`,\n );\n }\n if (!out.includes(name)) out.push(name);\n }\n return out;\n}\n\n/** The sources this run consults: `--sources`, else config `derive.sources`, else all four. */\nfunction resolveSources(\n flag: string[] | undefined,\n configured: readonly DeriveSource[] | undefined,\n): DeriveSource[] {\n const names = flag ?? configured ?? DERIVE_SOURCES;\n const out: DeriveSource[] = [];\n for (const name of names) {\n if (!isDeriveSource(name)) {\n throw new DocmetaError(\n `\"${name}\" is not a source; sources are ${DERIVE_SOURCES.join(\", \")}`,\n );\n }\n if (!out.includes(name)) out.push(name);\n }\n return out;\n}\n\n/**\n * A file the run could not derive or write. Under `check` the error is a\n * finding too, shaped as `validate` shapes a parse failure, so the reporters\n * give it the reserved `manni/parse-error` rule rather than inventing one.\n */\nfunction errorResult(\n file: string,\n format: string,\n message: string,\n check: boolean,\n fields: DerivedField[] = [],\n): DeriveFileResult {\n return {\n file,\n format,\n fields,\n changed: false,\n error: message,\n ...(check\n ? {\n findings: [\n { schema: \"(parse)\", instancePath: \"\", message, keyword: \"parse\" },\n ],\n }\n : {}),\n };\n}\n\nfunction summarize(results: DeriveFileResult[]): DeriveSummary {\n const summary: DeriveSummary = {\n files: results.length,\n changed: 0,\n written: 0,\n stale: 0,\n unset: 0,\n unknown: 0,\n errors: 0,\n };\n for (const r of results) {\n if (r.changed) summary.changed++;\n if (r.error !== undefined) summary.errors++;\n for (const f of r.fields) {\n if (f.written) summary.written++;\n if (f.status === \"stale\") summary.stale++;\n else if (f.status === \"unset\") summary.unset++;\n else if (f.status === \"unknown\") summary.unknown++;\n }\n }\n return summary;\n}\n","/**\n * SARIF 2.1.0 — the interchange format GitHub code scanning, GitLab, and Azure\n * DevOps ingest directly.\n *\n * What `--format github` cannot do is persist: `::error` workflow commands\n * render on the pull request and then vanish with the job log. SARIF findings\n * become tracked alerts with state across commits, which is what makes \"when\n * did this regress\" and \"is metadata debt trending down\" answerable at all.\n *\n * Three properties carry that tracking, and each has a trap:\n *\n * - **`artifactLocation.uri` must be repository-root-relative.** GitHub\n * resolves it against the repository root and *silently drops* results that\n * do not resolve — the upload succeeds, with zero alerts. `ValidationResult`\n * labels are relative to whatever the run resolved against, which is only\n * coincidentally the repository root, so they are rebased here.\n * - **`ruleId` must not be built from prose.** See `./rule-id.ts`.\n * - **`partialFingerprints` must match the baseline's fingerprint.** One\n * identity function, two consumers.\n */\nimport { isAbsolute } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport type { FieldError, ValidationResult } from \"../types.js\";\nimport {\n canonicalFilePath,\n canonicalSchemaRef,\n fingerprint,\n type FingerprintContext,\n} from \"../core/baseline.js\";\nimport { findGitRoot } from \"../core/config.js\";\n// One definition, in core: commands set this label and reporters test for it,\n// so two copies would drift and a `<stdin>` result would acquire an\n// `artifactLocation.uri` naming a file that does not exist.\nimport { STDIN_LABEL } from \"../core/load-files.js\";\nimport { RESERVED_RULES, fieldLabel, ruleIdFor } from \"./rule-id.js\";\n\n/** Where a consumer is sent to read about docmeta itself. */\nconst INFORMATION_URI = \"https://hawkeyexl.github.io/manni/meta/\";\n\n/** Where a consumer is sent to read about one finding. */\nconst HELP_URI = \"https://hawkeyexl.github.io/manni/meta/fix/\";\n\n/**\n * The property-bag key GitHub keys alert identity on. Versioned deliberately,\n * and **not renamed with the tool**: the value is what lets an alert opened by\n * a docmeta run stay the same alert under manni. A new key would re-open every\n * finding once; that is what `/v2` is for, should the fingerprint ever change.\n */\nconst FINGERPRINT_KEY = \"docmetaViolation/v1\";\n\n/** Not a path anyone can resolve, so it can never be an artifact location. */\n// Imported rather than redeclared: two independent copies of this literal\n// would drift silently, and the failure mode is a `<stdin>` result acquiring an\n// `artifactLocation.uri` that names no file.\n\n/**\n * Said once, on stderr, when SARIF paths could not be made\n * repository-root-relative — the `GITIGNORE_UNAVAILABLE` precedent. Degrading\n * in silence is the wrong failure here: a uri that does not resolve produces a\n * *successful* upload with no alerts, so nothing downstream ever complains.\n */\nexport const SARIF_NO_GIT_ROOT =\n \"SARIF paths could not be made repository-root-relative: no git repository was found here. GitHub code scanning resolves artifactLocation.uri against the repository root and drops results that do not resolve, so an upload may report no findings at all.\";\n\nexport interface SarifOptions {\n /** The run's path frame. Without one, `file` labels are emitted as they are. */\n frame?: FingerprintContext;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n}\n\ninterface SarifRule {\n id: string;\n shortDescription: { text: string };\n helpUri: string;\n}\n\ninterface SarifResult {\n ruleId: string;\n level: \"error\";\n message: { text: string };\n locations: {\n physicalLocation: {\n artifactLocation: { uri: string };\n region?: { startLine: number };\n };\n }[];\n partialFingerprints: Record<string, string>;\n}\n\n/**\n * What a rule *is*, in one line.\n *\n * Only the reserved rules get bespoke prose; everything else is named by the\n * schema and keyword that produced it, which is all docmeta actually knows. A\n * per-keyword phrasebook would be prose docmeta would then have to keep in step\n * with Ajv's own vocabulary for no consumer benefit.\n */\nfunction describeRule(id: string, e: FieldError, schemaRef: string): string {\n return (\n RESERVED_RULES[id] ??\n `Schema \"${schemaRef}\" rejected the document on its \"${e.keyword}\" keyword.`\n );\n}\n\n/**\n * Said when a result had to be dropped because its path lies outside the\n * repository.\n *\n * Dropping is the only truthful option — GitHub would drop it anyway, having\n * failed to resolve it — but doing so in silence reproduces the exact failure\n * this reporter exists to prevent: an upload that succeeds while reporting\n * fewer findings than the run actually made.\n */\nexport const sarifDroppedNotice = (n: number): string =>\n `${n} SARIF ${n === 1 ? \"finding lies\" : \"findings lie\"} outside the repository and ${n === 1 ? \"was\" : \"were\"} omitted: an artifactLocation.uri that leaves the repository root cannot be resolved by a code-scanning consumer.`;\n\n/**\n * The frame `artifactLocation.uri` is measured against.\n *\n * Same rebase `canonicalFilePath` already performs for baseline keys, with\n * `base` swapped for the repository root. Returns null when there is nothing to\n * rebase against, which the caller reports rather than papers over.\n */\nfunction uriFrame(frame: FingerprintContext): FingerprintContext | null {\n const root = findGitRoot(frame.cwd);\n return root === null ? null : { ...frame, base: root };\n}\n\n/**\n * A uri SARIF accepts: relative, posix, and never climbing out of the\n * repository.\n *\n * A file above the repository root rebases to `../…`, which SARIF permits but\n * GitHub cannot resolve. There is nothing truthful to emit for it, so the\n * result is dropped rather than pointed at a path that does not exist — the\n * same reasoning that skips `<stdin>`.\n */\nfunction artifactUri(\n file: string,\n frame: FingerprintContext | undefined,\n): string | null {\n const uri = canonicalFilePath(file, frame);\n // An absolute path is not a repository-relative uri either. `relative()`\n // returns one when the two paths share no root, which on Windows is any\n // checkout and temp directory on different drives.\n if (uri === \"\" || uri.startsWith(\"../\") || isAbsolute(uri)) return null;\n return uri;\n}\n\nexport function renderSarif(\n results: ValidationResult[],\n opts: SarifOptions = {},\n): string {\n const { frame, onNotice } = opts;\n\n // Two frames, deliberately: fingerprints stay measured against the config's\n // directory (so a baseline recorded from anywhere matches), while uris are\n // measured against the repository root (so GitHub can resolve them).\n const rebased = frame ? uriFrame(frame) : undefined;\n if (frame && rebased === null) onNotice?.(SARIF_NO_GIT_ROOT);\n // With no repository there is no root to measure from, and falling back to\n // `frame` would measure against the *config's* directory — which for a config\n // outside the tree being validated yields `../…` for every file, and\n // `artifactUri` drops those. That turns \"no git repo\" into \"no findings at\n // all\". Measure from where the run actually resolved its inputs instead: the\n // paths are no longer repository-relative, which the notice above already\n // says, but they are at least the paths the user typed.\n const pathFrame =\n rebased ?? (frame ? { ...frame, base: frame.runBase ?? frame.cwd } : undefined);\n\n const rules = new Map<string, SarifRule>();\n const sarifResults: SarifResult[] = [];\n let dropped = 0;\n\n for (const r of results) {\n if (r.errors.length === 0) continue;\n // `<stdin>` is not a path; nothing is lost by leaving it out, so it is not\n // counted as a drop.\n if (r.file === STDIN_LABEL) continue;\n const docUri = artifactUri(r.file, pathFrame);\n\n for (const e of r.errors) {\n // A value a manifest supplied is located in the manifest (proposal\n // 0037), which may be the one file of the run that *is* inside the\n // repository when the documents are not, or the reverse — so each\n // finding resolves its own uri, and is dropped on its own.\n const uri = e.file != null ? artifactUri(e.file, pathFrame) : docUri;\n if (uri === null) {\n dropped += 1;\n continue;\n }\n const ruleId = ruleIdFor(e, frame);\n if (!rules.has(ruleId)) {\n rules.set(ruleId, {\n id: ruleId,\n shortDescription: {\n text: describeRule(ruleId, e, canonicalSchemaRef(e.schema, frame)),\n },\n helpUri: HELP_URI,\n });\n }\n sarifResults.push({\n ruleId,\n // Everything is `error`: docmeta has no severity concept to map onto\n // SARIF's triage axis. Tracked as issue #78, not hidden here.\n level: \"error\",\n message: { text: `${fieldLabel(e.instancePath)} ${e.message}` },\n locations: [\n {\n physicalLocation: {\n artifactLocation: { uri },\n // SARIF requires `startLine >= 1`. `0` is schema-invalid and `1`\n // silently mislocates the finding at the top of the file, so an\n // unknown line omits the region and renders file-level, which is\n // true. `startColumn` is deliberately still absent: html and xml\n // now populate `col`, but the rest of the region work (endLine,\n // endColumn, snippet) belongs to 0003, and a lone startColumn\n // would be the half of it that misleads.\n ...(e.line != null ? { region: { startLine: e.line } } : {}),\n },\n },\n ],\n partialFingerprints: { [FINGERPRINT_KEY]: fingerprint(e, frame) },\n });\n }\n }\n\n if (dropped > 0) onNotice?.(sarifDroppedNotice(dropped));\n\n return `${JSON.stringify(\n {\n $schema: \"https://json.schemastore.org/sarif-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"manni\",\n version: pkg.version,\n informationUri: INFORMATION_URI,\n // Only rules this run actually hit. Enumerating every keyword of\n // every schema would mean compiling and walking each one, for no\n // consumer benefit.\n rules: [...rules.values()],\n },\n },\n results: sarifResults,\n },\n ],\n },\n null,\n 2,\n )}`;\n}\n","/**\n * A violation's **rule identity**, shared by the SARIF `ruleId` and the JUnit\n * `<failure type>`.\n *\n * Built from `schema` + `keyword` and nothing else. `message` is Ajv-generated\n * prose, so a rule id derived from it would rename itself on any Ajv upgrade\n * and every historical alert in the consumer would close and reopen as new.\n * That is the same reasoning `src/core/baseline.ts` applies to fingerprints,\n * and for the same reason: these are the durable half of a violation.\n */\nimport type { FieldError } from \"../types.js\";\nimport { canonicalSchemaRef, type FingerprintContext } from \"../core/baseline.js\";\n\n/** The `schema` label the command layer stamps on its own failures. */\nconst SYNTHETIC_SCHEMA = \"(parse)\";\n\n/** A document whose metadata block could not be parsed. */\nexport const PARSE_ERROR_RULE = \"manni/parse-error\";\n\n/** A document no schema set could be resolved for. */\nexport const SCHEMA_ERROR_RULE = \"manni/schema-error\";\n\n/**\n * A document carrying a key a manifest owns (proposal 0037). Not a\n * synthetic-schema special case: `external:owned` is a builtin-shaped ref\n * like `check:<name>`, so the ordinary join produces this id.\n */\nexport const EXTERNAL_OWNED_RULE = \"external:owned/external\";\n\n/**\n * Two documents carry the same value of a manifest's join field (proposal\n * 0039), so one manifest entry matched both.\n */\nexport const EXTERNAL_DUPLICATE_RULE = \"external:duplicate/external\";\n\n/**\n * A managed field whose asserted value differs from the derived one, or is\n * missing while a source has one. `derived:stale` is builtin-shaped like the\n * external refs, so the ordinary join produces this id too.\n */\nexport const DERIVED_STALE_RULE = \"derived:stale/derived\";\n\n/** What each reserved rule means, for the consumer's rule listing. */\nexport const RESERVED_RULES: Record<string, string> = {\n [PARSE_ERROR_RULE]: \"The document's metadata block could not be parsed.\",\n [SCHEMA_ERROR_RULE]: \"No schema set could be resolved for the document.\",\n [EXTERNAL_OWNED_RULE]:\n \"The document carries a key a manifest owns; the manifest is the only place that key may be set.\",\n [EXTERNAL_DUPLICATE_RULE]:\n \"Two documents carry the same value of a manifest's join field, so one manifest entry matched both.\",\n [DERIVED_STALE_RULE]:\n \"A managed field whose value differs from what git, CODEOWNERS or the GitHub or GitLab review record says; run `manni meta derive` to refresh it.\",\n};\n\n/**\n * The rule id for one violation.\n *\n * docmeta's own failures carry `schema: \"(parse)\"` and no real keyword, so the\n * naive join yields `(parse)/parse` — a rule id that names an implementation\n * detail and reads as garbage in a security tab. They get reserved ids instead.\n *\n * With a `frame`, the schema reference is canonicalized exactly as a\n * fingerprint's is, so a local-file schema does not produce one rule id from\n * the repository root and a different, machine-specific one from `docs/`.\n */\nexport function ruleIdFor(e: FieldError, frame?: FingerprintContext): string {\n if (e.schema === SYNTHETIC_SCHEMA) {\n if (e.keyword === \"parse\") return PARSE_ERROR_RULE;\n if (e.keyword === \"schema\") return SCHEMA_ERROR_RULE;\n }\n return `${canonicalSchemaRef(e.schema, frame)}/${e.keyword}`;\n}\n\n/** `\"\"` is the whole document; every reporter spells that the same way. */\nexport function fieldLabel(instancePath: string): string {\n return instancePath === \"\" ? \"(root)\" : instancePath;\n}\n","/**\n * JUnit XML — what CI systems parse for the \"Tests\" tab.\n *\n * There is no authoritative JUnit schema; Jenkins, GitLab, CircleCI, and Azure\n * each accept a different superset. This writer sticks to the attributes all of\n * them honor (`name`, `tests`, `failures`, `errors`, `classname`, `type`,\n * `message`) and avoids the contested ones — `time`, which would be meaningless\n * here, `system-out`, and nested suites. That is a compatibility judgement, not\n * a specification.\n *\n * **One `<testcase>` per file, one `<failure>` per violation.** So the tab reads\n * \"2 tests, 1 failed\" and matches `2 files checked, 1 failed`.\n * Violation-as-testcase would make the test count rise and fall with document\n * quality, which reads as a suite someone broke.\n *\n * Escaping is the one thing a hand-rolled writer gets wrong. Messages carry\n * schema-authored text — a `pattern` regex may hold `<`, `&`, and quotes — and\n * paths can hold `&`. Every attribute value goes through `xmlEscape`; nothing\n * is interpolated raw.\n */\nimport type { FingerprintContext } from \"../core/baseline.js\";\nimport type { ValidationResult } from \"../types.js\";\nimport { fieldLabel, ruleIdFor } from \"./rule-id.js\";\n\n/** Suite and classname. One suite per run; nested suites are not portable. */\nconst SUITE_NAME = \"manni\";\nconst CLASS_NAME = \"manni.validate\";\n\nconst XML_ENTITIES: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&apos;\",\n};\n\n/**\n * Escape every XML metacharacter, and drop the control characters XML 1.0\n * forbids outright.\n *\n * `>` and `'` do not strictly need escaping in every position, but escaping all\n * five unconditionally means no caller has to know which position it is in —\n * which is precisely the reasoning a partial escaper gets wrong. The control\n * character strip is separate: those cannot be represented in XML 1.0 at all,\n * escaped or not, so a stray one makes the whole document unparseable rather\n * than merely mis-rendered. Tab, newline, and carriage return are legal, and\n * kept.\n */\n/**\n * XML 1.0's `Char` production, in full:\n *\n * #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n *\n * C0 controls are the familiar exclusion, but they are not the only one: a lone\n * surrogate half and the noncharacters U+FFFE/U+FFFF are equally illegal, and\n * both sit in a JavaScript string quite happily — a schema-authored `pattern`\n * or a filename can carry either. Iterating with `for…of` yields whole code\n * points, so a *well-formed* surrogate pair arrives as one astral character\n * (>= U+10000) and is kept; only an unpaired half falls in the D800-DFFF gap\n * and is dropped.\n */\nfunction isXmlChar(code: number): boolean {\n return (\n code === 0x9 ||\n code === 0xa ||\n code === 0xd ||\n (code >= 0x20 && code <= 0xd7ff) ||\n (code >= 0xe000 && code <= 0xfffd) ||\n (code >= 0x10000 && code <= 0x10ffff)\n );\n}\n\nexport function xmlEscape(value: string): string {\n let out = \"\";\n for (const ch of value) {\n const code = ch.codePointAt(0) ?? 0;\n if (!isXmlChar(code)) continue;\n out += XML_ENTITIES[ch] ?? ch;\n }\n return out;\n}\n\nconst attr = (name: string, value: string): string =>\n ` ${name}=\"${xmlEscape(value)}\"`;\n\nexport interface JunitOptions {\n /**\n * The `classname` each `<testcase>` carries: which docmeta command produced\n * these findings. Defaults to `docmeta.validate`, the only producer before\n * proposal 0026 made `query --check` a second one — whose findings must not\n * ship under validate's name.\n */\n classname?: string;\n /**\n * The run's path frame, used only to canonicalize a local-file schema ref in\n * `<failure type>`.\n *\n * Without it the attribute carries the ref exactly as the run received it —\n * `./my.schema.json` from the repo root, `../my.schema.json` from a\n * subdirectory, or a machine-absolute path once config discovery has rebased\n * it. SARIF's `ruleId` is already canonical, so a consumer correlating the two\n * for one run would find them disagreeing on the same violation.\n */\n frame?: FingerprintContext;\n}\n\nexport function renderJunit(\n results: ValidationResult[],\n opts: JunitOptions = {},\n): string {\n const tests = results.length;\n const failures = results.filter((r) => r.errors.length > 0).length;\n\n const counts =\n attr(\"name\", SUITE_NAME) +\n attr(\"tests\", String(tests)) +\n attr(\"failures\", String(failures)) +\n // Every violation is a `<failure>`; `errors` is reserved for a test that\n // could not run, which has no analogue here. Emitted as 0 rather than\n // omitted, because consumers read the attribute and show a blank column\n // without it.\n attr(\"errors\", \"0\");\n\n const lines: string[] = [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n `<testsuites${counts}>`,\n ` <testsuite${counts}>`,\n ];\n\n const classname = opts.classname ?? CLASS_NAME;\n for (const r of results) {\n const open = ` <testcase${attr(\"name\", r.file)}${attr(\"classname\", classname)}`;\n if (r.errors.length === 0) {\n // Self-closing: a passing test has nothing to carry.\n lines.push(`${open}/>`);\n continue;\n }\n lines.push(`${open}>`);\n for (const e of r.errors) {\n const where =\n e.file != null\n ? ` (${e.file}${e.line != null ? `:${e.line}` : \"\"})`\n : e.line != null\n ? ` (line ${e.line})`\n : \"\";\n lines.push(\n ` <failure${attr(\"type\", ruleIdFor(e, opts.frame))}${attr(\n \"message\",\n `${fieldLabel(e.instancePath)} ${e.message}${where}`,\n )}/>`,\n );\n }\n lines.push(\" </testcase>\");\n }\n\n lines.push(\" </testsuite>\", \"</testsuites>\");\n return lines.join(\"\\n\");\n}\n","/**\n * Terminal color, decided once for every tool under the umbrella.\n *\n * clig.dev: color only on a TTY, never under `NO_COLOR` or `--no-color`. Each\n * tool's reporters take the decision as a boolean and build a palette from it,\n * so no reporter ever consults the environment on its own.\n */\nimport pc from \"picocolors\";\n\nexport type Colors = ReturnType<typeof pc.createColors>;\n\n/** Build a picocolors palette with color explicitly on or off. */\nexport function palette(enabled: boolean): Colors {\n return pc.createColors(enabled);\n}\n\n/**\n * Decide whether to emit ANSI color: off when `--no-color`/`NO_COLOR`, on only\n * for a TTY otherwise. `forced` (from `--color`) overrides detection.\n */\nexport function shouldColor(opts: {\n noColor?: boolean;\n isTTY?: boolean;\n env?: NodeJS.ProcessEnv;\n}): boolean {\n const env = opts.env ?? process.env;\n if (opts.noColor) return false;\n if (env.NO_COLOR != null && env.NO_COLOR !== \"\") return false;\n return Boolean(opts.isTTY);\n}\n","/**\n * GitHub Actions workflow-command primitives, shared by every renderer in\n * every tool that emits `::error ...::<message>`.\n *\n * Its own module rather than a local function so a second renderer cannot\n * re-derive the rule and get the ordering wrong — the ordering is the part that\n * is easy to miss. Under `src/shared/` because the a11y reporter needs the\n * same two functions, and one tool must not reach into another's internals.\n */\n\n/**\n * Escape a workflow command's **message**.\n *\n * `::error ...::<message>` is a line-oriented protocol: a literal newline ends\n * the command, so an unescaped multi-line message truncates the annotation and\n * spills the rest into the log as plain text. `%` is the escape introducer, so\n * an unescaped one corrupts the message the runner decodes. Ajv quotes a\n * schema's `pattern` regex verbatim, which is where a stray `%` comes from in\n * practice.\n *\n * `%` **must** be replaced first. Doing the newlines first would turn a literal\n * LF into `%0A` and then the `%` pass would rewrite that to `%250A`, so the\n * annotation would display the escape sequence as text instead of a line break.\n *\n * Only these three. GitHub also treats `,` and `:` specially, but in the\n * command's *property* values (`file=`, `line=`), not in the message — encoding\n * them here would show up as `%3A` in the rendered annotation. That is what\n * {@link escapeWorkflowCommandProperty} is for.\n *\n * @see https://docs.github.com/actions/reference/workflow-commands-for-github-actions\n */\nexport function escapeWorkflowCommandMessage(message: string): string {\n return message\n .replace(/%/g, \"%25\")\n .replace(/\\r/g, \"%0D\")\n .replace(/\\n/g, \"%0A\");\n}\n\n/**\n * Escape a workflow command's **property value** — the right-hand side of\n * `file=`, `line=`, `col=`.\n *\n * Everything the message needs, plus `,` and `:`. Properties are comma-\n * separated and each is `name:value`-adjacent in the grammar, so an unescaped\n * separator inside a value silently re-partitions the command: a real path like\n * `docs/report,final.md` yields `file=docs/report` and a stray property named\n * `final.md`, and the annotation lands on the wrong file — or nowhere — with no\n * error anywhere.\n *\n * `%` first, for the same reason as the message escaper.\n */\nexport function escapeWorkflowCommandProperty(value: string): string {\n return value\n .replace(/%/g, \"%25\")\n .replace(/\\r/g, \"%0D\")\n .replace(/\\n/g, \"%0A\")\n .replace(/:/g, \"%3A\")\n .replace(/,/g, \"%2C\");\n}\n","/**\n * Reporters render validation results to a string. The command layer writes\n * the result to stdout; diagnostics go to stderr separately.\n */\nimport {\n DocmetaError,\n type BaselineSummary,\n type RunSummary,\n type ValidationResult,\n} from \"../types.js\";\nimport type { FingerprintContext } from \"../core/baseline.js\";\nimport { palette } from \"./color.js\";\nimport { fieldLabel } from \"./rule-id.js\";\nimport { renderSarif, type SarifOptions } from \"./sarif.js\";\nimport { renderJunit, type JunitOptions } from \"./junit.js\";\nimport {\n escapeWorkflowCommandMessage,\n escapeWorkflowCommandProperty,\n} from \"./github.js\";\n\nexport { renderSarif, SARIF_NO_GIT_ROOT } from \"./sarif.js\";\nexport type { SarifOptions } from \"./sarif.js\";\nexport { renderJunit, xmlEscape } from \"./junit.js\";\nexport type { JunitOptions } from \"./junit.js\";\nexport {\n escapeWorkflowCommandMessage,\n escapeWorkflowCommandProperty,\n} from \"./github.js\";\nexport {\n PARSE_ERROR_RULE,\n SCHEMA_ERROR_RULE,\n ruleIdFor,\n} from \"./rule-id.js\";\n\n/**\n * Every value `--format` accepts, in the order help and error messages list\n * them.\n *\n * The list is stated **once**. It used to live in five unlinked places — this\n * union, a separate `Set<string>` in the CLI, the error message, the option\n * description, and the docs — and the `Set` was not tied to the union at all,\n * so widening the union alone type-checked and still rejected the new value at\n * runtime. Deriving the union from the array makes that drift impossible.\n */\nexport const REPORT_FORMATS = [\n \"pretty\",\n \"json\",\n \"github\",\n \"sarif\",\n \"junit\",\n] as const;\n\nexport type ReportFormat = (typeof REPORT_FORMATS)[number];\n\n/**\n * A format list as a sentence fragment: `\"pretty or json\"`,\n * `\"pretty, json, or github\"`.\n *\n * The two-value case is why this is a function rather than one `join`. A pair\n * takes no comma before \"or\", and `get` and `schemas` have said \"Use pretty or\n * json.\" since long before the list was shared — a mechanical\n * `map(...).join(\", \")` would have quietly reworded every one of those messages\n * to \"pretty, or json\".\n */\nexport function formatList(formats: readonly string[]): string {\n // Destructured and guarded rather than indexed. `noUncheckedIndexedAccess`\n // types `formats[0]` as `string | undefined` however the length was checked,\n // so the interpolation below would happily print \"undefined\" — these two\n // guards say what `length < 2` said, in a form the compiler can carry.\n const [first, second] = formats;\n if (first === undefined) return \"\";\n if (second === undefined) return first;\n // Still needed, and not redundant however it reads: a defined `second` proves\n // there are *at least* two, not exactly two. Three or more falls through to\n // the comma-joined form below.\n if (formats.length === 2) return `${first} or ${second}`;\n return formats\n .map((format, i) => (i === formats.length - 1 ? `or ${format}` : format))\n .join(\", \");\n}\n\n/** `\"pretty, json, github, sarif, or junit\"`, for messages and help text. */\nexport const REPORT_FORMAT_LIST = formatList(REPORT_FORMATS);\n\nexport function isReportFormat(value: string): value is ReportFormat {\n return (REPORT_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * The formats **every** command produces.\n *\n * `get` and `schemas` accept exactly these two, and each used to spell the pair\n * out inline in `src/cli.ts` as `format !== \"pretty\" && format !== \"json\"` with\n * a hand-written \"Use pretty or json.\" beside it — the same stringly-typed\n * drift this module's `REPORT_FORMATS` comment describes, reproduced three more\n * times. Stated once, the guard and the message cannot disagree.\n */\nexport const COMMON_FORMATS = [\"pretty\", \"json\"] as const;\n\nexport type CommonFormat = (typeof COMMON_FORMATS)[number];\n\n/** `\"pretty or json\"`, for messages and help text. */\nexport const COMMON_FORMAT_LIST = formatList(COMMON_FORMATS);\n\nexport function isCommonFormat(value: string): value is CommonFormat {\n return (COMMON_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * The formats `query` accepts, one six-value list with per-value gates:\n * `pretty | json | csv` render result rows unconditionally (csv is proposal\n * 0029), and the findings three — `github | sarif | junit` — are legal only\n * under `--check` (proposal 0026).\n *\n * A list of its own rather than `REPORT_FORMATS`: `validate`'s list and\n * `query`'s grow independently — `csv` lives here and not there — and one\n * shared const would make every addition to either a change to both.\n */\nexport const QUERY_FORMATS = [\n \"pretty\",\n \"json\",\n \"csv\",\n \"github\",\n \"sarif\",\n \"junit\",\n] as const;\n\nexport type QueryFormat = (typeof QUERY_FORMATS)[number];\n\n/** `\"pretty, json, csv, github, sarif, or junit\"`, for messages and help. */\nexport const QUERY_FORMAT_LIST = formatList(QUERY_FORMATS);\n\nexport function isQueryFormat(value: string): value is QueryFormat {\n return (QUERY_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * The `query` formats that render **findings** rather than rows — legal only\n * with `--check`, and only when the result carries the `path` column the\n * finding convention is built from. Typed as its own union (not just a set\n * membership test) so the CLI's dispatch can hand a narrowed format straight\n * to `render`, which takes `ReportFormat` and has no `csv` case.\n */\nexport const QUERY_FINDINGS_FORMATS = [\n \"github\",\n \"sarif\",\n \"junit\",\n] as const satisfies readonly QueryFormat[];\n\nexport type QueryFindingsFormat = (typeof QUERY_FINDINGS_FORMATS)[number];\n\n/**\n * A *narrowing* guard on purpose: the CLI's query switch handles the findings\n * formats in an early return, and this is what lets its remaining cases stay\n * compile-time exhaustive over `pretty | json | csv` — a bare `Set.has` would\n * leave the union unnarrowed and force the `never` guard out.\n */\nexport function isQueryFindingsFormat(\n value: QueryFormat,\n): value is QueryFindingsFormat {\n return (QUERY_FINDINGS_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * Formats something other than a person reads.\n *\n * These own stdout completely: a diagnostic printed alongside them (which\n * config governed the run, say) would corrupt the parse. Colored escape codes\n * would too, which is why the same predicate answers both questions.\n */\nexport const MACHINE_FORMATS: ReadonlySet<ReportFormat> = new Set<ReportFormat>(\n [\"json\", \"github\", \"sarif\", \"junit\"],\n);\n\nexport const isMachineFormat = (format: ReportFormat): boolean =>\n MACHINE_FORMATS.has(format);\n\n/**\n * Formats whose output may legitimately be empty.\n *\n * `github` prints one annotation per finding, so a clean run has nothing to\n * say. Every other format has an **envelope** that must arrive even when it\n * holds nothing: a zero-byte SARIF file makes `upload-sarif` fail outright, and\n * a zero-byte JUnit file reads as a lost report rather than a passing one. So\n * emptiness is a property of the format, not of the text — which is what the\n * CLI's old bare `if (text.length > 0)` guard got wrong.\n */\nexport const OMITTED_WHEN_CLEAN: ReadonlySet<ReportFormat> =\n new Set<ReportFormat>([\"github\"]);\n\nexport interface ReportOptions extends SarifOptions, JunitOptions {\n color?: boolean;\n /** In pretty output, omit passing files. */\n quiet?: boolean;\n}\n\nexport type { FingerprintContext };\n\nconst plural = (n: number, one: string, many: string): string =>\n `${n} ${n === 1 ? one : many}`;\n\n/**\n * The baseline's line in the summary.\n *\n * A baseline is amnesty, and amnesty that goes quiet becomes permanent — so the\n * count is printed on **every** run, including the one where nothing was\n * forgiven, rather than only when something changes. The stale clause is what\n * makes a rename diagnosable: without it the user sees a wall of \"new\" findings\n * with no hint that the fix is a re-record.\n */\nfunction baselineLines(b: BaselineSummary): string[] {\n if (b.written) {\n const added = b.added ?? 0;\n const removed = b.removed ?? 0;\n return [\n `Baseline written to ${b.path}`,\n ` ${plural(b.recorded, \"finding\", \"findings\")} recorded (+${added} new, -${removed} ${\n removed === 1 ? \"no longer occurs\" : \"no longer occur\"\n })`,\n ];\n }\n const head = plural(b.recorded, \"baselined finding\", \"baselined findings\");\n if (b.stale === 0) return [head];\n const stale = b.stale === 1 ? \"1 no longer occurs\" : `${b.stale} no longer occur`;\n return [`${head}, ${stale} — run --write-baseline to prune`];\n}\n\nexport function renderPretty(\n results: ValidationResult[],\n summary: RunSummary,\n opts: ReportOptions = {},\n): string {\n const c = palette(opts.color ?? false);\n const lines: string[] = [];\n\n for (const r of results) {\n // What the baseline forgave here, so a passing file still shows its debt.\n const forgiven =\n r.baselined != null && r.baselined > 0\n ? c.dim(` (${r.baselined} baselined)`)\n : \"\";\n if (r.ok) {\n if (!opts.quiet) lines.push(`${c.green(\"✓\")} ${r.file}${forgiven}`);\n continue;\n }\n lines.push(`${c.red(\"✗\")} ${r.file}${forgiven}`);\n for (const e of r.errors) {\n // A value a manifest supplied is located in the manifest, not the\n // document, and the location says so (proposal 0037).\n const loc =\n e.file != null\n ? c.dim(` (${e.file}${e.line != null ? `:${e.line}` : \"\"})`)\n : e.line != null\n ? c.dim(` (line ${e.line})`)\n : \"\";\n lines.push(\n ` ${c.cyan(fieldLabel(e.instancePath))} ${e.message}${loc} ${c.dim(\n `[${e.schema}]`,\n )}`,\n );\n }\n }\n\n // Files `.gitignore` took away are named on the summary line, not left to be\n // inferred from a count that quietly shrank. A gate getting quieter without\n // being asked is the dangerous direction of change; this is what makes it\n // auditable. Omitted at zero, which is every run in a clean repo.\n const skipped =\n summary.gitignoreSkipped != null && summary.gitignoreSkipped > 0\n ? `, ${summary.gitignoreSkipped} skipped by .gitignore`\n : \"\";\n const summaryText = `${summary.files} file${summary.files === 1 ? \"\" : \"s\"} checked, ${summary.passed} passed, ${summary.failed} failed, ${summary.errors} error${summary.errors === 1 ? \"\" : \"s\"}${skipped}`;\n if (lines.length > 0) lines.push(\"\");\n lines.push(summary.failed > 0 ? c.red(summaryText) : c.green(summaryText));\n if (summary.baseline) {\n for (const l of baselineLines(summary.baseline)) lines.push(c.dim(l));\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderJson(\n results: ValidationResult[],\n summary: RunSummary,\n): string {\n return JSON.stringify({ summary, results }, null, 2);\n}\n\nexport function renderGithub(results: ValidationResult[]): string {\n const lines: string[] = [];\n for (const r of results) {\n for (const e of r.errors) {\n const params = [`file=${escapeWorkflowCommandProperty(e.file ?? r.file)}`];\n if (e.line != null) params.push(`line=${e.line}`);\n if (e.col != null) params.push(`col=${e.col}`);\n // Escaped as one string, after assembly: the schema id and the field\n // label are as capable of carrying a `%` as the message is.\n const msg = escapeWorkflowCommandMessage(\n `[${e.schema}] ${fieldLabel(e.instancePath)} ${e.message}`,\n );\n lines.push(`::error ${params.join(\",\")}::${msg}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nexport function render(\n format: ReportFormat,\n results: ValidationResult[],\n summary: RunSummary,\n opts: ReportOptions = {},\n): string {\n switch (format) {\n case \"json\":\n return renderJson(results, summary);\n case \"github\":\n return renderGithub(results);\n case \"sarif\":\n return renderSarif(results, opts);\n case \"junit\":\n return renderJunit(results, opts);\n case \"pretty\":\n return renderPretty(results, summary, opts);\n default: {\n // Exhaustive: adding a format to `REPORT_FORMATS` without a case here is\n // a compile error. The throw is for the runtime half — `render` is public\n // API, and before this existed a caller passing \"sarif\" fell through to\n // `pretty` and got a human report where it asked for a machine one.\n const unreachable: never = format;\n throw new DocmetaError(\n `Unknown report format ${JSON.stringify(unreachable)}. Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n }\n}\n","/**\n * Reporter for `fill`.\n *\n * `render()` in ./index.ts is keyed to ValidationResult/RunSummary, so `fill`\n * gets its own renderer rather than a fourth branch there. The colour palette is\n * shared, so NO_COLOR and TTY behaviour stay identical across commands.\n *\n * The report always states the threshold and names the fields that fell below\n * it. A skipped field that is invisible is indistinguishable from a field the\n * model never considered, and the difference matters to whoever has to fill it\n * in by hand.\n */\nimport { DocmetaError } from \"../types.js\";\nimport type { FillRun } from \"../commands/fill-types.js\";\nimport { toJsonText } from \"../core/json-text.js\";\nimport { palette } from \"./color.js\";\nimport {\n escapeWorkflowCommandMessage,\n escapeWorkflowCommandProperty,\n} from \"./github.js\";\nimport { formatList } from \"./index.js\";\n\n/**\n * Every value `fill -f` accepts, in the order help and error messages list\n * them. Derived union, one statement of the list — the same rule\n * `REPORT_FORMATS` documents at length in ./index.ts, which this file used to\n * break by spelling `\"pretty\" | \"json\"` out a second time.\n *\n * `sarif` and `junit` are deliberately absent: they describe *findings in\n * files*, and a skipped optional property is a proposal with a confidence\n * score, not a finding. See 0003 § stress test 8.\n */\nexport const FILL_FORMATS = [\"pretty\", \"json\", \"github\"] as const;\n\nexport type FillReportFormat = (typeof FILL_FORMATS)[number];\n\n/** `\"pretty, json, or github\"`, for messages and help text. */\nexport const FILL_FORMAT_LIST = formatList(FILL_FORMATS);\n\nexport function isFillFormat(value: string): value is FillReportFormat {\n return (FILL_FORMATS as readonly string[]).includes(value);\n}\n\nexport interface FillReportOptions {\n color?: boolean;\n /**\n * In pretty output, omit files with nothing to report.\n *\n * \"Nothing\" is narrow on purpose — see `renderFillPretty`.\n */\n quiet?: boolean;\n}\n\nexport function renderFillJson(run: FillRun): string {\n return JSON.stringify(run, null, 2);\n}\n\nconst score = (n: number): string => n.toFixed(2);\n\nexport function renderFillPretty(\n run: FillRun,\n opts: FillReportOptions = {},\n): string {\n const c = palette(opts.color ?? false);\n const lines: string[] = [];\n\n for (const result of run.results) {\n if (result.error != null) {\n lines.push(`${c.red(\"✗\")} ${result.file}`);\n lines.push(` ${result.error}`);\n continue;\n }\n if (result.fields.length === 0) continue;\n\n const written = result.fields.filter((f) => f.written);\n // What `--quiet` may hide, and it is a short list. \"Files with no\n // proposals\" would be a no-op — the guard above already drops those — so\n // the only files left to drop are the ones with nothing *written*, and\n // those are precisely the files carrying a required skip, which is what\n // makes the run exit 1. Hiding them would hide the reason for the failure,\n // so a required skip (like an error, handled above) always prints.\n const requiredSkipped = result.fields.some((f) => f.required && !f.written);\n if (opts.quiet && written.length === 0 && !requiredSkipped) continue;\n const low = result.fields.filter((f) => f.skipReason === \"low-confidence\");\n const other = result.fields.filter(\n (f) => !f.written && f.skipReason !== \"low-confidence\",\n );\n\n const mark = written.length > 0 ? c.green(\"✓\") : c.dim(\"·\");\n lines.push(`${mark} ${result.file}`);\n for (const f of written) {\n lines.push(\n ` ${c.cyan(f.field)} ${formatValue(f.value)} ${c.dim(score(f.confidence))}`,\n );\n }\n if (low.length > 0) {\n lines.push(\n c.dim(\n ` below ${run.threshold}: ${low\n .map((f) => `${f.field} ${score(f.confidence)}`)\n .join(\", \")}`,\n ),\n );\n }\n for (const f of other) {\n lines.push(c.dim(` ${f.skipReason ?? \"skipped\"}: ${f.field}`));\n }\n }\n\n const { summary } = run;\n const verb = run.dryRun ? \"would be written\" : \"written\";\n const parts = [\n // Which provider ran decides what the proposals and the cost mean, and\n // under `auto` it is not something the user chose — so say it rather than\n // making them pass -f json to find out.\n `${run.provider}/${run.model}`,\n `Threshold ${run.threshold}`,\n `${summary.files} file${summary.files === 1 ? \"\" : \"s\"}`,\n `${summary.written} field${summary.written === 1 ? \"\" : \"s\"} ${verb}`,\n `${summary.skipped} skipped`,\n ];\n if (summary.errors > 0) parts.push(`${summary.errors} errored`);\n if (summary.cached > 0) parts.push(`${summary.cached} cached`);\n // claude-cli reports no token usage, so a $0.00 there means \"unknown\", not\n // \"free\" — say nothing rather than imply a verified zero.\n if (summary.costUsd > 0) parts.push(`$${summary.costUsd.toFixed(4)}`);\n\n if (lines.length > 0) lines.push(\"\");\n const footer = parts.join(\" · \");\n lines.push(summary.requiredSkipped > 0 ? c.yellow(footer) : footer);\n\n if (summary.requiredSkipped > 0) {\n lines.push(\n c.yellow(\n `${summary.requiredSkipped} required field${summary.requiredSkipped === 1 ? \"\" : \"s\"} could not be filled confidently — fill ${summary.requiredSkipped === 1 ? \"it\" : \"them\"} in by hand.`,\n ),\n );\n }\n if (run.turnsSpent) {\n lines.push(\n c.yellow(\"--max-turns reached; some files were not processed.\"),\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Named to avoid shadowing `renderFill`'s `format` parameter. */\nfunction formatValue(value: unknown): string {\n if (typeof value === \"string\") return value;\n // `toJsonText`, not `JSON.stringify`, so the `String(value)` fallback stays\n // visibly reachable — see there.\n return toJsonText(value) ?? String(value);\n}\n\n/**\n * GitHub Actions annotations for the work `fill` could **not** do.\n *\n * One `::error` per property the schema requires that was not filled — the same\n * set that drives `fill`'s exit code 1. Optional skips stay silent, matching\n * the exit-code rule: a skipped optional property is a normal outcome, and\n * annotating it would make every run look broken.\n *\n * No `line=`. A `FilledField` carries no location — unlike a validation error,\n * a proposal is about a property that is *missing* from the document, so there\n * is nothing to point at. GitHub anchors a file-only annotation to line 1.\n *\n * The escaping is `escapeWorkflowCommandMessage`, shared with `validate`'s\n * renderer rather than re-derived: the `%`-before-newline ordering is the part\n * that is easy to get wrong.\n */\nexport function renderFillGithub(run: FillRun): string {\n const lines: string[] = [];\n for (const result of run.results) {\n const file = escapeWorkflowCommandProperty(result.file);\n // A file-level error — an unparseable document, a read-only format, a\n // provider failure — counts toward `summary.errors` and so drives exit 1\n // exactly as a required skip does. Emitting nothing for it left a red run\n // with no annotation anywhere: CI fails, and the Files tab is clean.\n if (result.error != null) {\n lines.push(\n `::error file=${file}::${escapeWorkflowCommandMessage(`[fill] ${result.error}`)}`,\n );\n continue;\n }\n for (const f of result.fields) {\n if (!f.required || f.written) continue;\n const why =\n f.skipReason === \"low-confidence\"\n ? `confidence ${score(f.confidence)} is below the ${run.threshold} threshold`\n : (f.skipReason ?? \"skipped\");\n const msg = escapeWorkflowCommandMessage(\n `[fill] ${f.field} is required and was not filled (${why})`,\n );\n lines.push(`::error file=${file}::${msg}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nexport function renderFill(\n format: FillReportFormat,\n run: FillRun,\n opts: FillReportOptions = {},\n): string {\n switch (format) {\n case \"json\":\n return renderFillJson(run);\n case \"github\":\n return renderFillGithub(run);\n case \"pretty\":\n return renderFillPretty(run, opts);\n default: {\n // Exhaustive, like `render()`: adding a format to `FILL_FORMATS` without\n // a case here is a compile error, and the throw covers the runtime half —\n // `renderFill` is public API, and a caller asking for a machine format\n // must not be handed a human report instead.\n const unreachable: never = format;\n throw new DocmetaError(\n `Unknown report format ${JSON.stringify(unreachable)}. Use ${FILL_FORMAT_LIST}.`,\n );\n }\n }\n}\n","/**\n * Reporter for `derive`.\n *\n * Two shapes, decided by the run. An apply or dry run reports *changes* —\n * what each field went from and to, with the evidence — and has its own\n * `pretty` and `json`. A `--check` run reports *findings*, and every format\n * including `pretty` and `json` is handed to `render()` in ./index.ts, so\n * `github`, `sarif` and `junit` come for free and a stale stamp lands in the\n * same annotation, rule id (`derived:stale/derived`) and JUnit case shape a\n * schema violation does. That is why the findings formats are refused\n * without `--check`: they describe findings, and only `--check` produces any.\n */\nimport { DocmetaError, type RunSummary, type ValidationResult } from \"../types.js\";\nimport type { DeriveFileResult, DeriveRun } from \"../commands/derive.js\";\nimport type { DerivedField } from \"../core/derive/types.js\";\nimport { toJsonText } from \"../core/json-text.js\";\nimport { palette } from \"./color.js\";\nimport { formatList, render, type ReportOptions } from \"./index.js\";\n\n/**\n * Every value `derive -f` accepts: the same five as `validate`, because a\n * `--check` run renders through validate's reporters. Stated as its own list\n * so the two can grow apart without either edit reaching the other.\n */\nexport const DERIVE_FORMATS = [\"pretty\", \"json\", \"github\", \"sarif\", \"junit\"] as const;\n\nexport type DeriveReportFormat = (typeof DERIVE_FORMATS)[number];\n\n/** `\"pretty, json, github, sarif, or junit\"`, for messages and help text. */\nexport const DERIVE_FORMAT_LIST = formatList(DERIVE_FORMATS);\n\nexport function isDeriveFormat(value: string): value is DeriveReportFormat {\n return (DERIVE_FORMATS as readonly string[]).includes(value);\n}\n\n/** The JUnit `classname` a derive finding ships under, not validate's. */\nconst JUNIT_CLASSNAME = \"manni.derive\";\n\nexport type DeriveReportOptions = ReportOptions;\n\nexport function renderDerive(\n run: DeriveRun,\n format: DeriveReportFormat,\n opts: DeriveReportOptions = {},\n): string {\n if (run.check) {\n const { results, summary } = asValidation(run);\n return render(format, results, summary, {\n classname: JUNIT_CLASSNAME,\n ...opts,\n });\n }\n switch (format) {\n case \"json\":\n return JSON.stringify(run, null, 2);\n case \"pretty\":\n return renderDerivePretty(run, opts);\n case \"github\":\n case \"sarif\":\n case \"junit\":\n throw new DocmetaError(\n `${format} is a findings format, which only --check produces`,\n );\n default: {\n // Exhaustive, like `render()`: a format added to `DERIVE_FORMATS`\n // without a case here is a compile error, and the throw covers a\n // caller of the public API handing in a string the union does not name.\n const unreachable: never = format;\n throw new DocmetaError(\n `Unknown report format ${JSON.stringify(unreachable)}. Use ${DERIVE_FORMAT_LIST}.`,\n );\n }\n }\n}\n\n/** A `--check` run as `validate` would report it: one result per file, its findings as errors. */\nfunction asValidation(run: DeriveRun): { results: ValidationResult[]; summary: RunSummary } {\n const results = run.results.map((r): ValidationResult => {\n const errors = r.findings ?? [];\n return { file: r.file, format: r.format, ok: errors.length === 0, schemas: [], errors };\n });\n const failed = results.filter((r) => !r.ok).length;\n return {\n results,\n summary: {\n files: results.length,\n passed: results.length - failed,\n failed,\n errors: results.reduce((n, r) => n + r.errors.length, 0),\n },\n };\n}\n\nconst plural = (n: number, noun: string): string => `${n} ${noun}${n === 1 ? \"\" : \"s\"}`;\n\nexport function renderDerivePretty(run: DeriveRun, opts: DeriveReportOptions = {}): string {\n const c = palette(opts.color ?? false);\n const lines: string[] = [];\n\n for (const result of run.results) {\n if (result.error !== undefined) {\n lines.push(`${c.red(\"✗\")} ${result.file}`);\n lines.push(` ${result.error}`);\n continue;\n }\n const pending = result.fields.filter((f) => f.status === \"stale\" || f.status === \"unset\");\n if (pending.length === 0) {\n if (opts.quiet) continue;\n lines.push(`${result.file} ${c.dim(\"current\")}${unknownNote(result, c.dim)}`);\n continue;\n }\n lines.push(result.file);\n const nameWidth = Math.max(...pending.map((f) => f.field.length));\n const changeWidth = Math.max(...pending.map((f) => change(f).length));\n for (const f of pending) {\n const name = c.cyan(f.field.padEnd(nameWidth));\n const from = f.status === \"unset\" ? c.dim(\"(unset)\") : c.dim(fmt(f.asserted));\n const to = c.green(fmt(f.derived));\n const pad = \" \".repeat(changeWidth - change(f).length);\n const trail = c.dim(`(${f.source ?? \"a source\"}: ${f.evidence ?? \"no evidence\"})`);\n lines.push(` ${name} ${from} → ${to}${pad} ${trail}`);\n }\n const note = unknownNote(result, c.dim);\n if (note !== \"\") lines.push(` ${note}`);\n }\n\n const s = run.summary;\n const parts = [plural(s.files, \"file\")];\n if (run.dryRun) {\n parts.push(`${s.changed} would change`, plural(s.stale + s.unset, \"field\"));\n } else {\n parts.push(`${s.changed} changed`, `${plural(s.written, \"field\")} written`);\n }\n if (s.errors > 0) parts.push(plural(s.errors, \"error\"));\n let footer = parts.join(\", \");\n if (run.dryRun) footer += \" — dry run, nothing written\";\n\n if (lines.length > 0) lines.push(\"\");\n lines.push(s.errors > 0 ? c.yellow(footer) : footer);\n return lines.join(\"\\n\");\n}\n\n/** `from → to` uncolored, for measuring the column. */\nfunction change(f: DerivedField): string {\n const from = f.status === \"unset\" ? \"(unset)\" : fmt(f.asserted);\n return `${from} → ${fmt(f.derived)}`;\n}\n\n/** Which of a file's fields no source could answer, so silence is not mistaken for agreement. */\nfunction unknownNote(result: DeriveFileResult, dim: (s: string) => string): string {\n const unknown = result.fields.filter((f) => f.status === \"unknown\").map((f) => f.field);\n if (unknown.length === 0) return \"\";\n return dim(` (${unknown.join(\", \")}: no source could answer)`);\n}\n\n/** Strings bare, everything else as compact JSON. */\nfunction fmt(value: unknown): string {\n if (typeof value === \"string\") return value;\n // `toJsonText`, not `JSON.stringify`, so the `String(value)` fallback stays\n // visibly reachable — see there.\n return toJsonText(value) ?? String(value);\n}\n","/**\n * Reporter for `get`.\n *\n * `render()` in ./index.ts is keyed to ValidationResult/RunSummary, so `get`\n * gets its own renderer, exactly as `fill` does. It lived inline in\n * `src/cli.ts` until `--quiet` arrived and made the question \"who decides what\n * is printed?\" answerable in two places at once.\n *\n * `--quiet` is a **reporter** concern, not a core one. `GetOptions` /\n * `GetFileResult` are public API, and a programmatic caller handed a silently\n * filtered array cannot tell a filtered run from an empty one — so `runGet`\n * returns every file it read, and the filtering happens here, where it only\n * affects text a person is reading.\n */\nimport type { GetFileResult } from \"../commands/get.js\";\nimport { compareDerived, type DerivedValue } from \"../core/derive/types.js\";\nimport { palette } from \"./color.js\";\n\nexport interface GetReportOptions {\n color?: boolean;\n /** In pretty output, omit files where every requested field is unset. */\n quiet?: boolean;\n}\n\n/** `(unset)` for a missing field; JSON for anything that is not a string. */\nexport function stringifyValue(value: unknown): string {\n if (value === undefined) return \"(unset)\";\n if (typeof value === \"string\") return value;\n return JSON.stringify(value);\n}\n\n/**\n * The evidence as the source wrote it, so the reader can check the claim\n * without re-running — minus a trailing `(<value>)` that repeats the derived\n * value, since the value is already on the line. The git source spells a date\n * fact `body changed in 424f71a (2026-09-07)` so that it stands alone in\n * `query`'s `_sources` column, where nothing else names the date.\n */\nfunction evidenceOf(d: DerivedValue): string {\n const repeated = ` (${stringifyValue(d.value)})`;\n return d.evidence.endsWith(repeated)\n ? d.evidence.slice(0, -repeated.length)\n : d.evidence;\n}\n\n/**\n * The annotation after a resolved value (proposal 0043): which side the value\n * came from, and — when the two sides disagree — what the other one says.\n * Five cases, and only five:\n *\n * 1. asserted, with no derived value or no derivable field → `(asserted)`\n * 2. nothing asserted, a source answered → `(derived, <source>: <evidence>)`\n * 3. both, agreeing as `validate` judges it → `(asserted)`\n * 4. both, disagreeing → `(asserted; <source> says <value>, <evidence>)`\n * 5. neither → nothing at all; the value already prints `(unset)`\n *\n * Case 4 is the drift `validate` files as `derived:stale`. The asserted value\n * is what prints, because that is what the page publishes, and the evidence\n * is named beside it rather than in place of it.\n */\nfunction annotation(r: GetFileResult, field: string): string {\n const origin = r.origin?.[field];\n if (origin === undefined) return \"\";\n const d = r.derived?.[field] ?? null;\n if (origin === \"derived\") {\n // Unreachable with null evidence — `origin` only says `derived` when a\n // source answered — but the record is public API, so a caller that built\n // one by hand gets a plain line rather than a crash.\n return d == null ? \"\" : ` (derived, ${d.source}: ${evidenceOf(d)})`;\n }\n if (d == null) return \" (asserted)\";\n // Judged as `validate` judges it, with lists as multisets, so the two can\n // never disagree about whether a value is drift.\n if (compareDerived(field, r.resolved?.[field], d).status === \"current\") {\n return \" (asserted)\";\n }\n return ` (asserted; ${d.source} says ${stringifyValue(d.value)}, ${evidenceOf(d)})`;\n}\n\n/**\n * One `<file>: <field>=<value>` line per requested field per file. The value\n * is the **resolved** one where the run derived (proposal 0043), followed by\n * the annotation saying which side answered; under `--no-derived` it is what\n * the document stores, with no annotation at all.\n *\n * `quiet` hides a file only when **every** requested field is unset, judged\n * after resolving — so a page whose only `owner` comes from CODEOWNERS is\n * shown, where before the flag hid it. A file where one field resolved and\n * another did not is still printed, `(unset)` included: the flag hides files,\n * never values, so `--quiet` can never be the reason a value the user asked\n * for went missing.\n */\nexport function renderGet(\n results: GetFileResult[],\n fields: string[],\n opts: GetReportOptions = {},\n): string {\n const c = palette(opts.color ?? false);\n const lines: string[] = [];\n for (const r of results) {\n // Checked before `quiet`, deliberately. An unparseable file resolves no\n // values, so the quiet rule below would hide the one file the reader most\n // needs to see — and `--quiet` must never be the reason a missing value\n // goes unexplained, which is the same rule that keeps it hiding files\n // rather than values.\n if (r.error !== undefined) {\n lines.push(`${c.dim(`${r.file}:`)} ${c.red(`(parse) ${r.error}`)}`);\n continue;\n }\n // What the line reports: the resolved value where the run derived, and\n // what the document stores where it did not. `--quiet` reads the same\n // record, so it hides a file only when nothing at all answered for it.\n const effective = r.resolved ?? r.values;\n if (opts.quiet && fields.every((f) => effective[f] === undefined)) continue;\n for (const f of fields) {\n const note = annotation(r, f);\n const suffix = note === \"\" ? \"\" : c.dim(note);\n lines.push(\n `${c.dim(`${r.file}:`)} ${f}=${stringifyValue(effective[f])}${suffix}`,\n );\n }\n }\n return lines.join(\"\\n\");\n}\n","/**\n * Reporter for `query`.\n *\n * Same split as `get`: `runQuery` returns every row, and presentation —\n * alignment, the row count, the `--check` verdict — happens here, where it\n * only affects text a person is reading. `json` output never passes through\n * this module; the CLI prints the bare row array, mirroring `get`'s bare\n * array, and the exit code (not the envelope) carries the `--check` verdict.\n */\nimport type { QueryChange, QueryRun } from \"../commands/query.js\";\nimport { palette, type Colors } from \"./color.js\";\nimport { stringifyValue } from \"./get.js\";\n\nexport interface QueryReportOptions {\n color?: boolean;\n /** `--check`: append a ✓/✗ verdict line instead of the plain count. */\n check?: boolean;\n /** `--dry-run` (or `--check`): the changes were previewed, not applied. */\n dryRun?: boolean;\n}\n\n/**\n * SQL NULL prints as `(null)`; everything else as `get` prints values —\n * except a bigint, which a SQL expression can hand back and which\n * `stringifyValue`'s JSON.stringify would throw on.\n */\nfunction cell(value: unknown): string {\n if (value === null) return \"(null)\";\n return typeof value === \"bigint\" ? String(value) : stringifyValue(value);\n}\n\n/**\n * An aligned table (header + rows) and a trailing count line. The last column\n * is never padded, so no line carries trailing spaces. A metadata edit\n * renders as its per-file diff instead of a row table (0022).\n */\nexport function renderQuery(\n run: QueryRun,\n opts: QueryReportOptions = {},\n): string {\n const c = palette(opts.color ?? false);\n if (run.changes) return renderChanges(run.changes, c, opts);\n const lines: string[] = [];\n if (run.rows.length > 0) {\n const widths = run.columns.map((col) =>\n Math.max(col.length, ...run.rows.map((r) => cell(r[col]).length)),\n );\n const pad = (text: string, i: number): string =>\n i === run.columns.length - 1 ? text : text.padEnd(widths[i] ?? 0);\n lines.push(run.columns.map((col, i) => c.bold(pad(col, i))).join(\" \"));\n for (const row of run.rows) {\n lines.push(run.columns.map((col, i) => pad(cell(row[col]), i)).join(\" \"));\n }\n }\n const n = run.rows.length;\n const count = `${n} row${n === 1 ? \"\" : \"s\"}`;\n lines.push(\n opts.check\n ? n > 0\n ? c.red(`✗ ${count} — check failed`)\n : c.green(`✓ ${count}`)\n : c.dim(count),\n );\n return lines.join(\"\\n\");\n}\n\n/**\n * CSV over result rows (proposal 0029). The dialect, chosen once:\n *\n * - header row always — a zero-row result is the header alone, which a script\n * can tell apart from an error that printed nothing;\n * - LF line endings — a deliberate divergence from RFC 4180's CRLF, named in\n * the reference; quoting itself is RFC 4180 (a field containing a comma,\n * quote, or newline is quoted, and quotes double);\n * - SQL `NULL` → empty field;\n * - arrays and objects stay the JSON text the projection already holds.\n *\n * Rows only, by contract: changes are heterogeneous per-file diffs, not a\n * table, and the CLI refuses them before this is called.\n */\n/** A CSV field needing quoting: it contains a comma, quote, or newline. */\nconst CSV_NEEDS_QUOTING = /[\",\\n\\r]/;\n\nexport function renderQueryCsv(\n run: Pick<QueryRun, \"columns\" | \"rows\">,\n): string {\n const field = (value: unknown): string => {\n if (value === null || value === undefined) return \"\";\n const text =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"bigint\"\n ? String(value)\n : stringifyValue(value); // a BLOB or other oddity, `get`'s way\n return CSV_NEEDS_QUOTING.test(text)\n ? `\"${text.replaceAll('\"', '\"\"')}\"`\n : text;\n };\n return [\n run.columns.map(field).join(\",\"),\n ...run.rows.map((row) => run.columns.map((c) => field(row[c])).join(\",\")),\n ].join(\"\\n\");\n}\n\n/**\n * `<file>: <key>: <from> -> <to>` per changed cell, then the verdict: what\n * was written, what a preview would write, or the ✓/✗ of a `--check` drift\n * gate. `from` is `(unset)` when the file had no value for the key.\n */\nfunction renderChanges(\n changes: QueryChange[],\n c: Colors,\n opts: QueryReportOptions,\n): string {\n const lines = changes.map((ch) => {\n if (\"config\" in ch) {\n return `${c.dim(`config ${ch.file}:`)} ${ch.key}: ${cellFrom(ch.from)} -> ${cell(ch.to)}`;\n }\n if (\"schema\" in ch) {\n const fork = ch.forkedFrom ? ` ${c.dim(`(forked from ${ch.forkedFrom})`)}` : \"\";\n if (ch.op === \"rename\") {\n return `${c.dim(`schema ${ch.file}:`)} ${ch.key} -> ${ch.renamedTo ?? ch.key}${fork}`;\n }\n if (ch.op === \"drop\") {\n return `${c.dim(`schema ${ch.file}:`)} - ${ch.key}${fork}`;\n }\n // The whole resulting property, format and enum included, so a\n // near-miss (`DUE-DATE` mapping to nothing) is visible as an\n // unconstrained `+ key` before anything is written (0028).\n const detail = [\n ch.type,\n ch.format !== undefined ? `format ${ch.format}` : undefined,\n // JSON spellings, so the numeric enum [1] and the string enum [\"1\"]\n // read as the distinct properties they are.\n ch.enum !== undefined\n ? `enum [${ch.enum.map((v) => JSON.stringify(v)).join(\", \")}]`\n : undefined,\n ch.required ? \"required\" : undefined,\n ]\n .filter(Boolean)\n .join(\", \");\n return `${c.dim(`schema ${ch.file}:`)} + ${ch.key}${detail ? ` (${detail})` : \"\"}${fork}`;\n }\n if (\"cleared\" in ch) {\n return `${c.dim(`${ch.file}:`)} (frontmatter removed: ${Object.keys(ch.from).join(\", \")})`;\n }\n if (\"created\" in ch) {\n const kv = Object.entries(ch.to)\n .map(([k, v]) => `${k}=${cell(v)}`)\n .join(\", \");\n return `${c.dim(`${ch.file}:`)} (created: ${kv})`;\n }\n if (\"renamed\" in ch) {\n return `${c.dim(`${ch.file} ->`)} ${ch.renamed} ${c.dim(\"(moved)\")}`;\n }\n if (\"renamedFrom\" in ch) {\n return `${c.dim(`${ch.file}:`)} ${ch.renamedFrom} -> ${ch.key} ${c.dim(\"(key renamed)\")}`;\n }\n if (\"deleted\" in ch) {\n return `${c.dim(`${ch.file}:`)} ${ch.key}: ${cellFrom(ch.from)} -> (deleted)`;\n }\n return `${c.dim(`${ch.file}:`)} ${ch.key}: ${cellFrom(ch.from)} -> ${cell(ch.to)}`;\n });\n const n = changes.length;\n // Deliberately counts every file the run touches — schema and config\n // included: they are writes the user is approving, and a pure DDL edit\n // reporting \"across 0 files\" would claim less than it does.\n const files = new Set(changes.map((ch) => ch.file)).size;\n const count = `${n} change${n === 1 ? \"\" : \"s\"} across ${files} file${files === 1 ? \"\" : \"s\"}`;\n // `--check` outranks the dry-run hint: it implies the dry run, and its\n // verdict is the line the exit code answers to.\n if (opts.check) {\n lines.push(\n n > 0 ? c.red(`✗ ${count} — check failed`) : c.green(\"✓ 0 changes\"),\n );\n } else if (opts.dryRun) {\n lines.push(\n n > 0\n ? `${count} — ${c.dim(\"dry run; run again without --dry-run to apply\")}`\n : c.dim(\"0 changes\"),\n );\n } else {\n lines.push(n > 0 ? c.green(`✓ ${count} — written`) : c.dim(\"0 changes\"));\n }\n return lines.join(\"\\n\");\n}\n\n/** A preview's `from`: `(unset)` only for a key the file never had. */\nfunction cellFrom(value: unknown): string {\n return value === undefined ? \"(unset)\" : cell(value);\n}\n"],"mappings":"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","names":["picomatch","parsed","name","posix","picomatch","resolve","stat","join","join","stat","createHash","readFile","Buffer","text","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","__default","wait","resolve","name","text","Buffer","parsed","readFile","memberOf","RETRY_DELAY_MS","isAbort","stripBom","parsed","parseDocument","isMap","parseToml","parseDocument","isMap","parsed","TOML_KEY","TOML_TABLE","text","parseToml","name","parseYamlScalar","typeValue","parseYamlScalar","text","under","name","parseYamlScalar","elementName","attr","name","name","byExtension","isMap","attr","typeValue","parseYamlScalar","name","text","attr","name","open","attr","items","name","attr","anchor","open","DQ","next","verify","attr","text","parseYamlScalar","typeValue","parseYamlScalar","name","text","source","stringifyYaml","name","escapeAttr","DQ","emitScalar","elementTextEdit","insertEdit","spliceAll","verify","attrValueSpan","open","text","stringifyYaml","name","readFile","isAbsolute","relative","resolve","sep","LineCounter","isMap","isScalar","parseDocument","stat","relative","resolve","picomatch","dirname","relative","resolve","dirname","join","resolve","resolve","dirname","relative","stat","resolve","relative","found","picomatch","sep","relative","text","isAbsolute","resolve","join","readFile","LineCounter","parseDocument","isScalar","isMap","memberOf","deepEqual","resolve","parseYaml","readFile","dirname","join","relative","resolve","text","readFile","relative","resolve","name","join","dirname","rejectUnknownKeys","parsed","text","parseYaml","run","git","resolve","isAbsolute","relative","resolvePath","sep","name","j","tokens","text","relative","resolvePath","sep","isAbsolute","name","name","createHash","join","change","spawn","DEFAULT_TIMEOUT_MS","text","text","unavailable","resolvePath","parsed","project","name","DEFAULT_TIMEOUT_MS","isRecord","resolvePath","change","dirname","resolve","existsSync","readFile","dirname","relative","resolve","sep","picomatch","resolve","existsSync","text","name","owners","matcherCache","picomatch","dirname","parsed","toPosix","relative","readFile","sep","spawn","dirname","extname","relative","sep","run","dirname","relative","sep","text","name","extname","spawn","name","git","dirname","unavailable","resolve","existsSync","readFile","resolve","extname","createHash","readFile","relative","resolve","relative","resolve","createHash","text","readFile","name","text","tokens","resolve","existsSync","name","readFile","extname","applied","readFile","resolve","extname","derivableFields","own","resolve","readFile","extname","run","existsSync","mkdir","readFile","dirname","extname","isAbsolute","join","relative","resolve","sep","parseDocument","parseYaml","relative","sep","parsed","name","text","parseDocument","parseYaml","resolve","join","isAbsolute","existsSync","readFile","mkdir","dirname","stat","extname","existsSync","mkdir","readFile","rename","rm","dirname","isAbsolute","resolve","extname","sep","parseDocument","isMap","isSeq","isScalar","own","readFile","resolve","extname","run","name","rm","mkdir","dirname","text","open","i","cell","isAbsolute","parsed","existsSync","parseDocument","isScalar","isMap","isSeq","keyOf","sep","rename","readFile","resolve","extname","join","join","run","merged","resolve","readFile","extname","own","name","items","readFile","extname","resolve","resolve","extname","readFile","name","errorResult","summarize","isAbsolute","isAbsolute","name","open","run","run","plural","name","fmt","run","text"]}