mason-context 0.17.1 → 0.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/mason-audit.js +127 -34
- package/dist/mason-audit.js.map +1 -1
- package/dist/mason-auto.js +309 -99
- package/dist/mason-auto.js.map +1 -1
- package/dist/mason-mcp.js +235 -93
- package/dist/mason-mcp.js.map +1 -1
- package/dist/mason.js +342 -117
- package/dist/mason.js.map +1 -1
- package/package.json +1 -1
package/dist/mason-audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/paths.ts","../src/utils/files.ts","../src/utils/storage.ts","../src/test-map.ts","../src/snapshot/snapshot.ts","../src/drift/drift.ts","../src/audit/commands.ts","../src/audit/tree.ts","../src/audit/claims.ts","../src/audit/git.ts","../src/audit/inputs.ts","../src/audit/docs.ts","../src/audit/types.ts","../src/audit/scope.ts","../src/audit/checks/deleted-reference.ts","../src/audit/checks/new-module.ts","../src/audit/checks/stale-count.ts","../src/audit/checks/dead-command.ts","../src/audit/release-metadata.ts","../src/audit/checks/deps-changed.ts","../src/context/lexical.ts","../src/context/trust.ts","../src/decisions/provenance.ts","../src/decisions/decisions.ts","../src/decisions/drift.ts","../src/audit/checks/decision-anchor.ts","../src/audit/checks/index.ts","../src/audit/findings.ts","../src/automation/store.ts","../src/audit/repair.ts","../src/audit/advisory-review.ts","../src/audit/audit.ts","../src/audit/cli.ts","../src/audit/advisory-cli.ts","../bin/mason-audit.ts"],"sourcesContent":["import path from \"node:path\";\n\n/** One canonical representation for stored paths and decision anchors. */\nexport function normalizeRepoPath(value: string): string | null {\n const slash = value.replace(/\\\\/g, \"/\");\n if (!slash || slash.includes(\"\\0\") || path.posix.isAbsolute(slash) || /^[A-Za-z]:/.test(slash)) return null;\n if (slash.split(\"/\").includes(\"..\")) return null;\n const normalized = path.posix.normalize(slash).replace(/\\/$/, \"\");\n return normalized === \".\" ? null : normalized;\n}\n\nexport function sanitizeRepoPaths(files: string[]): string[] {\n return [...new Set(files.map(normalizeRepoPath).filter((p): p is string => p !== null))];\n}\n\nexport function isWithinRoot(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative !== \"..\" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);\n}\n\nexport function anchorMatches(anchor: string, file: string): boolean {\n const a = normalizeRepoPath(anchor);\n const f = normalizeRepoPath(file);\n return a !== null && f !== null && (a === f || f.startsWith(`${a}/`));\n}\n\nexport function matchingPaths(anchors: string[], files: Iterable<string>): string[] {\n return [...new Set(files)].filter(file => anchors.some(anchor => anchorMatches(anchor, file)));\n}\n","import fs from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport fg from \"fast-glob\";\nimport { isWithinRoot, normalizeRepoPath } from \"./paths.js\";\n\nconst exec = promisify(execFile);\nexport const SOURCE_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"mts\", \"cts\", \"mjs\", \"cjs\", \"vue\", \"svelte\", \"kt\", \"kts\", \"java\", \"py\", \"go\", \"rs\", \"swift\", \"rb\", \"cs\", \"cpp\", \"c\", \"h\", \"hpp\", \"dart\", \"php\"];\nexport const SOURCE_GLOB = `**/*.{${SOURCE_EXTENSIONS.join(\",\")}}`;\nexport const SOURCE_IGNORE = [\n \"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.gradle/**\",\n \"**/target/**\", \"**/.git/**\", \"**/.mason/**\", \"**/vendor/**\", \"**/__pycache__/**\",\n \"**/venv/**\", \"**/.venv/**\", \"**/*.min.*\", \"**/*.map\", \"**/*.lock\",\n \"**/generated/**\", \"**/*.generated.*\", \"**/R.java\", \"**/BuildConfig.java\",\n \"**/package-lock.json\", \"**/yarn.lock\", \"**/pnpm-lock.yaml\",\n];\nexport const MAX_SOURCE_BYTES = 1024 * 1024;\nexport interface ProjectConfig { patterns?: string[]; alwaysInclude?: string[]; ignore?: string[] }\nexport interface SourceFile { path: string; content: string; totalLines: number }\n\nexport function isSensitiveFile(file: string): boolean {\n return file.split(/[\\\\/]/).some(part =>\n /^(?:\\.env(?:\\..*)?|id_rsa.*|id_ed25519.*)$|\\.(?:pem|key|p12|pfx|jks|keystore)$|credentials\\.|secret|^local\\.properties$/i.test(part)\n );\n}\n\n/** Bound reads even if a file grows after stat. Only read regular files. */\nexport async function readBoundedFile(file: string, maxBytes: number): Promise<string | null> {\n // Do not block on a FIFO or follow a symlink substituted after resolution.\n const handle = await fs.open(file, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOFOLLOW);\n try {\n const stat = await handle.stat();\n if (!stat.isFile() || stat.size > maxBytes) return null;\n const buffer = Buffer.alloc(Math.min(maxBytes + 1, stat.size + 1));\n let bytes = 0;\n while (bytes < buffer.length) {\n const result = await handle.read(buffer, bytes, buffer.length - bytes, null);\n if (result.bytesRead === 0) break;\n bytes += result.bytesRead;\n }\n return bytes === buffer.length ? null : buffer.subarray(0, bytes).toString(\"utf8\");\n } finally { await handle.close(); }\n}\n\nexport async function loadProjectConfig(root: string): Promise<ProjectConfig> {\n try {\n const canonicalRoot = await fs.realpath(root);\n const configPath = await fs.realpath(path.join(root, \".mason/config.json\"));\n if (!isWithinRoot(canonicalRoot, configPath)) throw new Error(\"Project configuration resolves outside the repository\");\n const raw = await readBoundedFile(configPath, 64 * 1024);\n if (raw === null) throw new Error(\"Project configuration is not a regular file or exceeds 64 KiB\");\n const value = JSON.parse(raw);\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"Expected a configuration object\");\n const config: ProjectConfig = {};\n for (const key of [\"patterns\", \"alwaysInclude\", \"ignore\"] as const) {\n if (value[key] === undefined) continue;\n if (!Array.isArray(value[key]) || !value[key].every((s: unknown) => typeof s === \"string\")) {\n throw new Error(`Configuration ${key} must be an array of strings`);\n }\n config[key] = value[key];\n }\n return config;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw new Error(`Cannot apply project file policy: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/** Scoped to one operation, so a later tool call sees newly edited files/ignores. */\nexport async function createFileAccess(rootDir: string) {\n const root = path.resolve(rootDir);\n const canonicalRoot = await fs.realpath(root).catch(() => root);\n const config = await loadProjectConfig(root);\n const ignore = [...SOURCE_IGNORE, ...(config.ignore ?? [])];\n let gitFiles: Set<string> | null = null;\n try {\n const { stdout } = await exec(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });\n gitFiles = new Set(stdout.split(\"\\0\").filter(Boolean));\n } catch {\n // File-system projects are supported. Fail closed if this IS a Git repo.\n let inGit = false;\n try { await exec(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: root }); inGit = true; } catch { /* no Git */ }\n if (inGit) throw new Error(\"Cannot enumerate Git files safely\");\n }\n\n async function resolve(file: string): Promise<string | null> {\n const relative = normalizeRepoPath(file);\n if (!relative || isSensitiveFile(relative) || (gitFiles && !gitFiles.has(relative))) return null;\n const candidate = path.join(root, relative);\n try {\n const real = await fs.realpath(candidate);\n if (!isWithinRoot(canonicalRoot, real) || isSensitiveFile(path.relative(canonicalRoot, real))) return null;\n const stat = await fs.stat(real);\n if (!stat.isFile() || stat.size > MAX_SOURCE_BYTES) return null;\n // A symlink must not bypass the target's ignore policy either.\n if (gitFiles && !gitFiles.has(path.relative(canonicalRoot, real).split(path.sep).join(\"/\"))) return null;\n return real;\n } catch { return null; }\n }\n\n async function list(patterns: string | string[] = SOURCE_GLOB, options: { deep?: number; dot?: boolean } = {}): Promise<string[]> {\n const found = await fg(patterns, { cwd: root, ignore, followSymbolicLinks: false, ...options });\n const safe = await Promise.all(found.map(async f => (await resolve(f)) ? f : null));\n return safe.filter((f): f is string => f !== null).sort();\n }\n\n async function read(file: string): Promise<SourceFile | null> {\n const relative = normalizeRepoPath(file);\n if (!relative) return null;\n const real = await resolve(relative);\n if (!real) return null;\n // Apply the same glob exclusions to explicit reads and symlink targets.\n for (const rel of new Set([relative, path.relative(canonicalRoot, real).split(path.sep).join(\"/\")])) {\n if (!(await fg(fg.escapePath(rel), { cwd: root, ignore, dot: true })).length) return null;\n }\n try {\n const content = await readBoundedFile(real, MAX_SOURCE_BYTES);\n return content === null ? null : { path: relative, content, totalLines: content.split(\"\\n\").length };\n } catch { return null; }\n }\n return { root, config, list, read };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { normalizeRepoPath } from \"./paths.js\";\nimport { readBoundedFile } from \"./files.js\";\n\nexport interface StoreDiagnostic { path: string; message: string }\n\n/** Metadata paths may not contain symlinks, including their parent directories. */\nexport async function storePath(root: string, relative: string, createParents = false): Promise<string> {\n const normalized = normalizeRepoPath(relative);\n if (!normalized) throw new Error(`Invalid store path: ${relative}`);\n let current = await fs.realpath(root);\n const parts = normalized.split(\"/\");\n for (let i = 0; i < parts.length; i++) {\n current = path.join(current, parts[i]);\n let stat;\n try { stat = await fs.lstat(current); } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n if (createParents && i < parts.length - 1) {\n try { await fs.mkdir(current); } catch (mkdirError) {\n if ((mkdirError as NodeJS.ErrnoException).code !== \"EEXIST\") throw mkdirError;\n }\n stat = await fs.lstat(current);\n }\n }\n if (stat?.isSymbolicLink()) throw new Error(`Symlink in store path: ${relative}`);\n }\n return current;\n}\n\nexport async function readStoreJson(root: string, relative: string): Promise<unknown | null> {\n try {\n const file = await storePath(root, relative);\n const raw = await readBoundedFile(file, 10 * 1024 * 1024);\n if (raw === null) throw new Error(\"file is not regular or exceeds 10 MiB\");\n const parsed: unknown = JSON.parse(raw);\n if (parsed === null) throw new Error(\"expected a JSON object, received null\");\n return parsed;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw new Error(`Invalid Mason store ${relative}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });\n }\n}\n\nexport async function writeStoreJson(root: string, relative: string, value: unknown): Promise<void> {\n const payload = JSON.stringify(value, null, 2) + \"\\n\";\n if (Buffer.byteLength(payload) > 10 * 1024 * 1024) {\n throw new Error(`Mason store ${relative} exceeds 10 MiB`);\n }\n const file = await storePath(root, relative, true);\n const temporary = path.join(path.dirname(file), `.${path.basename(file)}.${randomUUID()}.tmp`);\n try {\n const handle = await fs.open(temporary, \"wx\", 0o600);\n try { await handle.writeFile(payload, \"utf8\"); await handle.sync(); }\n finally { await handle.close(); }\n await fs.rename(temporary, file);\n } finally { await fs.rm(temporary, { force: true }); }\n}\n","import path from \"node:path\";\nimport { createFileAccess } from \"./utils/files.js\";\n\nexport interface TestPair {\n test: string;\n source: string;\n confidence: string;\n}\n\nexport interface TestMapResult {\n totalTestFiles: number;\n paired: TestPair[];\n unmatched: string[];\n}\n\nexport async function buildTestMap(dir: string): Promise<TestMapResult> {\n const rootDir = path.resolve(dir);\n const access = await createFileAccess(rootDir);\n\n // Find all test files\n const testPatterns = [\n \"**/*.test.*\", \"**/*.spec.*\",\n \"**/*Test.kt\", \"**/*Test.java\", \"**/*Tests.kt\", \"**/*Tests.java\",\n \"**/test_*.py\", \"**/*_test.py\",\n \"**/*_test.go\",\n \"**/*Tests.swift\", \"**/*Test.swift\",\n \"**/*_test.rs\",\n ];\n const testFiles = await access.list(testPatterns);\n\n // Find all source files\n const sourceFiles = await access.list();\n\n // Build source file index by base name (without extension)\n const sourceByBaseName = new Map<string, string[]>();\n for (const file of sourceFiles) {\n if (testFiles.includes(file)) continue; // Skip test files\n const baseName = path.basename(file).replace(/\\.[^.]+$/, \"\");\n const existing = sourceByBaseName.get(baseName) ?? [];\n existing.push(file);\n sourceByBaseName.set(baseName, existing);\n }\n\n // Match test files to source files by name\n const paired: TestPair[] = [];\n const unmatched: string[] = [];\n\n for (const testFile of testFiles) {\n const testBaseName = path.basename(testFile).replace(/\\.[^.]+$/, \"\");\n\n // Strip test suffixes/prefixes to get the source name\n const sourceName = testBaseName\n .replace(/Test$|Tests$|Spec$|\\.test$|\\.spec$/, \"\")\n .replace(/^test_|_test$/, \"\");\n\n if (!sourceName) {\n unmatched.push(testFile);\n continue;\n }\n\n const candidates = sourceByBaseName.get(sourceName);\n if (candidates && candidates.length > 0) {\n // If multiple candidates, prefer one in a similar directory path\n const testDir = path.dirname(testFile);\n const bestMatch = candidates.reduce((best, candidate) => {\n const candidateDir = path.dirname(candidate);\n const bestDir = path.dirname(best);\n const candidateOverlap = commonSegments(testDir, candidateDir);\n const bestOverlap = commonSegments(testDir, bestDir);\n return candidateOverlap > bestOverlap ? candidate : best;\n });\n\n paired.push({\n test: testFile,\n source: bestMatch,\n confidence: candidates.length === 1 ? \"exact\" : \"best-guess\",\n });\n } else {\n unmatched.push(testFile);\n }\n }\n\n return { totalTestFiles: testFiles.length, paired, unmatched };\n}\n\nfunction commonSegments(pathA: string, pathB: string): number {\n const segsA = pathA.split(\"/\");\n const segsB = pathB.split(\"/\");\n let count = 0;\n for (let i = 0; i < Math.min(segsA.length, segsB.length); i++) {\n if (segsA[i] === segsB[i]) count++;\n else break;\n }\n return count;\n}\n","import path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { createFileAccess } from \"../utils/files.js\";\nexport { SOURCE_GLOB, SOURCE_IGNORE } from \"../utils/files.js\";\nimport { readStoreJson, writeStoreJson, type StoreDiagnostic } from \"../utils/storage.js\";\nimport { z } from \"zod\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { buildTestMap } from \"../test-map.js\";\n\nconst exec = promisify(execFile);\n\nexport interface FeatureEntry {\n description: string;\n files: string[];\n tests?: string[];\n /**\n * Commit this entry was last verified against. Entries updated by an\n * incremental save carry HEAD here; untouched entries keep the hash the\n * map had before the save, so drift stays visible per entry. Absent means\n * \"as of the snapshot's top-level gitHash\".\n */\n refreshedHash?: string;\n /**\n * Whether this is a user-facing capability or internal infrastructure\n * (DI wiring, config loading, logging, provider/transport plumbing).\n * Capabilities are published to product-facing docs (Confluence);\n * infrastructure stays in the AI concept map only. Defaults to \"capability\"\n * when absent (older snapshots) — see normalizeFeatureType.\n */\n type?: \"capability\" | \"infrastructure\";\n /**\n * When an assistant last confirmed this entry's files actually implement\n * the claimed feature (verify_snapshot flow). Absent on older snapshots\n * and never-verified entries. Drift checks freshness against git; this\n * checks the map was CORRECT in the first place.\n */\n verifiedAt?: string;\n verifiedHash?: string;\n /** Set when verification judged the entry wrong — re-map it. */\n verificationFailed?: boolean;\n verificationNote?: string;\n}\n\nexport type FeatureType = \"capability\" | \"infrastructure\";\n\n/**\n * Coerce an arbitrary type value to a known classification. Anything that\n * isn't explicitly \"infrastructure\" defaults to \"capability\" — so older\n * snapshots and unclassified entries are treated as user-facing (published),\n * never silently hidden.\n */\nexport function normalizeFeatureType(value: unknown): FeatureType {\n return value === \"infrastructure\" ? \"infrastructure\" : \"capability\";\n}\n\nexport interface FlowEntry {\n description: string;\n chain: string[];\n /** See FeatureEntry.refreshedHash. */\n refreshedHash?: string;\n /** See FeatureEntry.verifiedAt / verificationFailed. */\n verifiedAt?: string;\n verifiedHash?: string;\n verificationFailed?: boolean;\n verificationNote?: string;\n}\n\nexport interface Snapshot {\n version: 2;\n createdAt: string;\n updatedAt: string;\n gitHash: string;\n features: Record<string, FeatureEntry>;\n flows: Record<string, FlowEntry>;\n}\n\nconst repoPath = z.string().refine(value => normalizeRepoPath(value) !== null, \"Expected a relative repository path\");\nconst verificationFields = {\n refreshedHash: z.string().optional(), verifiedAt: z.string().optional(),\n verifiedHash: z.string().optional(), verificationFailed: z.boolean().optional(),\n verificationNote: z.string().optional(),\n};\nexport const featureSchema = z.object({\n description: z.string(), files: z.array(repoPath), tests: z.array(repoPath).optional(),\n type: z.enum([\"capability\", \"infrastructure\"]).optional(), ...verificationFields,\n}).passthrough();\nexport const flowSchema = z.object({ description: z.string(), chain: z.array(repoPath), ...verificationFields }).passthrough();\nconst snapshotSchema = z.object({\n version: z.literal(2), createdAt: z.string(), updatedAt: z.string(), gitHash: z.string(),\n features: z.record(featureSchema), flows: z.record(flowSchema),\n}).passthrough();\n\nexport async function loadSnapshot(rootDir: string): Promise<Snapshot | null> {\n const parsed = await readStoreJson(rootDir, \".mason/snapshot.json\");\n if (parsed === null || (parsed as { version?: number }).version === 1) return null;\n const result = snapshotSchema.safeParse(parsed);\n if (!result.success) throw new Error(`Invalid Mason snapshot: ${result.error.message}`);\n return result.data;\n}\n\n/** Context and onboarding can use decisions even when the optional map is broken. */\nexport async function inspectSnapshot(rootDir: string): Promise<{\n status: \"available\" | \"missing\" | \"invalid\";\n snapshot: Snapshot | null;\n diagnostics: StoreDiagnostic[];\n}> {\n try {\n const raw = await readStoreJson(rootDir, \".mason/snapshot.json\");\n const snapshot = raw === null ? null : snapshotSchema.parse(raw);\n return { status: snapshot ? \"available\" : \"missing\", snapshot, diagnostics: [] };\n } catch (error) {\n return { status: \"invalid\", snapshot: null, diagnostics: [{\n path: \".mason/snapshot.json\", message: error instanceof Error ? error.message : String(error),\n }] };\n }\n}\n\nexport async function saveSnapshot(rootDir: string, snapshot: Snapshot): Promise<void> {\n await writeStoreJson(rootDir, \".mason/snapshot.json\", snapshotSchema.parse(snapshot));\n}\n\nexport async function getCurrentGitHash(rootDir: string): Promise<string> {\n try {\n const { stdout } = await exec(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: rootDir,\n });\n return stdout.trim();\n } catch {\n return \"unknown\";\n }\n}\n\nexport const DEFAULT_BATCH_SIZE = 50;\nconst SKELETON_CHARS = 500;\nconst DEEP_SAMPLE_CHARS = 1500;\nconst DEEP_SAMPLES_PER_BATCH = 3;\n\nexport interface SnapshotBatch {\n offset: number;\n batchSize: number;\n nextOffset: number | null;\n totalFiles: number;\n skeletons: Array<{ path: string; content: string }>;\n samples: Array<{ path: string; content: string }>;\n testPairs: Array<{ test: string; source: string; confidence: string }>;\n}\n\nexport async function listSourceFiles(resolvedRoot: string): Promise<string[]> {\n return (await createFileAccess(resolvedRoot)).list();\n}\n\nexport async function prepareSnapshotBatch(\n rootDir: string,\n offset: number,\n batchSize: number = DEFAULT_BATCH_SIZE,\n scopeFiles?: string[]\n): Promise<SnapshotBatch> {\n const resolvedRoot = path.resolve(rootDir);\n const access = await createFileAccess(resolvedRoot);\n let allFiles = await access.list();\n if (scopeFiles) {\n // Intersect with the real source list: keeps ignore rules and path safety,\n // and silently drops scope entries that no longer exist on disk. An empty\n // scope stays empty — it must not fall back to walking the whole project.\n const scopeSet = new Set(scopeFiles);\n allFiles = allFiles.filter((f) => scopeSet.has(f));\n }\n const totalFiles = allFiles.length;\n const safeOffset = Math.max(0, Math.min(offset, totalFiles));\n const batchPaths = allFiles.slice(safeOffset, safeOffset + batchSize);\n\n const skeletons: Array<{ path: string; content: string }> = [];\n for (const filePath of batchPaths) {\n const full = await access.read(filePath);\n if (full) {\n skeletons.push({\n path: full.path,\n content: full.content.slice(0, SKELETON_CHARS),\n });\n }\n }\n\n // Pick a few files from this batch to read deeply for grounding. Spread\n // evenly across the batch so the deep samples represent the batch's range.\n const samples: Array<{ path: string; content: string }> = [];\n if (skeletons.length > 0) {\n const step = Math.max(1, Math.floor(skeletons.length / DEEP_SAMPLES_PER_BATCH));\n for (let i = 0; i < skeletons.length && samples.length < DEEP_SAMPLES_PER_BATCH; i += step) {\n const full = await access.read(skeletons[i].path);\n if (full) {\n samples.push({\n path: full.path,\n content: full.content.slice(0, DEEP_SAMPLE_CHARS),\n });\n }\n }\n }\n\n // Only include test pairs that involve files in this batch — keeps the\n // appendix relevant and small.\n const batchPathSet = new Set(batchPaths);\n const allTestPairs = (await buildTestMap(resolvedRoot)).paired;\n const testPairs = allTestPairs.filter(\n (p) => batchPathSet.has(p.test) || batchPathSet.has(p.source)\n );\n\n const nextOffset =\n safeOffset + batchSize >= totalFiles ? null : safeOffset + batchSize;\n\n return {\n offset: safeOffset,\n batchSize,\n nextOffset,\n totalFiles,\n skeletons,\n samples,\n testPairs,\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport {\n loadSnapshot,\n getCurrentGitHash,\n listSourceFiles,\n} from \"../snapshot/snapshot.js\";\nimport type { Snapshot } from \"../snapshot/snapshot.js\";\nimport type { Freshness } from \"../context/trust.js\";\nimport { matchingPaths } from \"../utils/paths.js\";\n\nconst exec = promisify(execFile);\n\n// Incremental refresh stops paying off once a large share of the map is\n// touched — but small absolute counts are always cheap to refresh in place,\n// so both thresholds must be exceeded before recommending a full rebuild.\nconst FULL_REBUILD_FRACTION = 0.4;\nconst FULL_REBUILD_MIN_CHANGED_MAPPED_FILES = 10;\n\nexport type ChangeStatus = \"added\" | \"modified\" | \"deleted\" | \"renamed\";\n\nexport interface FileChange {\n status: ChangeStatus;\n /** Current path (the new path for renames). */\n path: string;\n /** Pre-rename path, only present for renames. */\n previousPath?: string;\n}\n\nexport type DriftRecommendation = \"up-to-date\" | \"incremental\" | \"full-rebuild\";\n\nexport interface WorkingTreeReport {\n available: boolean;\n changedFiles: string[];\n untrackedFiles: string[];\n}\n\nexport interface DriftReport {\n /** Live entry state; committed drift alone continues to drive CLI exit codes. */\n featureFreshness?: Record<string, Freshness>;\n flowFreshness?: Record<string, Freshness>;\n workingTree?: WorkingTreeReport;\n verification?: { neverVerified: number; failed: string[] };\n stale: boolean;\n snapshotHash: string;\n headHash: string;\n /** Commits between the snapshot and HEAD; null when history is unavailable. */\n commitsBehind: number | null;\n /**\n * False when the snapshot commit is unreachable (shallow clone, rewritten\n * history) — staleFeatures/unmappedFiles/renames cannot be computed then.\n */\n historyAvailable: boolean;\n /** Current paths of every file changed since the snapshot. */\n changedFiles: string[];\n /** Stale feature name → the mapped files that changed under it. */\n staleFeatures: Record<string, string[]>;\n /** Stale flow name → the chain files that changed under it. */\n staleFlows: Record<string, string[]>;\n totalFeatures: number;\n totalFlows: number;\n /** New source files not referenced by any feature or flow. */\n unmappedFiles: string[];\n /** Files referenced by the map that no longer exist on disk. */\n ghostFiles: string[];\n renames: Array<{ from: string; to: string }>;\n recommendation: DriftRecommendation;\n}\n\nfunction parseChanges(output: string): FileChange[] {\n const fields = output.split(\"\\0\");\n const changes: FileChange[] = [];\n for (let i = 0; i < fields.length && fields[i];) {\n const code = fields[i++];\n const first = fields[i++];\n if (!first) break;\n const second = /^[RC]/.test(code) ? fields[i++] : undefined;\n const change: FileChange = second\n ? code.startsWith(\"R\") ? { status: \"renamed\", path: second, previousPath: first } : { status: \"added\", path: second }\n : { status: code === \"A\" ? \"added\" : code === \"D\" ? \"deleted\" : \"modified\", path: first };\n if (change.path.startsWith(\".mason/\") && (!change.previousPath || change.previousPath.startsWith(\".mason/\"))) continue;\n changes.push(change);\n }\n return changes;\n}\n\nexport function touchedPaths(changes: FileChange[]): string[] {\n return [...new Set(changes.flatMap(c => c.previousPath ? [c.previousPath, c.path] : [c.path]))].sort();\n}\n\nexport async function getChangesWithStatus(resolvedRoot: string, fromHash: string, toHash = \"HEAD\"): Promise<FileChange[] | null> {\n if (!fromHash || fromHash === \"unknown\" || fromHash.startsWith(\"-\") || !toHash || toHash === \"unknown\" || toHash.startsWith(\"-\")) return null;\n try {\n const { stdout } = await exec(\"git\", [\"diff\", \"--name-status\", \"-z\", \"-M\", fromHash, toHash, \"--\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 });\n return parseChanges(stdout);\n } catch { return null; }\n}\n\nexport async function getWorkingTree(resolvedRoot: string): Promise<WorkingTreeReport> {\n try {\n const [diff, untracked] = await Promise.all([\n exec(\"git\", [\"diff\", \"--name-status\", \"-z\", \"-M\", \"HEAD\", \"--\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),\n exec(\"git\", [\"ls-files\", \"-z\", \"--others\", \"--exclude-standard\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),\n ]);\n const untrackedFiles = untracked.stdout.split(\"\\0\").filter(f => f && !f.startsWith(\".mason/\"));\n return { available: true, changedFiles: [...new Set([...touchedPaths(parseChanges(diff.stdout)), ...untrackedFiles])].sort(), untrackedFiles };\n } catch { return { available: false, changedFiles: [], untrackedFiles: [] }; }\n}\n\nasync function countCommitsBehind(\n resolvedRoot: string,\n fromHash: string\n): Promise<number | null> {\n if (!fromHash || fromHash === \"unknown\" || fromHash.startsWith(\"-\")) return null;\n try {\n const { stdout } = await exec(\n \"git\",\n [\"rev-list\", \"--count\", `${fromHash}..HEAD`],\n { cwd: resolvedRoot }\n );\n const count = Number.parseInt(stdout.trim(), 10);\n return Number.isNaN(count) ? null : count;\n } catch {\n return null;\n }\n}\n\nfunction collectMappedFiles(snapshot: Snapshot): Set<string> {\n const mappedFiles = new Set<string>();\n for (const feature of Object.values(snapshot.features)) {\n for (const f of feature.files) mappedFiles.add(f);\n for (const t of feature.tests ?? []) mappedFiles.add(t);\n }\n for (const flow of Object.values(snapshot.flows)) {\n for (const f of flow.chain) mappedFiles.add(f);\n }\n return mappedFiles;\n}\n\nasync function findGhostFiles(\n resolvedRoot: string,\n mappedFiles: Set<string>\n): Promise<string[]> {\n const ghosts: string[] = [];\n for (const file of mappedFiles) {\n try {\n await fs.access(path.join(resolvedRoot, file));\n } catch {\n ghosts.push(file);\n }\n }\n return ghosts.sort();\n}\n\n/**\n * Compare the concept map against HEAD and report feature-level drift.\n * Fully deterministic — git + filesystem only, no LLM involved.\n * Returns null when no snapshot exists.\n */\nexport async function computeDrift(rootDir: string): Promise<DriftReport | null> {\n const root = path.resolve(rootDir);\n const snapshot = await loadSnapshot(root);\n if (!snapshot) return null;\n const [headHash, workingTree] = await Promise.all([getCurrentGitHash(root), getWorkingTree(root)]);\n const hashFor = (entry: { refreshedHash?: string }) => entry.refreshedHash ?? snapshot.gitHash;\n const entries = [...Object.values(snapshot.features), ...Object.values(snapshot.flows)];\n const hashes = new Set([snapshot.gitHash, ...entries.map(hashFor)]);\n const changesByHash = new Map<string, FileChange[] | null>();\n await Promise.all([...hashes].map(async hash => {\n changesByHash.set(hash, hash === headHash && headHash !== \"unknown\" ? [] : await getChangesWithStatus(root, hash));\n }));\n const historyAvailable = headHash !== \"unknown\" && [...changesByHash.values()].every(changes => changes !== null);\n const mappedFiles = collectMappedFiles(snapshot);\n const report: DriftReport = {\n stale: !historyAvailable,\n snapshotHash: snapshot.gitHash, headHash,\n commitsBehind: 0, historyAvailable,\n changedFiles: [], staleFeatures: {}, staleFlows: {},\n totalFeatures: Object.keys(snapshot.features).length,\n totalFlows: Object.keys(snapshot.flows).length,\n unmappedFiles: [], ghostFiles: await findGhostFiles(root, mappedFiles), renames: [],\n recommendation: historyAvailable ? \"up-to-date\" : \"full-rebuild\",\n featureFreshness: {}, flowFreshness: {}, workingTree,\n verification: {\n neverVerified: entries.filter(e => !e.verifiedAt).length,\n failed: [...Object.entries(snapshot.features), ...Object.entries(snapshot.flows)].filter(([, e]) => e.verificationFailed).map(([name]) => name),\n },\n };\n const counts = await Promise.all([...hashes].map(hash => hash === headHash ? 0 : countCommitsBehind(root, hash)));\n const knownCounts = counts.filter((n): n is number => n !== null);\n report.commitsBehind = knownCounts.length ? Math.max(...knownCounts) : null;\n\n const check = (name: string, files: string[], hash: string, staleEntries: Record<string, string[]>, freshness: Record<string, Freshness>) => {\n const changes = changesByHash.get(hash);\n const committedHits = changes ? matchingPaths(files, touchedPaths(changes)) : [];\n if (committedHits.length) staleEntries[name] = committedHits;\n const localHits = matchingPaths(files, workingTree.changedFiles);\n freshness[name] = files.length === 0 || changes === null || changes === undefined || !workingTree.available ? \"unknown\"\n : committedHits.length || localHits.length || files.some(f => report.ghostFiles.includes(f)) ? \"changed\" : \"current\";\n };\n for (const [name, feature] of Object.entries(snapshot.features)) {\n check(name, [...feature.files, ...(feature.tests ?? [])], hashFor(feature), report.staleFeatures, report.featureFreshness!);\n }\n for (const [name, flow] of Object.entries(snapshot.flows)) {\n check(name, flow.chain, hashFor(flow), report.staleFlows, report.flowFreshness!);\n }\n\n const allChanges = [...changesByHash.values()].flatMap(changes => changes ?? []);\n report.changedFiles = [...new Set(allChanges.map(c => c.path))].sort();\n // Complete coverage, including omissions from a map saved at HEAD. Untracked\n // files remain in workingTree and never change the committed-drift exit code.\n const sourceFiles = new Set(await listSourceFiles(root));\n let committedFiles: Set<string> = new Set();\n try {\n const { stdout } = await exec(\"git\", [\"ls-tree\", \"-r\", \"--name-only\", \"-z\", \"HEAD\"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });\n committedFiles = new Set(stdout.split(\"\\0\").filter(Boolean));\n } catch { report.historyAvailable = false; report.stale = true; }\n report.unmappedFiles = [...sourceFiles].filter(f => committedFiles.has(f) && !mappedFiles.has(f)).sort();\n const renames = new Map<string, { from: string; to: string }>();\n for (const change of allChanges) {\n if (change.status === \"renamed\" && change.previousPath) renames.set(`${change.previousPath}\\0${change.path}`, { from: change.previousPath, to: change.path });\n }\n report.renames = [...renames.values()];\n const changedMapped = new Set([...Object.values(report.staleFeatures).flat(), ...Object.values(report.staleFlows).flat()]);\n // A locally deleted file is a live-edit warning, not committed map drift.\n const committedGhosts = report.ghostFiles.filter(f => !workingTree.changedFiles.includes(f));\n report.stale ||= changedMapped.size > 0 || report.unmappedFiles.length > 0 || committedGhosts.length > 0;\n if (!report.historyAvailable) report.recommendation = \"full-rebuild\";\n else if (!report.stale) report.recommendation = \"up-to-date\";\n else report.recommendation = changedMapped.size >= FULL_REBUILD_MIN_CHANGED_MAPPED_FILES && changedMapped.size / Math.max(1, mappedFiles.size) > FULL_REBUILD_FRACTION ? \"full-rebuild\" : \"incremental\";\n return report;\n}\n","import path from \"node:path\";\nimport type { CommandClaim } from \"./types.js\";\n\nconst TOKEN = `(?:\"[^\"\\\\n]*\"|'[^'\\\\n]*'|[^\\\\s\\x60;&|]+)`;\nconst COMMAND = new RegExp(`\\\\b(npm|pnpm|yarn)((?:[ \\\\t]+${TOKEN})*?)[ \\\\t]+run[ \\\\t]+([A-Za-z0-9:_.-]+)`, \"g\");\nconst literal = (value: string) => {\n const unquoted = value.replace(/^([\"'])(.*)\\1$/, \"$2\");\n return /[$`*?\\[\\]{}~\\\\\\x00-\\x1f]/.test(unquoted) || path.posix.isAbsolute(unquoted) ? null : unquoted;\n};\n\nfunction splitCommands(line: string): string[] {\n const parts: string[] = [];\n let quote = \"\", start = 0;\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n if (char === \"\\\\\") { i++; continue; }\n if (quote) { if (char === quote) quote = \"\"; continue; }\n if (char === \"'\" || char === '\"') { quote = char; continue; }\n if (char === \";\" || line.slice(i, i + 2) === \"&&\") {\n parts.push(line.slice(start, i));\n if (char === \"&\") i++;\n start = i + 1;\n }\n }\n parts.push(line.slice(start));\n return parts;\n}\n\n/** Deliberately small shell subset: literal cd and npm-family run invocations. */\nexport function commandClaims(line: string, lineNo: number, cwd?: string | null, shell = false): { claims: CommandClaim[]; cwd: string | null | undefined } {\n const claims: CommandClaim[] = [];\n const segments = splitCommands(line);\n for (const segment of segments) {\n const text = segment.trim().replace(/^\\$\\s+/, \"\");\n if (text.startsWith(\"#\") || /^(?:echo|printf)\\b/.test(text)) continue;\n const cd = text.match(/^cd\\s+(.+)$/);\n if (cd) {\n const directory = literal(cd[1]);\n cwd = directory === null || cwd === null || /\\s/.test(directory) && !/^[\"']/.test(cd[1])\n ? null : path.posix.join(cwd ?? \".\", directory);\n continue;\n }\n for (const match of text.matchAll(COMMAND)) {\n const flags = match[2].trim();\n const selector = flags.match(/^(?:--prefix|--dir|-C)(?:\\s+|=)(.+)$/);\n let directory = cwd;\n let scopeUnknown: string | undefined;\n if ((shell && match.index !== 0) || match[3].startsWith(\"-\")) scopeUnknown = \"Unsupported shell wrapper or options before the script.\";\n if (selector) {\n const selected = literal(selector[1]);\n directory = selected === null || cwd === null ? null : path.posix.join(cwd ?? \".\", selected);\n } else if (flags) scopeUnknown = \"Unsupported package-manager options before run: \" + flags;\n const tail = text.slice(match.index! + match[0].length).split(/\\s--(?:\\s|$)/)[0];\n if (/(?:^|\\s)(?:--workspace(?:s)?|-w|--filter|-F|--prefix|--dir|-C|--if-present)(?:\\s|=|$)/.test(tail)) {\n scopeUnknown = \"Package selection or conditional options after the script need review.\";\n }\n if (/[|()]/.test(text) || /\\b(?:pushd|popd|if|for|while)\\b/.test(text) || directory === null) {\n scopeUnknown = \"The command's working directory or shell control flow could not be resolved.\";\n }\n claims.push({ scriptName: match[3], invocation: match[0], excerpt: match[0], line: lineNo,\n ...(directory !== undefined && directory !== null ? { directory } : {}), ...(scopeUnknown ? { scopeUnknown } : {}) });\n }\n // An unresolved directory change must not leave later commands apparently scoped.\n if (/\\b(?:cd|pushd|popd)\\b/.test(text)) cwd = null;\n }\n return { claims, cwd };\n}\n","import type { PathClaim } from \"./types.js\";\n\n/**\n * A fenced block is treated as a directory tree only when it clearly is one —\n * below this many branch-glyph lines it's more likely an ASCII sketch.\n */\nconst MIN_GLYPH_LINES = 3;\n\nconst GLYPHS = [\"├──\", \"└──\"] as const;\n\nfunction glyphIndex(line: string): number {\n for (const glyph of GLYPHS) {\n const idx = line.indexOf(glyph);\n if (idx !== -1) return idx;\n }\n return -1;\n}\n\n/** Tree furniture: blank, or only vertical bars and whitespace. */\nfunction isSpacerLine(line: string): boolean {\n return /^[\\s│|]*$/.test(line);\n}\n\n/**\n * Strip an inline comment/annotation from a tree entry. Entries commonly\n * carry `# comment` or column-aligned notes after two or more spaces.\n */\nfunction entryName(afterGlyph: string): string | null {\n let name = afterGlyph.replace(/^\\s+/, \"\");\n const hash = name.search(/\\s+#/);\n if (hash !== -1) name = name.slice(0, hash);\n const columns = name.search(/\\s{2,}/);\n if (columns !== -1) name = name.slice(0, columns);\n name = name.trim();\n // A name with remaining internal whitespace is not a path — treat the\n // line as malformed rather than guessing.\n if (!name || /\\s/.test(name)) return null;\n return name;\n}\n\n/**\n * Reconstruct full paths from an ASCII directory tree inside a fenced block.\n *\n * The failure mode must always be a missed claim, never an invented path: a\n * line that doesn't parse cleanly aborts reconstruction below it, and every\n * emitted path still passes the deleted-reference provability gate later.\n *\n * `blockLines` are the fence's content lines; `blockStartLine` is the 1-based\n * doc line number of the first content line.\n */\nexport function extractTreeClaims(\n blockLines: string[],\n blockStartLine: number\n): PathClaim[] {\n const glyphLines = blockLines.filter((l) => glyphIndex(l) !== -1).length;\n if (glyphLines < MIN_GLYPH_LINES) return [];\n\n const claims: PathClaim[] = [];\n // Directories on the path from the root to the current entry, keyed by the\n // column their branch glyph appeared at.\n const stack: Array<{ col: number; name: string }> = [];\n let rootPrefix = \"\";\n let started = false;\n\n for (let i = 0; i < blockLines.length; i++) {\n const line = blockLines[i];\n const col = glyphIndex(line);\n\n if (col === -1) {\n if (isSpacerLine(line)) continue;\n if (!started) {\n // A bare `src/` line above the first glyph names the tree's root.\n const candidate = line.trim();\n if (candidate.endsWith(\"/\") && !/\\s/.test(candidate)) {\n rootPrefix = candidate.replace(/\\/+$/, \"\");\n claims.push({\n path: rootPrefix,\n line: blockStartLine + i,\n excerpt: candidate,\n });\n }\n continue;\n }\n // Unparseable line after the tree began: stop here, keep what we have.\n return claims;\n }\n\n started = true;\n const name = entryName(line.slice(col + GLYPHS[0].length));\n if (name === null) return claims;\n\n while (stack.length > 0 && stack[stack.length - 1].col >= col) {\n stack.pop();\n }\n\n const isDir = name.endsWith(\"/\");\n const cleanName = name.replace(/\\/+$/, \"\");\n const segments = [\n ...(rootPrefix ? [rootPrefix] : []),\n ...stack.map((s) => s.name),\n cleanName,\n ];\n claims.push({\n path: segments.join(\"/\"),\n line: blockStartLine + i,\n excerpt: name,\n });\n\n if (isDir) stack.push({ col, name: cleanName });\n }\n\n return claims;\n}\n","import MarkdownIt from \"markdown-it\";\nimport { commandClaims } from \"./commands.js\";\nimport type {\n CommandClaim,\n CountClaim,\n DocClaims,\n PathClaim,\n} from \"./types.js\";\nimport { extractTreeClaims } from \"./tree.js\";\n\n/**\n * Single-segment names that count as path claims without containing a \"/\".\n * Anything else without a slash is prose (\"name your file `config.ts`\"), not\n * a claim about this repo.\n */\nconst ROOT_FILE_NAMES = new Set([\n \"package.json\",\n \"package-lock.json\",\n \"pnpm-workspace.yaml\",\n \"tsconfig.json\",\n \"tsup.config.ts\",\n \"vitest.config.ts\",\n \"Makefile\",\n \"Dockerfile\",\n \"docker-compose.yml\",\n \"Cargo.toml\",\n \"go.mod\",\n \"go.sum\",\n \"pyproject.toml\",\n \"requirements.txt\",\n \"Gemfile\",\n \"composer.json\",\n \"settings.gradle.kts\",\n \"settings.gradle\",\n \"build.gradle.kts\",\n \"build.gradle\",\n \"manifest.json\",\n \"server.json\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\",\n \"CLAUDE.md\",\n \"AGENTS.md\",\n \".gitignore\",\n \".env.example\",\n]);\n\nconst SHELL_FENCE_INFOS = new Set([\"\", \"bash\", \"sh\", \"shell\", \"console\", \"zsh\"]);\n\nconst markdown = new MarkdownIt(\"commonmark\", { html: false });\nconst COUNT_RE = /(\\d+)\\s+(modules?|packages?|workspaces?|crates?)\\b/gi;\n/** \"3 package managers\" is not a package count. */\nconst COUNT_DENYLIST_RE = /^\\s*(manager|registr|lock|json)/i;\n\nconst IGNORE_LINE = \"<!-- mason:ignore -->\";\nconst IGNORE_START = \"<!-- mason:ignore-start -->\";\nconst IGNORE_END = \"<!-- mason:ignore-end -->\";\n\n/**\n * Normalize a candidate token into a repo-relative path claim, or return\n * null when the token is not a claim about this repo (URL, glob,\n * placeholder, relative import example, bare word).\n */\nexport function normalizePathToken(token: string): string | null {\n let t = token.trim();\n if (!t) return null;\n if (/\\s/.test(t)) return null;\n if (t.includes(\"://\") || t.includes(\"\\\\\")) return null;\n if (/[*?[\\]{}<>$`]/.test(t)) return null;\n if (t.startsWith(\"/\") || t.startsWith(\"~\") || t.startsWith(\"./\") || t.startsWith(\"../\")) {\n return null;\n }\n // `src/mcp/tools.ts:189` claims the file, not the line.\n t = t.replace(/:\\d+(?:-\\d+)?$/, \"\");\n if (t.includes(\":\")) return null;\n const normalized = t.replace(/\\/+$/, \"\");\n if (!normalized) return null;\n // `server/src/test/kotlin/...` — a dots-only segment is an \"and so on\"\n // placeholder, not a claim.\n if (normalized.split(\"/\").some((seg) => /^\\.+$/.test(seg))) return null;\n if (normalized.includes(\"/\")) return normalized;\n return ROOT_FILE_NAMES.has(normalized) ? normalized : null;\n}\n\n/** A fence line that is exactly one path-shaped token is a file-list claim. */\nfunction exactTokenPath(line: string): string | null {\n const trimmed = line.trim();\n if (!trimmed || /\\s/.test(trimmed) || !trimmed.includes(\"/\")) return null;\n return normalizePathToken(trimmed);\n}\n\nfunction computeIgnoredLines(lines: string[]): boolean[] {\n const ignored = new Array<boolean>(lines.length).fill(false);\n let inRegion = false;\n let ignoreNext = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes(IGNORE_START)) {\n inRegion = true;\n ignored[i] = true;\n continue;\n }\n if (line.includes(IGNORE_END)) {\n inRegion = false;\n ignored[i] = true;\n continue;\n }\n if (inRegion) {\n ignored[i] = true;\n continue;\n }\n if (ignoreNext) {\n if (line.trim().length === 0) continue; // skip blanks to the next real line\n ignored[i] = true;\n ignoreNext = false;\n continue;\n }\n if (line.includes(IGNORE_LINE)) {\n ignored[i] = true;\n const rest = line.replace(IGNORE_LINE, \"\").trim();\n if (rest.length === 0) ignoreNext = true;\n }\n }\n return ignored;\n}\n\n/**\n * Extract every checkable claim from a context-file's markdown. Deterministic\n * and purely lexical — precision comes from the checks' provability gates,\n * not from clever parsing here.\n */\nexport function extractClaims(content: string): DocClaims {\n const lines = content.split(\"\\n\");\n const ignored = computeIgnoredLines(lines);\n\n const paths = new Map<string, PathClaim>();\n const counts: CountClaim[] = [];\n const commands = new Map<string, CommandClaim>();\n\n const addPath = (claim: PathClaim): void => {\n const key = [claim.relativeTo ?? \"scope\", claim.path].join(\":\");\n if (!paths.has(key)) paths.set(key, claim);\n };\n const addCommand = (claim: CommandClaim): void => {\n const key = JSON.stringify([claim.scriptName, claim.directory, claim.scopeUnknown]);\n if (!commands.has(key)) commands.set(key, claim);\n };\n\n // A real Markdown parser distinguishes reference links, images and escaped\n // destinations from code examples. Ignore markers preserve source line offsets.\n const parsed = markdown.parse(lines.map((line, i) => ignored[i] ? \"\" : line).join(\"\\n\"), {});\n for (const token of parsed) {\n if (token.type !== \"inline\" || !token.map) continue;\n let line = token.map[0] + 1;\n for (const child of token.children ?? []) {\n const target = child.type === \"link_open\" ? child.attrGet(\"href\") : child.type === \"image\" ? child.attrGet(\"src\") : null;\n if (target && !/^(?:[a-z][a-z0-9+.-]*:|[\\/#~])/i.test(target)) {\n let pathname: string | null = null;\n try { pathname = decodeURIComponent(target.split(/[?#]/)[0]); } catch { /* Unsupported URL encoding. */ }\n if (pathname && !/[$*?{}<>\\\\\\x00-\\x1f]/.test(pathname)) {\n addPath({ path: pathname, line, excerpt: target, relativeTo: \"document\" });\n }\n }\n if (child.type === \"softbreak\" || child.type === \"hardbreak\") line++;\n else line += child.content.split(\"\\n\").length - 1;\n }\n }\n\n let shellCwd: string | null | undefined;\n let inFence = false;\n let fenceInfo = \"\";\n let fenceMarker = \"\";\n let blockLines: string[] = [];\n let blockStartLine = 0;\n\n const processBlock = (): void => {\n for (const claim of extractTreeClaims(blockLines, blockStartLine)) {\n addPath(claim);\n }\n for (let i = 0; i < blockLines.length; i++) {\n const exact = exactTokenPath(blockLines[i]);\n if (exact) {\n addPath({\n path: exact,\n line: blockStartLine + i,\n excerpt: blockLines[i].trim(),\n });\n }\n }\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNo = i + 1;\n const fenceMatch = line.match(/^\\s*(```+|~~~+)(.*)$/);\n\n if (fenceMatch) {\n if (!inFence) {\n inFence = true;\n fenceMarker = fenceMatch[1][0];\n fenceInfo = fenceMatch[2].trim().toLowerCase();\n blockLines = [];\n shellCwd = undefined;\n blockStartLine = lineNo + 1;\n } else if (fenceMatch[1][0] === fenceMarker) {\n inFence = false;\n processBlock();\n }\n continue;\n }\n\n if (inFence) {\n // Ignored lines become spacers so the rest of a tree still parses.\n blockLines.push(ignored[i] ? \"\" : line);\n if (!ignored[i] && SHELL_FENCE_INFOS.has(fenceInfo)) {\n const scanned = commandClaims(line, lineNo, shellCwd, true);\n shellCwd = scanned.cwd;\n for (const claim of scanned.claims) addCommand(claim);\n }\n continue;\n }\n\n if (ignored[i]) continue;\n\n for (const m of line.matchAll(/`([^`]+)`/g)) {\n const normalized = normalizePathToken(m[1]);\n if (normalized) {\n addPath({ path: normalized, line: lineNo, excerpt: m[1] });\n }\n }\n for (const m of line.matchAll(/\"([A-Za-z][\\w.@-]*(?:\\/[\\w.@-]+)+\\/?)\"/g)) {\n const normalized = normalizePathToken(m[1]);\n if (normalized) {\n addPath({ path: normalized, line: lineNo, excerpt: m[1] });\n }\n }\n for (const m of line.matchAll(COUNT_RE)) {\n const rest = line.slice((m.index ?? 0) + m[0].length);\n if (COUNT_DENYLIST_RE.test(rest)) continue;\n counts.push({\n count: Number.parseInt(m[1], 10),\n unit: m[2].toLowerCase(),\n line: lineNo,\n excerpt: m[0],\n });\n }\n for (const match of line.matchAll(/`([^`]+)`/g)) {\n for (const claim of commandClaims(match[1], lineNo, undefined, true).claims) addCommand(claim);\n }\n for (const claim of commandClaims(line.replace(/`[^`]+`/g, \"\"), lineNo).claims) addCommand(claim);\n }\n\n // An unclosed fence still gets its block processed — trees at the end of a\n // truncated doc are claims too.\n if (inFence) processBlock();\n\n return {\n paths: [...paths.values()],\n counts,\n commands: [...commands.values()],\n };\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { CommitRef } from \"./types.js\";\n\nconst exec = promisify(execFile);\n\nconst COMMIT_FORMAT = \"%H%x09%cI%x09%s\";\n\nfunction parseCommitLine(line: string): CommitRef | null {\n const parts = line.split(\"\\t\");\n if (parts.length < 3 || !parts[0]) return null;\n return { hash: parts[0], date: parts[1], subject: parts.slice(2).join(\"\\t\") };\n}\n\n/** Most recent commit touching a path, or null if the path was never tracked. */\nexport async function lastCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\"log\", \"-1\", `--format=${COMMIT_FORMAT}`, \"--\", `:(literal)${relPath}`],\n { cwd: resolvedRoot }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\n/** The commit that deleted a path, or null if none did. */\nexport async function deletingCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\n \"log\",\n \"-1\",\n \"--diff-filter=D\",\n `--format=${COMMIT_FORMAT}`,\n \"--\",\n `:(literal)${relPath}`,\n ],\n { cwd: resolvedRoot }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\n/** Oldest commit touching a path (used to date a directory's appearance). */\nexport async function firstCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\"log\", \"--reverse\", `--format=${COMMIT_FORMAT}`, \"--\", `:(literal)${relPath}`],\n { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\nexport interface RangeCommits {\n commits: Array<CommitRef & { files: string[] }>;\n total: number;\n}\n\n/**\n * Commits in fromHash..HEAD touching any of the pathspecs, newest first, with\n * the touched files per commit. Rev-range, not --since: immune to rebase date\n * skew and CI checkout mtimes. Returns null when the range is uncomputable\n * (unreachable base commit, shallow clone, no git).\n */\nexport async function commitsTouchingSince(\n resolvedRoot: string,\n fromHash: string,\n pathspecs: string[]\n): Promise<RangeCommits | null> {\n if (!fromHash || fromHash === \"unknown\") return null;\n try {\n const { stdout } = await exec(\n \"git\",\n [\n \"log\",\n `${fromHash}..HEAD`,\n `--format=%x01${COMMIT_FORMAT}`,\n \"--name-only\",\n \"--\",\n ...pathspecs,\n ],\n { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }\n );\n\n const commits: Array<CommitRef & { files: string[] }> = [];\n // \\x01 marks each commit header so name-only file lists can't be\n // mistaken for headers.\n for (const block of stdout.split(\"\\x01\")) {\n if (!block.trim()) continue;\n const lines = block.split(\"\\n\").filter((l) => l.trim().length > 0);\n const ref = parseCommitLine(lines[0]);\n if (!ref) continue;\n commits.push({ ...ref, files: lines.slice(1).map((l) => l.trim()) });\n }\n return { commits, total: commits.length };\n } catch {\n return null;\n }\n}\n","import fs from \"node:fs/promises\";\nimport * as nativeFs from \"node:fs\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { Readable } from \"node:stream\";\nimport fg from \"fast-glob\";\nimport { readBoundedFile, SOURCE_EXTENSIONS } from \"../utils/files.js\";\nimport { storePath } from \"../utils/storage.js\";\n\nconst execute = promisify(execFile);\nconst MAX_INPUTS = 100_000;\n\n/** Check the paths a particular audit actually reads, including their parents. */\nexport async function auditInputPath(root: string, file: string): Promise<string> {\n if (file === \".\") return fs.realpath(root);\n try { return await storePath(root, file); }\n catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Symlink\")) {\n throw new Error(`Audit input contains a symbolic link: ${file}. Its evidence could not be verified.`, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function readAuditInput(root: string, file: string): Promise<string | null> {\n try {\n const value = await readBoundedFile(await auditInputPath(root, file), 10 * 1024 * 1024);\n if (value === null) throw new Error(`Unreadable or oversized audit input: ${file}`);\n return value;\n } catch (error) {\n if ([\"ENOENT\", \"ENOTDIR\"].includes((error as NodeJS.ErrnoException).code ?? \"\")) return null;\n throw error;\n }\n}\n\n/** Bound relevant results and directory traversal, without counting unrelated files. */\nexport async function auditGlob(root: string, patterns: string | string[], options: {\n ignore?: string[]; onlyDirectories?: boolean; followSymbolicLinks?: boolean; label: string; select?: (file: string) => boolean;\n}): Promise<string[]> {\n if (Array.isArray(patterns) && !patterns.length) return [];\n const directories = new Set<string>();\n // fast-glob may stat a link, but must never enumerate a linked directory.\n // Validate each traversal and each selected result instead of scanning the\n // entire repository just to reject unrelated symlinks.\n const readdir = ((directory: string, opts: unknown, callback: (error: unknown, entries?: unknown) => void) => {\n const relative = path.relative(root, directory).split(path.sep).join(\"/\") || \".\";\n directories.add(relative);\n if (directories.size > MAX_INPUTS) {\n callback(new Error(`${options.label} exceeds ${MAX_INPUTS.toLocaleString(\"en-US\")} directories while inspecting ${relative}. Narrow this check's inputs.`));\n return;\n }\n auditInputPath(root, relative).then(() => {\n nativeFs.readdir(directory, opts as { withFileTypes: true }, callback as (error: NodeJS.ErrnoException | null, entries: nativeFs.Dirent[]) => void);\n }, callback);\n }) as typeof nativeFs.readdir;\n // Literal workspace patterns use lstat instead of readdir. Validate them\n // before fast-glob can silently discard a dangling link as a missing file.\n const lstat = ((file: string, callback: (error: unknown, stat?: nativeFs.Stats) => void) => {\n const relative = path.relative(root, file).split(path.sep).join(\"/\") || \".\";\n auditInputPath(root, relative).then(() => nativeFs.lstat(file, callback), callback);\n }) as typeof nativeFs.lstat;\n const stream = fg.stream(patterns, { cwd: root, ignore: options.ignore,\n onlyFiles: false, onlyDirectories: options.onlyDirectories, objectMode: true,\n followSymbolicLinks: options.followSymbolicLinks ?? true, fs: { readdir, lstat }, concurrency: 16 }) as Readable;\n const matches: string[] = [];\n try {\n for await (const value of stream) {\n const entry = value as fg.Entry;\n const file = entry.path;\n if (options.select && !options.select(file)) continue;\n await auditInputPath(root, file);\n if (!options.onlyDirectories && !entry.dirent.isFile()) continue;\n matches.push(file);\n if (matches.length > MAX_INPUTS) {\n const largest = [...matches.reduce((counts, item) => {\n const dir = item.split(\"/\")[0]; counts.set(dir, (counts.get(dir) ?? 0) + 1); return counts;\n }, new Map<string, number>())].sort((a, b) => b[1] - a[1]).slice(0, 3);\n throw new Error(`${options.label} exceeds ${MAX_INPUTS.toLocaleString(\"en-US\")} relevant paths. Largest directories: ${largest.map(([dir, count]) => `${dir} (${count})`).join(\", \")}. Narrow this check's inputs.`);\n }\n }\n } finally { stream.destroy(); }\n return matches.sort();\n}\n\n/** Git prunes ignored trees before discovery; tracked source remains visible. */\nexport async function gitSourcePaths(root: string): Promise<string[]> {\n const { stdout } = await execute(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\", \"--\",\n ...SOURCE_EXTENSIONS.map(extension => `:(glob)**/*.${extension}`)],\n { cwd: root, maxBuffer: 32 * 1024 * 1024, timeout: 10_000 });\n return [...new Set(stdout.split(\"\\0\").filter(Boolean))].sort();\n}\n\n/** Small directory batches, never a repository-wide inventory of ignored files. */\nexport async function gitIgnoredPaths(root: string, files: string[]): Promise<Set<string>> {\n if (!files.length) return new Set();\n const operation = execute(\"git\", [\"check-ignore\", \"-z\", \"--stdin\"],\n { cwd: root, maxBuffer: 4 * 1024 * 1024, timeout: 10_000 });\n operation.child.stdin!.on(\"error\", () => { /* The child exit reports a failed query. */ });\n operation.child.stdin!.end(files.join(\"\\0\") + \"\\0\");\n try { return new Set((await operation).stdout.split(\"\\0\").filter(Boolean)); }\n catch (error) {\n if ((error as { code?: number }).code === 1) return new Set(); // No ignored paths.\n throw error;\n }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { extractClaims } from \"./claims.js\";\nimport { lastCommitOf } from \"./git.js\";\nimport fg from \"fast-glob\";\nimport { auditGlob, auditInputPath, readAuditInput } from \"./inputs.js\";\nimport { loadProjectConfig } from \"../utils/files.js\";\nimport type { CommitRef, DocClaims } from \"./types.js\";\n\nconst exec = promisify(execFile);\n\n/**\n * Instruction entry points written by setup. Audit discovery is broader and\n * preserves actual filename casing; setup/teardown must not edit every README.\n */\nexport const DOC_CANDIDATES = [\n \"AGENTS.md\",\n \"CLAUDE.md\",\n \".claude/CLAUDE.md\",\n] as const;\n\nexport interface AuditDoc {\n /** Repo-relative posix path. */\n path: string;\n content: string;\n /** Directory whose instructions this document describes, not a proven shell cwd. */\n scope: string;\n kind: \"instructions\" | \"readme\";\n lineCount: number;\n /** Null when the doc is untracked. */\n lastCommit: CommitRef | null;\n /** Uncommitted edits present. */\n dirty: boolean;\n claims: DocClaims;\n}\n\nasync function isDirty(resolvedRoot: string, relPath: string): Promise<boolean> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\"status\", \"--porcelain\", \"--\", `:(literal)${relPath}`],\n { cwd: resolvedRoot }\n );\n return stdout.trim().length > 0;\n } catch {\n return true;\n }\n}\n\n/** Readme/instruction discovery shares the exact inventory used by automation. */\nexport async function discoverDocPaths(root: string): Promise<string[]> {\n let candidates: string[] = [];\n try {\n const { stdout } = await exec(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\", \"--\",\n \":(icase,glob)**/readme.md\", \":(icase,glob)**/agents.md\", \":(icase,glob)**/claude.md\"],\n { cwd: root, maxBuffer: 16 * 1024 * 1024, timeout: 10000 });\n candidates = stdout.split(\"\\0\").filter(Boolean);\n } catch (error) {\n // Outside Git we still discover documents so the audit can report Git unavailable.\n try { await exec(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: root }); }\n catch { return localDocPaths(root); }\n throw error;\n }\n candidates.push(...await localDocPaths(root));\n const config = await loadProjectConfig(root);\n const excluded = [\"**/node_modules/**\", \"**/vendor/**\", \"**/dist/**\", \"**/build/**\", \"**/target/**\",\n \"**/.git/**\", \"**/.venv/**\", \"**/venv/**\", \".mason/**\", ...(config.ignore ?? [])];\n // Static patterns preserve literal metacharacters and reject selected symlinks.\n const paths: string[] = [];\n const unique = [...new Set(candidates)].sort();\n for (let offset = 0; offset < unique.length; offset += 256) {\n paths.push(...await auditGlob(root, unique.slice(offset, offset + 256).map(p => fg.escapePath(p)), {\n ignore: excluded, followSymbolicLinks: false, label: \"Documentation discovery\",\n }));\n if (paths.length > 10000) throw new Error(\"Documentation discovery exceeds 10,000 relevant files; narrow .mason/config.json ignore patterns.\");\n }\n const priority = (file: string) => {\n const index = (DOC_CANDIDATES as readonly string[]).findIndex(p => p.toLowerCase() === file.toLowerCase());\n return index < 0 ? DOC_CANDIDATES.length : index;\n };\n return paths.sort((a, b) => priority(a) - priority(b) || a.localeCompare(b));\n}\n\n/** Explicit local entry points may be ignored; preserve their real spelling. */\nasync function localDocPaths(root: string): Promise<string[]> {\n const paths: string[] = [];\n for (const dir of [\".\", \".claude\"]) {\n let entries;\n try { entries = await fs.readdir(await auditInputPath(root, dir), { withFileTypes: true }); }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue; throw error; }\n for (const entry of entries) if (/^(?:agents|claude|readme)\\.md$/i.test(entry.name)) {\n paths.push(path.posix.join(dir, entry.name));\n }\n }\n return paths;\n}\n\nexport function documentScope(file: string): string {\n const parent = path.posix.dirname(file);\n return path.posix.basename(parent).toLowerCase() === \".claude\" ? path.posix.dirname(parent) : parent;\n}\n\nexport async function discoverDocs(resolvedRoot: string): Promise<AuditDoc[]> {\n const docs: AuditDoc[] = [];\n for (const candidate of await discoverDocPaths(resolvedRoot)) {\n const content = await readAuditInput(resolvedRoot, candidate);\n if (content === null) throw new Error(\"Document disappeared during discovery: \" + candidate);\n const [lastCommit, dirty] = await Promise.all([lastCommitOf(resolvedRoot, candidate), isDirty(resolvedRoot, candidate)]);\n docs.push({ path: candidate, content, scope: documentScope(candidate),\n kind: /^readme\\.md$/i.test(path.posix.basename(candidate)) ? \"readme\" : \"instructions\",\n lineCount: content.split(\"\\n\").length, lastCommit, dirty, claims: extractClaims(content) });\n }\n return docs;\n}\n","import type { decisionProvenance } from \"../decisions/provenance.js\";\n\nexport type IssueType =\n | \"deleted-reference\"\n | \"new-module\"\n | \"stale-count\"\n | \"dead-command\";\n\nexport type AdvisoryType = \"deps-changed\" | \"decision-anchor-drift\" | IssueType;\n\nexport type CheckName = IssueType | AdvisoryType;\n\nexport const ALL_CHECKS: CheckName[] = [\n \"deleted-reference\",\n \"new-module\",\n \"stale-count\",\n \"dead-command\",\n \"deps-changed\",\n \"decision-anchor-drift\",\n];\n\n/**\n * \"certain\" — the claim is provably false (a tracked path is gone, a computed\n * count differs, a script is absent from a resolved manifest). \"likely\" is\n * retained for older reports. Inferred scope and speculative omissions are\n * advisory; even a certain mismatch needs semantic review before repair.\n */\nexport type Confidence = \"certain\" | \"likely\";\n\nexport interface CommitRef {\n hash: string;\n date: string;\n subject: string;\n}\n\nexport interface DocAnchor {\n /** Repo-relative doc path, e.g. \"CLAUDE.md\" or \".claude/CLAUDE.md\". */\n doc: string;\n /** 1-based line of the claim; null for doc-level issues (new-module). */\n line: number | null;\n /** The claim exactly as written, e.g. \"src/utils/logger.ts\". */\n excerpt: string | null;\n}\n\nexport interface ClaimScope {\n basis: \"repository\" | \"document\" | \"document-link\" | \"explicit\";\n directory: string;\n /** Exact repository-relative paths/manifests considered by the check. */\n candidates: string[];\n}\n\nexport type Evidence =\n | {\n kind: \"missing-path\";\n claimed: string;\n renamedTo: string | null;\n deletedInCommit: CommitRef | null;\n everTracked: boolean;\n parentDirExists: boolean;\n resolvedPath?: string;\n scope?: ClaimScope;\n }\n | {\n kind: \"unmentioned-dir\";\n dir: string;\n sourceFileCount: number;\n firstCommit: CommitRef | null;\n checkedDocs: string[];\n }\n | {\n kind: \"count-mismatch\";\n claimed: number;\n actual: number;\n unit: string;\n /** Where the actual count came from, e.g. \"package.json workspaces\". */\n countedFrom: string;\n members: string[];\n }\n | {\n kind: \"missing-script\";\n scriptName: string;\n invocation: string;\n manifestsChecked: string[];\n availableScripts: string[];\n scope?: ClaimScope;\n }\n | {\n kind: \"doc-behind-manifests\";\n docLastCommit: CommitRef;\n manifestCommits: Array<CommitRef & { files: string[] }>;\n totalCommits: number;\n }\n | {\n kind: \"decision-anchor\";\n provenance?: ReturnType<typeof decisionProvenance>;\n decisionId: string;\n title: string;\n changedFiles: string[];\n refreshedHash: string;\n };\n\nexport interface AuditIssue {\n type: IssueType;\n message: string;\n anchor: DocAnchor;\n confidence: Confidence;\n evidence: Evidence;\n}\n\n/**\n * Advisories require judgment and never drive the ordinary audit exit code.\n * Historical advisories require a separate review. Explicitly recheckable\n * candidates can cease to be detected without asserting semantic approval.\n */\nexport interface AuditAdvisory {\n type: AdvisoryType;\n message: string;\n anchor: DocAnchor;\n evidence: Evidence;\n resolution?: \"recheck\";\n}\n\nexport interface AuditDocInfo {\n path: string;\n scope?: string;\n kind?: \"instructions\" | \"readme\";\n lastCommit: CommitRef | null;\n /** Uncommitted edits present — deps-changed is suppressed for dirty docs. */\n dirty: boolean;\n lineCount: number;\n}\n\nexport interface AuditReport {\n /** Additive-only schema — this output is a CI contract. */\n version: 1;\n root: string;\n gitAvailable: boolean;\n /** Commit and exact check scope used by this run. */\n headHash?: string;\n checksRun?: CheckName[];\n docs: AuditDocInfo[];\n /** Whether .mason/decisions/ existed and was checked. */\n decisionsChecked: boolean;\n /** Drive exit code 1. */\n issues: AuditIssue[];\n /** Never drive the exit code. */\n advisories: AuditAdvisory[];\n /** Original committed evidence retained while local doc edits suppress reporting. */\n suppressedAdvisories?: AuditAdvisory[];\n skippedChecks: Array<{ check: string; reason: string; doc?: string }>;\n clean: boolean;\n /** Additive assessment status; original advisory evidence remains intact. */\n advisoryReviews?: import(\"./advisory-review.js\").AdvisoryReviewSummary[];\n}\n\nexport interface PathClaim {\n path: string;\n line: number;\n excerpt: string;\n /** Markdown links resolve against the physical document directory. */\n relativeTo?: \"document\";\n}\n\nexport interface CountClaim {\n count: number;\n unit: string;\n line: number;\n excerpt: string;\n}\n\nexport interface CommandClaim {\n scriptName: string;\n invocation: string;\n line: number;\n excerpt: string;\n /** A literal cd/directory flag, relative to the document's assumed cwd. */\n directory?: string;\n scopeUnknown?: string;\n}\n\nexport interface DocClaims {\n paths: PathClaim[];\n counts: CountClaim[];\n commands: CommandClaim[];\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { auditInputPath } from \"./inputs.js\";\nimport { documentScope } from \"./docs.js\";\nimport type { ClaimScope, PathClaim } from \"./types.js\";\n\n/** Lexical containment, before inspecting any path from documentation. */\nexport function scopedPath(directory: string, value: string): string | null {\n if (path.posix.isAbsolute(value) || value.includes(\"\\\\\") || /[\\x00-\\x1f]/.test(value)) return null;\n const resolved = path.posix.normalize(path.posix.join(directory, value));\n return resolved === \"..\" || resolved.startsWith(\"../\") ? null : resolved;\n}\n\nexport function pathClaimScope(doc: string, claim: PathClaim): ClaimScope | null {\n const directory = claim.relativeTo === \"document\" ? path.posix.dirname(doc) : documentScope(doc);\n const local = scopedPath(directory, claim.path);\n if (!local) return null;\n const candidates = claim.relativeTo === \"document\" || directory === \".\" ? [local]\n : [...new Set([local, scopedPath(\".\", claim.path)].filter((p): p is string => p !== null))];\n return { basis: claim.relativeTo === \"document\" ? \"document-link\" : directory === \".\" ? \"repository\" : \"document\",\n directory, candidates };\n}\n\n/** Missing is distinct from unreadable/unsafe; cache and checks use the same observation. */\nexport async function pathExists(root: string, file: string): Promise<boolean> {\n try { await fs.access(await auditInputPath(root, file)); return true; }\n catch (error) {\n // A child of a regular file cannot exist either. Keep symlink and access\n // failures distinct: neither establishes that a reference is missing.\n if ([\"ENOENT\", \"ENOTDIR\"].includes((error as NodeJS.ErrnoException).code ?? \"\")) return false;\n throw error;\n }\n}\n\nexport function gitMetadataPath(file: string): boolean {\n return file.split(\"/\").includes(\".git\");\n}\n\nexport function optionalMasonPath(file: string): boolean {\n return file.split(\"/\").includes(\".mason\");\n}\n","import path from \"node:path\";\nimport { deletingCommitOf, lastCommitOf } from \"../git.js\";\nimport { gitMetadataPath, optionalMasonPath, pathClaimScope, pathExists } from \"../scope.js\";\nimport type { Evidence } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/** Prove removed references only when their scope is resolved. */\nexport async function checkDeletedReferences(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n for (const doc of ctx.docs) {\n const changes = ctx.changesSinceDoc.get(doc.path);\n const renames = new Map((changes ?? []).filter(c => c.status === \"renamed\" && c.previousPath)\n .map(c => [c.previousPath!, c.path]));\n for (const claim of doc.claims.paths) {\n const scope = pathClaimScope(doc.path, claim);\n if (!scope) {\n result.skipped.push({ check: \"deleted-reference\", doc: doc.path,\n reason: `Reference ${claim.excerpt} is outside the repository or has an unsupported path.` });\n continue;\n }\n if (scope.candidates.some(optionalMasonPath)) continue;\n if (scope.candidates.some(gitMetadataPath)) {\n result.skipped.push({ check: \"deleted-reference\", doc: doc.path,\n reason: `Reference ${claim.path} names Git metadata, whose layout varies between checkouts; it was not verified as a repository file.` });\n continue;\n }\n if ((await Promise.all(scope.candidates.map(file => pathExists(ctx.root, file)))).some(Boolean)) continue;\n\n const candidates = await Promise.all(scope.candidates.map(async file => ({ file,\n tracked: await lastCommitOf(ctx.root, file), parent: await pathExists(ctx.root, path.posix.dirname(file)) })));\n const candidate = candidates.find(c => c.tracked || renames.has(c.file)) ?? candidates.find(c => c.parent);\n // No history/parent for a bare path is usually an illustrative example.\n if (!candidate && claim.relativeTo !== \"document\") continue;\n const resolvedPath = candidate?.file ?? scope.candidates[0];\n const renamedTo = renames.get(resolvedPath) ?? null;\n const deletedInCommit = candidate?.tracked && !renamedTo ? await deletingCommitOf(ctx.root, resolvedPath) : null;\n const evidence: Evidence = { kind: \"missing-path\", claimed: claim.path, resolvedPath, scope,\n renamedTo, deletedInCommit, everTracked: !!candidate?.tracked || !!renamedTo, parentDirExists: candidate?.parent ?? false };\n const anchor = { doc: doc.path, line: claim.line, excerpt: claim.excerpt };\n const message = renamedTo ? `\\`${resolvedPath}\\` was renamed to \\`${renamedTo}\\``\n : `\\`${resolvedPath}\\` does not exist` + (deletedInCommit\n ? ` – deleted in ${deletedInCommit.hash.slice(0, 7)} \"${deletedInCommit.subject}\" (${deletedInCommit.date.slice(0, 10)})` : \"\");\n if (scope.basis !== \"document\" && (renamedTo || candidate?.tracked)) {\n result.issues.push({ type: \"deleted-reference\", message, anchor, confidence: \"certain\", evidence });\n } else {\n result.advisories.push({ resolution: \"recheck\", type: \"deleted-reference\", message: message + (scope.basis === \"document\"\n ? \"; the bare path's document/repository scope needs review.\"\n : \"; no tracked history establishes it as a required file. Review for a typo, generated output, or example.\"), anchor, evidence });\n }\n }\n }\n return result;\n}\n","import fg from \"fast-glob\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { loadProjectConfig, SOURCE_IGNORE } from \"../../utils/files.js\";\nimport { auditGlob, auditInputPath, gitIgnoredPaths, gitSourcePaths } from \"../inputs.js\";\nimport { firstCommitOf } from \"../git.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/** Directories that are never \"modules\" worth documenting. */\nconst DIR_DENYLIST = new Set([\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \"target\",\n \"vendor\",\n \"__pycache__\",\n \"venv\",\n \".venv\",\n \".git\",\n \".gradle\",\n \".mason\",\n \".claude\",\n \".github\",\n \".vscode\",\n \".idea\",\n]);\n\n/** Second-level dirs need a bit more substance before they count. */\nconst SECOND_LEVEL_MIN_SOURCE_FILES = 2;\n/**\n * Descend into a top-level dir only when the docs evidently enumerate its\n * children — at least this many of its subdirs already mentioned.\n */\nconst ENUMERATION_THRESHOLD = 2;\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Word-boundary mention check across the union of all docs — `app` must not\n * match \"application\", and a dir mentioned only in AGENTS.md must not be\n * flagged against CLAUDE.md.\n */\nfunction isMentioned(combinedDocs: string, name: string): boolean {\n const re = new RegExp(\n `(^|[^A-Za-z0-9_-])${escapeRegExp(name)}(/|[^A-Za-z0-9_-]|$)`,\n \"im\"\n );\n return re.test(combinedDocs);\n}\n\nexport async function checkNewModules(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n if (ctx.docs.length === 0) return result;\n\n const combinedDocs = moduleDocumentation(ctx.docs);\n const primaryDoc = ctx.docs[0].path;\n const checkedDocs = ctx.docs.map((d) => d.path);\n\n const flag = async (dir: string, sourceFileCount: number): Promise<void> => {\n result.advisories.push({\n resolution: \"recheck\",\n type: \"new-module\",\n message: `directory \\`${dir}/\\` contains ${sourceFileCount} source file${sourceFileCount === 1 ? \"\" : \"s\"} but is not mentioned in the discovered documentation; review whether it needs documenting`,\n anchor: { doc: primaryDoc, line: null, excerpt: dir },\n evidence: {\n kind: \"unmentioned-dir\",\n dir,\n sourceFileCount,\n firstCommit: await firstCommitOf(ctx.root, dir),\n checkedDocs,\n },\n });\n };\n\n for (const candidate of await moduleCandidates(ctx.root, combinedDocs)) {\n await flag(candidate.dir, candidate.sourceFileCount);\n }\n\n return result;\n}\n\n/** Nested documentation establishes a directory is documented without requiring\n * every package README to repeat its full repository path. */\nexport function moduleDocumentation(docs: Array<{ path: string; content: string }>): string {\n return docs.map(doc => doc.content + \"\\n\" + (path.posix.dirname(doc.path) === \".\" ? \"\" : path.posix.dirname(doc.path) + \"/\")).join(\"\\n\");\n}\n\n/** Shared dependency witness: cache exactly the module candidates the audit observes. */\nexport async function moduleCandidates(root: string, combinedDocs: string) {\n const [config, sourcePaths] = await Promise.all([loadProjectConfig(root), gitSourcePaths(root)]);\n const ignore = [...SOURCE_IGNORE, ...(config.ignore ?? [])];\n const sources = sourcePaths.filter(file => !file.split(\"/\").some(part => part.startsWith(\".\")));\n const listSubdirs = async (dir: string): Promise<string[]> => {\n const entries = await fs.readdir(await auditInputPath(root, dir), { withFileTypes: true });\n // A directory alias is not another source module. Only inspect a link\n // when Git's source inventory actually requires paths beneath it (for\n // example, a tracked source directory replaced by a local symlink).\n const dirs = entries.filter(entry => (entry.isDirectory() || entry.isSymbolicLink()\n && sources.some(file => file.startsWith(path.posix.join(dir, entry.name) + \"/\")))\n && !entry.name.startsWith(\".\") && !DIR_DENYLIST.has(entry.name))\n .map(entry => path.posix.join(dir, entry.name));\n const ignored = await gitIgnoredPaths(root, dirs);\n // An ignore rule does not remove already tracked source from the audit.\n const visible = new Set(dirs.filter(dir => !ignored.has(dir) || sources.some(file => file.startsWith(dir + \"/\"))));\n return (await auditGlob(root, dir === \".\" ? \"*\" : `${fg.escapePath(dir)}/*`, {\n ignore, onlyDirectories: true, label: \"Module directory discovery\", select: file => visible.has(file),\n })).map(file => path.posix.basename(file));\n };\n const countSourceFiles = async (dir: string): Promise<number> => {\n const files = sources.filter(file => file.startsWith(dir + \"/\"));\n let count = 0;\n // Literal path batches avoid compiling one enormous glob pattern set in a\n // genuinely large source module. Apply exclusions before counting results.\n for (let offset = 0; offset < files.length; offset += 256) {\n count += (await auditGlob(root, files.slice(offset, offset + 256).map(file => fg.escapePath(file)), {\n ignore, followSymbolicLinks: false, label: `Source discovery in ${dir}`,\n })).length;\n if (count > 100000) throw new Error(`Source discovery in ${dir} exceeds 100,000 relevant files. Exclude generated source with .mason/config.json ignore patterns or narrow this audit's checks.`);\n }\n return count;\n };\n const candidates: Array<{ dir: string; sourceFileCount: number }> = [];\n for (const topDir of await listSubdirs(\".\")) {\n const topMentioned = isMentioned(combinedDocs, topDir);\n\n if (!topMentioned) {\n const count = await countSourceFiles(topDir);\n if (count >= 1) candidates.push({ dir: topDir, sourceFileCount: count });\n continue;\n }\n\n // The docs know this dir. If they enumerate its children (several\n // subdirs already mentioned), an unmentioned sibling is drift — this is\n // how a freshly added module under src/ gets caught.\n const subdirs = await listSubdirs(topDir);\n const mentioned = subdirs.filter((s) => isMentioned(combinedDocs, s));\n if (mentioned.length < ENUMERATION_THRESHOLD) continue;\n\n for (const sub of subdirs) {\n if (isMentioned(combinedDocs, sub)) continue;\n const count = await countSourceFiles(`${topDir}/${sub}`);\n if (count >= SECOND_LEVEL_MIN_SOURCE_FILES) {\n candidates.push({ dir: `${topDir}/${sub}`, sourceFileCount: count });\n }\n }\n }\n\n return candidates;\n}\n","import path from \"node:path\";\nimport { documentScope } from \"../docs.js\";\nimport { auditGlob, readAuditInput } from \"../inputs.js\";\nimport type { CountClaim } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst MEMBERS_CAP = 50;\n\ninterface CountSource {\n actual: number;\n countedFrom: string;\n members: string[];\n}\n\nasync function countGradleModules(root: string): Promise<CountSource | null> {\n for (const name of [\"settings.gradle.kts\", \"settings.gradle\"]) {\n const content = await readAuditInput(root, name);\n if (content === null) continue;\n // include(\":a\", \":b\") — count quoted project strings, not include() calls.\n const members: string[] = [];\n for (const call of content.matchAll(/include\\s*\\(([^)]*)\\)/g)) {\n for (const proj of call[1].matchAll(/[\"']([^\"']+)[\"']/g)) {\n members.push(proj[1]);\n }\n }\n if (members.length === 0) return null;\n return { actual: members.length, countedFrom: name, members };\n }\n return null;\n}\n\nasync function countNpmWorkspaces(root: string): Promise<CountSource | null> {\n const pkgRaw = await readAuditInput(root, \"package.json\");\n if (pkgRaw !== null) {\n let globs: string[] = [];\n try {\n const pkg = JSON.parse(pkgRaw);\n globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : [];\n } catch {\n // Malformed package.json — nothing provable here.\n }\n if (globs.length > 0) {\n const matched = await auditGlob(root,\n globs.map((g) => `${g.replace(/\\/+$/, \"\")}/package.json`),\n { ignore: [\"**/node_modules/**\"], label: \"npm workspace discovery\" }\n );\n return {\n actual: matched.length,\n countedFrom: \"package.json workspaces\",\n members: matched.map((m) => path.dirname(m)).sort(),\n };\n }\n }\n\n const pnpmRaw = await readAuditInput(root, \"pnpm-workspace.yaml\");\n if (pnpmRaw !== null) {\n const globs: string[] = [];\n let inPackages = false;\n for (const line of pnpmRaw.split(\"\\n\")) {\n if (/^packages\\s*:/.test(line)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n const entry = line.match(/^\\s*-\\s*[\"']?([^\"'#\\s]+)/);\n if (entry) {\n if (!entry[1].startsWith(\"!\")) globs.push(entry[1]);\n } else if (line.trim().length > 0 && !line.startsWith(\" \")) {\n inPackages = false;\n }\n }\n }\n if (globs.length > 0) {\n const matched = await auditGlob(root,\n globs.map((g) => `${g.replace(/\\/+$/, \"\")}/package.json`),\n { ignore: [\"**/node_modules/**\"], label: \"pnpm workspace discovery\" }\n );\n return {\n actual: matched.length,\n countedFrom: \"pnpm-workspace.yaml\",\n members: matched.map((m) => path.dirname(m)).sort(),\n };\n }\n }\n return null;\n}\n\nasync function countCargoCrates(root: string): Promise<CountSource | null> {\n const content = await readAuditInput(root, \"Cargo.toml\");\n if (content === null) return null;\n const membersBlock = content.match(/members\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (!membersBlock) return null;\n const entries = [...membersBlock[1].matchAll(/[\"']([^\"']+)[\"']/g)].map(\n (m) => m[1]\n );\n if (entries.length === 0) return null;\n\n // Workspace members may be globs (\"crates/*\") — resolve them against\n // directories that actually contain a Cargo.toml.\n const members = new Set<string>();\n for (const entry of entries) {\n if (/[*?[\\]{}]/.test(entry)) {\n const matched = await auditGlob(root, `${entry.replace(/\\/+$/, \"\")}/Cargo.toml`, {\n ignore: [\"**/target/**\"],\n label: \"Cargo workspace discovery\",\n });\n for (const m of matched) members.add(path.dirname(m));\n } else if (\n (await readAuditInput(root, path.posix.join(entry, \"Cargo.toml\"))) !== null\n ) {\n members.add(entry);\n }\n }\n if (members.size === 0) return null;\n return {\n actual: members.size,\n countedFrom: \"Cargo.toml workspace members\",\n members: [...members].sort(),\n };\n}\n\n/**\n * Map a claim's unit to the ecosystem that can prove it. When the mapped\n * ecosystem has no workspace manifest in this repo, the claim is skipped —\n * \"12 packages\" in a Gradle repo proves nothing either way.\n */\nexport async function resolveCountSource(\n root: string,\n claim: CountClaim\n): Promise<CountSource | null> {\n const unit = claim.unit.replace(/s$/, \"\");\n if (unit === \"module\") return countGradleModules(root);\n if (unit === \"workspace\") return countNpmWorkspaces(root);\n if (unit === \"crate\") return countCargoCrates(root);\n // \"packages\" is ecosystem-ambiguous — first manifest that resolves wins.\n return (\n (await countNpmWorkspaces(root)) ??\n (await countCargoCrates(root)) ??\n (await countGradleModules(root))\n );\n}\n\n/** Nested documents cannot assert the root workspace's count implicitly. */\nexport async function resolveDocCountSource(root: string, doc: string, claim: CountClaim): Promise<CountSource | null> {\n const scope = documentScope(doc);\n const source = await resolveCountSource(path.join(root, scope), claim);\n if (!source || scope === \".\") return source;\n return { ...source, countedFrom: scope + \"/\" + source.countedFrom,\n members: source.members.map(member => scope + \"/\" + member) };\n}\n\nexport async function checkStaleCounts(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n\n for (const doc of ctx.docs) {\n for (const claim of doc.claims.counts) {\n const source = await resolveDocCountSource(ctx.root, doc.path, claim);\n if (source === null) {\n result.skipped.push({ check: \"stale-count\", doc: doc.path,\n reason: `${doc.path}: cannot resolve a workspace manifest for \"${claim.excerpt}\"` });\n continue;\n }\n if (source.actual === claim.count) continue;\n result.issues.push({\n type: \"stale-count\",\n message: `says \"${claim.excerpt}\" but ${source.countedFrom} resolves to ${source.actual}`,\n anchor: { doc: doc.path, line: claim.line, excerpt: claim.excerpt },\n confidence: \"certain\",\n evidence: {\n kind: \"count-mismatch\",\n claimed: claim.count,\n actual: source.actual,\n unit: claim.unit,\n countedFrom: source.countedFrom,\n members: source.members.slice(0, MEMBERS_CAP),\n },\n });\n }\n }\n\n return result;\n}\n","import path from \"node:path\";\nimport { auditGlob, readAuditInput } from \"../inputs.js\";\nimport { documentScope } from \"../docs.js\";\nimport { scopedPath } from \"../scope.js\";\nimport type { ClaimScope, CommandClaim } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst AVAILABLE_SCRIPTS_CAP = 30;\nfunction scriptsOf(raw: string): string[] | null {\n try {\n const pkg = JSON.parse(raw);\n if (!pkg || typeof pkg !== \"object\" || Array.isArray(pkg)) return null;\n if (pkg.scripts === undefined) return [];\n return pkg.scripts && typeof pkg.scripts === \"object\" && !Array.isArray(pkg.scripts)\n && Object.values(pkg.scripts).every(value => typeof value === \"string\") ? Object.keys(pkg.scripts) : null;\n } catch { return null; }\n}\n\ninterface Resolution {\n doc: string; claim: CommandClaim; scope: ClaimScope; manifest: string | null;\n scripts: string[]; elsewhere: string[]; problem?: string;\n}\n\n/** Shared dependency resolver: the cache records every manifest actually consulted. */\nexport async function commandInputs(root: string, docs: Array<{ path: string; claims: { commands: CommandClaim[] } }>) {\n const contents = new Map<string, string | null>();\n const read = async (file: string) => {\n if (!contents.has(file)) contents.set(file, await readAuditInput(root, file));\n return contents.get(file)!;\n };\n await read(\"package.json\");\n let inventory: string[] | undefined;\n const resolutions: Resolution[] = [];\n for (const doc of docs) for (const claim of doc.claims.commands) {\n const base = documentScope(doc.path);\n const directory = scopedPath(base, claim.directory ?? \".\");\n const scope: ClaimScope = { basis: claim.directory === undefined ? \"document\" : \"explicit\",\n directory: directory ?? base, candidates: [] };\n const resolution: Resolution = { doc: doc.path, claim, scope, manifest: null, scripts: [], elsewhere: [] };\n resolutions.push(resolution);\n if (claim.scopeUnknown || directory === null) {\n resolution.problem = claim.scopeUnknown ?? \"The command's directory leaves the repository.\";\n continue;\n }\n let cursor = directory;\n while (true) {\n const manifest = path.posix.join(cursor, \"package.json\");\n scope.candidates.push(manifest);\n const raw = await read(manifest);\n if (raw !== null) {\n resolution.manifest = manifest;\n const scripts = scriptsOf(raw);\n if (scripts === null) resolution.problem = \"Invalid package manifest: \" + manifest;\n else resolution.scripts = scripts;\n break;\n }\n // An explicit directory is a declared execution scope, never silently use a sibling.\n if (claim.directory !== undefined || cursor === \".\") break;\n cursor = path.posix.dirname(cursor);\n }\n if (!resolution.manifest && !resolution.problem) {\n resolution.problem = `No package.json for the command's scope (${directory}).`;\n }\n if (resolution.problem || resolution.scripts.includes(claim.scriptName) || claim.directory !== undefined) continue;\n inventory ??= await commandManifests(root);\n for (const manifest of [...new Set([\"package.json\", ...inventory])].sort()) {\n if (scope.candidates.includes(manifest)) continue;\n scope.candidates.push(manifest);\n const raw = await read(manifest);\n if (raw === null) continue;\n const scripts = scriptsOf(raw);\n if (scripts === null) resolution.problem = \"Cannot establish script availability: invalid manifest \" + manifest;\n else if (scripts.includes(claim.scriptName)) resolution.elsewhere.push(manifest);\n }\n }\n return { manifests: [...contents].sort(([a], [b]) => a.localeCompare(b)), resolutions };\n}\n\nexport async function checkDeadCommands(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n const { resolutions } = await commandInputs(ctx.root, ctx.docs);\n for (const { doc, claim, scope, scripts, elsewhere, problem, manifest } of resolutions) {\n if (problem) {\n result.skipped.push({ check: \"dead-command\", doc, reason: problem });\n continue;\n }\n if (scripts.includes(claim.scriptName)) continue;\n const evidence = { kind: \"missing-script\" as const, scriptName: claim.scriptName, invocation: claim.invocation,\n manifestsChecked: scope.candidates, availableScripts: scripts.slice(0, AVAILABLE_SCRIPTS_CAP), scope };\n const anchor = { doc, line: claim.line, excerpt: claim.excerpt };\n const message = `\\`${claim.invocation}\\` names script \"${claim.scriptName}\", which is absent from ${manifest}`;\n // Nested docs imply a package, but may describe commands run from another cwd.\n const certain = documentScope(doc) === \".\" && (scope.basis === \"explicit\" || !elsewhere.length);\n if (certain) result.issues.push({ type: \"dead-command\", message, anchor, confidence: \"certain\", evidence });\n else result.advisories.push({ resolution: \"recheck\", type: \"dead-command\", message: message + (elsewhere.length\n ? `; it exists in ${elsewhere.join(\", \")}. Clarify the intended working directory.`\n : \"; the intended working directory needs review.\"), anchor, evidence });\n }\n return result;\n}\n\n/** Ignored workspace manifests may still be explicit command dependencies. */\nexport function commandManifests(root: string): Promise<string[]> {\n return auditGlob(root, \"**/package.json\", {\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \".mason/reports/**\", \"package.json\"],\n label: \"Command manifest discovery\",\n });\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { RangeCommits } from \"./git.js\";\n\nconst exec = promisify(execFile);\nasync function git(root: string, args: string[]) {\n return (await exec(\"git\", args, { cwd: root, timeout: 10000, maxBuffer: 2 * 1024 * 1024 })).stdout;\n}\n\n/** A deliberately narrow recognizer, not a Gradle evaluator. Unknown syntax stays advisory. */\nfunction withoutAndroidReleaseValues(text: string): string | null {\n if (/\\/\\*|\"\"\"|'''/.test(text) || !/id\\s*\\(?\\s*[\"']com\\.android\\.(application|library)[\"']/.test(text)) return null;\n const scopes: string[] = [];\n const normalized: string[] = [];\n let assignments = 0;\n for (const line of text.split(\"\\n\")) {\n // Remove ordinary quoted strings and line comments solely for brace tracking.\n const code = line.replace(/\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\/\\/.*$/g, token => token.startsWith(\"//\") ? \"\" : '\"\"');\n const assignment = line.match(/^(\\s*)(versionName|versionCode)(\\s*(?:=\\s*|\\s+))(\"[A-Za-z0-9._+-]+\"|'[A-Za-z0-9._+-]+'|\\d+)(\\s*)$/);\n if (assignment && scopes.join(\"/\") === \"android/defaultConfig\" &&\n (assignment[2] === \"versionCode\" ? /^\\d+$/.test(assignment[4]) : /^[\"']/.test(assignment[4]))) {\n normalized.push(assignment[1] + assignment[2] + assignment[3] + \"<release-value>\" + assignment[5]);\n assignments++;\n } else {\n // References can feed dependency coordinates or other executable configuration.\n if (/\\bversion(?:Name|Code)\\b/.test(line)) return null;\n normalized.push(line);\n }\n const named = code.match(/^\\s*(android|defaultConfig)\\s*\\{\\s*$/)?.[1];\n for (const brace of code.matchAll(/[{}]/g)) {\n if (brace[0] === \"{\") scopes.push(named ?? \"unknown\");\n else if (!scopes.length) return null;\n else scopes.pop();\n }\n }\n return assignments && !scopes.length ? normalized.join(\"\\n\") : null;\n}\n\n/** Only omit single-parent commits whose every touched manifest is proven release metadata. */\nexport async function releaseMetadataOnly(root: string, commit: RangeCommits[\"commits\"][number]): Promise<boolean> {\n if (!commit.files.length || !commit.files.every(file => /(^|\\/)build\\.gradle(?:\\.kts)?$/.test(file))) return false;\n try {\n const parents = (await git(root, [\"rev-list\", \"--parents\", \"-n\", \"1\", commit.hash])).trim().split(/\\s+/);\n if (parents.length !== 2) return false;\n for (const file of commit.files) {\n const raw = await git(root, [\"diff\", \"--raw\", \"-z\", \"--no-renames\", \"--no-ext-diff\", \"--no-textconv\", parents[1], commit.hash, \"--\", file]);\n if (!/^:(100644|100755) \\1 [a-f0-9]+ [a-f0-9]+ M\\0/.test(raw)) return false;\n const [before, after] = await Promise.all([\n git(root, [\"show\", parents[1] + \":\" + file]), git(root, [\"show\", commit.hash + \":\" + file]),\n ]);\n const previous = withoutAndroidReleaseValues(before);\n if (previous === null || previous !== withoutAndroidReleaseValues(after)) return false;\n }\n return true;\n } catch { return false; }\n}\n","import { documentScope } from \"../docs.js\";\nimport { releaseMetadataOnly } from \"../release-metadata.js\";\nimport { commitsTouchingSince } from \"../git.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst MANIFEST_COMMITS_CAP = 10;\n\n/**\n * Tracked manifest files at any depth. Lockfiles are pure churn and are\n * deliberately not matched.\n */\nconst MANIFEST_PATHSPECS = [\n \":(glob)**/package.json\",\n \":(glob)**/build.gradle.kts\",\n \":(glob)**/build.gradle\",\n \"settings.gradle.kts\",\n \"settings.gradle\",\n \"gradle/libs.versions.toml\",\n \":(glob)**/Cargo.toml\",\n \"go.mod\",\n \"pyproject.toml\",\n \"requirements.txt\",\n \"Gemfile\",\n \"composer.json\",\n];\n\n/** Share exact dependency scope with persisted advisory assessments. */\nexport function manifestPathspecs(doc: string): string[] {\n const scope = documentScope(doc);\n if (scope === \".\") return MANIFEST_PATHSPECS;\n const escaped = scope.replace(/[\\\\*?\\[\\]]/g, \"\\\\$&\");\n return MANIFEST_PATHSPECS.map(spec => spec.startsWith(\":(glob)\")\n ? \":(glob)\" + escaped + \"/\" + spec.slice(\":(glob)\".length) : \":(literal)\" + scope + \"/\" + spec);\n}\n\n/**\n * Advisory, never an issue: a manifest commit after the doc's last commit\n * proves recency ordering, not that any specific claim is false — and it can\n * never be closed by editing the doc within the same run.\n */\nexport async function checkDepsChanged(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n result.suppressedAdvisories = [];\n const releaseOnly = new Map<string, boolean>();\n\n for (const doc of ctx.docs) {\n if (!doc.lastCommit) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path} has no commit history`,\n });\n continue;\n }\n if (doc.dirty) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path} has uncommitted edits – suppressed while in flight`,\n });\n }\n\n const range = await commitsTouchingSince(\n ctx.root,\n doc.lastCommit.hash,\n manifestPathspecs(doc.path)\n );\n if (range === null) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path}: commit range unreachable (shallow clone?)`,\n });\n continue;\n }\n // Bound extra history reads. Older/ambiguous commits remain advisory.\n const relevant = [];\n for (const commit of range.commits) {\n if (!releaseOnly.has(commit.hash) && releaseOnly.size < 100) {\n releaseOnly.set(commit.hash, await releaseMetadataOnly(ctx.root, commit));\n }\n if (!releaseOnly.get(commit.hash)) relevant.push(commit);\n }\n range.commits = relevant;\n range.total = relevant.length;\n if (range.total === 0) continue;\n\n const latest = range.commits[0];\n (doc.dirty ? result.suppressedAdvisories : result.advisories).push({\n type: \"deps-changed\",\n message: `dependency manifests touched by ${range.total} commit${range.total === 1 ? \"\" : \"s\"} since ${doc.path} was last committed (latest: ${latest.hash.slice(0, 7)} \"${latest.subject}\")`,\n anchor: { doc: doc.path, line: null, excerpt: null },\n evidence: {\n kind: \"doc-behind-manifests\",\n docLastCommit: doc.lastCommit,\n manifestCommits: range.commits.slice(0, MANIFEST_COMMITS_CAP),\n totalCommits: range.total,\n },\n });\n }\n\n return result;\n}\n","import path from \"node:path\";\n\n// Question/filler words that carry no signal about which entry a task\n// touches. Domain words (\"auth\", \"drift\") are never in this list.\nconst STOPWORDS = new Set([\n \"the\", \"a\", \"an\", \"and\", \"or\", \"of\", \"to\", \"in\", \"on\", \"for\", \"with\",\n \"how\", \"does\", \"do\", \"is\", \"are\", \"was\", \"what\", \"where\", \"which\", \"why\",\n \"when\", \"who\", \"i\", \"we\", \"my\", \"our\", \"you\", \"your\", \"it\", \"its\", \"this\",\n \"that\", \"these\", \"those\", \"can\", \"could\", \"should\", \"would\", \"will\",\n \"want\", \"need\", \"please\", \"about\", \"into\", \"from\", \"when\", \"there\", \"any\",\n \"all\", \"some\", \"not\", \"but\", \"also\", \"just\", \"like\", \"get\", \"make\", \"use\",\n \"new\", \"work\", \"works\", \"working\", \"implement\", \"implemented\", \"change\",\n \"changed\", \"file\", \"files\", \"code\",\n]);\n\n/** Split camelCase/PascalCase/kebab/snake/path into lowercase word tokens. */\nexport function tokenize(text: string): string[] {\n return text\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 2 && !STOPWORDS.has(t));\n}\n\n/** Crude singular/plural folding so \"flows\" matches \"flow\" etc. */\nexport function stem(token: string): string {\n return token.length > 3 && token.endsWith(\"s\") ? token.slice(0, -1) : token;\n}\n\nexport function tokenSet(text: string): Set<string> {\n return new Set(tokenize(text).map(stem));\n}\n\nexport interface Scorable {\n name: string;\n description: string;\n files: string[];\n}\n\n/**\n * Lexical relevance of one entry to the task. Name hits are the strongest\n * signal, then description, then file-path words. Each distinct task token\n * counts once at its best weight, so a token appearing everywhere doesn't\n * triple-count.\n */\nexport function scoreEntry(taskTokens: Set<string>, entry: Scorable): number {\n const nameTokens = tokenSet(entry.name);\n const descTokens = tokenSet(entry.description);\n const fileTokens = tokenSet(entry.files.map((f) => path.basename(f)).join(\" \"));\n\n let score = 0;\n for (const token of taskTokens) {\n if (nameTokens.has(token)) score += 3;\n else if (descTokens.has(token)) score += 1;\n else if (fileTokens.has(token)) score += 1;\n }\n return score;\n}\n\n/** Jaccard similarity of two token sets: |∩| / |∪|, 0 when both empty. */\nexport function jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n let intersection = 0;\n for (const token of a) if (b.has(token)) intersection++;\n return intersection / (a.size + b.size - intersection);\n}\n","export type Freshness = \"current\" | \"changed\" | \"unknown\";\nexport interface TrustState {\n freshness: Freshness;\n verification: \"unverified\" | \"passed\" | \"failed\";\n verifiedAt?: string;\n verifiedHash?: string;\n reasons: string[];\n}\n\nexport function assessTrust(entry: { verifiedAt?: string; verifiedHash?: string; verificationFailed?: boolean; verificationNote?: string }, freshness: Freshness): TrustState {\n const verification = entry.verificationFailed ? \"failed\" : entry.verifiedAt ? \"passed\" : \"unverified\";\n const reasons: string[] = [];\n if (freshness === \"unknown\") reasons.push(\"Anchors, history, or working-tree evidence are unavailable; verify before relying on this entry.\");\n if (freshness === \"changed\") reasons.push(\"Anchored files changed; verify against current code before relying on this entry.\");\n if (verification === \"failed\") reasons.push(`Verification failed: ${entry.verificationNote ?? \"re-map this entry before relying on it\"}`);\n if (verification === \"unverified\") reasons.push(\"No correctness verification has been recorded.\");\n return { freshness, verification, verifiedAt: entry.verifiedAt, verifiedHash: entry.verifiedHash, reasons };\n}\n\nexport function trustHint(states: TrustState[]): string {\n const parts: string[] = [];\n if (states.some(s => s.verification === \"failed\")) parts.push(\"Verification failed for returned entries; do not rely on those descriptions until corrected.\");\n if (states.some(s => s.freshness === \"unknown\")) parts.push(\"Freshness is unknown for some returned entries; inspect their files before relying on them.\");\n if (states.some(s => s.freshness === \"changed\")) parts.push(\"Some returned entries have changed files, including possible local edits; verify against the current code.\");\n if (!parts.length) parts.push(\"No changes detected in the returned anchors. This does not prove the descriptions are correct.\");\n if (states.some(s => s.verification === \"unverified\")) parts.push(\"Some entries have never been verified; read their evidence or use verify_snapshot for map descriptions.\");\n return parts.join(\" \");\n}\n","import { z } from \"zod\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { assessTrust, type Freshness } from \"../context/trust.js\";\n\nconst text = (max: number) => z.string().trim().min(1).max(max);\nexport const decisionSourceSchema = z.object({\n kind: z.enum([\"pull_request\", \"issue\", \"incident\", \"discussion\", \"document\", \"other\"]),\n reference: text(1000),\n note: text(500).optional(),\n}).strict();\nexport type DecisionSource = z.infer<typeof decisionSourceSchema>;\nexport const attributionSchema = z.object({\n owner: text(200).nullable().optional(),\n sources: z.array(decisionSourceSchema).max(20).optional(),\n actor: text(200).optional(),\n});\nconst contentSchema = z.object({\n title: z.string().min(1), body: z.string().min(1),\n category: z.enum([\"decision\", \"gotcha\", \"deprecation\", \"convention\"]),\n files: z.array(z.string().refine(f => normalizeRepoPath(f) !== null)),\n owner: text(200).optional(), sources: z.array(decisionSourceSchema).max(20),\n});\nconst approvalSchema = z.enum([\"unreviewed\", \"proposed\", \"accepted\"]);\nconst statusSchema = z.enum([\"active\", \"superseded\", \"retired\"]);\nexport const reviewEvidenceSchema = z.object({\n baseHash: z.string(), headHash: z.string(), historyAvailable: z.boolean(),\n changedFiles: z.array(z.string()), localChanges: z.array(z.string()),\n});\nconst eventSchema = z.object({\n kind: z.enum([\"imported\", \"created\", \"revised\", \"accepted\", \"reaffirmed\", \"retired\", \"superseded\"]),\n at: z.string().datetime(), actor: text(200).optional(), note: text(1500).optional(),\n revision: z.number().int().positive(), content: contentSchema,\n approval: approvalSchema, status: statusSchema, refreshedHash: z.string(),\n evidence: reviewEvidenceSchema.optional(),\n});\nexport type DecisionEvent = z.infer<typeof eventSchema>;\nexport type DecisionApproval = z.infer<typeof approvalSchema>;\nexport type DecisionContent = z.infer<typeof contentSchema>;\n\nconst legacySchema = z.object({\n version: z.literal(1), id: z.string().regex(/^[a-zA-Z0-9_-]+$/),\n title: z.string().min(1), body: z.string().min(1),\n category: contentSchema.shape.category, files: contentSchema.shape.files,\n createdAt: z.string(), updatedAt: z.string(), refreshedHash: z.string(),\n status: z.enum([\"active\", \"superseded\"]), supersededBy: z.string().optional(),\n}).passthrough();\nconst currentSchema = legacySchema.extend({\n version: z.literal(2), status: statusSchema,\n approval: approvalSchema, revision: z.number().int().positive(),\n owner: text(200).optional(), sources: z.array(decisionSourceSchema).max(20),\n history: z.array(eventSchema).min(1),\n}).superRefine((record, ctx) => {\n const invalid = (message: string) => ctx.addIssue({ code: \"custom\", message });\n const same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\n let previous: DecisionEvent | undefined;\n for (const event of record.history) {\n if (!previous) {\n if (![\"created\", \"imported\"].includes(event.kind) || event.revision !== 1) invalid(\"History must begin with creation or legacy import at revision 1\");\n if (event.approval !== (event.kind === \"created\" ? \"proposed\" : \"unreviewed\")) invalid(\"Initial records cannot claim acceptance\");\n } else {\n if ([\"created\", \"imported\"].includes(event.kind)) invalid(\"History cannot restart\");\n if (previous.status !== \"active\") invalid(\"Archived decisions cannot be changed\");\n if (event.revision !== previous.revision + (event.kind === \"revised\" ? 1 : 0)) invalid(\"Invalid revision sequence\");\n if (event.kind !== \"revised\" && !same(event.content, previous.content)) invalid(\"A review cannot silently revise decision content\");\n if (event.kind === \"reaffirmed\" && previous.approval !== \"accepted\") invalid(\"Only accepted decisions can be reaffirmed\");\n if (event.kind === \"accepted\" && previous.approval === \"accepted\") invalid(\"Use reaffirmation for an accepted decision\");\n const approval = event.kind === \"revised\" ? \"proposed\" : [\"accepted\", \"reaffirmed\"].includes(event.kind) ? \"accepted\" : previous.approval;\n if (event.approval !== approval) invalid(\"Approval disagrees with review history\");\n if (![\"accepted\", \"reaffirmed\"].includes(event.kind) && event.refreshedHash !== previous.refreshedHash) invalid(\"Only a review can refresh the evidence baseline\");\n }\n if (event.kind !== \"imported\" && event.status !== (event.kind === \"retired\" ? \"retired\" : event.kind === \"superseded\" ? \"superseded\" : \"active\")) invalid(\"Lifecycle disagrees with history\");\n if ([\"accepted\", \"reaffirmed\", \"retired\"].includes(event.kind) && (!event.actor || !event.note || !event.evidence)) invalid(\"Reviews require a named reviewer, reason, and code evidence\");\n if ([\"accepted\", \"reaffirmed\"].includes(event.kind)) {\n if (!event.content.owner || !event.content.sources.length) invalid(\"Accepted decisions require an owner and source\");\n if (!event.evidence || !/^[a-f0-9]{40,64}$/.test(event.evidence.headHash) || event.refreshedHash !== event.evidence.headHash || event.evidence.localChanges.length) invalid(\"Acceptance requires a committed evidence baseline\");\n }\n previous = event;\n }\n if (!previous || !same(previous.content, decisionContent(record)) || previous.approval !== record.approval || previous.status !== record.status || previous.revision !== record.revision || previous.refreshedHash !== record.refreshedHash) invalid(\"Decision does not match the final history event\");\n});\n\nexport const decisionSchema = z.union([legacySchema, currentSchema]);\nexport type DecisionRecord = z.infer<typeof decisionSchema>;\nexport type ReviewedDecisionRecord = z.infer<typeof currentSchema>;\n\nexport function decisionContent(record: Pick<DecisionRecord, \"title\" | \"body\" | \"category\" | \"files\"> & { owner?: unknown; sources?: unknown }): DecisionContent {\n return { title: record.title, body: record.body, category: record.category, files: record.files,\n ...(typeof record.owner === \"string\" ? { owner: record.owner } : {}),\n sources: Array.isArray(record.sources) ? record.sources as DecisionSource[] : [],\n };\n}\n\n/** Reading legacy records never upgrades their approval or rewrites their files. */\nexport function decisionApproval(record: DecisionRecord): DecisionApproval {\n return record.version === 1 ? \"unreviewed\" : record.approval;\n}\n\n/** The last accepted revision remains operative while a replacement is drafted.\n * This is a read-only projection; writes and review tokens use the complete record.\n * Archived records never regain authority from their history.\n */\nexport function effectiveDecision(record: DecisionRecord): DecisionRecord {\n if (record.version !== 2 || record.status !== \"active\" || record.approval !== \"proposed\") return record;\n let index = record.history.length - 1;\n while (index >= 0 && ![\"accepted\", \"reaffirmed\"].includes(record.history[index].kind)) index--;\n if (index < 0) return record;\n const event = record.history[index];\n return { ...record, ...event.content, owner: event.content.owner, approval: \"accepted\", revision: event.revision,\n refreshedHash: event.refreshedHash, updatedAt: event.at, history: record.history.slice(0, index + 1) };\n}\n\n/** Anchors relevant to either the operative knowledge or its pending proposal. */\nexport function decisionAnchors(record: DecisionRecord): string[] {\n return [...new Set([...effectiveDecision(record).files, ...record.files])];\n}\n\nexport function importLegacy(record: DecisionRecord, now: string): ReviewedDecisionRecord {\n if (record.version === 2) return record;\n // Ignore unrecognized legacy fields: they are not evidence of authorship or approval.\n const content = decisionContent({ title: record.title, body: record.body, category: record.category, files: record.files });\n return { id: record.id, createdAt: record.createdAt, updatedAt: record.updatedAt, status: record.status, refreshedHash: record.refreshedHash, supersededBy: record.supersededBy, ...content, version: 2, approval: \"unreviewed\", revision: 1,\n history: [{ kind: \"imported\", at: now, revision: 1, content, approval: \"unreviewed\", status: record.status, refreshedHash: record.refreshedHash,\n note: \"Imported a legacy record. Prior authorship and review history are unknown.\" }],\n };\n}\n\nexport function decisionProvenance(record: DecisionRecord, freshness: Freshness = \"unknown\") {\n const approval = decisionApproval(record);\n const review = record.version === 2 ? [...record.history].reverse().find(e => [\"accepted\", \"reaffirmed\"].includes(e.kind) && e.revision === record.revision) : undefined;\n return {\n approval, revision: record.version === 2 ? record.revision : 0,\n owner: record.version === 2 ? record.owner ?? null : null,\n sources: record.version === 2 ? record.sources : [],\n guidance: record.status !== \"active\" ? \"historical\" : approval === \"accepted\" ? \"constraint\" : approval === \"proposed\" ? \"proposal\" : \"unreviewed\",\n reviewRequired: record.status === \"active\" && (approval !== \"accepted\" || freshness !== \"current\"),\n lastReview: review ? { reviewer: review.actor!, at: review.at, note: review.note!, gitHash: review.refreshedHash } : null,\n };\n}\n\nexport function decisionTrust(record: DecisionRecord, freshness: Freshness) {\n const review = decisionProvenance(record, freshness).lastReview;\n return assessTrust(review ? { verifiedAt: review.at, verifiedHash: review.gitHash } : {}, freshness);\n}\n\nfunction revisionKnowledge(record: DecisionRecord, freshness: Freshness) {\n return { ...decisionContent(record), ...decisionProvenance(record, freshness), trust: decisionTrust(record, freshness) };\n}\n\n/** Readers show accepted content first and label the unaccepted draft separately. */\nexport function decisionKnowledge(record: DecisionRecord, freshness: Freshness = \"unknown\", proposalFreshness: Freshness = \"unknown\") {\n const effective = effectiveDecision(record);\n return { ...revisionKnowledge(effective, freshness),\n ...(effective !== record ? { pendingProposal: revisionKnowledge(record, proposalFreshness) } : {}) };\n}\n\nexport function compactDecisionKnowledge(...args: Parameters<typeof decisionKnowledge>) {\n const { body, pendingProposal, ...summary } = decisionKnowledge(...args);\n if (!pendingProposal) return summary;\n const { body: proposalBody, ...proposal } = pendingProposal;\n return { ...summary, pendingProposal: proposal };\n}\n\nexport const DECISION_GUIDANCE = \"Accepted decisions are recorded team constraints, subject to freshness checks. A pendingProposal is an unaccepted replacement; the accepted revision remains operative until explicit acceptance or retirement. Proposals are suggestions; legacy unreviewed records need confirmation. Use review_decision to inspect provenance and record an authorized review; identities and sources are recorded assertions, not authenticated proof.\";\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { readStoreJson, writeStoreJson, storePath, type StoreDiagnostic } from \"../utils/storage.js\";\nimport { sanitizeRepoPaths } from \"../utils/paths.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { jaccard, tokenSet } from \"../context/lexical.js\";\nimport { attributionSchema, decisionSchema, decisionContent, decisionApproval, effectiveDecision, importLegacy, type DecisionSource, type DecisionRecord, type ReviewedDecisionRecord } from \"./provenance.js\";\nexport type { DecisionRecord } from \"./provenance.js\";\n\nexport type DecisionCategory =\n | \"decision\"\n | \"gotcha\"\n | \"deprecation\"\n | \"convention\";\nexport type DecisionStatus = \"active\" | \"superseded\" | \"retired\";\n\nexport const TITLE_MAX_CHARS = 80;\nexport const BODY_RECOMMENDED_CHARS = 1500;\nexport const BODY_MAX_CHARS = 2500;\nexport const MAX_ACTIVE_DECISIONS = 150;\n\n// Share validation with MCP so rejected tool calls include the actual length.\nconst boundedText = (field: string, max: number, hint: string) => z.string({\n errorMap: (issue, ctx) => ({ message: issue.code === \"too_big\"\n ? `${field} has ${ctx.data.length} characters; maximum is ${max} (${ctx.data.length - max} over). ${hint}`\n : ctx.defaultError }),\n}).trim().min(1, `${field} must be non-empty`).max(max);\n\nexport const decisionTitleSchema = boundedText(\"title\", TITLE_MAX_CHARS, \"Tighten it to a specific headline.\");\nexport const decisionBodySchema = boundedText(\"body\", BODY_MAX_CHARS,\n `Aim for ${BODY_RECOMMENDED_CHARS} characters or fewer. Preserve the rule, reason, and exceptions; put supporting references in sources.`);\n\nconst DUPLICATE_JACCARD = 0.5;\nconst DUPLICATE_JACCARD_WITH_SHARED_FILE = 0.35;\n\nexport async function loadDecisionStore(rootDir: string): Promise<{ records: DecisionRecord[]; diagnostics: StoreDiagnostic[] }> {\n const records: DecisionRecord[] = [];\n const diagnostics: StoreDiagnostic[] = [];\n let entries: string[];\n try { entries = await fs.readdir(await storePath(rootDir, \".mason/decisions\")); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") diagnostics.push({ path: \".mason/decisions\", message: String(error) });\n return { records, diagnostics };\n }\n for (const entry of entries.sort()) {\n if (!entry.endsWith(\".json\")) continue;\n const relative = `.mason/decisions/${entry}`;\n try {\n const record = decisionSchema.parse(await readStoreJson(rootDir, relative));\n if (entry !== `${record.id}.json`) throw new Error(\"Record id does not match its filename\");\n records.push(record);\n } catch (error) { diagnostics.push({ path: relative, message: error instanceof Error ? error.message : String(error) }); }\n }\n return { records, diagnostics };\n}\n\nexport async function loadDecisions(rootDir: string): Promise<DecisionRecord[]> {\n return (await loadDecisionStore(rootDir)).records;\n}\n\nexport async function saveDecisionRecord(rootDir: string, record: DecisionRecord): Promise<void> {\n const validated = decisionSchema.parse(record);\n await writeStoreJson(rootDir, `.mason/decisions/${validated.id}.json`, validated);\n}\n\n/**\n * Deterministic, human-readable id: base slug ≤60 chars, ending at a word\n * boundary when possible. A single longer word is cut to fit.\n * A slug collision with a DIFFERENT record appends a 6-hex content suffix.\n */\nexport function decisionIdFor(\n title: string,\n body: string,\n existingIds: Set<string>\n): string {\n const fullSlug = title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n let slug = fullSlug.slice(0, 60);\n if (fullSlug.length > 60 && fullSlug[60] !== \"-\") {\n const boundary = slug.lastIndexOf(\"-\");\n if (boundary > 0) slug = slug.slice(0, boundary);\n }\n slug = slug.replace(/-+$/, \"\") || \"decision\";\n if (!existingIds.has(slug)) return slug;\n const suffix = createHash(\"sha1\")\n .update(title + body)\n .digest(\"hex\")\n .slice(0, 6);\n return `${slug}-${suffix}`;\n}\n\nexport function findNearDuplicate(\n candidate: { title: string; body: string; files: string[] },\n existing: DecisionRecord[]\n): { record: DecisionRecord; similarity: number } | null {\n const candidateTokens = tokenSet(`${candidate.title} ${candidate.body}`);\n const candidateFiles = new Set(candidate.files);\n let best: { record: DecisionRecord; similarity: number } | null = null;\n\n for (const record of existing) {\n if (record.status !== \"active\") continue;\n const similarity = jaccard(\n candidateTokens,\n tokenSet(`${record.title} ${record.body}`)\n );\n const sharesFile = record.files.some((f) => candidateFiles.has(f));\n const threshold = sharesFile\n ? DUPLICATE_JACCARD_WITH_SHARED_FILE\n : DUPLICATE_JACCARD;\n if (similarity >= threshold && (!best || similarity > best.similarity)) {\n best = { record, similarity };\n }\n }\n return best;\n}\n\nexport interface UpsertDecisionInput {\n title: string;\n body: string;\n category: DecisionCategory;\n files?: string[];\n owner?: string | null;\n sources?: DecisionSource[];\n /** Only supply a known identity; never infer authorship from Git configuration. */\n actor?: string;\n /** Existing id to revise. Unchanged content is a no-op; use review_decision to reaffirm. */\n id?: string;\n /** Id of a decision this one replaces; the old record is kept, marked superseded. */\n supersedes?: string;\n /** Save even when a near-duplicate was detected. */\n force?: boolean;\n}\n\nexport type UpsertDecisionResult =\n | {\n status: \"created\" | \"updated\" | \"unchanged\" | \"superseded_and_created\";\n id: string;\n totalActive: number;\n warnings: string[];\n approval?: \"unreviewed\" | \"proposed\" | \"accepted\";\n hint?: string;\n pruneCandidates?: string[];\n }\n | { status: \"duplicate_suspected\"; existing: DecisionRecord; hint: string }\n | { status: \"error\"; error: string };\n\n/** Serialize tool writes so prepared reviews cannot overwrite another decision edit. */\nexport async function withDecisionWrite<T>(root: string, operation: () => Promise<T>): Promise<T | { status: \"error\"; error: string }> {\n const lockPath = await storePath(root, \".mason/decisions/.write-lock\", true);\n let lock;\n try { lock = await fs.open(lockPath, \"wx\", 0o600); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") return { status: \"error\", error: \"Decision store is locked by another write. Retry after it finishes; an abandoned .mason/decisions/.write-lock must be removed only after confirming no writer is running.\" };\n throw error;\n }\n try { return await operation(); }\n finally { await lock.close(); await fs.unlink(lockPath); }\n}\n\nexport async function upsertDecision(rootDir: string, input: UpsertDecisionInput): Promise<UpsertDecisionResult> {\n const parsedTitle = decisionTitleSchema.safeParse(input.title), parsedBody = decisionBodySchema.safeParse(input.body);\n if (!parsedTitle.success) return { status: \"error\", error: parsedTitle.error.issues[0].message };\n if (!parsedBody.success) return { status: \"error\", error: parsedBody.error.issues[0].message };\n const title = parsedTitle.data, body = parsedBody.data;\n const attribution = attributionSchema.safeParse(input);\n if (!attribution.success) return { status: \"error\", error: attribution.error.message };\n if (input.id && input.supersedes) return { status: \"error\", error: \"Use either id to revise or supersedes to replace a record, not both.\" };\n return withDecisionWrite(rootDir, async () => {\n const store = await loadDecisionStore(rootDir);\n if (store.diagnostics.length) return { status: \"error\", error: \"Repair malformed decision records before saving: \" + store.diagnostics.map(d => d.path).join(\", \") };\n const existing = store.records, byId = new Map(existing.map(r => [r.id, r]));\n const now = new Date().toISOString(), head = await getCurrentGitHash(rootDir);\n const warnings: string[] = [];\n if (body.length > BODY_RECOMMENDED_CHARS) warnings.push(`body has ${body.length} characters, above the recommended ${BODY_RECOMMENDED_CHARS}; matching context and hooks include it in full. Keep the rule, reason, and exceptions concise; use sources for supporting references.`);\n const files = sanitizeRepoPaths(input.files ?? []);\n if (input.files && files.length < input.files.length) warnings.push(\"some anchor paths were outside the repo or duplicated and were dropped\");\n for (const file of files) {\n try { await fs.access(path.join(rootDir, file)); }\n catch { warnings.push(`anchor file does not exist on disk: ${file}`); }\n }\n const hint = \"Saved locally for review and commit. Proposals are not accepted constraints; an existing accepted revision remains operative while its replacement is proposed. Use review_decision to inspect evidence and record an authorized acceptance or reaffirmation.\";\n if (input.id) {\n const original = byId.get(input.id);\n if (!original) return { status: \"error\", error: `no decision with id \"${input.id}\"` };\n if (original.status !== \"active\") return { status: \"error\", error: \"Archived records cannot be revised; create a new proposal.\" };\n const record = importLegacy(original, now);\n const content = decisionContent({ ...record, title, body, category: input.category,\n files: input.files !== undefined ? files : record.files,\n owner: attribution.data.owner === undefined ? record.owner : attribution.data.owner ?? undefined,\n sources: attribution.data.sources ?? record.sources,\n });\n if (JSON.stringify(content) === JSON.stringify(decisionContent(record))) {\n return { status: \"unchanged\", id: record.id, totalActive: existing.filter(r => r.status === \"active\").length, approval: decisionApproval(original), warnings,\n hint: \"Unchanged content; no review or freshness stamp was written. Use review_decision for explicit re-verification.\" };\n }\n const revision = record.revision + 1;\n const updated: ReviewedDecisionRecord = { ...record, ...content, owner: content.owner, updatedAt: now, revision, approval: \"proposed\",\n history: [...record.history, { kind: \"revised\", at: now, actor: attribution.data.actor, revision, content, approval: \"proposed\", status: \"active\", refreshedHash: record.refreshedHash }],\n };\n await saveDecisionRecord(rootDir, updated);\n return { status: \"updated\", id: record.id, totalActive: existing.filter(r => r.status === \"active\").length, approval: \"proposed\", warnings, hint };\n }\n const old = input.supersedes ? byId.get(input.supersedes) : undefined;\n if (input.supersedes && !old) return { status: \"error\", error: `no decision with id \"${input.supersedes}\" to supersede` };\n if (old && (old.status !== \"active\" || decisionApproval(effectiveDecision(old)) === \"accepted\")) {\n return { status: \"error\", error: \"A proposal cannot supersede an accepted or archived record. Create and review the replacement separately, then explicitly retire the old decision with review_decision.\" };\n }\n if (!input.force) {\n const duplicate = findNearDuplicate({ title, body, files }, existing);\n if (duplicate) return { status: \"duplicate_suspected\", existing: duplicate.record, hint: `A similar decision exists (\"${duplicate.record.title}\"). Call save_decision with id=\"${duplicate.record.id}\" to revise it, or force:true if distinct.` };\n }\n const id = decisionIdFor(title, body, new Set(byId.keys()));\n if (byId.has(id)) return { status: \"error\", error: `Decision id collision: ${id}. Choose a distinct title or revise the existing record.` };\n const content = decisionContent({ title, body, category: input.category, files, owner: attribution.data.owner ?? undefined, sources: attribution.data.sources ?? [] });\n const record: ReviewedDecisionRecord = { ...content, version: 2, id, createdAt: now, updatedAt: now, refreshedHash: head,\n status: \"active\", approval: \"proposed\", revision: 1,\n history: [{ kind: \"created\", at: now, actor: attribution.data.actor, revision: 1, content, approval: \"proposed\", status: \"active\", refreshedHash: head }],\n };\n // Write the replacement first: a failed second write leaves both records\n // available instead of removing the original before its replacement exists.\n await saveDecisionRecord(rootDir, record);\n if (old) {\n const imported = importLegacy(old, now);\n await saveDecisionRecord(rootDir, { ...imported, status: \"superseded\", supersededBy: id, updatedAt: now,\n history: [...imported.history, { kind: \"superseded\", at: now, actor: attribution.data.actor, note: `Replaced by proposal ${id}`,\n revision: imported.revision, content: decisionContent(imported), approval: imported.approval, status: \"superseded\", refreshedHash: imported.refreshedHash }],\n });\n }\n const totalActive = existing.filter(r => r.status === \"active\").length + (old ? 0 : 1);\n const result: UpsertDecisionResult = { status: old ? \"superseded_and_created\" : \"created\", id, totalActive, approval: \"proposed\", warnings, hint };\n if (totalActive > MAX_ACTIVE_DECISIONS) {\n result.pruneCandidates = existing.filter(r => r.status !== \"active\").map(r => r.id).slice(0, 10);\n warnings.push(`${totalActive} active decisions exceeds the soft cap of ${MAX_ACTIVE_DECISIONS} — consider a cleanup PR (archived records first)`);\n }\n return result;\n });\n}\n","import path from \"node:path\";\nimport { getChangesWithStatus, getWorkingTree, touchedPaths } from \"../drift/drift.js\";\nimport { matchingPaths } from \"../utils/paths.js\";\nimport type { Freshness } from \"../context/trust.js\";\nimport type { StoreDiagnostic } from \"../utils/storage.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { loadDecisionStore } from \"./decisions.js\";\nimport type { DecisionRecord } from \"./decisions.js\";\nimport { effectiveDecision } from \"./provenance.js\";\n\n/**\n * Deliberately separate from DriftReport: mason-drift's exit codes and\n * --json shape are a CI contract, and `stale` there means MAP staleness.\n * Decision staleness is additive on top.\n */\nexport interface DecisionDriftReport {\n historyAvailable: boolean;\n freshness?: Record<string, Freshness>;\n diagnostics?: StoreDiagnostic[];\n totalDecisions: number;\n /** Decision id → anchor files changed since the record's refreshedHash. */\n staleDecisions: Record<string, string[]>;\n /** Draft anchors have their own freshness; they cannot replace accepted anchors. */\n pendingProposals?: Record<string, { freshness: Freshness; changedFiles: string[] }>;\n}\n\n/**\n * Flag active decisions whose anchor files changed since the record was\n * last verified. Anchorless decisions have unknown freshness and do not\n * contribute to committed drift.\n * Deterministic — git only, no LLM.\n */\nexport async function computeDecisionDrift(\n rootDir: string,\n decisions?: DecisionRecord[]\n): Promise<DecisionDriftReport> {\n const resolvedRoot = path.resolve(rootDir);\n const store = decisions ? { records: decisions, diagnostics: [] } : await loadDecisionStore(resolvedRoot);\n const report: DecisionDriftReport = { historyAvailable: true, totalDecisions: store.records.length, staleDecisions: {}, freshness: {}, diagnostics: store.diagnostics };\n const [head, workingTree] = await Promise.all([getCurrentGitHash(resolvedRoot), getWorkingTree(resolvedRoot)]);\n const changesByHash = new Map<string, string[] | null>();\n const inspect = async (record: DecisionRecord): Promise<{ freshness: Freshness; changedFiles: string[] }> => {\n if (record.files.length === 0) return { freshness: \"unknown\", changedFiles: [] };\n let touched = changesByHash.get(record.refreshedHash);\n if (touched === undefined) {\n const changes = record.refreshedHash === head && head !== \"unknown\" ? [] : await getChangesWithStatus(resolvedRoot, record.refreshedHash);\n touched = changes === null ? null : touchedPaths(changes);\n changesByHash.set(record.refreshedHash, touched);\n }\n if (touched === null) report.historyAvailable = false;\n const hits = touched ? matchingPaths(record.files, touched) : [];\n const localHits = matchingPaths(record.files, workingTree.changedFiles);\n return { freshness: touched === null || !workingTree.available ? \"unknown\" : hits.length || localHits.length ? \"changed\" : \"current\", changedFiles: hits };\n };\n for (const record of store.records) {\n if (record.status !== \"active\") continue;\n const effective = effectiveDecision(record);\n const state = await inspect(effective);\n report.freshness![record.id] = state.freshness;\n if (state.changedFiles.length) report.staleDecisions[record.id] = state.changedFiles;\n if (effective !== record) (report.pendingProposals ??= {})[record.id] = await inspect(record);\n }\n return report;\n}\n","import { computeDecisionDrift } from \"../../decisions/drift.js\";\nimport { loadDecisionStore } from \"../../decisions/decisions.js\";\nimport { decisionProvenance, effectiveDecision } from \"../../decisions/provenance.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/**\n * Advisory only, and only when .mason/decisions/ exists (the zero-setup\n * path stays dark on bare repos). Decision records encode human knowledge —\n * they are surfaced for re-verification, never rewritten by the fix agent.\n */\nexport async function checkDecisionAnchors(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n if (!ctx.decisionsPresent) return result;\n\n const store = await loadDecisionStore(ctx.root);\n const records = store.records;\n for (const diagnostic of store.diagnostics) result.skipped.push({ check: \"decision-anchor-drift\", reason: `${diagnostic.path}: ${diagnostic.message}` });\n const drift = await computeDecisionDrift(ctx.root, records);\n if (!drift.historyAvailable) {\n result.skipped.push({\n check: \"decision-anchor-drift\",\n reason: \"some decision base commits are unreachable (shallow clone?)\",\n });\n }\n\n const changed = records.flatMap(record => [\n { record: effectiveDecision(record), changedFiles: drift.staleDecisions[record.id] ?? [], freshness: drift.freshness?.[record.id] ?? \"unknown\" },\n { record, changedFiles: drift.pendingProposals?.[record.id]?.changedFiles ?? [], freshness: drift.pendingProposals?.[record.id]?.freshness ?? \"unknown\" },\n ] as const);\n for (const { record, changedFiles, freshness } of changed) {\n if (!changedFiles.length) continue;\n const id = record.id;\n const provenance = decisionProvenance(record, freshness);\n result.advisories.push({\n type: \"decision-anchor-drift\",\n message: `decision \"${record.title}\" (${provenance.approval}) has anchor files that changed since its evidence baseline – needs human review`,\n anchor: {\n doc: `.mason/decisions/${id}.json`,\n line: null,\n excerpt: record.title,\n },\n evidence: {\n kind: \"decision-anchor\",\n provenance,\n decisionId: id,\n title: record.title,\n changedFiles,\n refreshedHash: record.refreshedHash,\n },\n });\n }\n\n return result;\n}\n","import type { FileChange } from \"../../drift/drift.js\";\nimport type { AuditAdvisory, AuditIssue, CheckName } from \"../types.js\";\nimport type { AuditDoc } from \"../docs.js\";\nimport { checkDeletedReferences } from \"./deleted-reference.js\";\nimport { checkNewModules } from \"./new-module.js\";\nimport { checkStaleCounts } from \"./stale-count.js\";\nimport { checkDeadCommands } from \"./dead-command.js\";\nimport { checkDepsChanged } from \"./deps-changed.js\";\nimport { checkDecisionAnchors } from \"./decision-anchor.js\";\n\nexport interface CheckContext {\n root: string;\n docs: AuditDoc[];\n headHash: string;\n /** Doc path → changes since the doc's last commit; null when uncomputable. */\n changesSinceDoc: Map<string, FileChange[] | null>;\n /** Whether .mason/decisions/ exists. */\n decisionsPresent: boolean;\n}\n\nexport interface CheckResult {\n issues: AuditIssue[];\n advisories: AuditAdvisory[];\n suppressedAdvisories?: AuditAdvisory[];\n skipped: Array<{ check: string; reason: string; doc?: string }>;\n}\n\nexport type CheckFn = (ctx: CheckContext) => Promise<CheckResult>;\n\nexport const CHECKS: Record<CheckName, CheckFn> = {\n \"deleted-reference\": checkDeletedReferences,\n \"new-module\": checkNewModules,\n \"stale-count\": checkStaleCounts,\n \"dead-command\": checkDeadCommands,\n \"deps-changed\": checkDepsChanged,\n \"decision-anchor-drift\": checkDecisionAnchors,\n};\n\nexport function emptyResult(): CheckResult {\n return { issues: [], advisories: [], skipped: [] };\n}\n","import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\nimport type { AuditIssue, AuditAdvisory } from \"./types.js\";\nexport type Finding = AuditIssue | AuditAdvisory;\nexport const digest = (value: unknown) => createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\");\nexport const checkSchema = z.enum([\"deleted-reference\", \"new-module\", \"stale-count\", \"dead-command\", \"deps-changed\", \"decision-anchor-drift\"]);\nexport const commitSchema = z.object({ hash: z.string().regex(/^[a-f0-9]{40,64}$/), date: z.string(), subject: z.string() });\nconst anchorSchema = z.object({ doc: z.string(), line: z.number().int().positive().nullable(), excerpt: z.string().nullable() });\nconst count = z.number().int().nonnegative();\nconst scopeSchema = z.object({ basis: z.enum([\"repository\", \"document\", \"document-link\", \"explicit\"]),\n directory: z.string(), candidates: z.array(z.string()) });\nconst evidenceSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"missing-path\"), claimed: z.string(), renamedTo: z.string().nullable(),\n deletedInCommit: commitSchema.nullable(), everTracked: z.boolean(), parentDirExists: z.boolean(), resolvedPath: z.string().optional(), scope: scopeSchema.optional() }),\n z.object({ kind: z.literal(\"unmentioned-dir\"), dir: z.string(), sourceFileCount: count,\n firstCommit: commitSchema.nullable(), checkedDocs: z.array(z.string()) }),\n z.object({ kind: z.literal(\"count-mismatch\"), claimed: count, actual: count, unit: z.string(),\n countedFrom: z.string(), members: z.array(z.string()) }),\n z.object({ kind: z.literal(\"missing-script\"), scriptName: z.string(), invocation: z.string(),\n manifestsChecked: z.array(z.string()), availableScripts: z.array(z.string()), scope: scopeSchema.optional() }),\n z.object({ kind: z.literal(\"doc-behind-manifests\"), docLastCommit: commitSchema,\n manifestCommits: z.array(commitSchema.extend({ files: z.array(z.string()) })), totalCommits: count }),\n z.object({ kind: z.literal(\"decision-anchor\"), decisionId: z.string(), title: z.string(),\n changedFiles: z.array(z.string()), refreshedHash: z.string(),\n provenance: z.object({}).passthrough().optional() }),\n]);\nconst findingSchema = z.object({ message: z.string(), anchor: anchorSchema, evidence: evidenceSchema });\nexport const issueSchema = findingSchema.extend({\n type: z.enum([\"deleted-reference\", \"new-module\", \"stale-count\", \"dead-command\"]),\n confidence: z.enum([\"certain\", \"likely\"]),\n});\nexport const advisorySchema = findingSchema.extend({ type: checkSchema, resolution: z.literal(\"recheck\").optional() });\nexport const checkResultSchema = z.object({\n issues: z.array(issueSchema), advisories: z.array(advisorySchema),\n suppressedAdvisories: z.array(advisorySchema).optional(),\n skipped: z.array(z.object({ check: z.string(), reason: z.string(), doc: z.string().optional() })),\n});\n/** Lines and wording can change without changing the underlying claim. */\nexport function findingId(finding: Finding): string {\n const e = finding.evidence;\n let key: unknown;\n switch (e.kind) {\n case \"missing-path\": key = e.resolvedPath && e.resolvedPath !== e.claimed ? [e.claimed, e.resolvedPath] : e.claimed; break;\n case \"unmentioned-dir\": key = e.dir; break;\n case \"count-mismatch\": key = [e.unit.replace(/s$/, \"\"), e.countedFrom]; break;\n case \"missing-script\": key = e.scope && e.scope.directory !== \".\" ? [e.scriptName, e.scope.directory] : e.scriptName; break;\n case \"doc-behind-manifests\": key = null; break;\n case \"decision-anchor\": key = [e.decisionId, e.provenance?.revision, e.provenance?.approval]; break;\n }\n return digest([finding.type, finding.anchor.doc, key]);\n}\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport { z } from \"zod\";\nimport { storePath } from \"../utils/storage.js\";\n\nexport const hostSchema = z.enum([\"claude\", \"codex\"]);\nexport type Host = z.infer<typeof hostSchema>;\nexport const events = [\"session_start\", \"turn_start\", \"before_tool\", \"after_tool\", \"task_end\"] as const;\nexport type Event = typeof events[number];\nexport const stateSchema = z.object({\n version: z.literal(1), root: z.string(), gitDir: z.string(), branch: z.string(),\n baselines: z.array(z.object({ path: z.string(), at: z.string(), event: z.string(), fingerprint: z.string() })).max(128),\n sessions: z.record(z.object({\n host: hostSchema, seen: z.string().nullable(), continued: z.boolean(),\n initialIssues: z.array(z.string()), initialDocs: z.record(z.string().nullable()),\n lastUsed: z.string(), mutationObserved: z.boolean(),\n pending: z.record(z.string()), coverageGaps: z.array(z.string()),\n events: z.record(z.object({ at: z.string(), count: z.number().int().positive() })),\n })),\n updatedAt: z.string(), fingerprint: z.string().nullable(),\n latest: z.string().nullable(),\n analysis: z.object({ id: z.string(), fingerprint: z.string(), completedAt: z.number(), path: z.string() }).optional(),\n});\nexport type State = z.infer<typeof stateSchema>;\nexport function parseState(raw: unknown): State {\n try { return stateSchema.parse(raw); }\n catch (error) { throw new Error(\"Invalid automation state; original evidence was retained.\", { cause: error }); }\n}\n\n/** Cross-process lock: a killed writer's lock is reclaimed only after its local PID is gone. */\nexport async function withLock<T>(root: string, directory: string, run: () => Promise<T>, waitMs = 5000): Promise<T> {\n const file = await storePath(root, directory + \"/lock\", true);\n const deadline = Date.now() + waitMs;\n let handle;\n while (!handle) {\n try {\n handle = await fs.open(file, \"wx\", 0o600);\n try { await handle.writeFile(JSON.stringify({ pid: process.pid, host: os.hostname() })); }\n catch (error) {\n await handle.close().catch(() => {});\n handle = undefined;\n await fs.rm(file, { force: true }).catch(() => {});\n throw error;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n // Do not steal malformed, remote, or live locks on a time-based guess.\n try {\n const owner = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (owner.host === os.hostname() && Number.isInteger(owner.pid) && owner.pid > 0) {\n try { process.kill(owner.pid, 0); }\n catch (probe) {\n if ((probe as NodeJS.ErrnoException).code === \"ESRCH\") {\n // Renaming a stale lock arbitrates reclamation without unlinking a new writer's lock.\n const reclaim = file + \".reclaim\";\n let guard;\n try {\n guard = await fs.open(reclaim, \"wx\", 0o600);\n const current = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (current.pid === owner.pid && current.host === owner.host) await fs.unlink(file);\n } finally { if (guard) { await guard.close(); await fs.rm(reclaim, { force: true }); } }\n }\n }\n }\n } catch { /* Another writer may be creating/releasing/reclaiming it. */ }\n if (Date.now() >= deadline) throw new Error(\"Automation is busy or its lock needs inspection: \" + file);\n await new Promise(resolve => setTimeout(resolve, 40));\n }\n }\n try { return await run(); }\n finally { await handle.close(); await fs.unlink(file); }\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { computeAudit, type AuditOptions } from \"./audit.js\";\nimport { discoverDocPaths } from \"./docs.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { getChangesWithStatus } from \"../drift/drift.js\";\nimport { readStoreJson, storePath, writeStoreJson } from \"../utils/storage.js\";\nimport { readBoundedFile } from \"../utils/files.js\";\nimport { isWithinRoot, normalizeRepoPath } from \"../utils/paths.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport type { AuditReport, CheckName } from \"./types.js\";\nimport { checkSchema, commitSchema, issueSchema, advisorySchema, digest, findingId, type Finding } from \"./findings.js\";\nimport { assessAdvisory, advisoryReviewInventory, reviewSummarySchema, type AdvisoryReviewSummary } from \"./advisory-review.js\";\nexport { checkResultSchema, findingId } from \"./findings.js\";\nconst count = z.number().int().nonnegative();\n\nconst reportSchema = z.object({\n version: z.literal(1), root: z.string(), gitAvailable: z.literal(true),\n headHash: commitSchema.shape.hash, checksRun: z.array(checkSchema).nonempty(),\n docs: z.array(z.object({ path: z.string().refine(value => normalizeRepoPath(value) === value), scope: z.string().optional(),\n kind: z.enum([\"instructions\", \"readme\"]).optional(), lastCommit: commitSchema.nullable(),\n dirty: z.boolean(), lineCount: count })).nonempty(),\n decisionsChecked: z.boolean(), clean: z.boolean(),\n issues: z.array(issueSchema), advisories: z.array(advisorySchema),\n suppressedAdvisories: z.array(advisorySchema).optional(),\n skippedChecks: z.array(z.object({ check: z.string(), reason: z.string(), doc: z.string().optional() })),\n});\nconst baselineSchema = z.object({\n kind: z.literal(\"mason-audit-repair\"), version: z.literal(1),\n createdAt: z.string().datetime(), report: reportSchema, digest: z.string().regex(/^[a-f0-9]{64}$/),\n});\n\n\nexport type RepairStatus = \"resolved\" | \"unresolved\" | \"review-required\" | \"unverified\";\n\nexport interface RepairFinding {\n id: string;\n original: Finding;\n status: RepairStatus;\n reason: string;\n current?: Finding;\n review?: AdvisoryReviewSummary;\n}\nexport const repairFindingSchema = z.object({\n id: z.string(), original: z.union([issueSchema, advisorySchema]),\n status: z.enum([\"resolved\", \"unresolved\", \"review-required\", \"unverified\"]), reason: z.string(),\n current: z.union([issueSchema, advisorySchema]).optional(),\n review: reviewSummarySchema.optional(),\n});\nexport interface RepairVerification {\n version: 1;\n action: \"verify\";\n baselinePath: string;\n baselineHead: string;\n currentHead: string | null;\n status: \"verified\" | \"issues-remain\" | \"incomplete\";\n findings: RepairFinding[];\n newFindings: Finding[];\n diagnostics: string[];\n currentAudit: AuditReport | null;\n counts: Record<RepairStatus, number>;\n scope: string;\n}\n\nfunction recheckable(finding: Finding): boolean {\n return !(\"confidence\" in finding) && finding.resolution === \"recheck\"\n && [\"deleted-reference\", \"dead-command\", \"new-module\"].includes(finding.type)\n && [\"missing-path\", \"missing-script\", \"unmentioned-dir\"].includes(finding.evidence.kind);\n}\nfunction allFindings(report: AuditReport): Finding[] {\n return [...report.issues, ...report.advisories, ...(report.suppressedAdvisories ?? [])];\n}\n\nasync function docState(root: string): Promise<string> {\n const docs = [];\n for (const doc of await discoverDocPaths(root)) {\n try {\n const content = await readBoundedFile(await storePath(root, doc), 10 * 1024 * 1024);\n if (content === null) throw new Error(\"Context file is not regular or exceeds 10 MiB: \" + doc);\n docs.push([doc, digest(content)]);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n docs.push([doc, null]);\n }\n }\n return digest(docs);\n}\n\n/** Refuse a verification assembled across a commit or instruction-file edit. */\nasync function stableAudit(root: string, checks: CheckName[], options: AuditOptions = {}) {\n const head = await getCurrentGitHash(root);\n const before = await docState(root);\n const report = await computeAudit(root, { ...options, checks });\n if (head !== await getCurrentGitHash(root) || before !== await docState(root) ||\n (report && report.headHash !== head)) {\n throw new Error(\"HEAD or context files changed during the audit; retry against a stable checkout.\");\n }\n return report;\n}\n\nexport async function prepareRepair(rootDir: string, checks: CheckName[] = ALL_CHECKS, options: AuditOptions = {}) {\n const root = await fs.realpath(rootDir);\n const selected = z.array(checkSchema).nonempty().parse(checks);\n const report = await stableAudit(root, selected, options);\n if (!report) throw new Error(\"No context files found to prepare a repair.\");\n if (!report.gitAvailable) throw new Error(\"Readable Git history is required to prepare a repair.\");\n // Canonicalize before hashing; validation on read must yield the same bytes.\n const storedReport = reportSchema.parse(report);\n const payload = { kind: \"mason-audit-repair\" as const, version: 1 as const,\n createdAt: new Date().toISOString(), report: storedReport };\n const baselinePath = \".mason/reports/repairs/\" + randomUUID() + \".json\";\n await writeStoreJson(root, baselinePath, { ...payload, digest: digest(payload) });\n return { version: 1 as const, action: \"prepare\" as const, baselinePath, report };\n}\n\nexport async function loadRepairBaseline(rootDir: string, baselinePath: string) {\n const root = await fs.realpath(rootDir);\n const declaredRoot = path.resolve(rootDir);\n const relative = path.isAbsolute(baselinePath)\n ? path.relative(isWithinRoot(declaredRoot, baselinePath) ? declaredRoot : root, baselinePath)\n : baselinePath;\n const stored = baselineSchema.parse(await readStoreJson(root, relative));\n const { digest: savedDigest, ...payload } = stored;\n if (digest(payload) !== savedDigest) throw new Error(\"Repair baseline was modified; use the original baseline.\");\n if (stored.report.root !== root) throw new Error(\"Repair baseline belongs to a different repository.\");\n const original = stored.report as AuditReport;\n return { root, relative, original };\n}\n\nexport async function verifyRepair(rootDir: string, baselinePath: string, options: AuditOptions = {}): Promise<RepairVerification> {\n const { root, relative, original } = await loadRepairBaseline(rootDir, baselinePath);\n const diagnostics: string[] = [];\n let reviewDigest: string | undefined;\n let current: AuditReport | null = null;\n try {\n reviewDigest = digest(await advisoryReviewInventory(root));\n current = await stableAudit(root, original.checksRun!, options);\n if (!current) diagnostics.push(\"No context files remain available to audit.\");\n else if (!current.gitAvailable) diagnostics.push(\"Git history is unavailable.\");\n for (const doc of original.docs) {\n if (!allFindings(original).some(f => f.anchor.doc === doc.path) || !current?.docs.some(d => d.path === doc.path)) continue;\n const content = await readBoundedFile(await storePath(root, doc.path), 10 * 1024 * 1024);\n if (content === null || !content.trim()) {\n diagnostics.push(\"Original context file \" + doc.path + \" is empty or unreadable; losing its claims does not verify a repair.\");\n }\n }\n if (await getChangesWithStatus(root, original.headHash!) === null) {\n diagnostics.push(\"The original audit commit is unavailable; repair history cannot be verified.\");\n }\n } catch (error) {\n diagnostics.push(error instanceof Error ? error.message : String(error));\n }\n const currentById = new Map((current ? allFindings(current) : []).map(f => [findingId(f), f]));\n const originalFindings = allFindings(original);\n const originalIds = new Set(originalFindings.map(findingId));\n const missingDocs = original.docs.filter(doc => !current?.docs.some(d => d.path === doc.path));\n for (const doc of missingDocs) diagnostics.push(\"Original context file \" + doc.path + \" is unavailable; removing it does not verify a repair.\");\n const findings = await Promise.all(originalFindings.map(async (finding): Promise<RepairFinding> => {\n const id = findingId(finding);\n const now = currentById.get(id);\n const base = { id, original: finding, ...(now ? { current: now } : {}) };\n if (diagnostics.length || !current) {\n return { ...base, status: \"unverified\", reason: \"The original audit scope could not be verified. See diagnostics.\" };\n }\n if (now && (\"confidence\" in finding || \"confidence\" in now)) {\n return { ...base, status: \"unresolved\", reason: \"The original check still reports this claim.\" };\n }\n const skipped = current.skippedChecks.filter(s => s.check === finding.type && (!s.doc || s.doc === finding.anchor.doc));\n if (!current.checksRun?.includes(finding.type) || skipped.length) {\n return { ...base, status: \"unverified\", reason: skipped.map(s => s.reason).join(\"; \") || \"The original check did not run.\" };\n }\n const review = await assessAdvisory(root, now ?? finding, original.headHash!);\n if (review) {\n if (review.status === \"unverified\") return { ...base, review, status: \"unverified\", reason: review.reason };\n if (review.status === \"current\") return { ...base, review, status: \"resolved\", reason: review.reason };\n return { ...base, review, status: \"review-required\", reason: review.reason };\n }\n if (!(\"confidence\" in finding) && (!recheckable(finding) || now)) {\n return { ...base, status: \"review-required\",\n reason: \"An audit cannot establish that this advisory was reviewed. Retain its original evidence and report a separate assessment; editing or committing the doc is not approval.\" };\n }\n return { ...base, status: \"resolved\", reason: \"The original check ran and no longer reports this claim. Inspect the edit for semantic correctness.\" };\n }));\n try {\n if (reviewDigest !== digest(await advisoryReviewInventory(root)) || current?.headHash !== await getCurrentGitHash(root)) {\n diagnostics.push(\"HEAD or advisory review records changed during verification; repeat against stable evidence.\");\n for (const finding of findings) { finding.status = \"unverified\"; finding.reason = diagnostics.at(-1)!; }\n }\n } catch (error) {\n diagnostics.push(String(error));\n for (const finding of findings) { finding.status = \"unverified\"; finding.reason = \"Advisory review evidence became unavailable during verification.\"; }\n }\n const newFindings = [...currentById].filter(([id]) => !originalIds.has(id)).map(([, f]) => f);\n const reviewedIds = new Set(current?.advisoryReviews?.filter(review => review.status === \"current\").map(review => review.id));\n const counts: Record<RepairStatus, number> = { resolved: 0, unresolved: 0, \"review-required\": 0, unverified: 0 };\n for (const f of findings) counts[f.status]++;\n const incomplete = diagnostics.length > 0 || counts.unverified > 0 || counts[\"review-required\"] > 0 ||\n (current?.skippedChecks.length ?? 0) > 0 || newFindings.some(f => !(\"confidence\" in f) && !reviewedIds.has(findingId(f)));\n const issuesRemain = counts.unresolved > 0 || newFindings.some(f => \"confidence\" in f);\n return {\n version: 1, action: \"verify\", baselinePath: relative, baselineHead: original.headHash!,\n currentHead: current?.gitAvailable ? current.headHash! : null,\n status: incomplete ? \"incomplete\" : issuesRemain ? \"issues-remain\" : \"verified\",\n findings, newFindings, diagnostics, currentAudit: current, counts,\n scope: \"Original audit checks over current context files and repository evidence. Resolved means no longer detected by the check or covered by an explicit assessment of current evidence; inspect each finding's reason and review. This is not a certification of documentation or application correctness.\",\n };\n}\n\nexport function repairExitCode(report: RepairVerification): number {\n return report.status === \"verified\" ? 0 : report.status === \"issues-remain\" ? 1 : 2;\n}\n\nexport function formatRepairSummary(report: RepairVerification): string {\n return [\n \"Repair verification: \" + report.status + \". Baseline: \" + report.baselinePath,\n ...report.findings.map(f => \" [\" + f.status + \"] \" + f.original.type + \" \" + f.original.anchor.doc + \": \" + f.original.message + \"\\n \" + f.reason + \"\\n findingId: \" + f.id),\n ...report.newFindings.map(f => \" [new] \" + f.type + \" \" + f.anchor.doc + \": \" + f.message),\n ...report.diagnostics.map(d => \" [unverified] \" + d),\n ...(report.currentAudit?.skippedChecks ?? []).map(s => \" [skipped] \" + s.check + \": \" + s.reason),\n report.scope,\n ].join(\"\\n\");\n}\n","import fs from \"node:fs/promises\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { advisorySchema, digest, findingId, type Finding } from \"./findings.js\";\nimport { manifestPathspecs } from \"./checks/deps-changed.js\";\nimport { readAuditInput } from \"./inputs.js\";\nimport { pathExists } from \"./scope.js\";\nimport { readStoreJson, storePath, writeStoreJson } from \"../utils/storage.js\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { withLock } from \"../automation/store.js\";\nimport { loadDecisionStore } from \"../decisions/decisions.js\";\nimport { computeDecisionDrift } from \"../decisions/drift.js\";\n\nconst execute = promisify(execFile);\nconst git = async (root: string, ...args: string[]) => (await execute(\"git\", args, { cwd: root, timeout: 10_000, maxBuffer: 8 * 1024 * 1024 })).stdout;\nconst hashSchema = z.string().regex(/^[a-f0-9]{64}$/);\nconst commitSchema = z.string().regex(/^[a-f0-9]{40,64}$/);\nconst evidenceSchema = z.object({\n head: commitSchema, fingerprint: hashSchema, scope: z.array(z.string()).min(1).max(1000),\n tree: z.string().max(2 * 1024 * 1024), lastScopeCommit: commitSchema,\n paths: z.array(z.object({ path: z.string(), exists: z.boolean() })).max(1000),\n});\nconst eventSchema = z.object({\n at: z.string().datetime(), reviewer: z.string().trim().min(1).max(200), note: z.string().trim().min(1).max(2500),\n outcome: z.enum([\"addressed\", \"inapplicable\", \"deferred\"]),\n finding: advisorySchema.refine(finding => finding.evidence.kind !== \"decision-anchor\", \"Decision findings use decision reviews\"), evidence: evidenceSchema,\n});\nconst recordSchema = z.object({ version: z.literal(1), id: hashSchema, events: z.array(eventSchema).min(1).max(200), digest: hashSchema });\ntype ReviewRecord = z.infer<typeof recordSchema>;\nexport const reviewSummarySchema = z.object({\n id: hashSchema, status: z.enum([\"current\", \"reopened\", \"deferred\", \"unverified\"]), reason: z.string(),\n recordPath: z.string().optional(), reviewer: z.string().optional(), note: z.string().optional(),\n outcome: z.enum([\"addressed\", \"inapplicable\", \"deferred\", \"accepted\", \"reaffirmed\", \"retired\"]).optional(),\n reviewedHead: z.string().optional(),\n});\nexport type AdvisoryReviewSummary = z.infer<typeof reviewSummarySchema>;\nexport const advisoryReviewRequest = z.object({\n baselinePath: z.string().min(1), findingId: hashSchema,\n action: z.enum([\"prepare\", \"addressed\", \"inapplicable\", \"deferred\"]).default(\"prepare\"),\n reviewer: eventSchema.shape.reviewer.optional(), note: eventSchema.shape.note.optional(), reviewToken: hashSchema.optional(),\n});\nexport type AdvisoryReviewInput = z.input<typeof advisoryReviewRequest>;\nconst recordPath = (id: string) => `.mason/reviews/advisories/${hashSchema.parse(id)}.json`;\n\nasync function readRecord(root: string, id: string): Promise<ReviewRecord | null> {\n const raw = await readStoreJson(root, recordPath(id));\n if (raw === null) return null;\n const record = recordSchema.parse(raw);\n const { digest: stored, ...payload } = record;\n if (record.id !== id || digest(payload) !== stored || record.events.some(event => findingId(event.finding as Finding) !== id\n || event.evidence.fingerprint !== digest([event.evidence.scope, event.evidence.tree, event.evidence.lastScopeCommit, event.evidence.paths]))) {\n throw new Error(\"Advisory review record is inconsistent or modified; inspect its history.\");\n }\n return record;\n}\n\nfunction scopes(finding: Finding): string[] {\n const files = [finding.anchor.doc], e = finding.evidence;\n if (e.kind === \"decision-anchor\") throw new Error(\"Use review_decision for decision acceptance, reaffirmation or retirement.\");\n if (e.kind === \"doc-behind-manifests\") return [`:(literal)${finding.anchor.doc}`, ...manifestPathspecs(finding.anchor.doc)];\n if (e.kind === \"missing-path\") files.push(...(e.scope?.candidates ?? [e.resolvedPath ?? e.claimed]));\n else if (e.kind === \"missing-script\") files.push(...e.manifestsChecked, ...(e.scope?.candidates ?? []));\n else if (e.kind === \"unmentioned-dir\") files.push(e.dir, ...e.checkedDocs);\n else throw new Error(\"This advisory has no supported review scope.\");\n return [...new Set(files)].map(file => {\n if (normalizeRepoPath(file) !== file) throw new Error(\"Advisory contains an invalid scoped path: \" + file);\n return `:(literal)${file}`;\n }).sort();\n}\n\n/** Committed, scoped Git evidence survives unrelated and review-record-only commits. */\nasync function reviewEvidence(root: string, finding: Finding) {\n if (normalizeRepoPath(finding.anchor.doc) !== finding.anchor.doc) throw new Error(\"Invalid advisory document path.\");\n const scope = scopes(finding);\n const head = (await git(root, \"rev-parse\", \"HEAD\")).trim();\n const tracked = (await git(root, \"ls-files\", \"--cached\", \"-z\", \"--\", ...scope)).split(\"\\0\").filter(Boolean);\n if (tracked.length > 20_000) throw new Error(\"Advisory scope exceeds 20,000 tracked files.\");\n const [tree, status, lastScopeCommit, document] = await Promise.all([\n tracked.length ? git(root, \"ls-tree\", \"-r\", \"-z\", \"HEAD\", \"--\", ...tracked.map(file => `:(literal)${file}`)) : \"\",\n git(root, \"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\", \"--\", ...scope),\n git(root, \"log\", \"-1\", \"--format=%H\", \"HEAD\", \"--\", ...scope).then(value => value.trim()),\n readAuditInput(root, finding.anchor.doc),\n ]);\n if (!document?.trim()) throw new Error(\"Original advisory document is missing, empty or unreadable.\");\n if (tree.length > 2 * 1024 * 1024 || tree.split(\"\\0\").length > 20_000) throw new Error(\"Advisory scope is too large for a complete review; narrow the documentation scope.\");\n // Reject symlinks rather than trusting a blob that describes an external target.\n for (const entry of tree.split(\"\\0\").filter(Boolean)) {\n const tab = entry.indexOf(\"\\t\"), file = entry.slice(tab + 1);\n if (entry.startsWith(\"120000 \") || entry.startsWith(\"160000 \")) throw new Error(\"Symlink or submodule in advisory review scope: \" + file);\n await storePath(root, file);\n }\n // Path checks observe presence even for explicitly documented ignored\n // outputs. Git alone cannot detect those appearing or disappearing.\n const paths = finding.evidence.kind === \"missing-path\" ? await Promise.all(\n (finding.evidence.scope?.candidates ?? [finding.evidence.resolvedPath ?? finding.evidence.claimed])\n .map(async file => ({ path: file, exists: await pathExists(root, file) }))) : [];\n let dirty = status.length > 0;\n if (finding.evidence.kind === \"missing-script\") {\n for (const file of [...finding.evidence.manifestsChecked, ...(finding.evidence.scope?.candidates ?? [])]) {\n if (!tracked.includes(file) && await pathExists(root, file)) dirty = true;\n }\n }\n const fingerprint = digest([scope, tree, lastScopeCommit, paths]);\n if ((await git(root, \"rev-parse\", \"HEAD\")).trim() !== head) throw new Error(\"HEAD changed while collecting review evidence.\");\n return { ...evidenceSchema.parse({ head, scope, tree, lastScopeCommit, paths, fingerprint }), dirty,\n documentDigest: digest(document) };\n}\n\nasync function decisionAssessment(root: string, finding: Finding, baselineHead: string): Promise<AdvisoryReviewSummary | null> {\n const evidence = finding.evidence;\n if (evidence.kind !== \"decision-anchor\") return null;\n const id = findingId(finding);\n const store = await loadDecisionStore(root);\n if (store.diagnostics.length) throw new Error(\"Decision records have unavailable or malformed evidence; review cannot be confirmed.\");\n const record = store.records.find(record => record.id === evidence.decisionId);\n if (!record || record.version !== 2) return null;\n const events = record.history.filter(event => [\"accepted\", \"reaffirmed\", \"retired\"].includes(event.kind));\n const event = events.at(-1);\n if (!event?.evidence || !event.actor || !event.note || !event.evidence.historyAvailable || event.evidence.localChanges.length) return null;\n try { await git(root, \"merge-base\", \"--is-ancestor\", baselineHead, event.evidence.headHash); }\n catch { return null; }\n const drift = await computeDecisionDrift(root, [record]);\n if (!drift.historyAvailable) throw new Error(\"Decision review history is unavailable.\");\n const retired = record.status === \"retired\" && event.kind === \"retired\";\n const current = retired || record.status === \"active\" && record.approval === \"accepted\"\n && drift.freshness?.[record.id] === \"current\" && !drift.pendingProposals?.[record.id];\n return { id, status: current ? \"current\" : \"reopened\", outcome: event.kind as \"accepted\" | \"reaffirmed\" | \"retired\",\n reviewer: event.actor, note: event.note, reviewedHead: event.evidence.headHash,\n recordPath: `.mason/decisions/${record.id}.json`, reason: current\n ? \"The existing decision review records acceptance, reaffirmation or retirement covering the original finding.\"\n : \"Decision content or anchor evidence changed after its review; review the decision again.\" };\n}\n\nexport async function assessAdvisory(root: string, finding: Finding, baselineHead: string): Promise<AdvisoryReviewSummary | null> {\n if (\"confidence\" in finding) return null;\n const id = findingId(finding);\n try {\n if (finding.evidence.kind === \"decision-anchor\") return await decisionAssessment(root, finding, baselineHead);\n const record = await readRecord(root, id);\n if (!record) return null;\n const event = record.events.at(-1)!;\n // Use the reviewed scope, not a newly shortened finding's preview of that scope.\n const current = await reviewEvidence(root, event.finding as Finding);\n await git(root, \"merge-base\", \"--is-ancestor\", event.evidence.head, current.head);\n const base = { id, recordPath: recordPath(id), reviewer: event.reviewer, note: event.note,\n outcome: event.outcome, reviewedHead: event.evidence.head };\n if (current.dirty || current.fingerprint !== event.evidence.fingerprint || digest(scopes(finding)) !== digest(event.evidence.scope)) return { ...base, status: \"reopened\", reason: \"Relevant document or repository evidence changed after the assessment; prepare a new review.\" };\n return { ...base, status: event.outcome === \"deferred\" ? \"deferred\" : \"current\", reason: event.outcome === \"deferred\"\n ? \"The review was deferred and remains outstanding.\" : \"An explicit assessment covers the current committed scope. This does not approve an engineering decision or certify correctness.\" };\n } catch (error) { return { id, status: \"unverified\", reason: error instanceof Error ? error.message : String(error) }; }\n}\n\n/** Fingerprint receipt content so concurrent automation cannot publish an older assessment. */\nexport async function advisoryReviewInventory(root: string) {\n let names: string[];\n try { names = await fs.readdir(await storePath(root, \".mason/reviews/advisories\")); }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return []; throw error; }\n if (names.length > 5000) throw new Error(\"Advisory review inventory exceeds 5,000 records.\");\n return Promise.all(names.filter(name => name.endsWith(\".json\")).sort().map(async name => [name, await readAuditInput(root, \".mason/reviews/advisories/\" + name)]));\n}\n\nexport async function reviewAdvisory(rootDir: string, input: AdvisoryReviewInput) {\n const root = await fs.realpath(rootDir), request = advisoryReviewRequest.parse(input);\n const { loadRepairBaseline } = await import(\"./repair.js\");\n const baseline = await loadRepairBaseline(root, request.baselinePath);\n const finding = [...baseline.original.advisories, ...(baseline.original.suppressedAdvisories ?? [])].find(f => findingId(f) === request.findingId);\n if (!finding) throw new Error(\"No advisory with this findingId in the original baseline. Provable issues must be repaired and rechecked.\");\n if (finding.evidence.kind === \"decision-anchor\") return { status: \"decision-review-required\", decisionId: finding.evidence.decisionId,\n hint: \"Use review_decision to prepare evidence and record authorized acceptance, reaffirmation or retirement, then verify this original repair baseline. An advisory assessment cannot approve a decision.\" };\n const prepare = async () => {\n const record = await readRecord(root, request.findingId);\n const evidence = await reviewEvidence(root, finding);\n await git(root, \"merge-base\", \"--is-ancestor\", baseline.original.headHash!, evidence.head);\n const token = digest({ baseline: baseline.original, finding, evidence, record });\n return { record, evidence, token };\n };\n if (request.action === \"prepare\") {\n const state = await prepare();\n let diff: string | null = null, diffNote: string | undefined;\n const from = finding.evidence.kind === \"doc-behind-manifests\" ? finding.evidence.docLastCommit.hash : baseline.original.headHash!;\n try {\n const full = await git(root, \"diff\", \"--no-ext-diff\", \"--no-textconv\", \"--no-color\", \"--no-renames\", \"-U3\", from, state.evidence.head, \"--\", ...state.evidence.scope);\n diff = full.slice(0, 16000); if (full.length > diff.length) diffNote = \"Diff preview truncated; inspect the full scoped diff before reviewing.\";\n } catch { diffNote = \"Diff preview unavailable; inspect the original cited evidence directly before reviewing.\"; }\n if ((await prepare()).token !== state.token) throw new Error(\"Review evidence changed during preparation; retry.\");\n return { status: \"prepared\", findingId: request.findingId, finding, evidence: state.evidence,\n history: state.record?.events ?? [], reviewToken: state.token, diff, diffNote,\n hint: \"Inspect the original finding, scoped document and relevant code changes. Record addressed, inapplicable or deferred only when the user or cited project review authorizes that assessment. Supply the actual reviewer, reason in note and reviewToken. Relevant edits must be committed first. Deferral remains outstanding. Review identities are recorded assertions, not authenticated approvals.\" };\n }\n if (!request.reviewer || !request.note || !request.reviewToken) throw new Error(\"Prepare first; recording an assessment requires reviewToken, reviewer and note.\");\n return withLock(root, \".mason/reports/advisory-review-locks/\" + request.findingId, async () => {\n const state = await prepare();\n if (state.token !== request.reviewToken) throw new Error(\"Review conflict: evidence or review history changed since preparation. Prepare and inspect a new review.\");\n if (state.evidence.dirty) throw new Error(\"Commit relevant document and repository edits before recording the assessment. Unrelated local work may remain.\");\n if ((state.record?.events.length ?? 0) >= 200) throw new Error(\"Review history limit reached; existing events were retained.\");\n const { dirty, documentDigest, ...evidence } = state.evidence;\n const event = eventSchema.parse({ at: new Date().toISOString(), reviewer: request.reviewer, note: request.note,\n outcome: request.action, finding, evidence });\n const payload = { version: 1 as const, id: request.findingId, events: [...(state.record?.events ?? []), event] };\n if ((await prepare()).token !== state.token) throw new Error(\"Review conflict: evidence changed while recording the assessment.\");\n await writeStoreJson(root, recordPath(request.findingId), { ...payload, digest: digest(payload) });\n return { status: \"recorded\", recordPath: recordPath(request.findingId), event,\n hint: \"Review and commit this assessment record through the normal project workflow, then verify the original repair baseline. Relevant changes reopen the assessment; deferral remains outstanding.\" };\n });\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getChangesWithStatus } from \"../drift/drift.js\";\nimport type { FileChange } from \"../drift/drift.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { discoverDocs } from \"./docs.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport type { AuditReport, CheckName } from \"./types.js\";\nimport { CHECKS } from \"./checks/index.js\";\nimport { assessAdvisory } from \"./advisory-review.js\";\nimport type { CheckContext, CheckResult } from \"./checks/index.js\";\n\nexport interface AuditOptions {\n /** Subset of checks to run; defaults to all. */\n checks?: CheckName[];\n /** Internal execution boundary used by the automation dependency cache. */\n runCheck?: (name: CheckName, context: CheckContext) => Promise<CheckResult>;\n}\n\n/**\n * Audit discovered instruction files and READMEs\n * against repo reality. Fully deterministic — git, filesystem, and lexical\n * extraction only; no LLM, no network. Returns null when no context file\n * exists.\n */\nexport async function computeAudit(\n rootDir: string,\n options: AuditOptions = {}\n): Promise<AuditReport | null> {\n const resolvedRoot = path.resolve(rootDir);\n const [docs, headHash] = await Promise.all([discoverDocs(resolvedRoot), getCurrentGitHash(resolvedRoot)]);\n if (docs.length === 0) return null;\n\n const report: AuditReport = {\n version: 1,\n root: resolvedRoot,\n gitAvailable: headHash !== \"unknown\",\n headHash,\n checksRun: [],\n docs: docs.map((d) => ({\n path: d.path,\n scope: d.scope,\n kind: d.kind,\n lastCommit: d.lastCommit,\n dirty: d.dirty,\n lineCount: d.lineCount,\n })),\n decisionsChecked: false,\n issues: [],\n advisories: [],\n suppressedAdvisories: [],\n skippedChecks: [],\n clean: true,\n };\n\n // Without git the provability gates cannot run — the caller treats this\n // as an error rather than silently degrading precision.\n if (!report.gitAvailable) return report;\n\n const changesSinceDoc = new Map<string, FileChange[] | null>();\n for (const doc of docs) {\n changesSinceDoc.set(\n doc.path,\n doc.lastCommit\n ? await getChangesWithStatus(resolvedRoot, doc.lastCommit.hash)\n : null\n );\n }\n\n let decisionsPresent = false;\n try {\n await fs.access(path.join(resolvedRoot, \".mason\", \"decisions\"));\n decisionsPresent = true;\n } catch {\n // No decision store — the check stays dark (zero-setup path).\n }\n report.decisionsChecked = decisionsPresent;\n\n const ctx: CheckContext = {\n root: resolvedRoot,\n docs,\n headHash,\n changesSinceDoc,\n decisionsPresent,\n };\n\n const selected = options.checks ?? ALL_CHECKS;\n for (const name of ALL_CHECKS) {\n if (!selected.includes(name)) continue;\n const { issues, advisories, suppressedAdvisories, skipped } = await (options.runCheck\n ? options.runCheck(name, ctx) : CHECKS[name](ctx));\n report.checksRun!.push(name);\n report.issues.push(...issues);\n report.advisories.push(...advisories);\n report.suppressedAdvisories!.push(...(suppressedAdvisories ?? []));\n report.skippedChecks.push(...skipped);\n }\n\n report.clean = report.issues.length === 0;\n const reviews = (await Promise.all([...report.advisories, ...report.suppressedAdvisories!]\n .map(finding => assessAdvisory(resolvedRoot, finding, headHash)))).filter(review => review !== null);\n if (reviews.length) report.advisoryReviews = reviews;\n return report;\n}\n","import path from \"node:path\";\nimport { computeAudit } from \"./audit.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport { prepareRepair, verifyRepair, formatRepairSummary, repairExitCode } from \"./repair.js\";\nimport type { AuditIssue, AuditReport, CheckName } from \"./types.js\";\nimport { findingId } from \"./findings.js\";\nimport { runAdvisoryCli } from \"./advisory-cli.js\";\n\nexport const USAGE = `Usage: mason-audit [--dir <path>] [--json | --fix-prompt] [--checks <list>]\n\nAudits README.md and agent instruction files at any depth, preserving filename case\nagainst repo reality: referenced paths that no longer exist, undocumented\nmodules, stale counts, dead npm scripts, and manifests newer than the doc.\nDeterministic: no LLM call, no network – safe for CI. Works on any repo with\na context file; no Mason setup required.\n\nOptions:\n --dir <path> Project root to audit (default: current directory)\n --json Print the full audit report as JSON (additive-only schema)\n --fix-prompt When issues exist, print a work order for ANY coding agent\n (Claude, Codex, Gemini, ...) – pipe it to your agent CLI to\n repair the findings. Includes advisories that require review.\n --prepare-repair Save the original audit under .mason/reports/repairs/ before edits\n --verify-repair <path>\n Compare against that saved baseline, using its original checks\n --checks <list> Comma-separated subset of checks to run (default: all):\n ${ALL_CHECKS.join(\", \")}\n --help Show this help\n\nUse mason audit review --help to prepare and record an authorized advisory assessment.\n\nExit codes:\n 0 no issues (advisories may still be present)\n 1 provable issues found\n 2 error (no context file, not a git repository, bad arguments)\n\nWith --verify-repair: 0 verified by the original checks; 1 issues remain;\n2 incomplete (unverified findings, skipped checks, or advisories needing review).\nPreparation writes only a baseline; verification and ordinary audits are read-only.`;\n\nexport interface AuditCliIo {\n out: (line: string) => void;\n err: (line: string) => void;\n}\n\ninterface ParsedArgs {\n dir: string;\n json: boolean;\n fixPrompt: boolean;\n help: boolean;\n checks: CheckName[] | undefined;\n prepareRepair: boolean;\n baseline?: string;\n}\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n dir: process.cwd(),\n json: false,\n fixPrompt: false,\n help: false,\n checks: undefined,\n prepareRepair: false,\n };\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--json\") {\n parsed.json = true;\n } else if (arg === \"--fix-prompt\") {\n parsed.fixPrompt = true;\n } else if (arg === \"--prepare-repair\") {\n parsed.prepareRepair = true;\n } else if (arg === \"--verify-repair\") {\n const value = argv[++i];\n if (!value || value.startsWith(\"--\")) throw new Error(\"--verify-repair requires a baseline path\");\n parsed.baseline = value;\n } else if (arg === \"--help\" || arg === \"-h\") {\n parsed.help = true;\n } else if (arg === \"--dir\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--dir requires a path argument\");\n parsed.dir = value;\n } else if (arg === \"--checks\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--checks requires a comma-separated list\");\n const names = value.split(\",\").map((n) => n.trim()).filter(Boolean);\n if (!names.length) throw new Error(\"--checks requires at least one check\");\n for (const name of names) {\n if (!ALL_CHECKS.includes(name as CheckName)) {\n throw new Error(\n `Unknown check: ${name} (valid: ${ALL_CHECKS.join(\", \")})`\n );\n }\n }\n parsed.checks = names as CheckName[];\n } else if (!arg.startsWith(\"-\") && parsed.dir === process.cwd()) {\n parsed.dir = arg;\n } else {\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n return parsed;\n}\n\nfunction issueLine(issue: AuditIssue): string {\n const where =\n issue.anchor.line !== null ? `line ${issue.anchor.line}` : \"doc-level\";\n const likely = issue.confidence === \"likely\" ? \" (likely)\" : \"\";\n return ` [${issue.type}]${likely} ${where}: ${issue.message}`;\n}\n\nexport function formatAuditSummary(report: AuditReport): string {\n const lines: string[] = [];\n const reviewed = new Set(report.advisoryReviews?.filter(review => review.status === \"current\").map(review => review.id));\n const open = report.advisories.filter(finding => !reviewed.has(findingId(finding)));\n const suppressed = (report.suppressedAdvisories ?? []).filter(finding => !reviewed.has(findingId(finding)));\n const reviewCount = open.length + suppressed.length;\n\n for (const doc of report.docs) {\n const docIssues = report.issues.filter((i) => i.anchor.doc === doc.path);\n const committed = doc.lastCommit\n ? `last committed ${doc.lastCommit.date.slice(0, 10)}, ${doc.lastCommit.hash.slice(0, 7)}`\n : \"untracked\";\n if (docIssues.length === 0) {\n lines.push(`${doc.path} – clean (${committed})`);\n continue;\n }\n lines.push(\n `${doc.path} – ${docIssues.length} issue${docIssues.length === 1 ? \"\" : \"s\"} (${committed})`\n );\n for (const issue of docIssues) lines.push(issueLine(issue));\n }\n\n // Issues anchored outside the docs list (defensive; new-module anchors to\n // the primary doc, so this should stay empty).\n const docPaths = new Set(report.docs.map((d) => d.path));\n for (const issue of report.issues) {\n if (!docPaths.has(issue.anchor.doc)) lines.push(issueLine(issue));\n }\n\n if (open.length > 0) {\n lines.push(\"Advisories (do not affect the exit code):\");\n for (const advisory of open) {\n lines.push(` [${advisory.type}] ${advisory.anchor.doc}: ${advisory.message}`);\n }\n }\n if (report.skippedChecks.length > 0) {\n for (const skip of report.skippedChecks) {\n lines.push(` [skipped] ${skip.check}: ${skip.reason}`);\n }\n }\n\n if (reviewed.size) lines.push(`${reviewed.size} advisories have recorded assessments covering current evidence (see --json).`);\n for (const review of report.advisoryReviews ?? []) if (review.status !== \"current\") lines.push(` [${review.status}] ${review.reason}`);\n for (const advisory of suppressed) {\n lines.push(` [suppressed; unresolved] ${advisory.type} ${advisory.anchor.doc}: ${advisory.message}`);\n }\n\n lines.push(\n report.clean\n ? reviewCount || report.skippedChecks.length\n ? `No audit issues detected (${report.docs.length} docs audited); ${reviewCount} advisories remain for review, ${report.skippedChecks.length} checks skipped.`\n : `Context files are clean (${report.docs.length} doc${report.docs.length === 1 ? \"\" : \"s\"} audited).`\n : `${report.issues.length} issue${report.issues.length === 1 ? \"\" : \"s\"} across ${report.docs.length} doc${report.docs.length === 1 ? \"\" : \"s\"}.`\n );\n return lines.join(\"\\n\");\n}\n\n/**\n * Provider-neutral work order: any coding agent can execute it. The evidence\n * is deterministic; the agent's job is judgment scoped to exactly these\n * claims – never a free-form doc rewrite.\n */\nexport function formatFixPrompt(report: AuditReport, baselinePath?: string): string {\n const flaggedDocs = [...new Set(report.issues.map((i) => i.anchor.doc))];\n const lines: string[] = [];\n lines.push(\n \"Review the flagged context claims using the evidence below. Make minimal repairs within the user's authorized scope. A setup-only or audit-only request does not authorize rewriting existing documentation.\"\n );\n lines.push(\"\");\n lines.push(\"RULES:\");\n lines.push(baselinePath\n ? `- Preserve the original repair baseline: ${JSON.stringify(baselinePath)}. Do not replace it after editing.`\n : \"- Before the first edit, call mason_repair with action: prepare, or run mason-audit --prepare-repair --json with the same --dir and --checks. Keep the returned baselinePath through verification.\");\n lines.push(\n `- Edit ONLY these files: ${flaggedDocs.join(\", \") || \"none (advisory review only)\"}. Bring the docs into agreement with verified source evidence; do not change source code or configs to silence findings.`\n );\n lines.push(\n \"- Keep diffs minimal: change the smallest span that makes each claim true.\"\n );\n lines.push(\n \"- Never invent content. Every replacement must be grounded in the evidence below or in files you read from this repository.\"\n );\n lines.push(\"- Inspect likely findings before editing: heuristic evidence may describe an intentional omission or an example.\");\n lines.push(\n \"- deleted-reference: if evidence shows renamedTo, update the path; otherwise remove the reference, or rephrase to past tense if the sentence is about history. Deleted paths inside directory trees: delete the tree line.\"\n );\n lines.push(\n \"- stale-count: replace the number with the actual count from the evidence.\"\n );\n lines.push(\n \"- dead-command: replace with the correct script from availableScripts if an obvious rename exists; otherwise remove the command mention.\"\n );\n lines.push(\n \"- new-module: review whether the directory needs documenting; an omission alone does not establish a defect. Preserve scope and describe only what you verified.\"\n );\n lines.push(\n \"- Historical ADVISORIES require a separate authorized assessment using review_advisory with the baselinePath and findingId from verification. Prepare and inspect evidence first; record addressed, inapplicable or deferred with the actual reviewer, note and reviewToken. Decision findings use review_decision. Candidates marked resolution: recheck can be rerun to see whether the condition remains; this does not establish semantic approval. Report what remains unknown.\"\n );\n lines.push(\"\");\n lines.push(\"AUDIT REPORT (current context files and repository evidence, including local edits):\");\n lines.push(\n JSON.stringify(\n { root: report.root, checks: report.checksRun, issues: report.issues, advisories: report.advisories,\n suppressedAdvisories: report.suppressedAdvisories, skippedChecks: report.skippedChecks },\n null,\n 2\n )\n );\n lines.push(\"\");\n lines.push(\n \"After edits, call mason_repair with action: verify and the original baselinePath, or mason-audit --verify-repair <baselinePath> --dir <project>. Repeat against the same baseline after any final documentation commit. Summarize resolved, unresolved, review-required, unverified, and new findings with their evidence. Do not report a suppressed or unavailable check as fixed. This audit covers the listed documents and supported claims; application behavior and code examples need their own validation.\"\n );\n return lines.join(\"\\n\");\n}\n\nexport async function runAuditCli(\n argv: string[],\n io: AuditCliIo = {\n out: (line) => process.stdout.write(`${line}\\n`),\n err: (line) => process.stderr.write(`${line}\\n`),\n }\n): Promise<number> {\n if (argv[0] === \"review\") return runAdvisoryCli(argv.slice(1), io);\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n if (args.json && args.fixPrompt) {\n throw new Error(\"--json and --fix-prompt are mutually exclusive\");\n }\n if (args.baseline && (args.prepareRepair || args.checks || args.fixPrompt)) {\n throw new Error(\"--verify-repair cannot be combined with --prepare-repair, --checks, or --fix-prompt; verification uses the original scope\");\n }\n } catch (error) {\n io.err(error instanceof Error ? error.message : String(error));\n io.err(USAGE);\n return 2;\n }\n\n if (args.help) {\n io.out(USAGE);\n return 0;\n }\n\n const rootDir = path.resolve(args.dir);\n if (args.baseline || args.prepareRepair) {\n try {\n if (args.baseline) {\n const verification = await verifyRepair(rootDir, args.baseline);\n io.out(args.json ? JSON.stringify(verification, null, 2) : formatRepairSummary(verification));\n return repairExitCode(verification);\n }\n const prepared = await prepareRepair(rootDir, args.checks);\n io.out(args.json ? JSON.stringify({ ...prepared, workOrder: formatFixPrompt(prepared.report, prepared.baselinePath) }, null, 2)\n : args.fixPrompt ? formatFixPrompt(prepared.report, prepared.baselinePath)\n : `Repair baseline: ${prepared.baselinePath}\\n${formatAuditSummary(prepared.report)}`);\n return prepared.report.clean ? 0 : 1;\n } catch (error) {\n io.err(error instanceof Error ? error.message : String(error));\n return 2;\n }\n }\n const report = await computeAudit(rootDir, { checks: args.checks });\n\n if (!report) {\n io.err(\n `No README.md or agent instruction files found in ${rootDir}.`\n );\n return 2;\n }\n\n if (!report.gitAvailable) {\n io.err(\n `Could not determine git HEAD in ${rootDir} – not a git repository, or git is unavailable.`\n );\n return 2;\n }\n\n if (args.fixPrompt) {\n io.out(\n report.clean && !report.advisories.length && !report.suppressedAdvisories?.length\n ? formatAuditSummary(report) : formatFixPrompt(report)\n );\n return report.clean ? 0 : 1;\n }\n\n if (args.json) {\n io.out(JSON.stringify(report, null, 2));\n } else {\n io.out(formatAuditSummary(report));\n }\n return report.clean ? 0 : 1;\n}\n","import path from \"node:path\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { reviewAdvisory, type AdvisoryReviewInput } from \"./advisory-review.js\";\n\nconst USAGE = `Usage: mason audit review --baseline <path> --finding <id> [options]\n\nPrepare an advisory assessment against retained evidence (read-only by default).\n --dir <path> Repository root (default: current directory)\n --baseline <path> Original repair baseline\n --finding <id> findingId from repair verification or automation\n --outcome <value> Record addressed, inapplicable, or deferred\n --reviewer <name> Actual authorized reviewer\n --note <reason> Assessment reason\n --token <token> reviewToken returned by preparation\n --json Full evidence and review history\n\nRecording requires prior preparation and committed relevant edits. Review records\nbelong in Git under .mason/reviews/advisories/. Deferral remains outstanding.\nDecision findings use review_decision; this command never approves decisions.\nExit 0: prepared/recorded; 2: unavailable, conflict, or decision review required.`;\n\nexport async function runAdvisoryCli(args: string[], io = { out: (text: string) => console.log(text), err: (text: string) => console.error(text) }): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) { io.out(USAGE); return 0; }\n try {\n const flags: Record<string, string> = {}; let json = false;\n for (let i = 0; i < args.length; i++) {\n const flag = args[i];\n if (flag === \"--json\") { json = true; continue; }\n if (![\"--dir\", \"--baseline\", \"--finding\", \"--outcome\", \"--reviewer\", \"--note\", \"--token\"].includes(flag) || flags[flag]) throw new Error(\"Unexpected or repeated argument: \" + flag);\n const value = args[++i]; if (!value || value.startsWith(\"--\")) throw new Error(flag + \" requires a value.\");\n flags[flag] = value;\n }\n if (!flags[\"--outcome\"] && [\"--reviewer\", \"--note\", \"--token\"].some(key => flags[key])) throw new Error(\"Use --outcome to record an assessment.\");\n const input = { baselinePath: flags[\"--baseline\"], findingId: flags[\"--finding\"],\n action: flags[\"--outcome\"] ?? \"prepare\", reviewer: flags[\"--reviewer\"], note: flags[\"--note\"], reviewToken: flags[\"--token\"] } as AdvisoryReviewInput;\n const result = await reviewAdvisory(path.resolve(flags[\"--dir\"] ?? process.cwd()), input);\n if (json) io.out(JSON.stringify(result, null, 2));\n else {\n const lines = [`Advisory review: ${result.status}.`];\n if (\"finding\" in result && result.finding && result.evidence) lines.push(`[${result.finding.type}] ${result.finding.anchor.doc}: ${result.finding.message}`,\n `Finding: ${result.findingId}`, `Prepared against commit ${result.evidence.head.slice(0, 12)}.`,\n result.evidence.dirty ? \"Relevant files have uncommitted edits; commit them and prepare again before recording.\" : \"Relevant files are committed.\",\n `Review token: ${result.reviewToken}`, ...(result.diff ? [\"Scoped changes:\", result.diff] : []), ...(result.diffNote ? [result.diffNote] : []));\n if (\"event\" in result) lines.push(`${result.event.outcome} — ${result.event.reviewer}: ${result.event.note}`, `Record: ${result.recordPath}`);\n lines.push(result.hint);\n io.out(stripVTControlCharacters(lines.join(\"\\n\")));\n }\n return result.status === \"decision-review-required\" ? 2 : 0;\n } catch (error) { io.err(stripVTControlCharacters(error instanceof Error ? error.message : String(error))); return 2; }\n}\n","import { runAuditCli } from \"../src/audit/cli.js\";\n\nrunAuditCli(process.argv.slice(2)).then(\n (code) => { process.exitCode = code; },\n (err) => {\n process.stderr.write(`mason-audit error: ${err}\\n`);\n process.exitCode = 2;\n }\n);\n"],"mappings":"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","names":["path","fs","path","path","path","execFile","promisify","exec","fs","path","execFile","promisify","exec","path","text","execFile","promisify","exec","fs","path","execFile","promisify","fg","readdir","lstat","count","fs","path","execFile","promisify","fg","exec","fs","path","path","fg","fs","path","text","dir","count","path","path","execFile","promisify","exec","text","scopes","path","z","fs","path","z","path","init_drift","init_drift","createHash","z","fs","z","fs","path","randomUUID","z","count","fs","execFile","promisify","z","git","evidenceSchema","record","event","loadRepairBaseline","eventSchema","execute","commitSchema","init_drift","fs","path","path","path","text","USAGE","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/profile.ts","../src/utils/paths.ts","../src/utils/files.ts","../src/utils/storage.ts","../src/test-map.ts","../src/snapshot/snapshot.ts","../src/drift/drift.ts","../src/audit/commands.ts","../src/audit/tree.ts","../src/audit/claims.ts","../src/audit/git.ts","../src/audit/inputs.ts","../src/audit/docs.ts","../src/audit/types.ts","../src/audit/scope.ts","../src/audit/checks/deleted-reference.ts","../src/audit/checks/new-module.ts","../src/audit/checks/stale-count.ts","../src/audit/checks/dead-command.ts","../src/audit/release-metadata.ts","../src/audit/checks/deps-changed.ts","../src/context/lexical.ts","../src/context/trust.ts","../src/decisions/provenance.ts","../src/decisions/decisions.ts","../src/decisions/drift.ts","../src/audit/checks/decision-anchor.ts","../src/audit/checks/index.ts","../src/audit/findings.ts","../src/automation/store.ts","../src/audit/repair.ts","../src/audit/advisory-review.ts","../src/audit/audit.ts","../src/audit/cli.ts","../src/audit/advisory-cli.ts","../bin/mason-audit.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\ntype Timing = { calls: number; totalMs: number };\nconst profiles = new AsyncLocalStorage<Record<string, Timing>>();\n\n/** Opt-in, invocation-local timings. Labels are fixed in source; no repository data. */\nexport async function profilePhase<T>(label: string, run: () => Promise<T>): Promise<T> {\n const phases = profiles.getStore();\n if (!phases) return run();\n const start = performance.now();\n try { return await run(); }\n finally {\n const timing = phases[label] ??= { calls: 0, totalMs: 0 };\n timing.calls++;\n timing.totalMs += performance.now() - start;\n }\n}\n\nexport async function withProfile<T>(run: () => Promise<T>, emit: (json: string) => void): Promise<T> {\n const phases: Record<string, Timing> = {};\n const start = performance.now();\n return profiles.run(phases, async () => {\n try { return await run(); }\n finally {\n emit(JSON.stringify({ kind: \"mason-profile\", version: 1, totalMs: performance.now() - start, phases }));\n }\n });\n}\n","import path from \"node:path\";\n\n/** One canonical representation for stored paths and decision anchors. */\nexport function normalizeRepoPath(value: string): string | null {\n const slash = value.replace(/\\\\/g, \"/\");\n if (!slash || slash.includes(\"\\0\") || path.posix.isAbsolute(slash) || /^[A-Za-z]:/.test(slash)) return null;\n if (slash.split(\"/\").includes(\"..\")) return null;\n const normalized = path.posix.normalize(slash).replace(/\\/$/, \"\");\n return normalized === \".\" ? null : normalized;\n}\n\nexport function sanitizeRepoPaths(files: string[]): string[] {\n return [...new Set(files.map(normalizeRepoPath).filter((p): p is string => p !== null))];\n}\n\nexport function isWithinRoot(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return relative !== \"..\" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);\n}\n\nexport function anchorMatches(anchor: string, file: string): boolean {\n const a = normalizeRepoPath(anchor);\n const f = normalizeRepoPath(file);\n return a !== null && f !== null && (a === f || f.startsWith(`${a}/`));\n}\n\nexport function matchingPaths(anchors: string[], files: Iterable<string>): string[] {\n return [...new Set(files)].filter(file => anchors.some(anchor => anchorMatches(anchor, file)));\n}\n","import fs from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport fg from \"fast-glob\";\nimport { isWithinRoot, normalizeRepoPath } from \"./paths.js\";\n\nconst exec = promisify(execFile);\nexport const SOURCE_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"mts\", \"cts\", \"mjs\", \"cjs\", \"vue\", \"svelte\", \"kt\", \"kts\", \"java\", \"py\", \"go\", \"rs\", \"swift\", \"rb\", \"cs\", \"cpp\", \"c\", \"h\", \"hpp\", \"dart\", \"php\"];\nexport const SOURCE_GLOB = `**/*.{${SOURCE_EXTENSIONS.join(\",\")}}`;\nexport const SOURCE_IGNORE = [\n \"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.gradle/**\",\n \"**/target/**\", \"**/.git/**\", \"**/.mason/**\", \"**/vendor/**\", \"**/__pycache__/**\",\n \"**/venv/**\", \"**/.venv/**\", \"**/*.min.*\", \"**/*.map\", \"**/*.lock\",\n \"**/generated/**\", \"**/*.generated.*\", \"**/R.java\", \"**/BuildConfig.java\",\n \"**/package-lock.json\", \"**/yarn.lock\", \"**/pnpm-lock.yaml\",\n];\nexport const MAX_SOURCE_BYTES = 1024 * 1024;\nexport interface ProjectConfig { patterns?: string[]; alwaysInclude?: string[]; ignore?: string[] }\nexport interface SourceFile { path: string; content: string; totalLines: number }\n\nexport function isSensitiveFile(file: string): boolean {\n return file.split(/[\\\\/]/).some(part =>\n /^(?:\\.env(?:\\..*)?|id_rsa.*|id_ed25519.*)$|\\.(?:pem|key|p12|pfx|jks|keystore)$|credentials\\.|secret|^local\\.properties$/i.test(part)\n );\n}\n\n/** Bound reads even if a file grows after stat. Only read regular files. */\nexport async function readBoundedFile(file: string, maxBytes: number): Promise<string | null> {\n // Do not block on a FIFO or follow a symlink substituted after resolution.\n const handle = await fs.open(file, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOFOLLOW);\n try {\n const stat = await handle.stat();\n if (!stat.isFile() || stat.size > maxBytes) return null;\n const buffer = Buffer.alloc(Math.min(maxBytes + 1, stat.size + 1));\n let bytes = 0;\n while (bytes < buffer.length) {\n const result = await handle.read(buffer, bytes, buffer.length - bytes, null);\n if (result.bytesRead === 0) break;\n bytes += result.bytesRead;\n }\n return bytes === buffer.length ? null : buffer.subarray(0, bytes).toString(\"utf8\");\n } finally { await handle.close(); }\n}\n\nexport async function loadProjectConfig(root: string): Promise<ProjectConfig> {\n try {\n const canonicalRoot = await fs.realpath(root);\n const configPath = await fs.realpath(path.join(root, \".mason/config.json\"));\n if (!isWithinRoot(canonicalRoot, configPath)) throw new Error(\"Project configuration resolves outside the repository\");\n const raw = await readBoundedFile(configPath, 64 * 1024);\n if (raw === null) throw new Error(\"Project configuration is not a regular file or exceeds 64 KiB\");\n const value = JSON.parse(raw);\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"Expected a configuration object\");\n const config: ProjectConfig = {};\n for (const key of [\"patterns\", \"alwaysInclude\", \"ignore\"] as const) {\n if (value[key] === undefined) continue;\n if (!Array.isArray(value[key]) || !value[key].every((s: unknown) => typeof s === \"string\")) {\n throw new Error(`Configuration ${key} must be an array of strings`);\n }\n config[key] = value[key];\n }\n return config;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return {};\n throw new Error(`Cannot apply project file policy: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/** Scoped to one operation, so a later tool call sees newly edited files/ignores. */\nexport async function createFileAccess(rootDir: string) {\n const root = path.resolve(rootDir);\n const canonicalRoot = await fs.realpath(root).catch(() => root);\n const config = await loadProjectConfig(root);\n const ignore = [...SOURCE_IGNORE, ...(config.ignore ?? [])];\n let gitFiles: Set<string> | null = null;\n try {\n const { stdout } = await exec(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });\n gitFiles = new Set(stdout.split(\"\\0\").filter(Boolean));\n } catch {\n // File-system projects are supported. Fail closed if this IS a Git repo.\n let inGit = false;\n try { await exec(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: root }); inGit = true; } catch { /* no Git */ }\n if (inGit) throw new Error(\"Cannot enumerate Git files safely\");\n }\n\n async function resolve(file: string): Promise<string | null> {\n const relative = normalizeRepoPath(file);\n if (!relative || isSensitiveFile(relative) || (gitFiles && !gitFiles.has(relative))) return null;\n const candidate = path.join(root, relative);\n try {\n const real = await fs.realpath(candidate);\n if (!isWithinRoot(canonicalRoot, real) || isSensitiveFile(path.relative(canonicalRoot, real))) return null;\n const stat = await fs.stat(real);\n if (!stat.isFile() || stat.size > MAX_SOURCE_BYTES) return null;\n // A symlink must not bypass the target's ignore policy either.\n if (gitFiles && !gitFiles.has(path.relative(canonicalRoot, real).split(path.sep).join(\"/\"))) return null;\n return real;\n } catch { return null; }\n }\n\n async function list(patterns: string | string[] = SOURCE_GLOB, options: { deep?: number; dot?: boolean } = {}): Promise<string[]> {\n const found = await fg(patterns, { cwd: root, ignore, followSymbolicLinks: false, ...options });\n const safe = await Promise.all(found.map(async f => (await resolve(f)) ? f : null));\n return safe.filter((f): f is string => f !== null).sort();\n }\n\n async function read(file: string): Promise<SourceFile | null> {\n const relative = normalizeRepoPath(file);\n if (!relative) return null;\n const real = await resolve(relative);\n if (!real) return null;\n // Apply the same glob exclusions to explicit reads and symlink targets.\n for (const rel of new Set([relative, path.relative(canonicalRoot, real).split(path.sep).join(\"/\")])) {\n if (!(await fg(fg.escapePath(rel), { cwd: root, ignore, dot: true })).length) return null;\n }\n try {\n const content = await readBoundedFile(real, MAX_SOURCE_BYTES);\n return content === null ? null : { path: relative, content, totalLines: content.split(\"\\n\").length };\n } catch { return null; }\n }\n return { root, config, list, read };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { normalizeRepoPath } from \"./paths.js\";\nimport { readBoundedFile } from \"./files.js\";\n\nexport interface StoreDiagnostic { path: string; message: string }\n\n/** Metadata paths may not contain symlinks, including their parent directories. */\nexport async function storePath(root: string, relative: string, createParents = false): Promise<string> {\n const normalized = normalizeRepoPath(relative);\n if (!normalized) throw new Error(`Invalid store path: ${relative}`);\n let current = await fs.realpath(root);\n const parts = normalized.split(\"/\");\n for (let i = 0; i < parts.length; i++) {\n current = path.join(current, parts[i]);\n let stat;\n try { stat = await fs.lstat(current); } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n if (createParents && i < parts.length - 1) {\n try { await fs.mkdir(current); } catch (mkdirError) {\n if ((mkdirError as NodeJS.ErrnoException).code !== \"EEXIST\") throw mkdirError;\n }\n stat = await fs.lstat(current);\n }\n }\n if (stat?.isSymbolicLink()) throw new Error(`Symlink in store path: ${relative}`);\n }\n return current;\n}\n\nexport async function readStoreJson(root: string, relative: string): Promise<unknown | null> {\n try {\n const file = await storePath(root, relative);\n const raw = await readBoundedFile(file, 10 * 1024 * 1024);\n if (raw === null) throw new Error(\"file is not regular or exceeds 10 MiB\");\n const parsed: unknown = JSON.parse(raw);\n if (parsed === null) throw new Error(\"expected a JSON object, received null\");\n return parsed;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return null;\n throw new Error(`Invalid Mason store ${relative}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });\n }\n}\n\nexport async function writeStoreJson(root: string, relative: string, value: unknown): Promise<void> {\n const payload = JSON.stringify(value, null, 2) + \"\\n\";\n if (Buffer.byteLength(payload) > 10 * 1024 * 1024) {\n throw new Error(`Mason store ${relative} exceeds 10 MiB`);\n }\n const file = await storePath(root, relative, true);\n const temporary = path.join(path.dirname(file), `.${path.basename(file)}.${randomUUID()}.tmp`);\n try {\n const handle = await fs.open(temporary, \"wx\", 0o600);\n try { await handle.writeFile(payload, \"utf8\"); await handle.sync(); }\n finally { await handle.close(); }\n await fs.rename(temporary, file);\n } finally { await fs.rm(temporary, { force: true }); }\n}\n","import path from \"node:path\";\nimport { createFileAccess } from \"./utils/files.js\";\n\nexport interface TestPair {\n test: string;\n source: string;\n confidence: string;\n}\n\nexport interface TestMapResult {\n totalTestFiles: number;\n paired: TestPair[];\n unmatched: string[];\n}\n\nexport async function buildTestMap(dir: string): Promise<TestMapResult> {\n const rootDir = path.resolve(dir);\n const access = await createFileAccess(rootDir);\n\n // Find all test files\n const testPatterns = [\n \"**/*.test.*\", \"**/*.spec.*\",\n \"**/*Test.kt\", \"**/*Test.java\", \"**/*Tests.kt\", \"**/*Tests.java\",\n \"**/test_*.py\", \"**/*_test.py\",\n \"**/*_test.go\",\n \"**/*Tests.swift\", \"**/*Test.swift\",\n \"**/*_test.rs\",\n ];\n const testFiles = await access.list(testPatterns);\n\n // Find all source files\n const sourceFiles = await access.list();\n\n // Build source file index by base name (without extension)\n const sourceByBaseName = new Map<string, string[]>();\n for (const file of sourceFiles) {\n if (testFiles.includes(file)) continue; // Skip test files\n const baseName = path.basename(file).replace(/\\.[^.]+$/, \"\");\n const existing = sourceByBaseName.get(baseName) ?? [];\n existing.push(file);\n sourceByBaseName.set(baseName, existing);\n }\n\n // Match test files to source files by name\n const paired: TestPair[] = [];\n const unmatched: string[] = [];\n\n for (const testFile of testFiles) {\n const testBaseName = path.basename(testFile).replace(/\\.[^.]+$/, \"\");\n\n // Strip test suffixes/prefixes to get the source name\n const sourceName = testBaseName\n .replace(/Test$|Tests$|Spec$|\\.test$|\\.spec$/, \"\")\n .replace(/^test_|_test$/, \"\");\n\n if (!sourceName) {\n unmatched.push(testFile);\n continue;\n }\n\n const candidates = sourceByBaseName.get(sourceName);\n if (candidates && candidates.length > 0) {\n // If multiple candidates, prefer one in a similar directory path\n const testDir = path.dirname(testFile);\n const bestMatch = candidates.reduce((best, candidate) => {\n const candidateDir = path.dirname(candidate);\n const bestDir = path.dirname(best);\n const candidateOverlap = commonSegments(testDir, candidateDir);\n const bestOverlap = commonSegments(testDir, bestDir);\n return candidateOverlap > bestOverlap ? candidate : best;\n });\n\n paired.push({\n test: testFile,\n source: bestMatch,\n confidence: candidates.length === 1 ? \"exact\" : \"best-guess\",\n });\n } else {\n unmatched.push(testFile);\n }\n }\n\n return { totalTestFiles: testFiles.length, paired, unmatched };\n}\n\nfunction commonSegments(pathA: string, pathB: string): number {\n const segsA = pathA.split(\"/\");\n const segsB = pathB.split(\"/\");\n let count = 0;\n for (let i = 0; i < Math.min(segsA.length, segsB.length); i++) {\n if (segsA[i] === segsB[i]) count++;\n else break;\n }\n return count;\n}\n","import path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { createFileAccess } from \"../utils/files.js\";\nexport { SOURCE_GLOB, SOURCE_IGNORE } from \"../utils/files.js\";\nimport { readStoreJson, writeStoreJson, type StoreDiagnostic } from \"../utils/storage.js\";\nimport { z } from \"zod\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { buildTestMap } from \"../test-map.js\";\n\nconst exec = promisify(execFile);\n\nexport interface FeatureEntry {\n description: string;\n files: string[];\n tests?: string[];\n /**\n * Commit this entry was last verified against. Entries updated by an\n * incremental save carry HEAD here; untouched entries keep the hash the\n * map had before the save, so drift stays visible per entry. Absent means\n * \"as of the snapshot's top-level gitHash\".\n */\n refreshedHash?: string;\n /**\n * Whether this is a user-facing capability or internal infrastructure\n * (DI wiring, config loading, logging, provider/transport plumbing).\n * Capabilities are published to product-facing docs (Confluence);\n * infrastructure stays in the AI concept map only. Defaults to \"capability\"\n * when absent (older snapshots) — see normalizeFeatureType.\n */\n type?: \"capability\" | \"infrastructure\";\n /**\n * When an assistant last confirmed this entry's files actually implement\n * the claimed feature (verify_snapshot flow). Absent on older snapshots\n * and never-verified entries. Drift checks freshness against git; this\n * checks the map was CORRECT in the first place.\n */\n verifiedAt?: string;\n verifiedHash?: string;\n /** Set when verification judged the entry wrong — re-map it. */\n verificationFailed?: boolean;\n verificationNote?: string;\n}\n\nexport type FeatureType = \"capability\" | \"infrastructure\";\n\n/**\n * Coerce an arbitrary type value to a known classification. Anything that\n * isn't explicitly \"infrastructure\" defaults to \"capability\" — so older\n * snapshots and unclassified entries are treated as user-facing (published),\n * never silently hidden.\n */\nexport function normalizeFeatureType(value: unknown): FeatureType {\n return value === \"infrastructure\" ? \"infrastructure\" : \"capability\";\n}\n\nexport interface FlowEntry {\n description: string;\n chain: string[];\n /** See FeatureEntry.refreshedHash. */\n refreshedHash?: string;\n /** See FeatureEntry.verifiedAt / verificationFailed. */\n verifiedAt?: string;\n verifiedHash?: string;\n verificationFailed?: boolean;\n verificationNote?: string;\n}\n\nexport interface Snapshot {\n version: 2;\n createdAt: string;\n updatedAt: string;\n gitHash: string;\n features: Record<string, FeatureEntry>;\n flows: Record<string, FlowEntry>;\n}\n\nconst repoPath = z.string().refine(value => normalizeRepoPath(value) !== null, \"Expected a relative repository path\");\nconst verificationFields = {\n refreshedHash: z.string().optional(), verifiedAt: z.string().optional(),\n verifiedHash: z.string().optional(), verificationFailed: z.boolean().optional(),\n verificationNote: z.string().optional(),\n};\nexport const featureSchema = z.object({\n description: z.string(), files: z.array(repoPath), tests: z.array(repoPath).optional(),\n type: z.enum([\"capability\", \"infrastructure\"]).optional(), ...verificationFields,\n}).passthrough();\nexport const flowSchema = z.object({ description: z.string(), chain: z.array(repoPath), ...verificationFields }).passthrough();\nconst snapshotSchema = z.object({\n version: z.literal(2), createdAt: z.string(), updatedAt: z.string(), gitHash: z.string(),\n features: z.record(featureSchema), flows: z.record(flowSchema),\n}).passthrough();\n\nexport async function loadSnapshot(rootDir: string): Promise<Snapshot | null> {\n const parsed = await readStoreJson(rootDir, \".mason/snapshot.json\");\n if (parsed === null || (parsed as { version?: number }).version === 1) return null;\n const result = snapshotSchema.safeParse(parsed);\n if (!result.success) throw new Error(`Invalid Mason snapshot: ${result.error.message}`);\n return result.data;\n}\n\n/** Context and onboarding can use decisions even when the optional map is broken. */\nexport async function inspectSnapshot(rootDir: string): Promise<{\n status: \"available\" | \"missing\" | \"invalid\";\n snapshot: Snapshot | null;\n diagnostics: StoreDiagnostic[];\n}> {\n try {\n const raw = await readStoreJson(rootDir, \".mason/snapshot.json\");\n const snapshot = raw === null ? null : snapshotSchema.parse(raw);\n return { status: snapshot ? \"available\" : \"missing\", snapshot, diagnostics: [] };\n } catch (error) {\n return { status: \"invalid\", snapshot: null, diagnostics: [{\n path: \".mason/snapshot.json\", message: error instanceof Error ? error.message : String(error),\n }] };\n }\n}\n\nexport async function saveSnapshot(rootDir: string, snapshot: Snapshot): Promise<void> {\n await writeStoreJson(rootDir, \".mason/snapshot.json\", snapshotSchema.parse(snapshot));\n}\n\nexport async function getCurrentGitHash(rootDir: string): Promise<string> {\n try {\n const { stdout } = await exec(\"git\", [\"rev-parse\", \"HEAD\"], {\n cwd: rootDir,\n });\n return stdout.trim();\n } catch {\n return \"unknown\";\n }\n}\n\nexport const DEFAULT_BATCH_SIZE = 50;\nconst SKELETON_CHARS = 500;\nconst DEEP_SAMPLE_CHARS = 1500;\nconst DEEP_SAMPLES_PER_BATCH = 3;\n\nexport interface SnapshotBatch {\n offset: number;\n batchSize: number;\n nextOffset: number | null;\n totalFiles: number;\n skeletons: Array<{ path: string; content: string }>;\n samples: Array<{ path: string; content: string }>;\n testPairs: Array<{ test: string; source: string; confidence: string }>;\n}\n\nexport async function listSourceFiles(resolvedRoot: string): Promise<string[]> {\n return (await createFileAccess(resolvedRoot)).list();\n}\n\nexport async function prepareSnapshotBatch(\n rootDir: string,\n offset: number,\n batchSize: number = DEFAULT_BATCH_SIZE,\n scopeFiles?: string[]\n): Promise<SnapshotBatch> {\n const resolvedRoot = path.resolve(rootDir);\n const access = await createFileAccess(resolvedRoot);\n let allFiles = await access.list();\n if (scopeFiles) {\n // Intersect with the real source list: keeps ignore rules and path safety,\n // and silently drops scope entries that no longer exist on disk. An empty\n // scope stays empty — it must not fall back to walking the whole project.\n const scopeSet = new Set(scopeFiles);\n allFiles = allFiles.filter((f) => scopeSet.has(f));\n }\n const totalFiles = allFiles.length;\n const safeOffset = Math.max(0, Math.min(offset, totalFiles));\n const batchPaths = allFiles.slice(safeOffset, safeOffset + batchSize);\n\n const skeletons: Array<{ path: string; content: string }> = [];\n for (const filePath of batchPaths) {\n const full = await access.read(filePath);\n if (full) {\n skeletons.push({\n path: full.path,\n content: full.content.slice(0, SKELETON_CHARS),\n });\n }\n }\n\n // Pick a few files from this batch to read deeply for grounding. Spread\n // evenly across the batch so the deep samples represent the batch's range.\n const samples: Array<{ path: string; content: string }> = [];\n if (skeletons.length > 0) {\n const step = Math.max(1, Math.floor(skeletons.length / DEEP_SAMPLES_PER_BATCH));\n for (let i = 0; i < skeletons.length && samples.length < DEEP_SAMPLES_PER_BATCH; i += step) {\n const full = await access.read(skeletons[i].path);\n if (full) {\n samples.push({\n path: full.path,\n content: full.content.slice(0, DEEP_SAMPLE_CHARS),\n });\n }\n }\n }\n\n // Only include test pairs that involve files in this batch — keeps the\n // appendix relevant and small.\n const batchPathSet = new Set(batchPaths);\n const allTestPairs = (await buildTestMap(resolvedRoot)).paired;\n const testPairs = allTestPairs.filter(\n (p) => batchPathSet.has(p.test) || batchPathSet.has(p.source)\n );\n\n const nextOffset =\n safeOffset + batchSize >= totalFiles ? null : safeOffset + batchSize;\n\n return {\n offset: safeOffset,\n batchSize,\n nextOffset,\n totalFiles,\n skeletons,\n samples,\n testPairs,\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport {\n loadSnapshot,\n getCurrentGitHash,\n listSourceFiles,\n} from \"../snapshot/snapshot.js\";\nimport type { Snapshot } from \"../snapshot/snapshot.js\";\nimport type { Freshness } from \"../context/trust.js\";\nimport { matchingPaths } from \"../utils/paths.js\";\n\nconst exec = promisify(execFile);\n\n// Incremental refresh stops paying off once a large share of the map is\n// touched — but small absolute counts are always cheap to refresh in place,\n// so both thresholds must be exceeded before recommending a full rebuild.\nconst FULL_REBUILD_FRACTION = 0.4;\nconst FULL_REBUILD_MIN_CHANGED_MAPPED_FILES = 10;\n\nexport type ChangeStatus = \"added\" | \"modified\" | \"deleted\" | \"renamed\";\n\nexport interface FileChange {\n status: ChangeStatus;\n /** Current path (the new path for renames). */\n path: string;\n /** Pre-rename path, only present for renames. */\n previousPath?: string;\n}\n\nexport type DriftRecommendation = \"up-to-date\" | \"incremental\" | \"full-rebuild\";\n\nexport interface WorkingTreeReport {\n available: boolean;\n changedFiles: string[];\n untrackedFiles: string[];\n}\n\nexport interface DriftReport {\n /** Live entry state; committed drift alone continues to drive CLI exit codes. */\n featureFreshness?: Record<string, Freshness>;\n flowFreshness?: Record<string, Freshness>;\n workingTree?: WorkingTreeReport;\n verification?: { neverVerified: number; failed: string[] };\n stale: boolean;\n snapshotHash: string;\n headHash: string;\n /** Commits between the snapshot and HEAD; null when history is unavailable. */\n commitsBehind: number | null;\n /**\n * False when the snapshot commit is unreachable (shallow clone, rewritten\n * history) — staleFeatures/unmappedFiles/renames cannot be computed then.\n */\n historyAvailable: boolean;\n /** Current paths of every file changed since the snapshot. */\n changedFiles: string[];\n /** Stale feature name → the mapped files that changed under it. */\n staleFeatures: Record<string, string[]>;\n /** Stale flow name → the chain files that changed under it. */\n staleFlows: Record<string, string[]>;\n totalFeatures: number;\n totalFlows: number;\n /** New source files not referenced by any feature or flow. */\n unmappedFiles: string[];\n /** Files referenced by the map that no longer exist on disk. */\n ghostFiles: string[];\n renames: Array<{ from: string; to: string }>;\n recommendation: DriftRecommendation;\n}\n\nfunction parseChanges(output: string): FileChange[] {\n const fields = output.split(\"\\0\");\n const changes: FileChange[] = [];\n for (let i = 0; i < fields.length && fields[i];) {\n const code = fields[i++];\n const first = fields[i++];\n if (!first) break;\n const second = /^[RC]/.test(code) ? fields[i++] : undefined;\n const change: FileChange = second\n ? code.startsWith(\"R\") ? { status: \"renamed\", path: second, previousPath: first } : { status: \"added\", path: second }\n : { status: code === \"A\" ? \"added\" : code === \"D\" ? \"deleted\" : \"modified\", path: first };\n if (change.path.startsWith(\".mason/\") && (!change.previousPath || change.previousPath.startsWith(\".mason/\"))) continue;\n changes.push(change);\n }\n return changes;\n}\n\nexport function touchedPaths(changes: FileChange[]): string[] {\n return [...new Set(changes.flatMap(c => c.previousPath ? [c.previousPath, c.path] : [c.path]))].sort();\n}\n\nexport async function getChangesWithStatus(resolvedRoot: string, fromHash: string, toHash = \"HEAD\"): Promise<FileChange[] | null> {\n if (!fromHash || fromHash === \"unknown\" || fromHash.startsWith(\"-\") || !toHash || toHash === \"unknown\" || toHash.startsWith(\"-\")) return null;\n try {\n const { stdout } = await exec(\"git\", [\"diff\", \"--name-status\", \"-z\", \"-M\", fromHash, toHash, \"--\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 });\n return parseChanges(stdout);\n } catch { return null; }\n}\n\nexport async function getWorkingTree(resolvedRoot: string): Promise<WorkingTreeReport> {\n try {\n const [diff, untracked] = await Promise.all([\n exec(\"git\", [\"diff\", \"--name-status\", \"-z\", \"-M\", \"HEAD\", \"--\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),\n exec(\"git\", [\"ls-files\", \"-z\", \"--others\", \"--exclude-standard\"], { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }),\n ]);\n const untrackedFiles = untracked.stdout.split(\"\\0\").filter(f => f && !f.startsWith(\".mason/\"));\n return { available: true, changedFiles: [...new Set([...touchedPaths(parseChanges(diff.stdout)), ...untrackedFiles])].sort(), untrackedFiles };\n } catch { return { available: false, changedFiles: [], untrackedFiles: [] }; }\n}\n\nasync function countCommitsBehind(\n resolvedRoot: string,\n fromHash: string\n): Promise<number | null> {\n if (!fromHash || fromHash === \"unknown\" || fromHash.startsWith(\"-\")) return null;\n try {\n const { stdout } = await exec(\n \"git\",\n [\"rev-list\", \"--count\", `${fromHash}..HEAD`],\n { cwd: resolvedRoot }\n );\n const count = Number.parseInt(stdout.trim(), 10);\n return Number.isNaN(count) ? null : count;\n } catch {\n return null;\n }\n}\n\nfunction collectMappedFiles(snapshot: Snapshot): Set<string> {\n const mappedFiles = new Set<string>();\n for (const feature of Object.values(snapshot.features)) {\n for (const f of feature.files) mappedFiles.add(f);\n for (const t of feature.tests ?? []) mappedFiles.add(t);\n }\n for (const flow of Object.values(snapshot.flows)) {\n for (const f of flow.chain) mappedFiles.add(f);\n }\n return mappedFiles;\n}\n\nasync function findGhostFiles(\n resolvedRoot: string,\n mappedFiles: Set<string>\n): Promise<string[]> {\n const ghosts: string[] = [];\n for (const file of mappedFiles) {\n try {\n await fs.access(path.join(resolvedRoot, file));\n } catch {\n ghosts.push(file);\n }\n }\n return ghosts.sort();\n}\n\n/**\n * Compare the concept map against HEAD and report feature-level drift.\n * Fully deterministic — git + filesystem only, no LLM involved.\n * Returns null when no snapshot exists.\n */\nexport async function computeDrift(rootDir: string): Promise<DriftReport | null> {\n const root = path.resolve(rootDir);\n const snapshot = await loadSnapshot(root);\n if (!snapshot) return null;\n const [headHash, workingTree] = await Promise.all([getCurrentGitHash(root), getWorkingTree(root)]);\n const hashFor = (entry: { refreshedHash?: string }) => entry.refreshedHash ?? snapshot.gitHash;\n const entries = [...Object.values(snapshot.features), ...Object.values(snapshot.flows)];\n const hashes = new Set([snapshot.gitHash, ...entries.map(hashFor)]);\n const changesByHash = new Map<string, FileChange[] | null>();\n await Promise.all([...hashes].map(async hash => {\n changesByHash.set(hash, hash === headHash && headHash !== \"unknown\" ? [] : await getChangesWithStatus(root, hash));\n }));\n const historyAvailable = headHash !== \"unknown\" && [...changesByHash.values()].every(changes => changes !== null);\n const mappedFiles = collectMappedFiles(snapshot);\n const report: DriftReport = {\n stale: !historyAvailable,\n snapshotHash: snapshot.gitHash, headHash,\n commitsBehind: 0, historyAvailable,\n changedFiles: [], staleFeatures: {}, staleFlows: {},\n totalFeatures: Object.keys(snapshot.features).length,\n totalFlows: Object.keys(snapshot.flows).length,\n unmappedFiles: [], ghostFiles: await findGhostFiles(root, mappedFiles), renames: [],\n recommendation: historyAvailable ? \"up-to-date\" : \"full-rebuild\",\n featureFreshness: {}, flowFreshness: {}, workingTree,\n verification: {\n neverVerified: entries.filter(e => !e.verifiedAt).length,\n failed: [...Object.entries(snapshot.features), ...Object.entries(snapshot.flows)].filter(([, e]) => e.verificationFailed).map(([name]) => name),\n },\n };\n const counts = await Promise.all([...hashes].map(hash => hash === headHash ? 0 : countCommitsBehind(root, hash)));\n const knownCounts = counts.filter((n): n is number => n !== null);\n report.commitsBehind = knownCounts.length ? Math.max(...knownCounts) : null;\n\n const check = (name: string, files: string[], hash: string, staleEntries: Record<string, string[]>, freshness: Record<string, Freshness>) => {\n const changes = changesByHash.get(hash);\n const committedHits = changes ? matchingPaths(files, touchedPaths(changes)) : [];\n if (committedHits.length) staleEntries[name] = committedHits;\n const localHits = matchingPaths(files, workingTree.changedFiles);\n freshness[name] = files.length === 0 || changes === null || changes === undefined || !workingTree.available ? \"unknown\"\n : committedHits.length || localHits.length || files.some(f => report.ghostFiles.includes(f)) ? \"changed\" : \"current\";\n };\n for (const [name, feature] of Object.entries(snapshot.features)) {\n check(name, [...feature.files, ...(feature.tests ?? [])], hashFor(feature), report.staleFeatures, report.featureFreshness!);\n }\n for (const [name, flow] of Object.entries(snapshot.flows)) {\n check(name, flow.chain, hashFor(flow), report.staleFlows, report.flowFreshness!);\n }\n\n const allChanges = [...changesByHash.values()].flatMap(changes => changes ?? []);\n report.changedFiles = [...new Set(allChanges.map(c => c.path))].sort();\n // Complete coverage, including omissions from a map saved at HEAD. Untracked\n // files remain in workingTree and never change the committed-drift exit code.\n const sourceFiles = new Set(await listSourceFiles(root));\n let committedFiles: Set<string> = new Set();\n try {\n const { stdout } = await exec(\"git\", [\"ls-tree\", \"-r\", \"--name-only\", \"-z\", \"HEAD\"], { cwd: root, maxBuffer: 50 * 1024 * 1024 });\n committedFiles = new Set(stdout.split(\"\\0\").filter(Boolean));\n } catch { report.historyAvailable = false; report.stale = true; }\n report.unmappedFiles = [...sourceFiles].filter(f => committedFiles.has(f) && !mappedFiles.has(f)).sort();\n const renames = new Map<string, { from: string; to: string }>();\n for (const change of allChanges) {\n if (change.status === \"renamed\" && change.previousPath) renames.set(`${change.previousPath}\\0${change.path}`, { from: change.previousPath, to: change.path });\n }\n report.renames = [...renames.values()];\n const changedMapped = new Set([...Object.values(report.staleFeatures).flat(), ...Object.values(report.staleFlows).flat()]);\n // A locally deleted file is a live-edit warning, not committed map drift.\n const committedGhosts = report.ghostFiles.filter(f => !workingTree.changedFiles.includes(f));\n report.stale ||= changedMapped.size > 0 || report.unmappedFiles.length > 0 || committedGhosts.length > 0;\n if (!report.historyAvailable) report.recommendation = \"full-rebuild\";\n else if (!report.stale) report.recommendation = \"up-to-date\";\n else report.recommendation = changedMapped.size >= FULL_REBUILD_MIN_CHANGED_MAPPED_FILES && changedMapped.size / Math.max(1, mappedFiles.size) > FULL_REBUILD_FRACTION ? \"full-rebuild\" : \"incremental\";\n return report;\n}\n","import path from \"node:path\";\nimport type { CommandClaim } from \"./types.js\";\n\nconst TOKEN = `(?:\"[^\"\\\\n]*\"|'[^'\\\\n]*'|[^\\\\s\\x60;&|]+)`;\nconst COMMAND = new RegExp(`\\\\b(npm|pnpm|yarn)((?:[ \\\\t]+${TOKEN})*?)[ \\\\t]+run[ \\\\t]+([A-Za-z0-9:_.-]+)`, \"g\");\nconst literal = (value: string) => {\n const unquoted = value.replace(/^([\"'])(.*)\\1$/, \"$2\");\n return /[$`*?\\[\\]{}~\\\\\\x00-\\x1f]/.test(unquoted) || path.posix.isAbsolute(unquoted) ? null : unquoted;\n};\n\nfunction splitCommands(line: string): string[] {\n const parts: string[] = [];\n let quote = \"\", start = 0;\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n if (char === \"\\\\\") { i++; continue; }\n if (quote) { if (char === quote) quote = \"\"; continue; }\n if (char === \"'\" || char === '\"') { quote = char; continue; }\n if (char === \";\" || line.slice(i, i + 2) === \"&&\") {\n parts.push(line.slice(start, i));\n if (char === \"&\") i++;\n start = i + 1;\n }\n }\n parts.push(line.slice(start));\n return parts;\n}\n\n/** Deliberately small shell subset: literal cd and npm-family run invocations. */\nexport function commandClaims(line: string, lineNo: number, cwd?: string | null, shell = false): { claims: CommandClaim[]; cwd: string | null | undefined } {\n const claims: CommandClaim[] = [];\n const segments = splitCommands(line);\n for (const segment of segments) {\n const text = segment.trim().replace(/^\\$\\s+/, \"\");\n if (text.startsWith(\"#\") || /^(?:echo|printf)\\b/.test(text)) continue;\n const cd = text.match(/^cd\\s+(.+)$/);\n if (cd) {\n const directory = literal(cd[1]);\n cwd = directory === null || cwd === null || /\\s/.test(directory) && !/^[\"']/.test(cd[1])\n ? null : path.posix.join(cwd ?? \".\", directory);\n continue;\n }\n for (const match of text.matchAll(COMMAND)) {\n const flags = match[2].trim();\n const selector = flags.match(/^(?:--prefix|--dir|-C)(?:\\s+|=)(.+)$/);\n let directory = cwd;\n let scopeUnknown: string | undefined;\n if ((shell && match.index !== 0) || match[3].startsWith(\"-\")) scopeUnknown = \"Unsupported shell wrapper or options before the script.\";\n if (selector) {\n const selected = literal(selector[1]);\n directory = selected === null || cwd === null ? null : path.posix.join(cwd ?? \".\", selected);\n } else if (flags) scopeUnknown = \"Unsupported package-manager options before run: \" + flags;\n const tail = text.slice(match.index! + match[0].length).split(/\\s--(?:\\s|$)/)[0];\n if (/(?:^|\\s)(?:--workspace(?:s)?|-w|--filter|-F|--prefix|--dir|-C|--if-present)(?:\\s|=|$)/.test(tail)) {\n scopeUnknown = \"Package selection or conditional options after the script need review.\";\n }\n if (/[|()]/.test(text) || /\\b(?:pushd|popd|if|for|while)\\b/.test(text) || directory === null) {\n scopeUnknown = \"The command's working directory or shell control flow could not be resolved.\";\n }\n claims.push({ scriptName: match[3], invocation: match[0], excerpt: match[0], line: lineNo,\n ...(directory !== undefined && directory !== null ? { directory } : {}), ...(scopeUnknown ? { scopeUnknown } : {}) });\n }\n // An unresolved directory change must not leave later commands apparently scoped.\n if (/\\b(?:cd|pushd|popd)\\b/.test(text)) cwd = null;\n }\n return { claims, cwd };\n}\n","import type { PathClaim } from \"./types.js\";\n\n/**\n * A fenced block is treated as a directory tree only when it clearly is one —\n * below this many branch-glyph lines it's more likely an ASCII sketch.\n */\nconst MIN_GLYPH_LINES = 3;\n\nconst GLYPHS = [\"├──\", \"└──\"] as const;\n\nfunction glyphIndex(line: string): number {\n for (const glyph of GLYPHS) {\n const idx = line.indexOf(glyph);\n if (idx !== -1) return idx;\n }\n return -1;\n}\n\n/** Tree furniture: blank, or only vertical bars and whitespace. */\nfunction isSpacerLine(line: string): boolean {\n return /^[\\s│|]*$/.test(line);\n}\n\n/**\n * Strip an inline comment/annotation from a tree entry. Entries commonly\n * carry `# comment` or column-aligned notes after two or more spaces.\n */\nfunction entryName(afterGlyph: string): string | null {\n let name = afterGlyph.replace(/^\\s+/, \"\");\n const hash = name.search(/\\s+#/);\n if (hash !== -1) name = name.slice(0, hash);\n const columns = name.search(/\\s{2,}/);\n if (columns !== -1) name = name.slice(0, columns);\n name = name.trim();\n // A name with remaining internal whitespace is not a path — treat the\n // line as malformed rather than guessing.\n if (!name || /\\s/.test(name)) return null;\n return name;\n}\n\n/**\n * Reconstruct full paths from an ASCII directory tree inside a fenced block.\n *\n * The failure mode must always be a missed claim, never an invented path: a\n * line that doesn't parse cleanly aborts reconstruction below it, and every\n * emitted path still passes the deleted-reference provability gate later.\n *\n * `blockLines` are the fence's content lines; `blockStartLine` is the 1-based\n * doc line number of the first content line.\n */\nexport function extractTreeClaims(\n blockLines: string[],\n blockStartLine: number\n): PathClaim[] {\n const glyphLines = blockLines.filter((l) => glyphIndex(l) !== -1).length;\n if (glyphLines < MIN_GLYPH_LINES) return [];\n\n const claims: PathClaim[] = [];\n // Directories on the path from the root to the current entry, keyed by the\n // column their branch glyph appeared at.\n const stack: Array<{ col: number; name: string }> = [];\n let rootPrefix = \"\";\n let started = false;\n\n for (let i = 0; i < blockLines.length; i++) {\n const line = blockLines[i];\n const col = glyphIndex(line);\n\n if (col === -1) {\n if (isSpacerLine(line)) continue;\n if (!started) {\n // A bare `src/` line above the first glyph names the tree's root.\n const candidate = line.trim();\n if (candidate.endsWith(\"/\") && !/\\s/.test(candidate)) {\n rootPrefix = candidate.replace(/\\/+$/, \"\");\n claims.push({\n path: rootPrefix,\n line: blockStartLine + i,\n excerpt: candidate,\n });\n }\n continue;\n }\n // Unparseable line after the tree began: stop here, keep what we have.\n return claims;\n }\n\n started = true;\n const name = entryName(line.slice(col + GLYPHS[0].length));\n if (name === null) return claims;\n\n while (stack.length > 0 && stack[stack.length - 1].col >= col) {\n stack.pop();\n }\n\n const isDir = name.endsWith(\"/\");\n const cleanName = name.replace(/\\/+$/, \"\");\n const segments = [\n ...(rootPrefix ? [rootPrefix] : []),\n ...stack.map((s) => s.name),\n cleanName,\n ];\n claims.push({\n path: segments.join(\"/\"),\n line: blockStartLine + i,\n excerpt: name,\n });\n\n if (isDir) stack.push({ col, name: cleanName });\n }\n\n return claims;\n}\n","import MarkdownIt from \"markdown-it\";\nimport { commandClaims } from \"./commands.js\";\nimport type {\n CommandClaim,\n CountClaim,\n DocClaims,\n PathClaim,\n} from \"./types.js\";\nimport { extractTreeClaims } from \"./tree.js\";\n\n/**\n * Single-segment names that count as path claims without containing a \"/\".\n * Anything else without a slash is prose (\"name your file `config.ts`\"), not\n * a claim about this repo.\n */\nconst ROOT_FILE_NAMES = new Set([\n \"package.json\",\n \"package-lock.json\",\n \"pnpm-workspace.yaml\",\n \"tsconfig.json\",\n \"tsup.config.ts\",\n \"vitest.config.ts\",\n \"Makefile\",\n \"Dockerfile\",\n \"docker-compose.yml\",\n \"Cargo.toml\",\n \"go.mod\",\n \"go.sum\",\n \"pyproject.toml\",\n \"requirements.txt\",\n \"Gemfile\",\n \"composer.json\",\n \"settings.gradle.kts\",\n \"settings.gradle\",\n \"build.gradle.kts\",\n \"build.gradle\",\n \"manifest.json\",\n \"server.json\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"LICENSE\",\n \"CLAUDE.md\",\n \"AGENTS.md\",\n \".gitignore\",\n \".env.example\",\n]);\n\nconst SHELL_FENCE_INFOS = new Set([\"\", \"bash\", \"sh\", \"shell\", \"console\", \"zsh\"]);\n\nconst markdown = new MarkdownIt(\"commonmark\", { html: false });\nconst COUNT_RE = /(\\d+)\\s+(modules?|packages?|workspaces?|crates?)\\b/gi;\n/** \"3 package managers\" is not a package count. */\nconst COUNT_DENYLIST_RE = /^\\s*(manager|registr|lock|json)/i;\n\nconst IGNORE_LINE = \"<!-- mason:ignore -->\";\nconst IGNORE_START = \"<!-- mason:ignore-start -->\";\nconst IGNORE_END = \"<!-- mason:ignore-end -->\";\n\n/**\n * Normalize a candidate token into a repo-relative path claim, or return\n * null when the token is not a claim about this repo (URL, glob,\n * placeholder, relative import example, bare word).\n */\nexport function normalizePathToken(token: string): string | null {\n let t = token.trim();\n if (!t) return null;\n if (/\\s/.test(t)) return null;\n if (t.includes(\"://\") || t.includes(\"\\\\\")) return null;\n if (/[*?[\\]{}<>$`]/.test(t)) return null;\n if (t.startsWith(\"/\") || t.startsWith(\"~\") || t.startsWith(\"./\") || t.startsWith(\"../\")) {\n return null;\n }\n // `src/mcp/tools.ts:189` claims the file, not the line.\n t = t.replace(/:\\d+(?:-\\d+)?$/, \"\");\n if (t.includes(\":\")) return null;\n const normalized = t.replace(/\\/+$/, \"\");\n if (!normalized) return null;\n // `server/src/test/kotlin/...` — a dots-only segment is an \"and so on\"\n // placeholder, not a claim.\n if (normalized.split(\"/\").some((seg) => /^\\.+$/.test(seg))) return null;\n if (normalized.includes(\"/\")) return normalized;\n return ROOT_FILE_NAMES.has(normalized) ? normalized : null;\n}\n\n/** A fence line that is exactly one path-shaped token is a file-list claim. */\nfunction exactTokenPath(line: string): string | null {\n const trimmed = line.trim();\n if (!trimmed || /\\s/.test(trimmed) || !trimmed.includes(\"/\")) return null;\n return normalizePathToken(trimmed);\n}\n\nfunction computeIgnoredLines(lines: string[]): boolean[] {\n const ignored = new Array<boolean>(lines.length).fill(false);\n let inRegion = false;\n let ignoreNext = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.includes(IGNORE_START)) {\n inRegion = true;\n ignored[i] = true;\n continue;\n }\n if (line.includes(IGNORE_END)) {\n inRegion = false;\n ignored[i] = true;\n continue;\n }\n if (inRegion) {\n ignored[i] = true;\n continue;\n }\n if (ignoreNext) {\n if (line.trim().length === 0) continue; // skip blanks to the next real line\n ignored[i] = true;\n ignoreNext = false;\n continue;\n }\n if (line.includes(IGNORE_LINE)) {\n ignored[i] = true;\n const rest = line.replace(IGNORE_LINE, \"\").trim();\n if (rest.length === 0) ignoreNext = true;\n }\n }\n return ignored;\n}\n\n/**\n * Extract every checkable claim from a context-file's markdown. Deterministic\n * and purely lexical — precision comes from the checks' provability gates,\n * not from clever parsing here.\n */\nexport function extractClaims(content: string): DocClaims {\n const lines = content.split(\"\\n\");\n const ignored = computeIgnoredLines(lines);\n\n const paths = new Map<string, PathClaim>();\n const counts: CountClaim[] = [];\n const commands = new Map<string, CommandClaim>();\n\n const addPath = (claim: PathClaim): void => {\n const key = [claim.relativeTo ?? \"scope\", claim.path].join(\":\");\n if (!paths.has(key)) paths.set(key, claim);\n };\n const addCommand = (claim: CommandClaim): void => {\n const key = JSON.stringify([claim.scriptName, claim.directory, claim.scopeUnknown]);\n if (!commands.has(key)) commands.set(key, claim);\n };\n\n // A real Markdown parser distinguishes reference links, images and escaped\n // destinations from code examples. Ignore markers preserve source line offsets.\n const parsed = markdown.parse(lines.map((line, i) => ignored[i] ? \"\" : line).join(\"\\n\"), {});\n for (const token of parsed) {\n if (token.type !== \"inline\" || !token.map) continue;\n let line = token.map[0] + 1;\n for (const child of token.children ?? []) {\n const target = child.type === \"link_open\" ? child.attrGet(\"href\") : child.type === \"image\" ? child.attrGet(\"src\") : null;\n if (target && !/^(?:[a-z][a-z0-9+.-]*:|[\\/#~])/i.test(target)) {\n let pathname: string | null = null;\n try { pathname = decodeURIComponent(target.split(/[?#]/)[0]); } catch { /* Unsupported URL encoding. */ }\n if (pathname && !/[$*?{}<>\\\\\\x00-\\x1f]/.test(pathname)) {\n addPath({ path: pathname, line, excerpt: target, relativeTo: \"document\" });\n }\n }\n if (child.type === \"softbreak\" || child.type === \"hardbreak\") line++;\n else line += child.content.split(\"\\n\").length - 1;\n }\n }\n\n let shellCwd: string | null | undefined;\n let inFence = false;\n let fenceInfo = \"\";\n let fenceMarker = \"\";\n let blockLines: string[] = [];\n let blockStartLine = 0;\n\n const processBlock = (): void => {\n for (const claim of extractTreeClaims(blockLines, blockStartLine)) {\n addPath(claim);\n }\n for (let i = 0; i < blockLines.length; i++) {\n const exact = exactTokenPath(blockLines[i]);\n if (exact) {\n addPath({\n path: exact,\n line: blockStartLine + i,\n excerpt: blockLines[i].trim(),\n });\n }\n }\n };\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const lineNo = i + 1;\n const fenceMatch = line.match(/^\\s*(```+|~~~+)(.*)$/);\n\n if (fenceMatch) {\n if (!inFence) {\n inFence = true;\n fenceMarker = fenceMatch[1][0];\n fenceInfo = fenceMatch[2].trim().toLowerCase();\n blockLines = [];\n shellCwd = undefined;\n blockStartLine = lineNo + 1;\n } else if (fenceMatch[1][0] === fenceMarker) {\n inFence = false;\n processBlock();\n }\n continue;\n }\n\n if (inFence) {\n // Ignored lines become spacers so the rest of a tree still parses.\n blockLines.push(ignored[i] ? \"\" : line);\n if (!ignored[i] && SHELL_FENCE_INFOS.has(fenceInfo)) {\n const scanned = commandClaims(line, lineNo, shellCwd, true);\n shellCwd = scanned.cwd;\n for (const claim of scanned.claims) addCommand(claim);\n }\n continue;\n }\n\n if (ignored[i]) continue;\n\n for (const m of line.matchAll(/`([^`]+)`/g)) {\n const normalized = normalizePathToken(m[1]);\n if (normalized) {\n addPath({ path: normalized, line: lineNo, excerpt: m[1] });\n }\n }\n for (const m of line.matchAll(/\"([A-Za-z][\\w.@-]*(?:\\/[\\w.@-]+)+\\/?)\"/g)) {\n const normalized = normalizePathToken(m[1]);\n if (normalized) {\n addPath({ path: normalized, line: lineNo, excerpt: m[1] });\n }\n }\n for (const m of line.matchAll(COUNT_RE)) {\n const rest = line.slice((m.index ?? 0) + m[0].length);\n if (COUNT_DENYLIST_RE.test(rest)) continue;\n counts.push({\n count: Number.parseInt(m[1], 10),\n unit: m[2].toLowerCase(),\n line: lineNo,\n excerpt: m[0],\n });\n }\n for (const match of line.matchAll(/`([^`]+)`/g)) {\n for (const claim of commandClaims(match[1], lineNo, undefined, true).claims) addCommand(claim);\n }\n for (const claim of commandClaims(line.replace(/`[^`]+`/g, \"\"), lineNo).claims) addCommand(claim);\n }\n\n // An unclosed fence still gets its block processed — trees at the end of a\n // truncated doc are claims too.\n if (inFence) processBlock();\n\n return {\n paths: [...paths.values()],\n counts,\n commands: [...commands.values()],\n };\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { CommitRef } from \"./types.js\";\n\nconst exec = promisify(execFile);\n\nconst COMMIT_FORMAT = \"%H%x09%cI%x09%s\";\n\nfunction parseCommitLine(line: string): CommitRef | null {\n const parts = line.split(\"\\t\");\n if (parts.length < 3 || !parts[0]) return null;\n return { hash: parts[0], date: parts[1], subject: parts.slice(2).join(\"\\t\") };\n}\n\n/** Most recent commit touching a path, or null if the path was never tracked. */\nexport async function lastCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\"log\", \"-1\", `--format=${COMMIT_FORMAT}`, \"--\", `:(literal)${relPath}`],\n { cwd: resolvedRoot }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\n/** The commit that deleted a path, or null if none did. */\nexport async function deletingCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\n \"log\",\n \"-1\",\n \"--diff-filter=D\",\n `--format=${COMMIT_FORMAT}`,\n \"--\",\n `:(literal)${relPath}`,\n ],\n { cwd: resolvedRoot }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\n/** Oldest commit touching a path (used to date a directory's appearance). */\nexport async function firstCommitOf(\n resolvedRoot: string,\n relPath: string\n): Promise<CommitRef | null> {\n try {\n const { stdout } = await exec(\n \"git\",\n [\"log\", \"--reverse\", `--format=${COMMIT_FORMAT}`, \"--\", `:(literal)${relPath}`],\n { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }\n );\n const line = stdout.trim().split(\"\\n\")[0];\n return line ? parseCommitLine(line) : null;\n } catch {\n return null;\n }\n}\n\nexport interface RangeCommits {\n commits: Array<CommitRef & { files: string[] }>;\n total: number;\n}\n\n/**\n * Commits in fromHash..HEAD touching any of the pathspecs, newest first, with\n * the touched files per commit. Rev-range, not --since: immune to rebase date\n * skew and CI checkout mtimes. Returns null when the range is uncomputable\n * (unreachable base commit, shallow clone, no git).\n */\nexport async function commitsTouchingSince(\n resolvedRoot: string,\n fromHash: string,\n pathspecs: string[]\n): Promise<RangeCommits | null> {\n if (!fromHash || fromHash === \"unknown\") return null;\n try {\n const { stdout } = await exec(\n \"git\",\n [\n \"log\",\n `${fromHash}..HEAD`,\n `--format=%x01${COMMIT_FORMAT}`,\n \"--name-only\",\n \"--\",\n ...pathspecs,\n ],\n { cwd: resolvedRoot, maxBuffer: 10 * 1024 * 1024 }\n );\n\n const commits: Array<CommitRef & { files: string[] }> = [];\n // \\x01 marks each commit header so name-only file lists can't be\n // mistaken for headers.\n for (const block of stdout.split(\"\\x01\")) {\n if (!block.trim()) continue;\n const lines = block.split(\"\\n\").filter((l) => l.trim().length > 0);\n const ref = parseCommitLine(lines[0]);\n if (!ref) continue;\n commits.push({ ...ref, files: lines.slice(1).map((l) => l.trim()) });\n }\n return { commits, total: commits.length };\n } catch {\n return null;\n }\n}\n","import fs from \"node:fs/promises\";\nimport * as nativeFs from \"node:fs\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { Readable } from \"node:stream\";\nimport fg from \"fast-glob\";\nimport { readBoundedFile, SOURCE_EXTENSIONS } from \"../utils/files.js\";\nimport { storePath } from \"../utils/storage.js\";\n\nconst execute = promisify(execFile);\nconst MAX_INPUTS = 100_000;\n\n/** Check the paths a particular audit actually reads, including their parents. */\nexport async function auditInputPath(root: string, file: string): Promise<string> {\n if (file === \".\") return fs.realpath(root);\n try { return await storePath(root, file); }\n catch (error) {\n if (error instanceof Error && error.message.startsWith(\"Symlink\")) {\n throw new Error(`Audit input contains a symbolic link: ${file}. Its evidence could not be verified.`, { cause: error });\n }\n throw error;\n }\n}\n\nexport async function readAuditInput(root: string, file: string): Promise<string | null> {\n try {\n const value = await readBoundedFile(await auditInputPath(root, file), 10 * 1024 * 1024);\n if (value === null) throw new Error(`Unreadable or oversized audit input: ${file}`);\n return value;\n } catch (error) {\n if ([\"ENOENT\", \"ENOTDIR\"].includes((error as NodeJS.ErrnoException).code ?? \"\")) return null;\n throw error;\n }\n}\n\n/** Bound relevant results and directory traversal, without counting unrelated files. */\nexport async function auditGlob(root: string, patterns: string | string[], options: {\n ignore?: string[]; onlyDirectories?: boolean; followSymbolicLinks?: boolean; label: string; select?: (file: string) => boolean;\n}): Promise<string[]> {\n if (Array.isArray(patterns) && !patterns.length) return [];\n const directories = new Set<string>();\n // fast-glob may stat a link, but must never enumerate a linked directory.\n // Validate each traversal and each selected result instead of scanning the\n // entire repository just to reject unrelated symlinks.\n const readdir = ((directory: string, opts: unknown, callback: (error: unknown, entries?: unknown) => void) => {\n const relative = path.relative(root, directory).split(path.sep).join(\"/\") || \".\";\n directories.add(relative);\n if (directories.size > MAX_INPUTS) {\n callback(new Error(`${options.label} exceeds ${MAX_INPUTS.toLocaleString(\"en-US\")} directories while inspecting ${relative}. Narrow this check's inputs.`));\n return;\n }\n auditInputPath(root, relative).then(() => {\n nativeFs.readdir(directory, opts as { withFileTypes: true }, callback as (error: NodeJS.ErrnoException | null, entries: nativeFs.Dirent[]) => void);\n }, callback);\n }) as typeof nativeFs.readdir;\n // Literal workspace patterns use lstat instead of readdir. Validate them\n // before fast-glob can silently discard a dangling link as a missing file.\n const lstat = ((file: string, callback: (error: unknown, stat?: nativeFs.Stats) => void) => {\n const relative = path.relative(root, file).split(path.sep).join(\"/\") || \".\";\n auditInputPath(root, relative).then(() => nativeFs.lstat(file, callback), callback);\n }) as typeof nativeFs.lstat;\n const stream = fg.stream(patterns, { cwd: root, ignore: options.ignore,\n onlyFiles: false, onlyDirectories: options.onlyDirectories, objectMode: true,\n followSymbolicLinks: options.followSymbolicLinks ?? true, fs: { readdir, lstat }, concurrency: 16 }) as Readable;\n const matches: string[] = [];\n try {\n for await (const value of stream) {\n const entry = value as fg.Entry;\n const file = entry.path;\n if (options.select && !options.select(file)) continue;\n await auditInputPath(root, file);\n if (!options.onlyDirectories && !entry.dirent.isFile()) continue;\n matches.push(file);\n if (matches.length > MAX_INPUTS) {\n const largest = [...matches.reduce((counts, item) => {\n const dir = item.split(\"/\")[0]; counts.set(dir, (counts.get(dir) ?? 0) + 1); return counts;\n }, new Map<string, number>())].sort((a, b) => b[1] - a[1]).slice(0, 3);\n throw new Error(`${options.label} exceeds ${MAX_INPUTS.toLocaleString(\"en-US\")} relevant paths. Largest directories: ${largest.map(([dir, count]) => `${dir} (${count})`).join(\", \")}. Narrow this check's inputs.`);\n }\n }\n } finally { stream.destroy(); }\n return matches.sort();\n}\n\n/** Git prunes ignored trees before discovery; tracked source remains visible. */\nexport async function gitSourcePaths(root: string): Promise<string[]> {\n const { stdout } = await execute(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\", \"--\",\n ...SOURCE_EXTENSIONS.map(extension => `:(glob)**/*.${extension}`)],\n { cwd: root, maxBuffer: 32 * 1024 * 1024, timeout: 10_000 });\n return [...new Set(stdout.split(\"\\0\").filter(Boolean))].sort();\n}\n\n/** Small directory batches, never a repository-wide inventory of ignored files. */\nexport async function gitIgnoredPaths(root: string, files: string[]): Promise<Set<string>> {\n if (!files.length) return new Set();\n const operation = execute(\"git\", [\"check-ignore\", \"-z\", \"--stdin\"],\n { cwd: root, maxBuffer: 4 * 1024 * 1024, timeout: 10_000 });\n operation.child.stdin!.on(\"error\", () => { /* The child exit reports a failed query. */ });\n operation.child.stdin!.end(files.join(\"\\0\") + \"\\0\");\n try { return new Set((await operation).stdout.split(\"\\0\").filter(Boolean)); }\n catch (error) {\n if ((error as { code?: number }).code === 1) return new Set(); // No ignored paths.\n throw error;\n }\n}\n","import { profilePhase } from \"../utils/profile.js\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { extractClaims } from \"./claims.js\";\nimport { lastCommitOf } from \"./git.js\";\nimport fg from \"fast-glob\";\nimport { auditGlob, auditInputPath, readAuditInput } from \"./inputs.js\";\nimport { loadProjectConfig } from \"../utils/files.js\";\nimport type { CommitRef, DocClaims } from \"./types.js\";\n\nconst exec = promisify(execFile);\n\n/**\n * Instruction entry points written by setup. Audit discovery is broader and\n * preserves actual filename casing; setup/teardown must not edit every README.\n */\nexport const DOC_CANDIDATES = [\n \"AGENTS.md\",\n \"CLAUDE.md\",\n \".claude/CLAUDE.md\",\n] as const;\n\nexport interface AuditDoc {\n /** Repo-relative posix path. */\n path: string;\n content: string;\n /** Directory whose instructions this document describes, not a proven shell cwd. */\n scope: string;\n kind: \"instructions\" | \"readme\";\n lineCount: number;\n /** Null when the doc is untracked. */\n lastCommit: CommitRef | null;\n /** Uncommitted edits present. */\n dirty: boolean;\n claims: DocClaims;\n}\n\nasync function dirtyDocs(resolvedRoot: string, files: string[]): Promise<Set<string>> {\n if (!files.length) return new Set();\n try {\n const dirty = new Set<string>();\n for (let offset = 0; offset < files.length; offset += 256) {\n const { stdout } = await exec(\n \"git\",\n [\"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\", \"--\", ...files.slice(offset, offset + 256).map(file => `:(literal)${file}`)],\n { cwd: resolvedRoot, maxBuffer: 16 * 1024 * 1024, timeout: 10000 }\n );\n const entries = stdout.split(\"\\0\");\n for (let i = 0; i < entries.length; i++) {\n if (!entries[i]) continue;\n const status = entries[i].slice(0, 2);\n dirty.add(entries[i].slice(3));\n // Porcelain -z emits destination first, then the original rename/copy path.\n if (/[RC]/.test(status) && entries[i + 1]) dirty.add(entries[++i]);\n }\n }\n return dirty;\n } catch {\n return new Set(files);\n }\n}\n\n/** Readme/instruction discovery shares the exact inventory used by automation. */\nexport async function discoverDocPaths(root: string): Promise<string[]> {\n let candidates: string[] = [];\n try {\n const { stdout } = await exec(\"git\", [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\", \"--\",\n \":(icase,glob)**/readme.md\", \":(icase,glob)**/agents.md\", \":(icase,glob)**/claude.md\"],\n { cwd: root, maxBuffer: 16 * 1024 * 1024, timeout: 10000 });\n candidates = stdout.split(\"\\0\").filter(Boolean);\n } catch (error) {\n // Outside Git we still discover documents so the audit can report Git unavailable.\n try { await exec(\"git\", [\"rev-parse\", \"--git-dir\"], { cwd: root }); }\n catch { return localDocPaths(root); }\n throw error;\n }\n candidates.push(...await localDocPaths(root));\n const config = await loadProjectConfig(root);\n const excluded = [\"**/node_modules/**\", \"**/vendor/**\", \"**/dist/**\", \"**/build/**\", \"**/target/**\",\n \"**/.git/**\", \"**/.venv/**\", \"**/venv/**\", \".mason/**\", ...(config.ignore ?? [])];\n // Static patterns preserve literal metacharacters and reject selected symlinks.\n const paths: string[] = [];\n const unique = [...new Set(candidates)].sort();\n for (let offset = 0; offset < unique.length; offset += 256) {\n paths.push(...await auditGlob(root, unique.slice(offset, offset + 256).map(p => fg.escapePath(p)), {\n ignore: excluded, followSymbolicLinks: false, label: \"Documentation discovery\",\n }));\n if (paths.length > 10000) throw new Error(\"Documentation discovery exceeds 10,000 relevant files; narrow .mason/config.json ignore patterns.\");\n }\n const priority = (file: string) => {\n const index = (DOC_CANDIDATES as readonly string[]).findIndex(p => p.toLowerCase() === file.toLowerCase());\n return index < 0 ? DOC_CANDIDATES.length : index;\n };\n return paths.sort((a, b) => priority(a) - priority(b) || a.localeCompare(b));\n}\n\n/** Explicit local entry points may be ignored; preserve their real spelling. */\nasync function localDocPaths(root: string): Promise<string[]> {\n const paths: string[] = [];\n for (const dir of [\".\", \".claude\"]) {\n let entries;\n try { entries = await fs.readdir(await auditInputPath(root, dir), { withFileTypes: true }); }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") continue; throw error; }\n for (const entry of entries) if (/^(?:agents|claude|readme)\\.md$/i.test(entry.name)) {\n paths.push(path.posix.join(dir, entry.name));\n }\n }\n return paths;\n}\n\nexport function documentScope(file: string): string {\n const parent = path.posix.dirname(file);\n return path.posix.basename(parent).toLowerCase() === \".claude\" ? path.posix.dirname(parent) : parent;\n}\n\nexport async function discoverDocs(resolvedRoot: string): Promise<AuditDoc[]> {\n return profilePhase(\"audit.documents\", () => readDocs(resolvedRoot));\n}\n\nasync function readDocs(resolvedRoot: string): Promise<AuditDoc[]> {\n const docs: AuditDoc[] = [];\n const files = await discoverDocPaths(resolvedRoot);\n const dirty = await dirtyDocs(resolvedRoot, files);\n // Bound concurrent Git processes even when discovery reaches thousands of docs.\n for (let offset = 0; offset < files.length; offset += 4) {\n docs.push(...await Promise.all(files.slice(offset, offset + 4).map(async (candidate): Promise<AuditDoc> => {\n const [content, lastCommit] = await Promise.all([readAuditInput(resolvedRoot, candidate),\n profilePhase(\"audit.document-history\", () => lastCommitOf(resolvedRoot, candidate))]);\n if (content === null) throw new Error(\"Document disappeared during discovery: \" + candidate);\n return { path: candidate, content, scope: documentScope(candidate),\n kind: /^readme\\.md$/i.test(path.posix.basename(candidate)) ? \"readme\" : \"instructions\",\n lineCount: content.split(\"\\n\").length, lastCommit, dirty: dirty.has(candidate), claims: extractClaims(content) };\n })));\n }\n return docs;\n}\n","import type { decisionProvenance } from \"../decisions/provenance.js\";\n\nexport type IssueType =\n | \"deleted-reference\"\n | \"new-module\"\n | \"stale-count\"\n | \"dead-command\";\n\nexport type AdvisoryType = \"deps-changed\" | \"decision-anchor-drift\" | IssueType;\n\nexport type CheckName = IssueType | AdvisoryType;\n\nexport const ALL_CHECKS: CheckName[] = [\n \"deleted-reference\",\n \"new-module\",\n \"stale-count\",\n \"dead-command\",\n \"deps-changed\",\n \"decision-anchor-drift\",\n];\n\n/**\n * \"certain\" — the claim is provably false (a tracked path is gone, a computed\n * count differs, a script is absent from a resolved manifest). \"likely\" is\n * retained for older reports. Inferred scope and speculative omissions are\n * advisory; even a certain mismatch needs semantic review before repair.\n */\nexport type Confidence = \"certain\" | \"likely\";\n\nexport interface CommitRef {\n hash: string;\n date: string;\n subject: string;\n}\n\nexport interface DocAnchor {\n /** Repo-relative doc path, e.g. \"CLAUDE.md\" or \".claude/CLAUDE.md\". */\n doc: string;\n /** 1-based line of the claim; null for doc-level issues (new-module). */\n line: number | null;\n /** The claim exactly as written, e.g. \"src/utils/logger.ts\". */\n excerpt: string | null;\n}\n\nexport interface ClaimScope {\n basis: \"repository\" | \"document\" | \"document-link\" | \"explicit\";\n directory: string;\n /** Exact repository-relative paths/manifests considered by the check. */\n candidates: string[];\n}\n\nexport type Evidence =\n | {\n kind: \"missing-path\";\n claimed: string;\n renamedTo: string | null;\n deletedInCommit: CommitRef | null;\n everTracked: boolean;\n parentDirExists: boolean;\n resolvedPath?: string;\n scope?: ClaimScope;\n }\n | {\n kind: \"unmentioned-dir\";\n dir: string;\n sourceFileCount: number;\n firstCommit: CommitRef | null;\n checkedDocs: string[];\n }\n | {\n kind: \"count-mismatch\";\n claimed: number;\n actual: number;\n unit: string;\n /** Where the actual count came from, e.g. \"package.json workspaces\". */\n countedFrom: string;\n members: string[];\n }\n | {\n kind: \"missing-script\";\n scriptName: string;\n invocation: string;\n manifestsChecked: string[];\n availableScripts: string[];\n scope?: ClaimScope;\n }\n | {\n kind: \"doc-behind-manifests\";\n docLastCommit: CommitRef;\n manifestCommits: Array<CommitRef & { files: string[] }>;\n totalCommits: number;\n }\n | {\n kind: \"decision-anchor\";\n provenance?: ReturnType<typeof decisionProvenance>;\n decisionId: string;\n title: string;\n changedFiles: string[];\n refreshedHash: string;\n };\n\nexport interface AuditIssue {\n type: IssueType;\n message: string;\n anchor: DocAnchor;\n confidence: Confidence;\n evidence: Evidence;\n}\n\n/**\n * Advisories require judgment and never drive the ordinary audit exit code.\n * Historical advisories require a separate review. Explicitly recheckable\n * candidates can cease to be detected without asserting semantic approval.\n */\nexport interface AuditAdvisory {\n type: AdvisoryType;\n message: string;\n anchor: DocAnchor;\n evidence: Evidence;\n resolution?: \"recheck\";\n}\n\nexport interface AuditDocInfo {\n path: string;\n scope?: string;\n kind?: \"instructions\" | \"readme\";\n lastCommit: CommitRef | null;\n /** Uncommitted edits present — deps-changed is suppressed for dirty docs. */\n dirty: boolean;\n lineCount: number;\n}\n\nexport interface AuditReport {\n /** Additive-only schema — this output is a CI contract. */\n version: 1;\n root: string;\n gitAvailable: boolean;\n /** Commit and exact check scope used by this run. */\n headHash?: string;\n checksRun?: CheckName[];\n docs: AuditDocInfo[];\n /** Whether .mason/decisions/ existed and was checked. */\n decisionsChecked: boolean;\n /** Drive exit code 1. */\n issues: AuditIssue[];\n /** Never drive the exit code. */\n advisories: AuditAdvisory[];\n /** Original committed evidence retained while local doc edits suppress reporting. */\n suppressedAdvisories?: AuditAdvisory[];\n skippedChecks: Array<{ check: string; reason: string; doc?: string }>;\n clean: boolean;\n /** Additive assessment status; original advisory evidence remains intact. */\n advisoryReviews?: import(\"./advisory-review.js\").AdvisoryReviewSummary[];\n}\n\nexport interface PathClaim {\n path: string;\n line: number;\n excerpt: string;\n /** Markdown links resolve against the physical document directory. */\n relativeTo?: \"document\";\n}\n\nexport interface CountClaim {\n count: number;\n unit: string;\n line: number;\n excerpt: string;\n}\n\nexport interface CommandClaim {\n scriptName: string;\n invocation: string;\n line: number;\n excerpt: string;\n /** A literal cd/directory flag, relative to the document's assumed cwd. */\n directory?: string;\n scopeUnknown?: string;\n}\n\nexport interface DocClaims {\n paths: PathClaim[];\n counts: CountClaim[];\n commands: CommandClaim[];\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { auditInputPath } from \"./inputs.js\";\nimport { documentScope } from \"./docs.js\";\nimport type { ClaimScope, PathClaim } from \"./types.js\";\n\n/** Lexical containment, before inspecting any path from documentation. */\nexport function scopedPath(directory: string, value: string): string | null {\n if (path.posix.isAbsolute(value) || value.includes(\"\\\\\") || /[\\x00-\\x1f]/.test(value)) return null;\n const resolved = path.posix.normalize(path.posix.join(directory, value));\n return resolved === \"..\" || resolved.startsWith(\"../\") ? null : resolved;\n}\n\nexport function pathClaimScope(doc: string, claim: PathClaim): ClaimScope | null {\n const directory = claim.relativeTo === \"document\" ? path.posix.dirname(doc) : documentScope(doc);\n const local = scopedPath(directory, claim.path);\n if (!local) return null;\n const candidates = claim.relativeTo === \"document\" || directory === \".\" ? [local]\n : [...new Set([local, scopedPath(\".\", claim.path)].filter((p): p is string => p !== null))];\n return { basis: claim.relativeTo === \"document\" ? \"document-link\" : directory === \".\" ? \"repository\" : \"document\",\n directory, candidates };\n}\n\n/** Missing is distinct from unreadable/unsafe; cache and checks use the same observation. */\nexport async function pathExists(root: string, file: string): Promise<boolean> {\n try { await fs.access(await auditInputPath(root, file)); return true; }\n catch (error) {\n // A child of a regular file cannot exist either. Keep symlink and access\n // failures distinct: neither establishes that a reference is missing.\n if ([\"ENOENT\", \"ENOTDIR\"].includes((error as NodeJS.ErrnoException).code ?? \"\")) return false;\n throw error;\n }\n}\n\nexport function gitMetadataPath(file: string): boolean {\n return file.split(\"/\").includes(\".git\");\n}\n\nexport function optionalMasonPath(file: string): boolean {\n return file.split(\"/\").includes(\".mason\");\n}\n","import path from \"node:path\";\nimport { deletingCommitOf, lastCommitOf } from \"../git.js\";\nimport { gitMetadataPath, optionalMasonPath, pathClaimScope, pathExists } from \"../scope.js\";\nimport type { Evidence } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/** Prove removed references only when their scope is resolved. */\nexport async function checkDeletedReferences(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n for (const doc of ctx.docs) {\n const changes = ctx.changesSinceDoc.get(doc.path);\n const renames = new Map((changes ?? []).filter(c => c.status === \"renamed\" && c.previousPath)\n .map(c => [c.previousPath!, c.path]));\n for (const claim of doc.claims.paths) {\n const scope = pathClaimScope(doc.path, claim);\n if (!scope) {\n result.skipped.push({ check: \"deleted-reference\", doc: doc.path,\n reason: `Reference ${claim.excerpt} is outside the repository or has an unsupported path.` });\n continue;\n }\n if (scope.candidates.some(optionalMasonPath)) continue;\n if (scope.candidates.some(gitMetadataPath)) {\n result.skipped.push({ check: \"deleted-reference\", doc: doc.path,\n reason: `Reference ${claim.path} names Git metadata, whose layout varies between checkouts; it was not verified as a repository file.` });\n continue;\n }\n if ((await Promise.all(scope.candidates.map(file => pathExists(ctx.root, file)))).some(Boolean)) continue;\n\n const candidates = await Promise.all(scope.candidates.map(async file => ({ file,\n tracked: await lastCommitOf(ctx.root, file), parent: await pathExists(ctx.root, path.posix.dirname(file)) })));\n const candidate = candidates.find(c => c.tracked || renames.has(c.file)) ?? candidates.find(c => c.parent);\n // No history/parent for a bare path is usually an illustrative example.\n if (!candidate && claim.relativeTo !== \"document\") continue;\n const resolvedPath = candidate?.file ?? scope.candidates[0];\n const renamedTo = renames.get(resolvedPath) ?? null;\n const deletedInCommit = candidate?.tracked && !renamedTo ? await deletingCommitOf(ctx.root, resolvedPath) : null;\n const evidence: Evidence = { kind: \"missing-path\", claimed: claim.path, resolvedPath, scope,\n renamedTo, deletedInCommit, everTracked: !!candidate?.tracked || !!renamedTo, parentDirExists: candidate?.parent ?? false };\n const anchor = { doc: doc.path, line: claim.line, excerpt: claim.excerpt };\n const message = renamedTo ? `\\`${resolvedPath}\\` was renamed to \\`${renamedTo}\\``\n : `\\`${resolvedPath}\\` does not exist` + (deletedInCommit\n ? ` – deleted in ${deletedInCommit.hash.slice(0, 7)} \"${deletedInCommit.subject}\" (${deletedInCommit.date.slice(0, 10)})` : \"\");\n if (scope.basis !== \"document\" && (renamedTo || candidate?.tracked)) {\n result.issues.push({ type: \"deleted-reference\", message, anchor, confidence: \"certain\", evidence });\n } else {\n result.advisories.push({ resolution: \"recheck\", type: \"deleted-reference\", message: message + (scope.basis === \"document\"\n ? \"; the bare path's document/repository scope needs review.\"\n : \"; no tracked history establishes it as a required file. Review for a typo, generated output, or example.\"), anchor, evidence });\n }\n }\n }\n return result;\n}\n","import fg from \"fast-glob\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { loadProjectConfig, SOURCE_IGNORE } from \"../../utils/files.js\";\nimport { auditGlob, auditInputPath, gitIgnoredPaths, gitSourcePaths } from \"../inputs.js\";\nimport { firstCommitOf } from \"../git.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/** Directories that are never \"modules\" worth documenting. */\nconst DIR_DENYLIST = new Set([\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \"target\",\n \"vendor\",\n \"__pycache__\",\n \"venv\",\n \".venv\",\n \".git\",\n \".gradle\",\n \".mason\",\n \".claude\",\n \".github\",\n \".vscode\",\n \".idea\",\n]);\n\n/** Second-level dirs need a bit more substance before they count. */\nconst SECOND_LEVEL_MIN_SOURCE_FILES = 2;\n/**\n * Descend into a top-level dir only when the docs evidently enumerate its\n * children — at least this many of its subdirs already mentioned.\n */\nconst ENUMERATION_THRESHOLD = 2;\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Word-boundary mention check across the union of all docs — `app` must not\n * match \"application\", and a dir mentioned only in AGENTS.md must not be\n * flagged against CLAUDE.md.\n */\nfunction isMentioned(combinedDocs: string, name: string): boolean {\n const re = new RegExp(\n `(^|[^A-Za-z0-9_-])${escapeRegExp(name)}(/|[^A-Za-z0-9_-]|$)`,\n \"im\"\n );\n return re.test(combinedDocs);\n}\n\nexport async function checkNewModules(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n if (ctx.docs.length === 0) return result;\n\n const combinedDocs = moduleDocumentation(ctx.docs);\n const primaryDoc = ctx.docs[0].path;\n const checkedDocs = ctx.docs.map((d) => d.path);\n\n const flag = async (dir: string, sourceFileCount: number): Promise<void> => {\n result.advisories.push({\n resolution: \"recheck\",\n type: \"new-module\",\n message: `directory \\`${dir}/\\` contains ${sourceFileCount} source file${sourceFileCount === 1 ? \"\" : \"s\"} but is not mentioned in the discovered documentation; review whether it needs documenting`,\n anchor: { doc: primaryDoc, line: null, excerpt: dir },\n evidence: {\n kind: \"unmentioned-dir\",\n dir,\n sourceFileCount,\n firstCommit: await firstCommitOf(ctx.root, dir),\n checkedDocs,\n },\n });\n };\n\n for (const candidate of await moduleCandidates(ctx.root, combinedDocs)) {\n await flag(candidate.dir, candidate.sourceFileCount);\n }\n\n return result;\n}\n\n/** Nested documentation establishes a directory is documented without requiring\n * every package README to repeat its full repository path. */\nexport function moduleDocumentation(docs: Array<{ path: string; content: string }>): string {\n return docs.map(doc => doc.content + \"\\n\" + (path.posix.dirname(doc.path) === \".\" ? \"\" : path.posix.dirname(doc.path) + \"/\")).join(\"\\n\");\n}\n\n/** Shared dependency witness: cache exactly the module candidates the audit observes. */\nexport async function moduleCandidates(root: string, combinedDocs: string) {\n const [config, sourcePaths] = await Promise.all([loadProjectConfig(root), gitSourcePaths(root)]);\n const ignore = [...SOURCE_IGNORE, ...(config.ignore ?? [])];\n const sources = sourcePaths.filter(file => !file.split(\"/\").some(part => part.startsWith(\".\")));\n const listSubdirs = async (dir: string): Promise<string[]> => {\n const entries = await fs.readdir(await auditInputPath(root, dir), { withFileTypes: true });\n // A directory alias is not another source module. Only inspect a link\n // when Git's source inventory actually requires paths beneath it (for\n // example, a tracked source directory replaced by a local symlink).\n const dirs = entries.filter(entry => (entry.isDirectory() || entry.isSymbolicLink()\n && sources.some(file => file.startsWith(path.posix.join(dir, entry.name) + \"/\")))\n && !entry.name.startsWith(\".\") && !DIR_DENYLIST.has(entry.name))\n .map(entry => path.posix.join(dir, entry.name));\n const ignored = await gitIgnoredPaths(root, dirs);\n // An ignore rule does not remove already tracked source from the audit.\n const visible = new Set(dirs.filter(dir => !ignored.has(dir) || sources.some(file => file.startsWith(dir + \"/\"))));\n return (await auditGlob(root, dir === \".\" ? \"*\" : `${fg.escapePath(dir)}/*`, {\n ignore, onlyDirectories: true, label: \"Module directory discovery\", select: file => visible.has(file),\n })).map(file => path.posix.basename(file));\n };\n const countSourceFiles = async (dir: string): Promise<number> => {\n const files = sources.filter(file => file.startsWith(dir + \"/\"));\n let count = 0;\n // Literal path batches avoid compiling one enormous glob pattern set in a\n // genuinely large source module. Apply exclusions before counting results.\n for (let offset = 0; offset < files.length; offset += 256) {\n count += (await auditGlob(root, files.slice(offset, offset + 256).map(file => fg.escapePath(file)), {\n ignore, followSymbolicLinks: false, label: `Source discovery in ${dir}`,\n })).length;\n if (count > 100000) throw new Error(`Source discovery in ${dir} exceeds 100,000 relevant files. Exclude generated source with .mason/config.json ignore patterns or narrow this audit's checks.`);\n }\n return count;\n };\n const candidates: Array<{ dir: string; sourceFileCount: number }> = [];\n for (const topDir of await listSubdirs(\".\")) {\n const topMentioned = isMentioned(combinedDocs, topDir);\n\n if (!topMentioned) {\n const count = await countSourceFiles(topDir);\n if (count >= 1) candidates.push({ dir: topDir, sourceFileCount: count });\n continue;\n }\n\n // The docs know this dir. If they enumerate its children (several\n // subdirs already mentioned), an unmentioned sibling is drift — this is\n // how a freshly added module under src/ gets caught.\n const subdirs = await listSubdirs(topDir);\n const mentioned = subdirs.filter((s) => isMentioned(combinedDocs, s));\n if (mentioned.length < ENUMERATION_THRESHOLD) continue;\n\n for (const sub of subdirs) {\n if (isMentioned(combinedDocs, sub)) continue;\n const count = await countSourceFiles(`${topDir}/${sub}`);\n if (count >= SECOND_LEVEL_MIN_SOURCE_FILES) {\n candidates.push({ dir: `${topDir}/${sub}`, sourceFileCount: count });\n }\n }\n }\n\n return candidates;\n}\n","import path from \"node:path\";\nimport { documentScope } from \"../docs.js\";\nimport { auditGlob, readAuditInput } from \"../inputs.js\";\nimport type { CountClaim } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst MEMBERS_CAP = 50;\n\ninterface CountSource {\n actual: number;\n countedFrom: string;\n members: string[];\n}\n\nasync function countGradleModules(root: string): Promise<CountSource | null> {\n for (const name of [\"settings.gradle.kts\", \"settings.gradle\"]) {\n const content = await readAuditInput(root, name);\n if (content === null) continue;\n // include(\":a\", \":b\") — count quoted project strings, not include() calls.\n const members: string[] = [];\n for (const call of content.matchAll(/include\\s*\\(([^)]*)\\)/g)) {\n for (const proj of call[1].matchAll(/[\"']([^\"']+)[\"']/g)) {\n members.push(proj[1]);\n }\n }\n if (members.length === 0) return null;\n return { actual: members.length, countedFrom: name, members };\n }\n return null;\n}\n\nasync function countNpmWorkspaces(root: string): Promise<CountSource | null> {\n const pkgRaw = await readAuditInput(root, \"package.json\");\n if (pkgRaw !== null) {\n let globs: string[] = [];\n try {\n const pkg = JSON.parse(pkgRaw);\n globs = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : Array.isArray(pkg.workspaces?.packages)\n ? pkg.workspaces.packages\n : [];\n } catch {\n // Malformed package.json — nothing provable here.\n }\n if (globs.length > 0) {\n const matched = await auditGlob(root,\n globs.map((g) => `${g.replace(/\\/+$/, \"\")}/package.json`),\n { ignore: [\"**/node_modules/**\"], label: \"npm workspace discovery\" }\n );\n return {\n actual: matched.length,\n countedFrom: \"package.json workspaces\",\n members: matched.map((m) => path.dirname(m)).sort(),\n };\n }\n }\n\n const pnpmRaw = await readAuditInput(root, \"pnpm-workspace.yaml\");\n if (pnpmRaw !== null) {\n const globs: string[] = [];\n let inPackages = false;\n for (const line of pnpmRaw.split(\"\\n\")) {\n if (/^packages\\s*:/.test(line)) {\n inPackages = true;\n continue;\n }\n if (inPackages) {\n const entry = line.match(/^\\s*-\\s*[\"']?([^\"'#\\s]+)/);\n if (entry) {\n if (!entry[1].startsWith(\"!\")) globs.push(entry[1]);\n } else if (line.trim().length > 0 && !line.startsWith(\" \")) {\n inPackages = false;\n }\n }\n }\n if (globs.length > 0) {\n const matched = await auditGlob(root,\n globs.map((g) => `${g.replace(/\\/+$/, \"\")}/package.json`),\n { ignore: [\"**/node_modules/**\"], label: \"pnpm workspace discovery\" }\n );\n return {\n actual: matched.length,\n countedFrom: \"pnpm-workspace.yaml\",\n members: matched.map((m) => path.dirname(m)).sort(),\n };\n }\n }\n return null;\n}\n\nasync function countCargoCrates(root: string): Promise<CountSource | null> {\n const content = await readAuditInput(root, \"Cargo.toml\");\n if (content === null) return null;\n const membersBlock = content.match(/members\\s*=\\s*\\[([\\s\\S]*?)\\]/);\n if (!membersBlock) return null;\n const entries = [...membersBlock[1].matchAll(/[\"']([^\"']+)[\"']/g)].map(\n (m) => m[1]\n );\n if (entries.length === 0) return null;\n\n // Workspace members may be globs (\"crates/*\") — resolve them against\n // directories that actually contain a Cargo.toml.\n const members = new Set<string>();\n for (const entry of entries) {\n if (/[*?[\\]{}]/.test(entry)) {\n const matched = await auditGlob(root, `${entry.replace(/\\/+$/, \"\")}/Cargo.toml`, {\n ignore: [\"**/target/**\"],\n label: \"Cargo workspace discovery\",\n });\n for (const m of matched) members.add(path.dirname(m));\n } else if (\n (await readAuditInput(root, path.posix.join(entry, \"Cargo.toml\"))) !== null\n ) {\n members.add(entry);\n }\n }\n if (members.size === 0) return null;\n return {\n actual: members.size,\n countedFrom: \"Cargo.toml workspace members\",\n members: [...members].sort(),\n };\n}\n\n/**\n * Map a claim's unit to the ecosystem that can prove it. When the mapped\n * ecosystem has no workspace manifest in this repo, the claim is skipped —\n * \"12 packages\" in a Gradle repo proves nothing either way.\n */\nexport async function resolveCountSource(\n root: string,\n claim: CountClaim\n): Promise<CountSource | null> {\n const unit = claim.unit.replace(/s$/, \"\");\n if (unit === \"module\") return countGradleModules(root);\n if (unit === \"workspace\") return countNpmWorkspaces(root);\n if (unit === \"crate\") return countCargoCrates(root);\n // \"packages\" is ecosystem-ambiguous — first manifest that resolves wins.\n return (\n (await countNpmWorkspaces(root)) ??\n (await countCargoCrates(root)) ??\n (await countGradleModules(root))\n );\n}\n\n/** Nested documents cannot assert the root workspace's count implicitly. */\nexport async function resolveDocCountSource(root: string, doc: string, claim: CountClaim): Promise<CountSource | null> {\n const scope = documentScope(doc);\n const source = await resolveCountSource(path.join(root, scope), claim);\n if (!source || scope === \".\") return source;\n return { ...source, countedFrom: scope + \"/\" + source.countedFrom,\n members: source.members.map(member => scope + \"/\" + member) };\n}\n\nexport async function checkStaleCounts(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n\n for (const doc of ctx.docs) {\n for (const claim of doc.claims.counts) {\n const source = await resolveDocCountSource(ctx.root, doc.path, claim);\n if (source === null) {\n result.skipped.push({ check: \"stale-count\", doc: doc.path,\n reason: `${doc.path}: cannot resolve a workspace manifest for \"${claim.excerpt}\"` });\n continue;\n }\n if (source.actual === claim.count) continue;\n result.issues.push({\n type: \"stale-count\",\n message: `says \"${claim.excerpt}\" but ${source.countedFrom} resolves to ${source.actual}`,\n anchor: { doc: doc.path, line: claim.line, excerpt: claim.excerpt },\n confidence: \"certain\",\n evidence: {\n kind: \"count-mismatch\",\n claimed: claim.count,\n actual: source.actual,\n unit: claim.unit,\n countedFrom: source.countedFrom,\n members: source.members.slice(0, MEMBERS_CAP),\n },\n });\n }\n }\n\n return result;\n}\n","import path from \"node:path\";\nimport { auditGlob, readAuditInput } from \"../inputs.js\";\nimport { documentScope } from \"../docs.js\";\nimport { scopedPath } from \"../scope.js\";\nimport type { ClaimScope, CommandClaim } from \"../types.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst AVAILABLE_SCRIPTS_CAP = 30;\nfunction scriptsOf(raw: string): string[] | null {\n try {\n const pkg = JSON.parse(raw);\n if (!pkg || typeof pkg !== \"object\" || Array.isArray(pkg)) return null;\n if (pkg.scripts === undefined) return [];\n return pkg.scripts && typeof pkg.scripts === \"object\" && !Array.isArray(pkg.scripts)\n && Object.values(pkg.scripts).every(value => typeof value === \"string\") ? Object.keys(pkg.scripts) : null;\n } catch { return null; }\n}\n\ninterface Resolution {\n doc: string; claim: CommandClaim; scope: ClaimScope; manifest: string | null;\n scripts: string[]; elsewhere: string[]; problem?: string;\n}\n\n/** Shared dependency resolver: the cache records every manifest actually consulted. */\nexport async function commandInputs(root: string, docs: Array<{ path: string; claims: { commands: CommandClaim[] } }>) {\n const contents = new Map<string, string | null>();\n const read = async (file: string) => {\n if (!contents.has(file)) contents.set(file, await readAuditInput(root, file));\n return contents.get(file)!;\n };\n await read(\"package.json\");\n let inventory: string[] | undefined;\n const resolutions: Resolution[] = [];\n for (const doc of docs) for (const claim of doc.claims.commands) {\n const base = documentScope(doc.path);\n const directory = scopedPath(base, claim.directory ?? \".\");\n const scope: ClaimScope = { basis: claim.directory === undefined ? \"document\" : \"explicit\",\n directory: directory ?? base, candidates: [] };\n const resolution: Resolution = { doc: doc.path, claim, scope, manifest: null, scripts: [], elsewhere: [] };\n resolutions.push(resolution);\n if (claim.scopeUnknown || directory === null) {\n resolution.problem = claim.scopeUnknown ?? \"The command's directory leaves the repository.\";\n continue;\n }\n let cursor = directory;\n while (true) {\n const manifest = path.posix.join(cursor, \"package.json\");\n scope.candidates.push(manifest);\n const raw = await read(manifest);\n if (raw !== null) {\n resolution.manifest = manifest;\n const scripts = scriptsOf(raw);\n if (scripts === null) resolution.problem = \"Invalid package manifest: \" + manifest;\n else resolution.scripts = scripts;\n break;\n }\n // An explicit directory is a declared execution scope, never silently use a sibling.\n if (claim.directory !== undefined || cursor === \".\") break;\n cursor = path.posix.dirname(cursor);\n }\n if (!resolution.manifest && !resolution.problem) {\n resolution.problem = `No package.json for the command's scope (${directory}).`;\n }\n if (resolution.problem || resolution.scripts.includes(claim.scriptName) || claim.directory !== undefined) continue;\n inventory ??= await commandManifests(root);\n for (const manifest of [...new Set([\"package.json\", ...inventory])].sort()) {\n if (scope.candidates.includes(manifest)) continue;\n scope.candidates.push(manifest);\n const raw = await read(manifest);\n if (raw === null) continue;\n const scripts = scriptsOf(raw);\n if (scripts === null) resolution.problem = \"Cannot establish script availability: invalid manifest \" + manifest;\n else if (scripts.includes(claim.scriptName)) resolution.elsewhere.push(manifest);\n }\n }\n return { manifests: [...contents].sort(([a], [b]) => a.localeCompare(b)), resolutions };\n}\n\nexport async function checkDeadCommands(ctx: CheckContext): Promise<CheckResult> {\n const result = emptyResult();\n const { resolutions } = await commandInputs(ctx.root, ctx.docs);\n for (const { doc, claim, scope, scripts, elsewhere, problem, manifest } of resolutions) {\n if (problem) {\n result.skipped.push({ check: \"dead-command\", doc, reason: problem });\n continue;\n }\n if (scripts.includes(claim.scriptName)) continue;\n const evidence = { kind: \"missing-script\" as const, scriptName: claim.scriptName, invocation: claim.invocation,\n manifestsChecked: scope.candidates, availableScripts: scripts.slice(0, AVAILABLE_SCRIPTS_CAP), scope };\n const anchor = { doc, line: claim.line, excerpt: claim.excerpt };\n const message = `\\`${claim.invocation}\\` names script \"${claim.scriptName}\", which is absent from ${manifest}`;\n // Nested docs imply a package, but may describe commands run from another cwd.\n const certain = documentScope(doc) === \".\" && (scope.basis === \"explicit\" || !elsewhere.length);\n if (certain) result.issues.push({ type: \"dead-command\", message, anchor, confidence: \"certain\", evidence });\n else result.advisories.push({ resolution: \"recheck\", type: \"dead-command\", message: message + (elsewhere.length\n ? `; it exists in ${elsewhere.join(\", \")}. Clarify the intended working directory.`\n : \"; the intended working directory needs review.\"), anchor, evidence });\n }\n return result;\n}\n\n/** Ignored workspace manifests may still be explicit command dependencies. */\nexport function commandManifests(root: string): Promise<string[]> {\n return auditGlob(root, \"**/package.json\", {\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \".mason/reports/**\", \"package.json\"],\n label: \"Command manifest discovery\",\n });\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { RangeCommits } from \"./git.js\";\n\nconst exec = promisify(execFile);\nasync function git(root: string, args: string[]) {\n return (await exec(\"git\", args, { cwd: root, timeout: 10000, maxBuffer: 2 * 1024 * 1024 })).stdout;\n}\n\n/** A deliberately narrow recognizer, not a Gradle evaluator. Unknown syntax stays advisory. */\nfunction withoutAndroidReleaseValues(text: string): string | null {\n if (/\\/\\*|\"\"\"|'''/.test(text) || !/id\\s*\\(?\\s*[\"']com\\.android\\.(application|library)[\"']/.test(text)) return null;\n const scopes: string[] = [];\n const normalized: string[] = [];\n let assignments = 0;\n for (const line of text.split(\"\\n\")) {\n // Remove ordinary quoted strings and line comments solely for brace tracking.\n const code = line.replace(/\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|\\/\\/.*$/g, token => token.startsWith(\"//\") ? \"\" : '\"\"');\n const assignment = line.match(/^(\\s*)(versionName|versionCode)(\\s*(?:=\\s*|\\s+))(\"[A-Za-z0-9._+-]+\"|'[A-Za-z0-9._+-]+'|\\d+)(\\s*)$/);\n if (assignment && scopes.join(\"/\") === \"android/defaultConfig\" &&\n (assignment[2] === \"versionCode\" ? /^\\d+$/.test(assignment[4]) : /^[\"']/.test(assignment[4]))) {\n normalized.push(assignment[1] + assignment[2] + assignment[3] + \"<release-value>\" + assignment[5]);\n assignments++;\n } else {\n // References can feed dependency coordinates or other executable configuration.\n if (/\\bversion(?:Name|Code)\\b/.test(line)) return null;\n normalized.push(line);\n }\n const named = code.match(/^\\s*(android|defaultConfig)\\s*\\{\\s*$/)?.[1];\n for (const brace of code.matchAll(/[{}]/g)) {\n if (brace[0] === \"{\") scopes.push(named ?? \"unknown\");\n else if (!scopes.length) return null;\n else scopes.pop();\n }\n }\n return assignments && !scopes.length ? normalized.join(\"\\n\") : null;\n}\n\n/** Only omit single-parent commits whose every touched manifest is proven release metadata. */\nexport async function releaseMetadataOnly(root: string, commit: RangeCommits[\"commits\"][number]): Promise<boolean> {\n if (!commit.files.length || !commit.files.every(file => /(^|\\/)build\\.gradle(?:\\.kts)?$/.test(file))) return false;\n try {\n const parents = (await git(root, [\"rev-list\", \"--parents\", \"-n\", \"1\", commit.hash])).trim().split(/\\s+/);\n if (parents.length !== 2) return false;\n for (const file of commit.files) {\n const raw = await git(root, [\"diff\", \"--raw\", \"-z\", \"--no-renames\", \"--no-ext-diff\", \"--no-textconv\", parents[1], commit.hash, \"--\", file]);\n if (!/^:(100644|100755) \\1 [a-f0-9]+ [a-f0-9]+ M\\0/.test(raw)) return false;\n const [before, after] = await Promise.all([\n git(root, [\"show\", parents[1] + \":\" + file]), git(root, [\"show\", commit.hash + \":\" + file]),\n ]);\n const previous = withoutAndroidReleaseValues(before);\n if (previous === null || previous !== withoutAndroidReleaseValues(after)) return false;\n }\n return true;\n } catch { return false; }\n}\n","import { documentScope } from \"../docs.js\";\nimport { releaseMetadataOnly } from \"../release-metadata.js\";\nimport { commitsTouchingSince } from \"../git.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\nconst MANIFEST_COMMITS_CAP = 10;\n\n/**\n * Tracked manifest files at any depth. Lockfiles are pure churn and are\n * deliberately not matched.\n */\nconst MANIFEST_PATHSPECS = [\n \":(glob)**/package.json\",\n \":(glob)**/build.gradle.kts\",\n \":(glob)**/build.gradle\",\n \"settings.gradle.kts\",\n \"settings.gradle\",\n \"gradle/libs.versions.toml\",\n \":(glob)**/Cargo.toml\",\n \"go.mod\",\n \"pyproject.toml\",\n \"requirements.txt\",\n \"Gemfile\",\n \"composer.json\",\n];\n\n/** Share exact dependency scope with persisted advisory assessments. */\nexport function manifestPathspecs(doc: string): string[] {\n const scope = documentScope(doc);\n if (scope === \".\") return MANIFEST_PATHSPECS;\n const escaped = scope.replace(/[\\\\*?\\[\\]]/g, \"\\\\$&\");\n return MANIFEST_PATHSPECS.map(spec => spec.startsWith(\":(glob)\")\n ? \":(glob)\" + escaped + \"/\" + spec.slice(\":(glob)\".length) : \":(literal)\" + scope + \"/\" + spec);\n}\n\n/**\n * Advisory, never an issue: a manifest commit after the doc's last commit\n * proves recency ordering, not that any specific claim is false — and it can\n * never be closed by editing the doc within the same run.\n */\nexport async function checkDepsChanged(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n result.suppressedAdvisories = [];\n const releaseOnly = new Map<string, boolean>();\n\n for (const doc of ctx.docs) {\n if (!doc.lastCommit) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path} has no commit history`,\n });\n continue;\n }\n if (doc.dirty) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path} has uncommitted edits – suppressed while in flight`,\n });\n }\n\n const range = await commitsTouchingSince(\n ctx.root,\n doc.lastCommit.hash,\n manifestPathspecs(doc.path)\n );\n if (range === null) {\n result.skipped.push({\n check: \"deps-changed\",\n doc: doc.path,\n reason: `${doc.path}: commit range unreachable (shallow clone?)`,\n });\n continue;\n }\n // Bound extra history reads. Older/ambiguous commits remain advisory.\n const relevant = [];\n for (const commit of range.commits) {\n if (!releaseOnly.has(commit.hash) && releaseOnly.size < 100) {\n releaseOnly.set(commit.hash, await releaseMetadataOnly(ctx.root, commit));\n }\n if (!releaseOnly.get(commit.hash)) relevant.push(commit);\n }\n range.commits = relevant;\n range.total = relevant.length;\n if (range.total === 0) continue;\n\n const latest = range.commits[0];\n (doc.dirty ? result.suppressedAdvisories : result.advisories).push({\n type: \"deps-changed\",\n message: `dependency manifests touched by ${range.total} commit${range.total === 1 ? \"\" : \"s\"} since ${doc.path} was last committed (latest: ${latest.hash.slice(0, 7)} \"${latest.subject}\")`,\n anchor: { doc: doc.path, line: null, excerpt: null },\n evidence: {\n kind: \"doc-behind-manifests\",\n docLastCommit: doc.lastCommit,\n manifestCommits: range.commits.slice(0, MANIFEST_COMMITS_CAP),\n totalCommits: range.total,\n },\n });\n }\n\n return result;\n}\n","import path from \"node:path\";\n\n// Question/filler words that carry no signal about which entry a task\n// touches. Domain words (\"auth\", \"drift\") are never in this list.\nconst STOPWORDS = new Set([\n \"the\", \"a\", \"an\", \"and\", \"or\", \"of\", \"to\", \"in\", \"on\", \"for\", \"with\",\n \"how\", \"does\", \"do\", \"is\", \"are\", \"was\", \"what\", \"where\", \"which\", \"why\",\n \"when\", \"who\", \"i\", \"we\", \"my\", \"our\", \"you\", \"your\", \"it\", \"its\", \"this\",\n \"that\", \"these\", \"those\", \"can\", \"could\", \"should\", \"would\", \"will\",\n \"want\", \"need\", \"please\", \"about\", \"into\", \"from\", \"when\", \"there\", \"any\",\n \"all\", \"some\", \"not\", \"but\", \"also\", \"just\", \"like\", \"get\", \"make\", \"use\",\n \"new\", \"work\", \"works\", \"working\", \"implement\", \"implemented\", \"change\",\n \"changed\", \"file\", \"files\", \"code\",\n]);\n\n/** Split camelCase/PascalCase/kebab/snake/path into lowercase word tokens. */\nexport function tokenize(text: string): string[] {\n return text\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t.length > 2 && !STOPWORDS.has(t));\n}\n\n/** Crude singular/plural folding so \"flows\" matches \"flow\" etc. */\nexport function stem(token: string): string {\n return token.length > 3 && token.endsWith(\"s\") ? token.slice(0, -1) : token;\n}\n\nexport function tokenSet(text: string): Set<string> {\n return new Set(tokenize(text).map(stem));\n}\n\nexport interface Scorable {\n name: string;\n description: string;\n files: string[];\n}\n\n/**\n * Lexical relevance of one entry to the task. Name hits are the strongest\n * signal, then description, then file-path words. Each distinct task token\n * counts once at its best weight, so a token appearing everywhere doesn't\n * triple-count.\n */\nexport function scoreEntry(taskTokens: Set<string>, entry: Scorable): number {\n const nameTokens = tokenSet(entry.name);\n const descTokens = tokenSet(entry.description);\n const fileTokens = tokenSet(entry.files.map((f) => path.basename(f)).join(\" \"));\n\n let score = 0;\n for (const token of taskTokens) {\n if (nameTokens.has(token)) score += 3;\n else if (descTokens.has(token)) score += 1;\n else if (fileTokens.has(token)) score += 1;\n }\n return score;\n}\n\n/** Jaccard similarity of two token sets: |∩| / |∪|, 0 when both empty. */\nexport function jaccard(a: Set<string>, b: Set<string>): number {\n if (a.size === 0 && b.size === 0) return 0;\n let intersection = 0;\n for (const token of a) if (b.has(token)) intersection++;\n return intersection / (a.size + b.size - intersection);\n}\n","export type Freshness = \"current\" | \"changed\" | \"unknown\";\nexport interface TrustState {\n freshness: Freshness;\n verification: \"unverified\" | \"passed\" | \"failed\";\n verifiedAt?: string;\n verifiedHash?: string;\n reasons: string[];\n}\n\nexport function assessTrust(entry: { verifiedAt?: string; verifiedHash?: string; verificationFailed?: boolean; verificationNote?: string }, freshness: Freshness): TrustState {\n const verification = entry.verificationFailed ? \"failed\" : entry.verifiedAt ? \"passed\" : \"unverified\";\n const reasons: string[] = [];\n if (freshness === \"unknown\") reasons.push(\"Anchors, history, or working-tree evidence are unavailable; verify before relying on this entry.\");\n if (freshness === \"changed\") reasons.push(\"Anchored files changed; verify against current code before relying on this entry.\");\n if (verification === \"failed\") reasons.push(`Verification failed: ${entry.verificationNote ?? \"re-map this entry before relying on it\"}`);\n if (verification === \"unverified\") reasons.push(\"No correctness verification has been recorded.\");\n return { freshness, verification, verifiedAt: entry.verifiedAt, verifiedHash: entry.verifiedHash, reasons };\n}\n\nexport function trustHint(states: TrustState[]): string {\n const parts: string[] = [];\n if (states.some(s => s.verification === \"failed\")) parts.push(\"Verification failed for returned entries; do not rely on those descriptions until corrected.\");\n if (states.some(s => s.freshness === \"unknown\")) parts.push(\"Freshness is unknown for some returned entries; inspect their files before relying on them.\");\n if (states.some(s => s.freshness === \"changed\")) parts.push(\"Some returned entries have changed files, including possible local edits; verify against the current code.\");\n if (!parts.length) parts.push(\"No changes detected in the returned anchors. This does not prove the descriptions are correct.\");\n if (states.some(s => s.verification === \"unverified\")) parts.push(\"Some entries have never been verified; read their evidence or use verify_snapshot for map descriptions.\");\n return parts.join(\" \");\n}\n","import { z } from \"zod\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { assessTrust, type Freshness } from \"../context/trust.js\";\n\nconst text = (max: number) => z.string().trim().min(1).max(max);\nexport const decisionSourceSchema = z.object({\n kind: z.enum([\"pull_request\", \"issue\", \"incident\", \"discussion\", \"document\", \"other\"]),\n reference: text(1000),\n note: text(500).optional(),\n}).strict();\nexport type DecisionSource = z.infer<typeof decisionSourceSchema>;\nexport const attributionSchema = z.object({\n owner: text(200).nullable().optional(),\n sources: z.array(decisionSourceSchema).max(20).optional(),\n actor: text(200).optional(),\n});\nconst contentSchema = z.object({\n title: z.string().min(1), body: z.string().min(1),\n category: z.enum([\"decision\", \"gotcha\", \"deprecation\", \"convention\"]),\n files: z.array(z.string().refine(f => normalizeRepoPath(f) !== null)),\n owner: text(200).optional(), sources: z.array(decisionSourceSchema).max(20),\n});\nconst approvalSchema = z.enum([\"unreviewed\", \"proposed\", \"accepted\"]);\nconst statusSchema = z.enum([\"active\", \"superseded\", \"retired\"]);\nexport const reviewEvidenceSchema = z.object({\n baseHash: z.string(), headHash: z.string(), historyAvailable: z.boolean(),\n changedFiles: z.array(z.string()), localChanges: z.array(z.string()),\n});\nconst eventSchema = z.object({\n kind: z.enum([\"imported\", \"created\", \"revised\", \"accepted\", \"reaffirmed\", \"retired\", \"superseded\"]),\n at: z.string().datetime(), actor: text(200).optional(), note: text(1500).optional(),\n revision: z.number().int().positive(), content: contentSchema,\n approval: approvalSchema, status: statusSchema, refreshedHash: z.string(),\n evidence: reviewEvidenceSchema.optional(),\n});\nexport type DecisionEvent = z.infer<typeof eventSchema>;\nexport type DecisionApproval = z.infer<typeof approvalSchema>;\nexport type DecisionContent = z.infer<typeof contentSchema>;\n\nconst legacySchema = z.object({\n version: z.literal(1), id: z.string().regex(/^[a-zA-Z0-9_-]+$/),\n title: z.string().min(1), body: z.string().min(1),\n category: contentSchema.shape.category, files: contentSchema.shape.files,\n createdAt: z.string(), updatedAt: z.string(), refreshedHash: z.string(),\n status: z.enum([\"active\", \"superseded\"]), supersededBy: z.string().optional(),\n}).passthrough();\nconst currentSchema = legacySchema.extend({\n version: z.literal(2), status: statusSchema,\n approval: approvalSchema, revision: z.number().int().positive(),\n owner: text(200).optional(), sources: z.array(decisionSourceSchema).max(20),\n history: z.array(eventSchema).min(1),\n}).superRefine((record, ctx) => {\n const invalid = (message: string) => ctx.addIssue({ code: \"custom\", message });\n const same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\n let previous: DecisionEvent | undefined;\n for (const event of record.history) {\n if (!previous) {\n if (![\"created\", \"imported\"].includes(event.kind) || event.revision !== 1) invalid(\"History must begin with creation or legacy import at revision 1\");\n if (event.approval !== (event.kind === \"created\" ? \"proposed\" : \"unreviewed\")) invalid(\"Initial records cannot claim acceptance\");\n } else {\n if ([\"created\", \"imported\"].includes(event.kind)) invalid(\"History cannot restart\");\n if (previous.status !== \"active\") invalid(\"Archived decisions cannot be changed\");\n if (event.revision !== previous.revision + (event.kind === \"revised\" ? 1 : 0)) invalid(\"Invalid revision sequence\");\n if (event.kind !== \"revised\" && !same(event.content, previous.content)) invalid(\"A review cannot silently revise decision content\");\n if (event.kind === \"reaffirmed\" && previous.approval !== \"accepted\") invalid(\"Only accepted decisions can be reaffirmed\");\n if (event.kind === \"accepted\" && previous.approval === \"accepted\") invalid(\"Use reaffirmation for an accepted decision\");\n const approval = event.kind === \"revised\" ? \"proposed\" : [\"accepted\", \"reaffirmed\"].includes(event.kind) ? \"accepted\" : previous.approval;\n if (event.approval !== approval) invalid(\"Approval disagrees with review history\");\n if (![\"accepted\", \"reaffirmed\"].includes(event.kind) && event.refreshedHash !== previous.refreshedHash) invalid(\"Only a review can refresh the evidence baseline\");\n }\n if (event.kind !== \"imported\" && event.status !== (event.kind === \"retired\" ? \"retired\" : event.kind === \"superseded\" ? \"superseded\" : \"active\")) invalid(\"Lifecycle disagrees with history\");\n if ([\"accepted\", \"reaffirmed\", \"retired\"].includes(event.kind) && (!event.actor || !event.note || !event.evidence)) invalid(\"Reviews require a named reviewer, reason, and code evidence\");\n if ([\"accepted\", \"reaffirmed\"].includes(event.kind)) {\n if (!event.content.owner || !event.content.sources.length) invalid(\"Accepted decisions require an owner and source\");\n if (!event.evidence || !/^[a-f0-9]{40,64}$/.test(event.evidence.headHash) || event.refreshedHash !== event.evidence.headHash || event.evidence.localChanges.length) invalid(\"Acceptance requires a committed evidence baseline\");\n }\n previous = event;\n }\n if (!previous || !same(previous.content, decisionContent(record)) || previous.approval !== record.approval || previous.status !== record.status || previous.revision !== record.revision || previous.refreshedHash !== record.refreshedHash) invalid(\"Decision does not match the final history event\");\n});\n\nexport const decisionSchema = z.union([legacySchema, currentSchema]);\nexport type DecisionRecord = z.infer<typeof decisionSchema>;\nexport type ReviewedDecisionRecord = z.infer<typeof currentSchema>;\n\nexport function decisionContent(record: Pick<DecisionRecord, \"title\" | \"body\" | \"category\" | \"files\"> & { owner?: unknown; sources?: unknown }): DecisionContent {\n return { title: record.title, body: record.body, category: record.category, files: record.files,\n ...(typeof record.owner === \"string\" ? { owner: record.owner } : {}),\n sources: Array.isArray(record.sources) ? record.sources as DecisionSource[] : [],\n };\n}\n\n/** Reading legacy records never upgrades their approval or rewrites their files. */\nexport function decisionApproval(record: DecisionRecord): DecisionApproval {\n return record.version === 1 ? \"unreviewed\" : record.approval;\n}\n\n/** The last accepted revision remains operative while a replacement is drafted.\n * This is a read-only projection; writes and review tokens use the complete record.\n * Archived records never regain authority from their history.\n */\nexport function effectiveDecision(record: DecisionRecord): DecisionRecord {\n if (record.version !== 2 || record.status !== \"active\" || record.approval !== \"proposed\") return record;\n let index = record.history.length - 1;\n while (index >= 0 && ![\"accepted\", \"reaffirmed\"].includes(record.history[index].kind)) index--;\n if (index < 0) return record;\n const event = record.history[index];\n return { ...record, ...event.content, owner: event.content.owner, approval: \"accepted\", revision: event.revision,\n refreshedHash: event.refreshedHash, updatedAt: event.at, history: record.history.slice(0, index + 1) };\n}\n\n/** Anchors relevant to either the operative knowledge or its pending proposal. */\nexport function decisionAnchors(record: DecisionRecord): string[] {\n return [...new Set([...effectiveDecision(record).files, ...record.files])];\n}\n\nexport function importLegacy(record: DecisionRecord, now: string): ReviewedDecisionRecord {\n if (record.version === 2) return record;\n // Ignore unrecognized legacy fields: they are not evidence of authorship or approval.\n const content = decisionContent({ title: record.title, body: record.body, category: record.category, files: record.files });\n return { id: record.id, createdAt: record.createdAt, updatedAt: record.updatedAt, status: record.status, refreshedHash: record.refreshedHash, supersededBy: record.supersededBy, ...content, version: 2, approval: \"unreviewed\", revision: 1,\n history: [{ kind: \"imported\", at: now, revision: 1, content, approval: \"unreviewed\", status: record.status, refreshedHash: record.refreshedHash,\n note: \"Imported a legacy record. Prior authorship and review history are unknown.\" }],\n };\n}\n\nexport function decisionProvenance(record: DecisionRecord, freshness: Freshness = \"unknown\") {\n const approval = decisionApproval(record);\n const review = record.version === 2 ? [...record.history].reverse().find(e => [\"accepted\", \"reaffirmed\"].includes(e.kind) && e.revision === record.revision) : undefined;\n return {\n approval, revision: record.version === 2 ? record.revision : 0,\n owner: record.version === 2 ? record.owner ?? null : null,\n sources: record.version === 2 ? record.sources : [],\n guidance: record.status !== \"active\" ? \"historical\" : approval === \"accepted\" ? \"constraint\" : approval === \"proposed\" ? \"proposal\" : \"unreviewed\",\n reviewRequired: record.status === \"active\" && (approval !== \"accepted\" || freshness !== \"current\"),\n lastReview: review ? { reviewer: review.actor!, at: review.at, note: review.note!, gitHash: review.refreshedHash } : null,\n };\n}\n\nexport function decisionTrust(record: DecisionRecord, freshness: Freshness) {\n const review = decisionProvenance(record, freshness).lastReview;\n return assessTrust(review ? { verifiedAt: review.at, verifiedHash: review.gitHash } : {}, freshness);\n}\n\nfunction revisionKnowledge(record: DecisionRecord, freshness: Freshness) {\n return { ...decisionContent(record), ...decisionProvenance(record, freshness), trust: decisionTrust(record, freshness) };\n}\n\n/** Readers show accepted content first and label the unaccepted draft separately. */\nexport function decisionKnowledge(record: DecisionRecord, freshness: Freshness = \"unknown\", proposalFreshness: Freshness = \"unknown\") {\n const effective = effectiveDecision(record);\n return { ...revisionKnowledge(effective, freshness),\n ...(effective !== record ? { pendingProposal: revisionKnowledge(record, proposalFreshness) } : {}) };\n}\n\nexport function compactDecisionKnowledge(...args: Parameters<typeof decisionKnowledge>) {\n const { body, pendingProposal, ...summary } = decisionKnowledge(...args);\n if (!pendingProposal) return summary;\n const { body: proposalBody, ...proposal } = pendingProposal;\n return { ...summary, pendingProposal: proposal };\n}\n\nexport const DECISION_GUIDANCE = \"Accepted decisions are recorded team constraints, subject to freshness checks. A pendingProposal is an unaccepted replacement; the accepted revision remains operative until explicit acceptance or retirement. Proposals are suggestions; legacy unreviewed records need confirmation. Use review_decision to inspect provenance and record an authorized review; identities and sources are recorded assertions, not authenticated proof.\";\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { readStoreJson, writeStoreJson, storePath, type StoreDiagnostic } from \"../utils/storage.js\";\nimport { sanitizeRepoPaths } from \"../utils/paths.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { jaccard, tokenSet } from \"../context/lexical.js\";\nimport { attributionSchema, decisionSchema, decisionContent, decisionApproval, effectiveDecision, importLegacy, type DecisionSource, type DecisionRecord, type ReviewedDecisionRecord } from \"./provenance.js\";\nexport type { DecisionRecord } from \"./provenance.js\";\n\nexport type DecisionCategory =\n | \"decision\"\n | \"gotcha\"\n | \"deprecation\"\n | \"convention\";\nexport type DecisionStatus = \"active\" | \"superseded\" | \"retired\";\n\nexport const TITLE_MAX_CHARS = 80;\nexport const BODY_RECOMMENDED_CHARS = 1500;\nexport const BODY_MAX_CHARS = 2500;\nexport const MAX_ACTIVE_DECISIONS = 150;\n\n// Share validation with MCP so rejected tool calls include the actual length.\nconst boundedText = (field: string, max: number, hint: string) => z.string({\n errorMap: (issue, ctx) => ({ message: issue.code === \"too_big\"\n ? `${field} has ${ctx.data.length} characters; maximum is ${max} (${ctx.data.length - max} over). ${hint}`\n : ctx.defaultError }),\n}).trim().min(1, `${field} must be non-empty`).max(max);\n\nexport const decisionTitleSchema = boundedText(\"title\", TITLE_MAX_CHARS, \"Tighten it to a specific headline.\");\nexport const decisionBodySchema = boundedText(\"body\", BODY_MAX_CHARS,\n `Aim for ${BODY_RECOMMENDED_CHARS} characters or fewer. Preserve the rule, reason, and exceptions; put supporting references in sources.`);\n\nconst DUPLICATE_JACCARD = 0.5;\nconst DUPLICATE_JACCARD_WITH_SHARED_FILE = 0.35;\n\nexport async function loadDecisionStore(rootDir: string): Promise<{ records: DecisionRecord[]; diagnostics: StoreDiagnostic[] }> {\n const records: DecisionRecord[] = [];\n const diagnostics: StoreDiagnostic[] = [];\n let entries: string[];\n try { entries = await fs.readdir(await storePath(rootDir, \".mason/decisions\")); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") diagnostics.push({ path: \".mason/decisions\", message: String(error) });\n return { records, diagnostics };\n }\n for (const entry of entries.sort()) {\n if (!entry.endsWith(\".json\")) continue;\n const relative = `.mason/decisions/${entry}`;\n try {\n const record = decisionSchema.parse(await readStoreJson(rootDir, relative));\n if (entry !== `${record.id}.json`) throw new Error(\"Record id does not match its filename\");\n records.push(record);\n } catch (error) { diagnostics.push({ path: relative, message: error instanceof Error ? error.message : String(error) }); }\n }\n return { records, diagnostics };\n}\n\nexport async function loadDecisions(rootDir: string): Promise<DecisionRecord[]> {\n return (await loadDecisionStore(rootDir)).records;\n}\n\nexport async function saveDecisionRecord(rootDir: string, record: DecisionRecord): Promise<void> {\n const validated = decisionSchema.parse(record);\n await writeStoreJson(rootDir, `.mason/decisions/${validated.id}.json`, validated);\n}\n\n/**\n * Deterministic, human-readable id: base slug ≤60 chars, ending at a word\n * boundary when possible. A single longer word is cut to fit.\n * A slug collision with a DIFFERENT record appends a 6-hex content suffix.\n */\nexport function decisionIdFor(\n title: string,\n body: string,\n existingIds: Set<string>\n): string {\n const fullSlug = title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n let slug = fullSlug.slice(0, 60);\n if (fullSlug.length > 60 && fullSlug[60] !== \"-\") {\n const boundary = slug.lastIndexOf(\"-\");\n if (boundary > 0) slug = slug.slice(0, boundary);\n }\n slug = slug.replace(/-+$/, \"\") || \"decision\";\n if (!existingIds.has(slug)) return slug;\n const suffix = createHash(\"sha1\")\n .update(title + body)\n .digest(\"hex\")\n .slice(0, 6);\n return `${slug}-${suffix}`;\n}\n\nexport function findNearDuplicate(\n candidate: { title: string; body: string; files: string[] },\n existing: DecisionRecord[]\n): { record: DecisionRecord; similarity: number } | null {\n const candidateTokens = tokenSet(`${candidate.title} ${candidate.body}`);\n const candidateFiles = new Set(candidate.files);\n let best: { record: DecisionRecord; similarity: number } | null = null;\n\n for (const record of existing) {\n if (record.status !== \"active\") continue;\n const similarity = jaccard(\n candidateTokens,\n tokenSet(`${record.title} ${record.body}`)\n );\n const sharesFile = record.files.some((f) => candidateFiles.has(f));\n const threshold = sharesFile\n ? DUPLICATE_JACCARD_WITH_SHARED_FILE\n : DUPLICATE_JACCARD;\n if (similarity >= threshold && (!best || similarity > best.similarity)) {\n best = { record, similarity };\n }\n }\n return best;\n}\n\nexport interface UpsertDecisionInput {\n title: string;\n body: string;\n category: DecisionCategory;\n files?: string[];\n owner?: string | null;\n sources?: DecisionSource[];\n /** Only supply a known identity; never infer authorship from Git configuration. */\n actor?: string;\n /** Existing id to revise. Unchanged content is a no-op; use review_decision to reaffirm. */\n id?: string;\n /** Id of a decision this one replaces; the old record is kept, marked superseded. */\n supersedes?: string;\n /** Save even when a near-duplicate was detected. */\n force?: boolean;\n}\n\nexport type UpsertDecisionResult =\n | {\n status: \"created\" | \"updated\" | \"unchanged\" | \"superseded_and_created\";\n id: string;\n totalActive: number;\n warnings: string[];\n approval?: \"unreviewed\" | \"proposed\" | \"accepted\";\n hint?: string;\n pruneCandidates?: string[];\n }\n | { status: \"duplicate_suspected\"; existing: DecisionRecord; hint: string }\n | { status: \"error\"; error: string };\n\n/** Serialize tool writes so prepared reviews cannot overwrite another decision edit. */\nexport async function withDecisionWrite<T>(root: string, operation: () => Promise<T>): Promise<T | { status: \"error\"; error: string }> {\n const lockPath = await storePath(root, \".mason/decisions/.write-lock\", true);\n let lock;\n try { lock = await fs.open(lockPath, \"wx\", 0o600); }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EEXIST\") return { status: \"error\", error: \"Decision store is locked by another write. Retry after it finishes; an abandoned .mason/decisions/.write-lock must be removed only after confirming no writer is running.\" };\n throw error;\n }\n try { return await operation(); }\n finally { await lock.close(); await fs.unlink(lockPath); }\n}\n\nexport async function upsertDecision(rootDir: string, input: UpsertDecisionInput): Promise<UpsertDecisionResult> {\n const parsedTitle = decisionTitleSchema.safeParse(input.title), parsedBody = decisionBodySchema.safeParse(input.body);\n if (!parsedTitle.success) return { status: \"error\", error: parsedTitle.error.issues[0].message };\n if (!parsedBody.success) return { status: \"error\", error: parsedBody.error.issues[0].message };\n const title = parsedTitle.data, body = parsedBody.data;\n const attribution = attributionSchema.safeParse(input);\n if (!attribution.success) return { status: \"error\", error: attribution.error.message };\n if (input.id && input.supersedes) return { status: \"error\", error: \"Use either id to revise or supersedes to replace a record, not both.\" };\n return withDecisionWrite(rootDir, async () => {\n const store = await loadDecisionStore(rootDir);\n if (store.diagnostics.length) return { status: \"error\", error: \"Repair malformed decision records before saving: \" + store.diagnostics.map(d => d.path).join(\", \") };\n const existing = store.records, byId = new Map(existing.map(r => [r.id, r]));\n const now = new Date().toISOString(), head = await getCurrentGitHash(rootDir);\n const warnings: string[] = [];\n if (body.length > BODY_RECOMMENDED_CHARS) warnings.push(`body has ${body.length} characters, above the recommended ${BODY_RECOMMENDED_CHARS}; matching context and hooks include it in full. Keep the rule, reason, and exceptions concise; use sources for supporting references.`);\n const files = sanitizeRepoPaths(input.files ?? []);\n if (input.files && files.length < input.files.length) warnings.push(\"some anchor paths were outside the repo or duplicated and were dropped\");\n for (const file of files) {\n try { await fs.access(path.join(rootDir, file)); }\n catch { warnings.push(`anchor file does not exist on disk: ${file}`); }\n }\n const hint = \"Saved locally for review and commit. Proposals are not accepted constraints; an existing accepted revision remains operative while its replacement is proposed. Use review_decision to inspect evidence and record an authorized acceptance or reaffirmation.\";\n if (input.id) {\n const original = byId.get(input.id);\n if (!original) return { status: \"error\", error: `no decision with id \"${input.id}\"` };\n if (original.status !== \"active\") return { status: \"error\", error: \"Archived records cannot be revised; create a new proposal.\" };\n const record = importLegacy(original, now);\n const content = decisionContent({ ...record, title, body, category: input.category,\n files: input.files !== undefined ? files : record.files,\n owner: attribution.data.owner === undefined ? record.owner : attribution.data.owner ?? undefined,\n sources: attribution.data.sources ?? record.sources,\n });\n if (JSON.stringify(content) === JSON.stringify(decisionContent(record))) {\n return { status: \"unchanged\", id: record.id, totalActive: existing.filter(r => r.status === \"active\").length, approval: decisionApproval(original), warnings,\n hint: \"Unchanged content; no review or freshness stamp was written. Use review_decision for explicit re-verification.\" };\n }\n const revision = record.revision + 1;\n const updated: ReviewedDecisionRecord = { ...record, ...content, owner: content.owner, updatedAt: now, revision, approval: \"proposed\",\n history: [...record.history, { kind: \"revised\", at: now, actor: attribution.data.actor, revision, content, approval: \"proposed\", status: \"active\", refreshedHash: record.refreshedHash }],\n };\n await saveDecisionRecord(rootDir, updated);\n return { status: \"updated\", id: record.id, totalActive: existing.filter(r => r.status === \"active\").length, approval: \"proposed\", warnings, hint };\n }\n const old = input.supersedes ? byId.get(input.supersedes) : undefined;\n if (input.supersedes && !old) return { status: \"error\", error: `no decision with id \"${input.supersedes}\" to supersede` };\n if (old && (old.status !== \"active\" || decisionApproval(effectiveDecision(old)) === \"accepted\")) {\n return { status: \"error\", error: \"A proposal cannot supersede an accepted or archived record. Create and review the replacement separately, then explicitly retire the old decision with review_decision.\" };\n }\n if (!input.force) {\n const duplicate = findNearDuplicate({ title, body, files }, existing);\n if (duplicate) return { status: \"duplicate_suspected\", existing: duplicate.record, hint: `A similar decision exists (\"${duplicate.record.title}\"). Call save_decision with id=\"${duplicate.record.id}\" to revise it, or force:true if distinct.` };\n }\n const id = decisionIdFor(title, body, new Set(byId.keys()));\n if (byId.has(id)) return { status: \"error\", error: `Decision id collision: ${id}. Choose a distinct title or revise the existing record.` };\n const content = decisionContent({ title, body, category: input.category, files, owner: attribution.data.owner ?? undefined, sources: attribution.data.sources ?? [] });\n const record: ReviewedDecisionRecord = { ...content, version: 2, id, createdAt: now, updatedAt: now, refreshedHash: head,\n status: \"active\", approval: \"proposed\", revision: 1,\n history: [{ kind: \"created\", at: now, actor: attribution.data.actor, revision: 1, content, approval: \"proposed\", status: \"active\", refreshedHash: head }],\n };\n // Write the replacement first: a failed second write leaves both records\n // available instead of removing the original before its replacement exists.\n await saveDecisionRecord(rootDir, record);\n if (old) {\n const imported = importLegacy(old, now);\n await saveDecisionRecord(rootDir, { ...imported, status: \"superseded\", supersededBy: id, updatedAt: now,\n history: [...imported.history, { kind: \"superseded\", at: now, actor: attribution.data.actor, note: `Replaced by proposal ${id}`,\n revision: imported.revision, content: decisionContent(imported), approval: imported.approval, status: \"superseded\", refreshedHash: imported.refreshedHash }],\n });\n }\n const totalActive = existing.filter(r => r.status === \"active\").length + (old ? 0 : 1);\n const result: UpsertDecisionResult = { status: old ? \"superseded_and_created\" : \"created\", id, totalActive, approval: \"proposed\", warnings, hint };\n if (totalActive > MAX_ACTIVE_DECISIONS) {\n result.pruneCandidates = existing.filter(r => r.status !== \"active\").map(r => r.id).slice(0, 10);\n warnings.push(`${totalActive} active decisions exceeds the soft cap of ${MAX_ACTIVE_DECISIONS} — consider a cleanup PR (archived records first)`);\n }\n return result;\n });\n}\n","import path from \"node:path\";\nimport { getChangesWithStatus, getWorkingTree, touchedPaths } from \"../drift/drift.js\";\nimport { matchingPaths } from \"../utils/paths.js\";\nimport type { Freshness } from \"../context/trust.js\";\nimport type { StoreDiagnostic } from \"../utils/storage.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { loadDecisionStore } from \"./decisions.js\";\nimport type { DecisionRecord } from \"./decisions.js\";\nimport { effectiveDecision } from \"./provenance.js\";\n\n/**\n * Deliberately separate from DriftReport: mason-drift's exit codes and\n * --json shape are a CI contract, and `stale` there means MAP staleness.\n * Decision staleness is additive on top.\n */\nexport interface DecisionDriftReport {\n historyAvailable: boolean;\n freshness?: Record<string, Freshness>;\n diagnostics?: StoreDiagnostic[];\n totalDecisions: number;\n /** Decision id → anchor files changed since the record's refreshedHash. */\n staleDecisions: Record<string, string[]>;\n /** Draft anchors have their own freshness; they cannot replace accepted anchors. */\n pendingProposals?: Record<string, { freshness: Freshness; changedFiles: string[] }>;\n}\n\n/**\n * Flag active decisions whose anchor files changed since the record was\n * last verified. Anchorless decisions have unknown freshness and do not\n * contribute to committed drift.\n * Deterministic — git only, no LLM.\n */\nexport async function computeDecisionDrift(\n rootDir: string,\n decisions?: DecisionRecord[]\n): Promise<DecisionDriftReport> {\n const resolvedRoot = path.resolve(rootDir);\n const store = decisions ? { records: decisions, diagnostics: [] } : await loadDecisionStore(resolvedRoot);\n const report: DecisionDriftReport = { historyAvailable: true, totalDecisions: store.records.length, staleDecisions: {}, freshness: {}, diagnostics: store.diagnostics };\n const [head, workingTree] = await Promise.all([getCurrentGitHash(resolvedRoot), getWorkingTree(resolvedRoot)]);\n const changesByHash = new Map<string, string[] | null>();\n const inspect = async (record: DecisionRecord): Promise<{ freshness: Freshness; changedFiles: string[] }> => {\n if (record.files.length === 0) return { freshness: \"unknown\", changedFiles: [] };\n let touched = changesByHash.get(record.refreshedHash);\n if (touched === undefined) {\n const changes = record.refreshedHash === head && head !== \"unknown\" ? [] : await getChangesWithStatus(resolvedRoot, record.refreshedHash);\n touched = changes === null ? null : touchedPaths(changes);\n changesByHash.set(record.refreshedHash, touched);\n }\n if (touched === null) report.historyAvailable = false;\n const hits = touched ? matchingPaths(record.files, touched) : [];\n const localHits = matchingPaths(record.files, workingTree.changedFiles);\n return { freshness: touched === null || !workingTree.available ? \"unknown\" : hits.length || localHits.length ? \"changed\" : \"current\", changedFiles: hits };\n };\n for (const record of store.records) {\n if (record.status !== \"active\") continue;\n const effective = effectiveDecision(record);\n const state = await inspect(effective);\n report.freshness![record.id] = state.freshness;\n if (state.changedFiles.length) report.staleDecisions[record.id] = state.changedFiles;\n if (effective !== record) (report.pendingProposals ??= {})[record.id] = await inspect(record);\n }\n return report;\n}\n","import { computeDecisionDrift } from \"../../decisions/drift.js\";\nimport { loadDecisionStore } from \"../../decisions/decisions.js\";\nimport { decisionProvenance, effectiveDecision } from \"../../decisions/provenance.js\";\nimport type { CheckContext, CheckResult } from \"./index.js\";\nimport { emptyResult } from \"./index.js\";\n\n/**\n * Advisory only, and only when .mason/decisions/ exists (the zero-setup\n * path stays dark on bare repos). Decision records encode human knowledge —\n * they are surfaced for re-verification, never rewritten by the fix agent.\n */\nexport async function checkDecisionAnchors(\n ctx: CheckContext\n): Promise<CheckResult> {\n const result = emptyResult();\n if (!ctx.decisionsPresent) return result;\n\n const store = await loadDecisionStore(ctx.root);\n const records = store.records;\n for (const diagnostic of store.diagnostics) result.skipped.push({ check: \"decision-anchor-drift\", reason: `${diagnostic.path}: ${diagnostic.message}` });\n const drift = await computeDecisionDrift(ctx.root, records);\n if (!drift.historyAvailable) {\n result.skipped.push({\n check: \"decision-anchor-drift\",\n reason: \"some decision base commits are unreachable (shallow clone?)\",\n });\n }\n\n const changed = records.flatMap(record => [\n { record: effectiveDecision(record), changedFiles: drift.staleDecisions[record.id] ?? [], freshness: drift.freshness?.[record.id] ?? \"unknown\" },\n { record, changedFiles: drift.pendingProposals?.[record.id]?.changedFiles ?? [], freshness: drift.pendingProposals?.[record.id]?.freshness ?? \"unknown\" },\n ] as const);\n for (const { record, changedFiles, freshness } of changed) {\n if (!changedFiles.length) continue;\n const id = record.id;\n const provenance = decisionProvenance(record, freshness);\n result.advisories.push({\n type: \"decision-anchor-drift\",\n message: `decision \"${record.title}\" (${provenance.approval}) has anchor files that changed since its evidence baseline – needs human review`,\n anchor: {\n doc: `.mason/decisions/${id}.json`,\n line: null,\n excerpt: record.title,\n },\n evidence: {\n kind: \"decision-anchor\",\n provenance,\n decisionId: id,\n title: record.title,\n changedFiles,\n refreshedHash: record.refreshedHash,\n },\n });\n }\n\n return result;\n}\n","import type { FileChange } from \"../../drift/drift.js\";\nimport type { AuditAdvisory, AuditIssue, CheckName } from \"../types.js\";\nimport type { AuditDoc } from \"../docs.js\";\nimport { checkDeletedReferences } from \"./deleted-reference.js\";\nimport { checkNewModules } from \"./new-module.js\";\nimport { checkStaleCounts } from \"./stale-count.js\";\nimport { checkDeadCommands } from \"./dead-command.js\";\nimport { checkDepsChanged } from \"./deps-changed.js\";\nimport { checkDecisionAnchors } from \"./decision-anchor.js\";\n\nexport interface CheckContext {\n root: string;\n docs: AuditDoc[];\n headHash: string;\n /** Doc path → changes since the doc's last commit; null when uncomputable. */\n changesSinceDoc: Map<string, FileChange[] | null>;\n /** Whether .mason/decisions/ exists. */\n decisionsPresent: boolean;\n}\n\nexport interface CheckResult {\n issues: AuditIssue[];\n advisories: AuditAdvisory[];\n suppressedAdvisories?: AuditAdvisory[];\n skipped: Array<{ check: string; reason: string; doc?: string }>;\n}\n\nexport type CheckFn = (ctx: CheckContext) => Promise<CheckResult>;\n\nexport const CHECKS: Record<CheckName, CheckFn> = {\n \"deleted-reference\": checkDeletedReferences,\n \"new-module\": checkNewModules,\n \"stale-count\": checkStaleCounts,\n \"dead-command\": checkDeadCommands,\n \"deps-changed\": checkDepsChanged,\n \"decision-anchor-drift\": checkDecisionAnchors,\n};\n\nexport function emptyResult(): CheckResult {\n return { issues: [], advisories: [], skipped: [] };\n}\n","import { createHash } from \"node:crypto\";\nimport { z } from \"zod\";\nimport type { AuditIssue, AuditAdvisory } from \"./types.js\";\nexport type Finding = AuditIssue | AuditAdvisory;\nexport const digest = (value: unknown) => createHash(\"sha256\").update(JSON.stringify(value)).digest(\"hex\");\nexport const checkSchema = z.enum([\"deleted-reference\", \"new-module\", \"stale-count\", \"dead-command\", \"deps-changed\", \"decision-anchor-drift\"]);\nexport const commitSchema = z.object({ hash: z.string().regex(/^[a-f0-9]{40,64}$/), date: z.string(), subject: z.string() });\nconst anchorSchema = z.object({ doc: z.string(), line: z.number().int().positive().nullable(), excerpt: z.string().nullable() });\nconst count = z.number().int().nonnegative();\nconst scopeSchema = z.object({ basis: z.enum([\"repository\", \"document\", \"document-link\", \"explicit\"]),\n directory: z.string(), candidates: z.array(z.string()) });\nconst evidenceSchema = z.discriminatedUnion(\"kind\", [\n z.object({ kind: z.literal(\"missing-path\"), claimed: z.string(), renamedTo: z.string().nullable(),\n deletedInCommit: commitSchema.nullable(), everTracked: z.boolean(), parentDirExists: z.boolean(), resolvedPath: z.string().optional(), scope: scopeSchema.optional() }),\n z.object({ kind: z.literal(\"unmentioned-dir\"), dir: z.string(), sourceFileCount: count,\n firstCommit: commitSchema.nullable(), checkedDocs: z.array(z.string()) }),\n z.object({ kind: z.literal(\"count-mismatch\"), claimed: count, actual: count, unit: z.string(),\n countedFrom: z.string(), members: z.array(z.string()) }),\n z.object({ kind: z.literal(\"missing-script\"), scriptName: z.string(), invocation: z.string(),\n manifestsChecked: z.array(z.string()), availableScripts: z.array(z.string()), scope: scopeSchema.optional() }),\n z.object({ kind: z.literal(\"doc-behind-manifests\"), docLastCommit: commitSchema,\n manifestCommits: z.array(commitSchema.extend({ files: z.array(z.string()) })), totalCommits: count }),\n z.object({ kind: z.literal(\"decision-anchor\"), decisionId: z.string(), title: z.string(),\n changedFiles: z.array(z.string()), refreshedHash: z.string(),\n provenance: z.object({}).passthrough().optional() }),\n]);\nconst findingSchema = z.object({ message: z.string(), anchor: anchorSchema, evidence: evidenceSchema });\nexport const issueSchema = findingSchema.extend({\n type: z.enum([\"deleted-reference\", \"new-module\", \"stale-count\", \"dead-command\"]),\n confidence: z.enum([\"certain\", \"likely\"]),\n});\nexport const advisorySchema = findingSchema.extend({ type: checkSchema, resolution: z.literal(\"recheck\").optional() });\nexport const checkResultSchema = z.object({\n issues: z.array(issueSchema), advisories: z.array(advisorySchema),\n suppressedAdvisories: z.array(advisorySchema).optional(),\n skipped: z.array(z.object({ check: z.string(), reason: z.string(), doc: z.string().optional() })),\n});\n/** Lines and wording can change without changing the underlying claim. */\nexport function findingId(finding: Finding): string {\n const e = finding.evidence;\n let key: unknown;\n switch (e.kind) {\n case \"missing-path\": key = e.resolvedPath && e.resolvedPath !== e.claimed ? [e.claimed, e.resolvedPath] : e.claimed; break;\n case \"unmentioned-dir\": key = e.dir; break;\n case \"count-mismatch\": key = [e.unit.replace(/s$/, \"\"), e.countedFrom]; break;\n case \"missing-script\": key = e.scope && e.scope.directory !== \".\" ? [e.scriptName, e.scope.directory] : e.scriptName; break;\n case \"doc-behind-manifests\": key = null; break;\n case \"decision-anchor\": key = [e.decisionId, e.provenance?.revision, e.provenance?.approval]; break;\n }\n return digest([finding.type, finding.anchor.doc, key]);\n}\n","import fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport { z } from \"zod\";\nimport { storePath } from \"../utils/storage.js\";\n\nexport const hostSchema = z.enum([\"claude\", \"codex\"]);\nexport type Host = z.infer<typeof hostSchema>;\nexport const events = [\"session_start\", \"turn_start\", \"before_tool\", \"after_tool\", \"task_end\"] as const;\nexport type Event = typeof events[number];\nexport const stateSchema = z.object({\n version: z.literal(1), root: z.string(), gitDir: z.string(), branch: z.string(),\n baselines: z.array(z.object({ path: z.string(), at: z.string(), event: z.string(), fingerprint: z.string() })).max(128),\n sessions: z.record(z.object({\n host: hostSchema, seen: z.string().nullable(), continued: z.boolean(),\n initialIssues: z.array(z.string()), initialDocs: z.record(z.string().nullable()),\n lastUsed: z.string(), mutationObserved: z.boolean(),\n pending: z.record(z.string()), coverageGaps: z.array(z.string()),\n events: z.record(z.object({ at: z.string(), count: z.number().int().positive() })),\n })),\n updatedAt: z.string(), fingerprint: z.string().nullable(),\n latest: z.string().nullable(),\n analysis: z.object({ id: z.string(), fingerprint: z.string(), completedAt: z.number(), path: z.string() }).optional(),\n});\nexport type State = z.infer<typeof stateSchema>;\nexport function parseState(raw: unknown): State {\n try { return stateSchema.parse(raw); }\n catch (error) { throw new Error(\"Invalid automation state; original evidence was retained.\", { cause: error }); }\n}\n\n/** Cross-process lock: a killed writer's lock is reclaimed only after its local PID is gone. */\nexport async function withLock<T>(root: string, directory: string, run: () => Promise<T>, waitMs = 5000): Promise<T> {\n const file = await storePath(root, directory + \"/lock\", true);\n const deadline = Date.now() + waitMs;\n let handle;\n while (!handle) {\n try {\n handle = await fs.open(file, \"wx\", 0o600);\n try { await handle.writeFile(JSON.stringify({ pid: process.pid, host: os.hostname() })); }\n catch (error) {\n await handle.close().catch(() => {});\n handle = undefined;\n await fs.rm(file, { force: true }).catch(() => {});\n throw error;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n // Do not steal malformed, remote, or live locks on a time-based guess.\n try {\n const owner = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (owner.host === os.hostname() && Number.isInteger(owner.pid) && owner.pid > 0) {\n try { process.kill(owner.pid, 0); }\n catch (probe) {\n if ((probe as NodeJS.ErrnoException).code === \"ESRCH\") {\n // Renaming a stale lock arbitrates reclamation without unlinking a new writer's lock.\n const reclaim = file + \".reclaim\";\n let guard;\n try {\n guard = await fs.open(reclaim, \"wx\", 0o600);\n const current = JSON.parse(await fs.readFile(file, \"utf8\"));\n if (current.pid === owner.pid && current.host === owner.host) await fs.unlink(file);\n } finally { if (guard) { await guard.close(); await fs.rm(reclaim, { force: true }); } }\n }\n }\n }\n } catch { /* Another writer may be creating/releasing/reclaiming it. */ }\n if (Date.now() >= deadline) throw new Error(\"Automation is busy or its lock needs inspection: \" + file);\n await new Promise(resolve => setTimeout(resolve, 40));\n }\n }\n try { return await run(); }\n finally { await handle.close(); await fs.unlink(file); }\n}\n","import { profilePhase } from \"../utils/profile.js\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { z } from \"zod\";\nimport { computeAudit, type AuditOptions } from \"./audit.js\";\nimport { discoverDocPaths } from \"./docs.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { getChangesWithStatus } from \"../drift/drift.js\";\nimport { readStoreJson, storePath, writeStoreJson } from \"../utils/storage.js\";\nimport { readBoundedFile } from \"../utils/files.js\";\nimport { isWithinRoot, normalizeRepoPath } from \"../utils/paths.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport type { AuditReport, CheckName } from \"./types.js\";\nimport { checkSchema, commitSchema, issueSchema, advisorySchema, digest, findingId, type Finding } from \"./findings.js\";\nimport { assessAdvisory, advisoryReviewInventory, reviewSummarySchema, type AdvisoryReviewSummary } from \"./advisory-review.js\";\nexport { checkResultSchema, findingId } from \"./findings.js\";\nconst count = z.number().int().nonnegative();\n\nexport const reportSchema = z.object({\n version: z.literal(1), root: z.string(), gitAvailable: z.literal(true),\n headHash: commitSchema.shape.hash, checksRun: z.array(checkSchema).nonempty(),\n docs: z.array(z.object({ path: z.string().refine(value => normalizeRepoPath(value) === value), scope: z.string().optional(),\n kind: z.enum([\"instructions\", \"readme\"]).optional(), lastCommit: commitSchema.nullable(),\n dirty: z.boolean(), lineCount: count })).nonempty(),\n decisionsChecked: z.boolean(), clean: z.boolean(),\n issues: z.array(issueSchema), advisories: z.array(advisorySchema),\n suppressedAdvisories: z.array(advisorySchema).optional(),\n skippedChecks: z.array(z.object({ check: z.string(), reason: z.string(), doc: z.string().optional() })),\n});\nconst baselineSchema = z.object({\n kind: z.literal(\"mason-audit-repair\"), version: z.literal(1),\n createdAt: z.string().datetime(), report: reportSchema, digest: z.string().regex(/^[a-f0-9]{64}$/),\n});\n\n\nexport type RepairStatus = \"resolved\" | \"unresolved\" | \"review-required\" | \"unverified\";\n\nexport interface RepairFinding {\n id: string;\n original: Finding;\n status: RepairStatus;\n reason: string;\n current?: Finding;\n review?: AdvisoryReviewSummary;\n}\nexport const repairFindingSchema = z.object({\n id: z.string(), original: z.union([issueSchema, advisorySchema]),\n status: z.enum([\"resolved\", \"unresolved\", \"review-required\", \"unverified\"]), reason: z.string(),\n current: z.union([issueSchema, advisorySchema]).optional(),\n review: reviewSummarySchema.optional(),\n});\nexport interface RepairVerification {\n version: 1;\n action: \"verify\";\n baselinePath: string;\n baselineHead: string;\n currentHead: string | null;\n status: \"verified\" | \"issues-remain\" | \"incomplete\";\n findings: RepairFinding[];\n newFindings: Finding[];\n diagnostics: string[];\n currentAudit: AuditReport | null;\n counts: Record<RepairStatus, number>;\n scope: string;\n}\n\nfunction recheckable(finding: Finding): boolean {\n return !(\"confidence\" in finding) && finding.resolution === \"recheck\"\n && [\"deleted-reference\", \"dead-command\", \"new-module\"].includes(finding.type)\n && [\"missing-path\", \"missing-script\", \"unmentioned-dir\"].includes(finding.evidence.kind);\n}\nfunction allFindings(report: AuditReport): Finding[] {\n return [...report.issues, ...report.advisories, ...(report.suppressedAdvisories ?? [])];\n}\n\nasync function docState(root: string): Promise<string> {\n const docs = [];\n for (const doc of await discoverDocPaths(root)) {\n try {\n const content = await readBoundedFile(await storePath(root, doc), 10 * 1024 * 1024);\n if (content === null) throw new Error(\"Context file is not regular or exceeds 10 MiB: \" + doc);\n docs.push([doc, digest(content)]);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n docs.push([doc, null]);\n }\n }\n return digest(docs);\n}\n\n/** Refuse a verification assembled across a commit or instruction-file edit. */\nasync function stableAudit(root: string, checks: CheckName[], options: AuditOptions = {}): Promise<AuditReport | null> {\n return profilePhase(\"repair.audit\", () => readStableAudit(root, checks, options));\n}\n\nasync function readStableAudit(root: string, checks: CheckName[], options: AuditOptions) {\n const head = await getCurrentGitHash(root);\n const before = await docState(root);\n const report = await computeAudit(root, { ...options, checks });\n if (head !== await getCurrentGitHash(root) || before !== await docState(root) ||\n (report && report.headHash !== head)) {\n throw new Error(\"HEAD or context files changed during the audit; retry against a stable checkout.\");\n }\n return report;\n}\n\nexport async function prepareRepair(rootDir: string, checks: CheckName[] = ALL_CHECKS, options: AuditOptions = {}) {\n return prepareOriginal(rootDir, checks, options);\n}\n\ninterface RepairSession {\n audit: (checks: CheckName[]) => Promise<AuditReport | null>;\n document: (file: string) => Promise<string | null>;\n history: (head: string) => ReturnType<typeof getChangesWithStatus>;\n assessment: typeof assessAdvisory;\n}\n\n/** Share current evidence only within one operation, then validate it again.\n * Original baselines, their scope and their outcomes remain independent.\n */\nexport async function withRepairSession<T>(root: string, options: AuditOptions, run: (session: {\n prepare: () => ReturnType<typeof prepareRepair>;\n verify: (baselinePath: string) => Promise<RepairVerification>;\n currentAudit: () => Promise<AuditReport | null>;\n}) => Promise<T>, cachedAudit?: AuditReport): Promise<T> {\n const before = await Promise.all([getCurrentGitHash(root), docState(root), advisoryReviewInventory(root).then(digest)]);\n const audits = new Map<string, Promise<AuditReport | null>>();\n const documents = new Map<string, Promise<string | null>>();\n const history = new Map<string, ReturnType<typeof getChangesWithStatus>>();\n const assessments = new Map<string, ReturnType<typeof assessAdvisory>>();\n const memo = <T>(cache: Map<string, Promise<T>>, key: string, read: () => Promise<T>): Promise<T> => {\n if (!cache.has(key)) cache.set(key, read());\n return cache.get(key)!;\n };\n const session: RepairSession = {\n audit: checks => memo(audits, [...checks].sort().join(\",\"), async () => {\n if (cachedAudit && cachedAudit.headHash === before[0] && cachedAudit.root === root &&\n digest([...checks].sort()) === digest([...(cachedAudit.checksRun ?? [])].sort())) {\n // Raw audit results are cached, never their approval assessments. Original\n // baselines may refer to scopes no longer mentioned in the current docs.\n const current = structuredClone(cachedAudit);\n const reviews = (await Promise.all(allFindings(current).map(f => assessAdvisory(root, f, before[0])))).filter(r => r !== null);\n delete current.advisoryReviews;\n if (reviews.length) current.advisoryReviews = reviews;\n return current;\n }\n return computeAudit(root, { ...options, checks });\n }),\n document: file => memo(documents, file, async () => readBoundedFile(await storePath(root, file), 10 * 1024 * 1024)),\n history: head => memo(history, head, () => getChangesWithStatus(root, head)),\n assessment: (dir, finding, head) => memo(assessments, digest([dir, finding, head]), () => assessAdvisory(dir, finding, head)),\n };\n const result = await run({\n prepare: () => prepareOriginal(root, ALL_CHECKS, options, session),\n verify: baseline => profilePhase(\"repair.verify\", () => verifyOriginal(root, baseline, options, session)),\n currentAudit: () => session.audit(ALL_CHECKS),\n });\n const after = await Promise.all([getCurrentGitHash(root), docState(root), advisoryReviewInventory(root).then(digest)]);\n if (digest(before) !== digest(after)) throw new Error(\"HEAD, context files or advisory review records changed during verification; retry against stable evidence.\");\n return result;\n}\n\nasync function prepareOriginal(rootDir: string, checks: CheckName[], options: AuditOptions, session?: RepairSession) {\n const root = await fs.realpath(rootDir);\n const selected = z.array(checkSchema).nonempty().parse(checks);\n const report = await (session ? session.audit(selected) : stableAudit(root, selected, options));\n if (!report) throw new Error(\"No context files found to prepare a repair.\");\n if (!report.gitAvailable) throw new Error(\"Readable Git history is required to prepare a repair.\");\n // Canonicalize before hashing; validation on read must yield the same bytes.\n const storedReport = reportSchema.parse(report);\n const payload = { kind: \"mason-audit-repair\" as const, version: 1 as const,\n createdAt: new Date().toISOString(), report: storedReport };\n const baselinePath = \".mason/reports/repairs/\" + randomUUID() + \".json\";\n await writeStoreJson(root, baselinePath, { ...payload, digest: digest(payload) });\n return { version: 1 as const, action: \"prepare\" as const, baselinePath, report };\n}\n\nexport async function loadRepairBaseline(rootDir: string, baselinePath: string) {\n const root = await fs.realpath(rootDir);\n const declaredRoot = path.resolve(rootDir);\n const relative = path.isAbsolute(baselinePath)\n ? path.relative(isWithinRoot(declaredRoot, baselinePath) ? declaredRoot : root, baselinePath)\n : baselinePath;\n const stored = baselineSchema.parse(await readStoreJson(root, relative));\n const { digest: savedDigest, ...payload } = stored;\n if (digest(payload) !== savedDigest) throw new Error(\"Repair baseline was modified; use the original baseline.\");\n if (stored.report.root !== root) throw new Error(\"Repair baseline belongs to a different repository.\");\n const original = stored.report as AuditReport;\n return { root, relative, original };\n}\n\nexport async function verifyRepair(rootDir: string, baselinePath: string, options: AuditOptions = {}): Promise<RepairVerification> {\n return profilePhase(\"repair.verify\", () => verifyOriginal(rootDir, baselinePath, options));\n}\n\nasync function verifyOriginal(rootDir: string, baselinePath: string, options: AuditOptions, session?: RepairSession): Promise<RepairVerification> {\n const { root, relative, original } = await loadRepairBaseline(rootDir, baselinePath);\n const diagnostics: string[] = [];\n let reviewDigest: string | undefined;\n let current: AuditReport | null = null;\n try {\n if (!session) reviewDigest = digest(await advisoryReviewInventory(root));\n current = await (session ? session.audit(original.checksRun!) : stableAudit(root, original.checksRun!, options));\n if (!current) diagnostics.push(\"No context files remain available to audit.\");\n else if (!current.gitAvailable) diagnostics.push(\"Git history is unavailable.\");\n for (const doc of original.docs) {\n if (!allFindings(original).some(f => f.anchor.doc === doc.path) || !current?.docs.some(d => d.path === doc.path)) continue;\n const content = await (session ? session.document(doc.path) : readBoundedFile(await storePath(root, doc.path), 10 * 1024 * 1024));\n if (content === null || !content.trim()) {\n diagnostics.push(\"Original context file \" + doc.path + \" is empty or unreadable; losing its claims does not verify a repair.\");\n }\n }\n if (await (session ? session.history(original.headHash!) : getChangesWithStatus(root, original.headHash!)) === null) {\n diagnostics.push(\"The original audit commit is unavailable; repair history cannot be verified.\");\n }\n } catch (error) {\n diagnostics.push(error instanceof Error ? error.message : String(error));\n }\n const currentById = new Map((current ? allFindings(current) : []).map(f => [findingId(f), f]));\n const originalFindings = allFindings(original);\n const originalIds = new Set(originalFindings.map(findingId));\n const missingDocs = original.docs.filter(doc => !current?.docs.some(d => d.path === doc.path));\n for (const doc of missingDocs) diagnostics.push(\"Original context file \" + doc.path + \" is unavailable; removing it does not verify a repair.\");\n const findings = await Promise.all(originalFindings.map(async (finding): Promise<RepairFinding> => {\n const id = findingId(finding);\n const now = currentById.get(id);\n const base = { id, original: finding, ...(now ? { current: now } : {}) };\n if (diagnostics.length || !current) {\n return { ...base, status: \"unverified\", reason: \"The original audit scope could not be verified. See diagnostics.\" };\n }\n if (now && (\"confidence\" in finding || \"confidence\" in now)) {\n return { ...base, status: \"unresolved\", reason: \"The original check still reports this claim.\" };\n }\n const skipped = current.skippedChecks.filter(s => s.check === finding.type && (!s.doc || s.doc === finding.anchor.doc));\n if (!current.checksRun?.includes(finding.type) || skipped.length) {\n return { ...base, status: \"unverified\", reason: skipped.map(s => s.reason).join(\"; \") || \"The original check did not run.\" };\n }\n const review = await (session?.assessment ?? assessAdvisory)(root, now ?? finding, original.headHash!);\n if (review) {\n if (review.status === \"unverified\") return { ...base, review, status: \"unverified\", reason: review.reason };\n if (review.status === \"current\") return { ...base, review, status: \"resolved\", reason: review.reason };\n return { ...base, review, status: \"review-required\", reason: review.reason };\n }\n if (!(\"confidence\" in finding) && (!recheckable(finding) || now)) {\n return { ...base, status: \"review-required\",\n reason: \"An audit cannot establish that this advisory was reviewed. Retain its original evidence and report a separate assessment; editing or committing the doc is not approval.\" };\n }\n return { ...base, status: \"resolved\", reason: \"The original check ran and no longer reports this claim. Inspect the edit for semantic correctness.\" };\n }));\n if (!session) try {\n if (reviewDigest !== digest(await advisoryReviewInventory(root)) || current?.headHash !== await getCurrentGitHash(root)) {\n diagnostics.push(\"HEAD or advisory review records changed during verification; repeat against stable evidence.\");\n for (const finding of findings) { finding.status = \"unverified\"; finding.reason = diagnostics.at(-1)!; }\n }\n } catch (error) {\n diagnostics.push(String(error));\n for (const finding of findings) { finding.status = \"unverified\"; finding.reason = \"Advisory review evidence became unavailable during verification.\"; }\n }\n const newFindings = [...currentById].filter(([id]) => !originalIds.has(id)).map(([, f]) => f);\n const reviewedIds = new Set(current?.advisoryReviews?.filter(review => review.status === \"current\").map(review => review.id));\n const counts: Record<RepairStatus, number> = { resolved: 0, unresolved: 0, \"review-required\": 0, unverified: 0 };\n for (const f of findings) counts[f.status]++;\n const incomplete = diagnostics.length > 0 || counts.unverified > 0 || counts[\"review-required\"] > 0 ||\n (current?.skippedChecks.length ?? 0) > 0 || newFindings.some(f => !(\"confidence\" in f) && !reviewedIds.has(findingId(f)));\n const issuesRemain = counts.unresolved > 0 || newFindings.some(f => \"confidence\" in f);\n return {\n version: 1, action: \"verify\", baselinePath: relative, baselineHead: original.headHash!,\n currentHead: current?.gitAvailable ? current.headHash! : null,\n status: incomplete ? \"incomplete\" : issuesRemain ? \"issues-remain\" : \"verified\",\n findings, newFindings, diagnostics, currentAudit: current, counts,\n scope: \"Original audit checks over current context files and repository evidence. Resolved means no longer detected by the check or covered by an explicit assessment of current evidence; inspect each finding's reason and review. This is not a certification of documentation or application correctness.\",\n };\n}\n\nexport function repairExitCode(report: RepairVerification): number {\n return report.status === \"verified\" ? 0 : report.status === \"issues-remain\" ? 1 : 2;\n}\n\nexport function formatRepairSummary(report: RepairVerification): string {\n return [\n \"Repair verification: \" + report.status + \". Baseline: \" + report.baselinePath,\n ...report.findings.map(f => \" [\" + f.status + \"] \" + f.original.type + \" \" + f.original.anchor.doc + \": \" + f.original.message + \"\\n \" + f.reason + \"\\n findingId: \" + f.id),\n ...report.newFindings.map(f => \" [new] \" + f.type + \" \" + f.anchor.doc + \": \" + f.message),\n ...report.diagnostics.map(d => \" [unverified] \" + d),\n ...(report.currentAudit?.skippedChecks ?? []).map(s => \" [skipped] \" + s.check + \": \" + s.reason),\n report.scope,\n ].join(\"\\n\");\n}\n","import fs from \"node:fs/promises\";\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { z } from \"zod\";\nimport { advisorySchema, digest, findingId, type Finding } from \"./findings.js\";\nimport { manifestPathspecs } from \"./checks/deps-changed.js\";\nimport { readAuditInput } from \"./inputs.js\";\nimport { pathExists } from \"./scope.js\";\nimport { readStoreJson, storePath, writeStoreJson } from \"../utils/storage.js\";\nimport { normalizeRepoPath } from \"../utils/paths.js\";\nimport { withLock } from \"../automation/store.js\";\nimport { loadDecisionStore } from \"../decisions/decisions.js\";\nimport { computeDecisionDrift } from \"../decisions/drift.js\";\n\nconst execute = promisify(execFile);\nconst git = async (root: string, ...args: string[]) => (await execute(\"git\", args, { cwd: root, timeout: 10_000, maxBuffer: 8 * 1024 * 1024 })).stdout;\nconst hashSchema = z.string().regex(/^[a-f0-9]{64}$/);\nconst commitSchema = z.string().regex(/^[a-f0-9]{40,64}$/);\nconst evidenceSchema = z.object({\n head: commitSchema, fingerprint: hashSchema, scope: z.array(z.string()).min(1).max(1000),\n tree: z.string().max(2 * 1024 * 1024), lastScopeCommit: commitSchema,\n paths: z.array(z.object({ path: z.string(), exists: z.boolean() })).max(1000),\n});\nconst eventSchema = z.object({\n at: z.string().datetime(), reviewer: z.string().trim().min(1).max(200), note: z.string().trim().min(1).max(2500),\n outcome: z.enum([\"addressed\", \"inapplicable\", \"deferred\"]),\n finding: advisorySchema.refine(finding => finding.evidence.kind !== \"decision-anchor\", \"Decision findings use decision reviews\"), evidence: evidenceSchema,\n});\nconst recordSchema = z.object({ version: z.literal(1), id: hashSchema, events: z.array(eventSchema).min(1).max(200), digest: hashSchema });\ntype ReviewRecord = z.infer<typeof recordSchema>;\nexport const reviewSummarySchema = z.object({\n id: hashSchema, status: z.enum([\"current\", \"reopened\", \"deferred\", \"unverified\"]), reason: z.string(),\n recordPath: z.string().optional(), reviewer: z.string().optional(), note: z.string().optional(),\n outcome: z.enum([\"addressed\", \"inapplicable\", \"deferred\", \"accepted\", \"reaffirmed\", \"retired\"]).optional(),\n reviewedHead: z.string().optional(),\n});\nexport type AdvisoryReviewSummary = z.infer<typeof reviewSummarySchema>;\nexport const advisoryReviewRequest = z.object({\n baselinePath: z.string().min(1), findingId: hashSchema,\n action: z.enum([\"prepare\", \"addressed\", \"inapplicable\", \"deferred\"]).default(\"prepare\"),\n reviewer: eventSchema.shape.reviewer.optional(), note: eventSchema.shape.note.optional(), reviewToken: hashSchema.optional(),\n});\nexport type AdvisoryReviewInput = z.input<typeof advisoryReviewRequest>;\nconst recordPath = (id: string) => `.mason/reviews/advisories/${hashSchema.parse(id)}.json`;\n\nasync function readRecord(root: string, id: string): Promise<ReviewRecord | null> {\n const raw = await readStoreJson(root, recordPath(id));\n if (raw === null) return null;\n const record = recordSchema.parse(raw);\n const { digest: stored, ...payload } = record;\n if (record.id !== id || digest(payload) !== stored || record.events.some(event => findingId(event.finding as Finding) !== id\n || event.evidence.fingerprint !== digest([event.evidence.scope, event.evidence.tree, event.evidence.lastScopeCommit, event.evidence.paths]))) {\n throw new Error(\"Advisory review record is inconsistent or modified; inspect its history.\");\n }\n return record;\n}\n\nfunction scopes(finding: Finding): string[] {\n const files = [finding.anchor.doc], e = finding.evidence;\n if (e.kind === \"decision-anchor\") throw new Error(\"Use review_decision for decision acceptance, reaffirmation or retirement.\");\n if (e.kind === \"doc-behind-manifests\") return [`:(literal)${finding.anchor.doc}`, ...manifestPathspecs(finding.anchor.doc)];\n if (e.kind === \"missing-path\") files.push(...(e.scope?.candidates ?? [e.resolvedPath ?? e.claimed]));\n else if (e.kind === \"missing-script\") files.push(...e.manifestsChecked, ...(e.scope?.candidates ?? []));\n else if (e.kind === \"unmentioned-dir\") files.push(e.dir, ...e.checkedDocs);\n else throw new Error(\"This advisory has no supported review scope.\");\n return [...new Set(files)].map(file => {\n if (normalizeRepoPath(file) !== file) throw new Error(\"Advisory contains an invalid scoped path: \" + file);\n return `:(literal)${file}`;\n }).sort();\n}\n\n/** Committed, scoped Git evidence survives unrelated and review-record-only commits. */\nasync function reviewEvidence(root: string, finding: Finding) {\n if (normalizeRepoPath(finding.anchor.doc) !== finding.anchor.doc) throw new Error(\"Invalid advisory document path.\");\n const scope = scopes(finding);\n const head = (await git(root, \"rev-parse\", \"HEAD\")).trim();\n const tracked = (await git(root, \"ls-files\", \"--cached\", \"-z\", \"--\", ...scope)).split(\"\\0\").filter(Boolean);\n if (tracked.length > 20_000) throw new Error(\"Advisory scope exceeds 20,000 tracked files.\");\n const [tree, status, lastScopeCommit, document] = await Promise.all([\n tracked.length ? git(root, \"ls-tree\", \"-r\", \"-z\", \"HEAD\", \"--\", ...tracked.map(file => `:(literal)${file}`)) : \"\",\n git(root, \"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\", \"--\", ...scope),\n git(root, \"log\", \"-1\", \"--format=%H\", \"HEAD\", \"--\", ...scope).then(value => value.trim()),\n readAuditInput(root, finding.anchor.doc),\n ]);\n if (!document?.trim()) throw new Error(\"Original advisory document is missing, empty or unreadable.\");\n if (tree.length > 2 * 1024 * 1024 || tree.split(\"\\0\").length > 20_000) throw new Error(\"Advisory scope is too large for a complete review; narrow the documentation scope.\");\n // Reject symlinks rather than trusting a blob that describes an external target.\n for (const entry of tree.split(\"\\0\").filter(Boolean)) {\n const tab = entry.indexOf(\"\\t\"), file = entry.slice(tab + 1);\n if (entry.startsWith(\"120000 \") || entry.startsWith(\"160000 \")) throw new Error(\"Symlink or submodule in advisory review scope: \" + file);\n await storePath(root, file);\n }\n // Path checks observe presence even for explicitly documented ignored\n // outputs. Git alone cannot detect those appearing or disappearing.\n const paths = finding.evidence.kind === \"missing-path\" ? await Promise.all(\n (finding.evidence.scope?.candidates ?? [finding.evidence.resolvedPath ?? finding.evidence.claimed])\n .map(async file => ({ path: file, exists: await pathExists(root, file) }))) : [];\n let dirty = status.length > 0;\n if (finding.evidence.kind === \"missing-script\") {\n for (const file of [...finding.evidence.manifestsChecked, ...(finding.evidence.scope?.candidates ?? [])]) {\n if (!tracked.includes(file) && await pathExists(root, file)) dirty = true;\n }\n }\n const fingerprint = digest([scope, tree, lastScopeCommit, paths]);\n if ((await git(root, \"rev-parse\", \"HEAD\")).trim() !== head) throw new Error(\"HEAD changed while collecting review evidence.\");\n return { ...evidenceSchema.parse({ head, scope, tree, lastScopeCommit, paths, fingerprint }), dirty,\n documentDigest: digest(document) };\n}\n\nasync function decisionAssessment(root: string, finding: Finding, baselineHead: string): Promise<AdvisoryReviewSummary | null> {\n const evidence = finding.evidence;\n if (evidence.kind !== \"decision-anchor\") return null;\n const id = findingId(finding);\n const store = await loadDecisionStore(root);\n if (store.diagnostics.length) throw new Error(\"Decision records have unavailable or malformed evidence; review cannot be confirmed.\");\n const record = store.records.find(record => record.id === evidence.decisionId);\n if (!record || record.version !== 2) return null;\n const events = record.history.filter(event => [\"accepted\", \"reaffirmed\", \"retired\"].includes(event.kind));\n const event = events.at(-1);\n if (!event?.evidence || !event.actor || !event.note || !event.evidence.historyAvailable || event.evidence.localChanges.length) return null;\n try { await git(root, \"merge-base\", \"--is-ancestor\", baselineHead, event.evidence.headHash); }\n catch { return null; }\n const drift = await computeDecisionDrift(root, [record]);\n if (!drift.historyAvailable) throw new Error(\"Decision review history is unavailable.\");\n const retired = record.status === \"retired\" && event.kind === \"retired\";\n const current = retired || record.status === \"active\" && record.approval === \"accepted\"\n && drift.freshness?.[record.id] === \"current\" && !drift.pendingProposals?.[record.id];\n return { id, status: current ? \"current\" : \"reopened\", outcome: event.kind as \"accepted\" | \"reaffirmed\" | \"retired\",\n reviewer: event.actor, note: event.note, reviewedHead: event.evidence.headHash,\n recordPath: `.mason/decisions/${record.id}.json`, reason: current\n ? \"The existing decision review records acceptance, reaffirmation or retirement covering the original finding.\"\n : \"Decision content or anchor evidence changed after its review; review the decision again.\" };\n}\n\nexport async function assessAdvisory(root: string, finding: Finding, baselineHead: string): Promise<AdvisoryReviewSummary | null> {\n if (\"confidence\" in finding) return null;\n const id = findingId(finding);\n try {\n if (finding.evidence.kind === \"decision-anchor\") return await decisionAssessment(root, finding, baselineHead);\n const record = await readRecord(root, id);\n if (!record) return null;\n const event = record.events.at(-1)!;\n // Use the reviewed scope, not a newly shortened finding's preview of that scope.\n const current = await reviewEvidence(root, event.finding as Finding);\n await git(root, \"merge-base\", \"--is-ancestor\", event.evidence.head, current.head);\n const base = { id, recordPath: recordPath(id), reviewer: event.reviewer, note: event.note,\n outcome: event.outcome, reviewedHead: event.evidence.head };\n if (current.dirty || current.fingerprint !== event.evidence.fingerprint || digest(scopes(finding)) !== digest(event.evidence.scope)) return { ...base, status: \"reopened\", reason: \"Relevant document or repository evidence changed after the assessment; prepare a new review.\" };\n return { ...base, status: event.outcome === \"deferred\" ? \"deferred\" : \"current\", reason: event.outcome === \"deferred\"\n ? \"The review was deferred and remains outstanding.\" : \"An explicit assessment covers the current committed scope. This does not approve an engineering decision or certify correctness.\" };\n } catch (error) { return { id, status: \"unverified\", reason: error instanceof Error ? error.message : String(error) }; }\n}\n\n/** Fingerprint receipt content so concurrent automation cannot publish an older assessment. */\nexport async function advisoryReviewInventory(root: string) {\n let names: string[];\n try { names = await fs.readdir(await storePath(root, \".mason/reviews/advisories\")); }\n catch (error) { if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return []; throw error; }\n if (names.length > 5000) throw new Error(\"Advisory review inventory exceeds 5,000 records.\");\n return Promise.all(names.filter(name => name.endsWith(\".json\")).sort().map(async name => [name, await readAuditInput(root, \".mason/reviews/advisories/\" + name)]));\n}\n\nexport async function reviewAdvisory(rootDir: string, input: AdvisoryReviewInput) {\n const root = await fs.realpath(rootDir), request = advisoryReviewRequest.parse(input);\n const { loadRepairBaseline } = await import(\"./repair.js\");\n const baseline = await loadRepairBaseline(root, request.baselinePath);\n const finding = [...baseline.original.advisories, ...(baseline.original.suppressedAdvisories ?? [])].find(f => findingId(f) === request.findingId);\n if (!finding) throw new Error(\"No advisory with this findingId in the original baseline. Provable issues must be repaired and rechecked.\");\n if (finding.evidence.kind === \"decision-anchor\") return { status: \"decision-review-required\", decisionId: finding.evidence.decisionId,\n hint: \"Use review_decision to prepare evidence and record authorized acceptance, reaffirmation or retirement, then verify this original repair baseline. An advisory assessment cannot approve a decision.\" };\n const prepare = async () => {\n const record = await readRecord(root, request.findingId);\n const evidence = await reviewEvidence(root, finding);\n await git(root, \"merge-base\", \"--is-ancestor\", baseline.original.headHash!, evidence.head);\n const token = digest({ baseline: baseline.original, finding, evidence, record });\n return { record, evidence, token };\n };\n if (request.action === \"prepare\") {\n const state = await prepare();\n let diff: string | null = null, diffNote: string | undefined;\n const from = finding.evidence.kind === \"doc-behind-manifests\" ? finding.evidence.docLastCommit.hash : baseline.original.headHash!;\n try {\n const full = await git(root, \"diff\", \"--no-ext-diff\", \"--no-textconv\", \"--no-color\", \"--no-renames\", \"-U3\", from, state.evidence.head, \"--\", ...state.evidence.scope);\n diff = full.slice(0, 16000); if (full.length > diff.length) diffNote = \"Diff preview truncated; inspect the full scoped diff before reviewing.\";\n } catch { diffNote = \"Diff preview unavailable; inspect the original cited evidence directly before reviewing.\"; }\n if ((await prepare()).token !== state.token) throw new Error(\"Review evidence changed during preparation; retry.\");\n return { status: \"prepared\", findingId: request.findingId, finding, evidence: state.evidence,\n history: state.record?.events ?? [], reviewToken: state.token, diff, diffNote,\n hint: \"Inspect the original finding, scoped document and relevant code changes. Record addressed, inapplicable or deferred only when the user or cited project review authorizes that assessment. Supply the actual reviewer, reason in note and reviewToken. Relevant edits must be committed first. Deferral remains outstanding. Review identities are recorded assertions, not authenticated approvals.\" };\n }\n if (!request.reviewer || !request.note || !request.reviewToken) throw new Error(\"Prepare first; recording an assessment requires reviewToken, reviewer and note.\");\n return withLock(root, \".mason/reports/advisory-review-locks/\" + request.findingId, async () => {\n const state = await prepare();\n if (state.token !== request.reviewToken) throw new Error(\"Review conflict: evidence or review history changed since preparation. Prepare and inspect a new review.\");\n if (state.evidence.dirty) throw new Error(\"Commit relevant document and repository edits before recording the assessment. Unrelated local work may remain.\");\n if ((state.record?.events.length ?? 0) >= 200) throw new Error(\"Review history limit reached; existing events were retained.\");\n const { dirty, documentDigest, ...evidence } = state.evidence;\n const event = eventSchema.parse({ at: new Date().toISOString(), reviewer: request.reviewer, note: request.note,\n outcome: request.action, finding, evidence });\n const payload = { version: 1 as const, id: request.findingId, events: [...(state.record?.events ?? []), event] };\n if ((await prepare()).token !== state.token) throw new Error(\"Review conflict: evidence changed while recording the assessment.\");\n await writeStoreJson(root, recordPath(request.findingId), { ...payload, digest: digest(payload) });\n return { status: \"recorded\", recordPath: recordPath(request.findingId), event,\n hint: \"Review and commit this assessment record through the normal project workflow, then verify the original repair baseline. Relevant changes reopen the assessment; deferral remains outstanding.\" };\n });\n}\n","import { profilePhase } from \"../utils/profile.js\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getChangesWithStatus } from \"../drift/drift.js\";\nimport type { FileChange } from \"../drift/drift.js\";\nimport { getCurrentGitHash } from \"../snapshot/snapshot.js\";\nimport { discoverDocs } from \"./docs.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport type { AuditReport, CheckName } from \"./types.js\";\nimport { CHECKS } from \"./checks/index.js\";\nimport { assessAdvisory } from \"./advisory-review.js\";\nimport type { CheckContext, CheckResult } from \"./checks/index.js\";\n\nexport interface AuditOptions {\n /** Subset of checks to run; defaults to all. */\n checks?: CheckName[];\n /** Internal execution boundary used by the automation dependency cache. */\n runCheck?: (name: CheckName, context: CheckContext) => Promise<CheckResult>;\n}\n\n/**\n * Audit discovered instruction files and READMEs\n * against repo reality. Fully deterministic — git, filesystem, and lexical\n * extraction only; no LLM, no network. Returns null when no context file\n * exists.\n */\nexport async function computeAudit(\n rootDir: string,\n options: AuditOptions = {}\n): Promise<AuditReport | null> {\n return profilePhase(\"audit.current\", () => auditCurrent(rootDir, options));\n}\n\nasync function auditCurrent(rootDir: string, options: AuditOptions): Promise<AuditReport | null> {\n const resolvedRoot = path.resolve(rootDir);\n const [docs, headHash] = await Promise.all([discoverDocs(resolvedRoot), getCurrentGitHash(resolvedRoot)]);\n if (docs.length === 0) return null;\n\n const report: AuditReport = {\n version: 1,\n root: resolvedRoot,\n gitAvailable: headHash !== \"unknown\",\n headHash,\n checksRun: [],\n docs: docs.map((d) => ({\n path: d.path,\n scope: d.scope,\n kind: d.kind,\n lastCommit: d.lastCommit,\n dirty: d.dirty,\n lineCount: d.lineCount,\n })),\n decisionsChecked: false,\n issues: [],\n advisories: [],\n suppressedAdvisories: [],\n skippedChecks: [],\n clean: true,\n };\n\n // Without git the provability gates cannot run — the caller treats this\n // as an error rather than silently degrading precision.\n if (!report.gitAvailable) return report;\n\n const changesSinceDoc = new Map<string, FileChange[] | null>();\n const changesByCommit = new Map<string, FileChange[] | null>();\n for (const doc of docs) {\n const hash = doc.lastCommit?.hash;\n if (hash && !changesByCommit.has(hash)) changesByCommit.set(hash, await getChangesWithStatus(resolvedRoot, hash));\n changesSinceDoc.set(doc.path, hash ? changesByCommit.get(hash)! : null);\n }\n\n let decisionsPresent = false;\n try {\n await fs.access(path.join(resolvedRoot, \".mason\", \"decisions\"));\n decisionsPresent = true;\n } catch {\n // No decision store — the check stays dark (zero-setup path).\n }\n report.decisionsChecked = decisionsPresent;\n\n const ctx: CheckContext = {\n root: resolvedRoot,\n docs,\n headHash,\n changesSinceDoc,\n decisionsPresent,\n };\n\n const selected = options.checks ?? ALL_CHECKS;\n for (const name of ALL_CHECKS) {\n if (!selected.includes(name)) continue;\n const { issues, advisories, suppressedAdvisories, skipped } = await (options.runCheck\n ? options.runCheck(name, ctx) : CHECKS[name](ctx));\n report.checksRun!.push(name);\n report.issues.push(...issues);\n report.advisories.push(...advisories);\n report.suppressedAdvisories!.push(...(suppressedAdvisories ?? []));\n report.skippedChecks.push(...skipped);\n }\n\n report.clean = report.issues.length === 0;\n const reviews = (await Promise.all([...report.advisories, ...report.suppressedAdvisories!]\n .map(finding => assessAdvisory(resolvedRoot, finding, headHash)))).filter(review => review !== null);\n if (reviews.length) report.advisoryReviews = reviews;\n return report;\n}\n","import path from \"node:path\";\nimport { computeAudit } from \"./audit.js\";\nimport { ALL_CHECKS } from \"./types.js\";\nimport { prepareRepair, verifyRepair, formatRepairSummary, repairExitCode } from \"./repair.js\";\nimport type { AuditIssue, AuditReport, CheckName } from \"./types.js\";\nimport { findingId } from \"./findings.js\";\nimport { runAdvisoryCli } from \"./advisory-cli.js\";\n\nexport const USAGE = `Usage: mason-audit [--dir <path>] [--json | --fix-prompt] [--checks <list>]\n\nAudits README.md and agent instruction files at any depth, preserving filename case\nagainst repo reality: referenced paths that no longer exist, undocumented\nmodules, stale counts, dead npm scripts, and manifests newer than the doc.\nDeterministic: no LLM call, no network – safe for CI. Works on any repo with\na context file; no Mason setup required.\n\nOptions:\n --dir <path> Project root to audit (default: current directory)\n --json Print the full audit report as JSON (additive-only schema)\n --fix-prompt When issues exist, print a work order for ANY coding agent\n (Claude, Codex, Gemini, ...) – pipe it to your agent CLI to\n repair the findings. Includes advisories that require review.\n --prepare-repair Save the original audit under .mason/reports/repairs/ before edits\n --verify-repair <path>\n Compare against that saved baseline, using its original checks\n --checks <list> Comma-separated subset of checks to run (default: all):\n ${ALL_CHECKS.join(\", \")}\n --help Show this help\n\nUse mason audit review --help to prepare and record an authorized advisory assessment.\n\nExit codes:\n 0 no issues (advisories may still be present)\n 1 provable issues found\n 2 error (no context file, not a git repository, bad arguments)\n\nWith --verify-repair: 0 verified by the original checks; 1 issues remain;\n2 incomplete (unverified findings, skipped checks, or advisories needing review).\nPreparation writes only a baseline; verification and ordinary audits are read-only.`;\n\nexport interface AuditCliIo {\n out: (line: string) => void;\n err: (line: string) => void;\n}\n\ninterface ParsedArgs {\n dir: string;\n json: boolean;\n fixPrompt: boolean;\n help: boolean;\n checks: CheckName[] | undefined;\n prepareRepair: boolean;\n baseline?: string;\n}\n\nfunction parseArgs(argv: string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n dir: process.cwd(),\n json: false,\n fixPrompt: false,\n help: false,\n checks: undefined,\n prepareRepair: false,\n };\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--json\") {\n parsed.json = true;\n } else if (arg === \"--fix-prompt\") {\n parsed.fixPrompt = true;\n } else if (arg === \"--prepare-repair\") {\n parsed.prepareRepair = true;\n } else if (arg === \"--verify-repair\") {\n const value = argv[++i];\n if (!value || value.startsWith(\"--\")) throw new Error(\"--verify-repair requires a baseline path\");\n parsed.baseline = value;\n } else if (arg === \"--help\" || arg === \"-h\") {\n parsed.help = true;\n } else if (arg === \"--dir\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--dir requires a path argument\");\n parsed.dir = value;\n } else if (arg === \"--checks\") {\n const value = argv[++i];\n if (!value) throw new Error(\"--checks requires a comma-separated list\");\n const names = value.split(\",\").map((n) => n.trim()).filter(Boolean);\n if (!names.length) throw new Error(\"--checks requires at least one check\");\n for (const name of names) {\n if (!ALL_CHECKS.includes(name as CheckName)) {\n throw new Error(\n `Unknown check: ${name} (valid: ${ALL_CHECKS.join(\", \")})`\n );\n }\n }\n parsed.checks = names as CheckName[];\n } else if (!arg.startsWith(\"-\") && parsed.dir === process.cwd()) {\n parsed.dir = arg;\n } else {\n throw new Error(`Unknown argument: ${arg}`);\n }\n }\n return parsed;\n}\n\nfunction issueLine(issue: AuditIssue): string {\n const where =\n issue.anchor.line !== null ? `line ${issue.anchor.line}` : \"doc-level\";\n const likely = issue.confidence === \"likely\" ? \" (likely)\" : \"\";\n return ` [${issue.type}]${likely} ${where}: ${issue.message}`;\n}\n\nexport function formatAuditSummary(report: AuditReport): string {\n const lines: string[] = [];\n const reviewed = new Set(report.advisoryReviews?.filter(review => review.status === \"current\").map(review => review.id));\n const open = report.advisories.filter(finding => !reviewed.has(findingId(finding)));\n const suppressed = (report.suppressedAdvisories ?? []).filter(finding => !reviewed.has(findingId(finding)));\n const reviewCount = open.length + suppressed.length;\n\n for (const doc of report.docs) {\n const docIssues = report.issues.filter((i) => i.anchor.doc === doc.path);\n const committed = doc.lastCommit\n ? `last committed ${doc.lastCommit.date.slice(0, 10)}, ${doc.lastCommit.hash.slice(0, 7)}`\n : \"untracked\";\n if (docIssues.length === 0) {\n lines.push(`${doc.path} – clean (${committed})`);\n continue;\n }\n lines.push(\n `${doc.path} – ${docIssues.length} issue${docIssues.length === 1 ? \"\" : \"s\"} (${committed})`\n );\n for (const issue of docIssues) lines.push(issueLine(issue));\n }\n\n // Issues anchored outside the docs list (defensive; new-module anchors to\n // the primary doc, so this should stay empty).\n const docPaths = new Set(report.docs.map((d) => d.path));\n for (const issue of report.issues) {\n if (!docPaths.has(issue.anchor.doc)) lines.push(issueLine(issue));\n }\n\n if (open.length > 0) {\n lines.push(\"Advisories (do not affect the exit code):\");\n for (const advisory of open) {\n lines.push(` [${advisory.type}] ${advisory.anchor.doc}: ${advisory.message}`);\n }\n }\n if (report.skippedChecks.length > 0) {\n for (const skip of report.skippedChecks) {\n lines.push(` [skipped] ${skip.check}: ${skip.reason}`);\n }\n }\n\n if (reviewed.size) lines.push(`${reviewed.size} advisories have recorded assessments covering current evidence (see --json).`);\n for (const review of report.advisoryReviews ?? []) if (review.status !== \"current\") lines.push(` [${review.status}] ${review.reason}`);\n for (const advisory of suppressed) {\n lines.push(` [suppressed; unresolved] ${advisory.type} ${advisory.anchor.doc}: ${advisory.message}`);\n }\n\n lines.push(\n report.clean\n ? reviewCount || report.skippedChecks.length\n ? `No audit issues detected (${report.docs.length} docs audited); ${reviewCount} advisories remain for review, ${report.skippedChecks.length} checks skipped.`\n : `Context files are clean (${report.docs.length} doc${report.docs.length === 1 ? \"\" : \"s\"} audited).`\n : `${report.issues.length} issue${report.issues.length === 1 ? \"\" : \"s\"} across ${report.docs.length} doc${report.docs.length === 1 ? \"\" : \"s\"}.`\n );\n return lines.join(\"\\n\");\n}\n\n/**\n * Provider-neutral work order: any coding agent can execute it. The evidence\n * is deterministic; the agent's job is judgment scoped to exactly these\n * claims – never a free-form doc rewrite.\n */\nexport function formatFixPrompt(report: AuditReport, baselinePath?: string): string {\n const flaggedDocs = [...new Set(report.issues.map((i) => i.anchor.doc))];\n const lines: string[] = [];\n lines.push(\n \"Review the flagged context claims using the evidence below. Make minimal repairs within the user's authorized scope. A setup-only or audit-only request does not authorize rewriting existing documentation.\"\n );\n lines.push(\"\");\n lines.push(\"RULES:\");\n lines.push(baselinePath\n ? `- Preserve the original repair baseline: ${JSON.stringify(baselinePath)}. Do not replace it after editing.`\n : \"- Before the first edit, call mason_repair with action: prepare, or run mason-audit --prepare-repair --json with the same --dir and --checks. Keep the returned baselinePath through verification.\");\n lines.push(\n `- Edit ONLY these files: ${flaggedDocs.join(\", \") || \"none (advisory review only)\"}. Bring the docs into agreement with verified source evidence; do not change source code or configs to silence findings.`\n );\n lines.push(\n \"- Keep diffs minimal: change the smallest span that makes each claim true.\"\n );\n lines.push(\n \"- Never invent content. Every replacement must be grounded in the evidence below or in files you read from this repository.\"\n );\n lines.push(\"- Inspect likely findings before editing: heuristic evidence may describe an intentional omission or an example.\");\n lines.push(\n \"- deleted-reference: if evidence shows renamedTo, update the path; otherwise remove the reference, or rephrase to past tense if the sentence is about history. Deleted paths inside directory trees: delete the tree line.\"\n );\n lines.push(\n \"- stale-count: replace the number with the actual count from the evidence.\"\n );\n lines.push(\n \"- dead-command: replace with the correct script from availableScripts if an obvious rename exists; otherwise remove the command mention.\"\n );\n lines.push(\n \"- new-module: review whether the directory needs documenting; an omission alone does not establish a defect. Preserve scope and describe only what you verified.\"\n );\n lines.push(\n \"- Historical ADVISORIES require a separate authorized assessment using review_advisory with the baselinePath and findingId from verification. Prepare and inspect evidence first; record addressed, inapplicable or deferred with the actual reviewer, note and reviewToken. Decision findings use review_decision. Candidates marked resolution: recheck can be rerun to see whether the condition remains; this does not establish semantic approval. Report what remains unknown.\"\n );\n lines.push(\"\");\n lines.push(\"AUDIT REPORT (current context files and repository evidence, including local edits):\");\n lines.push(\n JSON.stringify(\n { root: report.root, checks: report.checksRun, issues: report.issues, advisories: report.advisories,\n suppressedAdvisories: report.suppressedAdvisories, skippedChecks: report.skippedChecks },\n null,\n 2\n )\n );\n lines.push(\"\");\n lines.push(\n \"After edits, call mason_repair with action: verify and the original baselinePath, or mason-audit --verify-repair <baselinePath> --dir <project>. Repeat against the same baseline after any final documentation commit. Summarize resolved, unresolved, review-required, unverified, and new findings with their evidence. Do not report a suppressed or unavailable check as fixed. This audit covers the listed documents and supported claims; application behavior and code examples need their own validation.\"\n );\n return lines.join(\"\\n\");\n}\n\nexport async function runAuditCli(\n argv: string[],\n io: AuditCliIo = {\n out: (line) => process.stdout.write(`${line}\\n`),\n err: (line) => process.stderr.write(`${line}\\n`),\n }\n): Promise<number> {\n if (argv[0] === \"review\") return runAdvisoryCli(argv.slice(1), io);\n let args: ParsedArgs;\n try {\n args = parseArgs(argv);\n if (args.json && args.fixPrompt) {\n throw new Error(\"--json and --fix-prompt are mutually exclusive\");\n }\n if (args.baseline && (args.prepareRepair || args.checks || args.fixPrompt)) {\n throw new Error(\"--verify-repair cannot be combined with --prepare-repair, --checks, or --fix-prompt; verification uses the original scope\");\n }\n } catch (error) {\n io.err(error instanceof Error ? error.message : String(error));\n io.err(USAGE);\n return 2;\n }\n\n if (args.help) {\n io.out(USAGE);\n return 0;\n }\n\n const rootDir = path.resolve(args.dir);\n if (args.baseline || args.prepareRepair) {\n try {\n if (args.baseline) {\n const verification = await verifyRepair(rootDir, args.baseline);\n io.out(args.json ? JSON.stringify(verification, null, 2) : formatRepairSummary(verification));\n return repairExitCode(verification);\n }\n const prepared = await prepareRepair(rootDir, args.checks);\n io.out(args.json ? JSON.stringify({ ...prepared, workOrder: formatFixPrompt(prepared.report, prepared.baselinePath) }, null, 2)\n : args.fixPrompt ? formatFixPrompt(prepared.report, prepared.baselinePath)\n : `Repair baseline: ${prepared.baselinePath}\\n${formatAuditSummary(prepared.report)}`);\n return prepared.report.clean ? 0 : 1;\n } catch (error) {\n io.err(error instanceof Error ? error.message : String(error));\n return 2;\n }\n }\n const report = await computeAudit(rootDir, { checks: args.checks });\n\n if (!report) {\n io.err(\n `No README.md or agent instruction files found in ${rootDir}.`\n );\n return 2;\n }\n\n if (!report.gitAvailable) {\n io.err(\n `Could not determine git HEAD in ${rootDir} – not a git repository, or git is unavailable.`\n );\n return 2;\n }\n\n if (args.fixPrompt) {\n io.out(\n report.clean && !report.advisories.length && !report.suppressedAdvisories?.length\n ? formatAuditSummary(report) : formatFixPrompt(report)\n );\n return report.clean ? 0 : 1;\n }\n\n if (args.json) {\n io.out(JSON.stringify(report, null, 2));\n } else {\n io.out(formatAuditSummary(report));\n }\n return report.clean ? 0 : 1;\n}\n","import path from \"node:path\";\nimport { stripVTControlCharacters } from \"node:util\";\nimport { reviewAdvisory, type AdvisoryReviewInput } from \"./advisory-review.js\";\n\nconst USAGE = `Usage: mason audit review --baseline <path> --finding <id> [options]\n\nPrepare an advisory assessment against retained evidence (read-only by default).\n --dir <path> Repository root (default: current directory)\n --baseline <path> Original repair baseline\n --finding <id> findingId from repair verification or automation\n --outcome <value> Record addressed, inapplicable, or deferred\n --reviewer <name> Actual authorized reviewer\n --note <reason> Assessment reason\n --token <token> reviewToken returned by preparation\n --json Full evidence and review history\n\nRecording requires prior preparation and committed relevant edits. Review records\nbelong in Git under .mason/reviews/advisories/. Deferral remains outstanding.\nDecision findings use review_decision; this command never approves decisions.\nExit 0: prepared/recorded; 2: unavailable, conflict, or decision review required.`;\n\nexport async function runAdvisoryCli(args: string[], io = { out: (text: string) => console.log(text), err: (text: string) => console.error(text) }): Promise<number> {\n if (args.includes(\"--help\") || args.includes(\"-h\")) { io.out(USAGE); return 0; }\n try {\n const flags: Record<string, string> = {}; let json = false;\n for (let i = 0; i < args.length; i++) {\n const flag = args[i];\n if (flag === \"--json\") { json = true; continue; }\n if (![\"--dir\", \"--baseline\", \"--finding\", \"--outcome\", \"--reviewer\", \"--note\", \"--token\"].includes(flag) || flags[flag]) throw new Error(\"Unexpected or repeated argument: \" + flag);\n const value = args[++i]; if (!value || value.startsWith(\"--\")) throw new Error(flag + \" requires a value.\");\n flags[flag] = value;\n }\n if (!flags[\"--outcome\"] && [\"--reviewer\", \"--note\", \"--token\"].some(key => flags[key])) throw new Error(\"Use --outcome to record an assessment.\");\n const input = { baselinePath: flags[\"--baseline\"], findingId: flags[\"--finding\"],\n action: flags[\"--outcome\"] ?? \"prepare\", reviewer: flags[\"--reviewer\"], note: flags[\"--note\"], reviewToken: flags[\"--token\"] } as AdvisoryReviewInput;\n const result = await reviewAdvisory(path.resolve(flags[\"--dir\"] ?? process.cwd()), input);\n if (json) io.out(JSON.stringify(result, null, 2));\n else {\n const lines = [`Advisory review: ${result.status}.`];\n if (\"finding\" in result && result.finding && result.evidence) lines.push(`[${result.finding.type}] ${result.finding.anchor.doc}: ${result.finding.message}`,\n `Finding: ${result.findingId}`, `Prepared against commit ${result.evidence.head.slice(0, 12)}.`,\n result.evidence.dirty ? \"Relevant files have uncommitted edits; commit them and prepare again before recording.\" : \"Relevant files are committed.\",\n `Review token: ${result.reviewToken}`, ...(result.diff ? [\"Scoped changes:\", result.diff] : []), ...(result.diffNote ? [result.diffNote] : []));\n if (\"event\" in result) lines.push(`${result.event.outcome} — ${result.event.reviewer}: ${result.event.note}`, `Record: ${result.recordPath}`);\n lines.push(result.hint);\n io.out(stripVTControlCharacters(lines.join(\"\\n\")));\n }\n return result.status === \"decision-review-required\" ? 2 : 0;\n } catch (error) { io.err(stripVTControlCharacters(error instanceof Error ? error.message : String(error))); return 2; }\n}\n","import { runAuditCli } from \"../src/audit/cli.js\";\n\nrunAuditCli(process.argv.slice(2)).then(\n (code) => { process.exitCode = code; },\n (err) => {\n process.stderr.write(`mason-audit error: ${err}\\n`);\n process.exitCode = 2;\n }\n);\n"],"mappings":"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","names":["path","fs","path","path","path","execFile","promisify","exec","fs","path","execFile","promisify","exec","path","text","execFile","promisify","exec","fs","path","execFile","promisify","fg","readdir","lstat","count","fs","path","execFile","promisify","fg","exec","fs","path","path","fg","fs","path","text","dir","count","path","path","execFile","promisify","exec","text","scopes","path","z","fs","path","z","path","init_drift","init_drift","createHash","z","fs","z","fs","path","randomUUID","z","count","fs","execFile","promisify","z","git","evidenceSchema","record","event","loadRepairBaseline","eventSchema","execute","commitSchema","init_drift","fs","path","path","path","text","USAGE","path"]}
|