@rungs/cli 0.1.0 → 0.1.2

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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli.ts", "../src/manifest.ts", "../src/glob.ts", "../src/detect.ts", "../src/add.ts", "../src/substitute.ts", "../src/render.ts", "../src/check.ts", "../src/engines.ts", "../src/engines2.ts", "../src/engines3.ts", "../src/lifecycle.ts"],
4
+ "sourcesContent": ["#!/usr/bin/env node\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join, resolve } from 'node:path';\nimport { auditModules, loadAllModules } from './manifest.ts';\nimport { detect, scanRepo } from './detect.ts';\nimport { addModule, adoptableGates, registerGates, resolveInstallOrder, writeInstallRecord } from './add.ts';\nimport { render, writeReport, type Harness } from './render.ts';\nimport { resolveParams } from './substitute.ts';\nimport { appendLedger, ledgerQuestions, loadRegistry, runGates } from './check.ts';\nimport { applyUpgrade, eject, planUpgrade, PROFILES, readRecord, setupGit } from './lifecycle.ts';\nimport type { DetectResult, Manifest } from './types.ts';\n\nconst HERE = dirname(fileURLToPath(import.meta.url));\nconst MODULES = join(HERE, '..', 'modules');\n\nconst c = {\n dim: (s: string) => `\\x1b[2m${s}\\x1b[0m`,\n bold: (s: string) => `\\x1b[1m${s}\\x1b[0m`,\n red: (s: string) => `\\x1b[31m${s}\\x1b[0m`,\n yellow: (s: string) => `\\x1b[33m${s}\\x1b[0m`,\n green: (s: string) => `\\x1b[32m${s}\\x1b[0m`,\n cyan: (s: string) => `\\x1b[36m${s}\\x1b[0m`,\n};\n\nconst STATE_LABEL: Record<DetectResult['state'], string> = {\n absent: c.dim('absent'),\n 'ours-current': c.green('ours'),\n 'ours-diverged': c.yellow('diverged'),\n theirs: c.cyan('theirs'),\n paradigm: c.yellow('paradigm'),\n unknown: c.red('unknown'),\n};\n\nfunction cmdModules(showParams = false) {\n const mods = loadAllModules(MODULES);\n console.log(c.bold(`\\n${mods.length} modules\\n`));\n for (const m of mods) {\n const deps = m.requires.length ? c.dim(` \u2190 ${m.requires.join(', ')}`) : '';\n console.log(` ${c.bold(m.name.padEnd(14))} rung ${m.rung}${deps}`);\n console.log(` ${' '.repeat(14)} ${c.dim(m.summary)}`);\n // Rendered from the manifest at the moment it is asked for, never written down. A committed\n // parameter table would be correct the day it was generated and silently wrong the day a\n // default moved \u2014 which is the failure this flag exists to answer (WI-006).\n if (!showParams) continue;\n for (const [name, spec] of Object.entries(m.params)) {\n const shown = spec.default === undefined ? c.dim('(none)') : JSON.stringify(spec.default);\n const notes = [\n spec.allowed ? `one of ${spec.allowed.map(String).join(' \u00B7 ')}` : '',\n // Behavioural parameters never appear as {{token}}, so a reader hunting for one in a\n // template would conclude the parameter was dead. Say so where they meet it.\n spec.consumed_by ? `behavioural \u2014 changes what \\`${spec.consumed_by}\\` does, not a template` : '',\n spec.required ? 'required' : '',\n ].filter(Boolean);\n console.log(` ${' '.repeat(14)} ${c.cyan(`${m.name}.${name}`.padEnd(30))} ${c.dim('=')} ${shown}`);\n if (spec.description) console.log(` ${' '.repeat(16)} ${c.dim(firstSentence(spec.description))}`);\n for (const n of notes) console.log(` ${' '.repeat(16)} ${c.dim(n)}`);\n }\n if (Object.keys(m.params).length) console.log();\n }\n if (showParams) {\n console.log(c.dim(' Set one with `--set module.param=value` on `add` or `init`; either spelling works.'));\n console.log(c.dim(' Resolved values are recorded in `.ai/rungs.toml`. See docs/design/parameters.md.\\n'));\n }\n\n const issues = auditModules(mods);\n console.log();\n if (issues.length === 0) {\n console.log(c.green(' audit clean') + c.dim(' \u2014 every parameter accounted for, every gate has a table and a why'));\n } else {\n console.log(c.red(` ${issues.length} issue(s):`));\n for (const i of issues) console.log(` ${c.yellow(i.module)} ${c.dim(i.kind)} \u2014 ${i.detail}`);\n }\n console.log();\n return issues.length === 0 ? 0 : 1;\n}\n\nfunction cmdDoctor(target: string) {\n const root = resolve(target);\n const mods = loadAllModules(MODULES);\n console.log(c.bold(`\\nrungs doctor \u2014 ${root}\\n`));\n\n const files = scanRepo(root);\n const record = readRecord(root);\n console.log(\n c.dim(` scanned ${files.length} files`) +\n (record ? c.dim(` \u00B7 installed ${Object.keys(record.modules).length} module(s)`) : c.dim(' \u00B7 not a rungs repo')) +\n '\\n',\n );\n\n const params = resolveParams(mods, Object.fromEntries(\n Object.entries(record?.modules ?? {}).flatMap(([n, e]) => (e.params ? [[n, e.params]] : [])),\n ), root);\n const skillsDir = record?.harnesses.includes('claude') === false ? '.agents/skills' : '.claude/skills';\n const results = mods.map((m) => {\n const installed = record?.modules[m.name];\n return detect(m, root, files, installed ? { ...installed, skillsDir, params_all: params } : undefined);\n });\n const byState = (s: DetectResult['state']) => results.filter((r) => r.state === s);\n\n for (const r of results) {\n const mod = mods.find((m) => m.name === r.module)!;\n const line = ` ${r.module.padEnd(14)} ${STATE_LABEL[r.state]}`;\n if (r.state === 'absent') {\n console.log(c.dim(line));\n continue;\n }\n console.log(line);\n if (r.ours) {\n const parts = [`v${r.ours.version}`, `${r.ours.current.length} current`];\n if (r.ours.stale.length) parts.push(c.cyan(`${r.ours.stale.length} stale`));\n if (r.ours.missing.length) parts.push(c.yellow(`${r.ours.missing.length} missing`));\n if (r.ours.kept.length) parts.push(c.dim(`${r.ours.kept.length} kept (yours from the start)`));\n console.log(c.dim(` ${parts.join(' \u00B7 ')}`));\n for (const f of r.ours.diverged.slice(0, 3)) {\n console.log(` ${c.yellow('diverged')} ${f} ${c.dim('\u2014 yours, never overwritten')}`);\n }\n if (r.ours.diverged.length > 3) console.log(c.dim(` \u2026and ${r.ours.diverged.length - 3} more`));\n if (r.ours.stale.length || r.ours.missing.length) {\n console.log(c.dim(' run `rungs upgrade --apply`'));\n }\n continue;\n }\n for (const p of r.matchedPaths.slice(0, 2)) {\n console.log(c.dim(` ${p.count}\u00D7 ${p.pattern} e.g. ${p.sample[0]}`));\n }\n if (r.matchedMarkers.length) console.log(c.dim(` markers: ${r.matchedMarkers.join(', ')}`));\n for (const prop of r.proposals) {\n console.log(` ${c.cyan('proposes')} ${prop.param} = ${c.bold(prop.value)} ${c.dim(`(${prop.evidence})`)}`);\n }\n for (const a of r.adoptable) {\n console.log(` ${c.cyan('adoptable')} ${a.count} as ${a.kind} ${c.dim(`e.g. ${a.sample[0]}`)}`);\n }\n if (r.paradigm) {\n console.log(` ${c.yellow('different paradigm')}: ${r.paradigm.id} ${c.dim(`(${r.paradigm.matched[0]})`)}`);\n if (r.paradigm.note) console.log(c.dim(` ${firstSentence(r.paradigm.note)}`));\n }\n if (mod.threshold?.confirm) {\n console.log(c.yellow(` threshold: ${mod.threshold.minimum}+ ${mod.threshold.metric} \u2014 add requires confirmation`));\n }\n }\n\n const ours = byState('ours-current').length + byState('ours-diverged').length;\n console.log(\n `\\n ${ours ? `${ours} installed (${byState('ours-diverged').length} diverged) \u00B7 ` : ''}` +\n `${byState('theirs').length} present \u00B7 ${byState('paradigm').length} different paradigm \u00B7 ` +\n `${byState('absent').length} absent\\n`,\n );\n\n // ADR-0005: state what this does not cover, every time. A green read is not\n // a verified one, and a low count may mean a narrow signature rather than a\n // clean repo.\n console.log(c.dim(' This reports presence, never quality. It cannot tell whether an adopted'));\n console.log(c.dim(' system is good, complete, or working \u2014 only that files are where a'));\n console.log(c.dim(\" module's files would be. Signatures under-detect on purpose.\\n\"));\n\n // `doctor` is the command the README makes the entry point, and it used to stop on the sentence\n // above \u2014 fifteen `absent` lines and nothing to do next. The recommendation is deliberately a\n // **single** command, and never the maximal one: the brief names selling rung 5 to a rung-1 repo\n // as the most likely way this tool does harm, so a repo with nothing is pointed at `tracked`\n // rather than at the fifteen things it could install (WI-005).\n const theirs = byState('theirs');\n console.log(c.bold(' Next\\n'));\n if (ours) {\n const behind = results.some((r) => r.ours?.stale.length || r.ours?.missing.length);\n console.log(\n behind\n ? ` ${c.cyan('rungs upgrade --apply')} ${c.dim('\u2014 bring the stale and missing files up to date')}`\n : ` ${c.cyan('rungs check')} ${c.dim('\u2014 run the gates this repo already registered')}`,\n );\n console.log(c.dim(` Add more with \\`rungs add <module>\\`; \\`rungs modules\\` lists the set.\\n`));\n } else if (theirs.length) {\n const names = theirs.map((r) => r.module).slice(0, 3).join(' ');\n console.log(` ${c.cyan(`rungs add ${names}`)} ${c.dim('\u2014 adopt what you already built, in place')}`);\n console.log(c.dim(' Nothing is overwritten. Files you already have are kept and reported as'));\n console.log(c.dim(' yours; only what is missing gets written.\\n'));\n } else {\n console.log(` ${c.cyan('rungs init . tracked')} ${c.dim('\u2014 instructions \u00B7 gates \u00B7 backlog \u00B7 findings \u00B7 adr \u00B7 session')}`);\n console.log(c.dim(' `tracked` is the rung for more than one thing in flight. `minimal` is just'));\n console.log(c.dim(' the entry document; higher profiles cost more than they return until the'));\n console.log(c.dim(' problem they answer actually exists. `rungs modules` lists all fifteen.\\n'));\n }\n return 0;\n}\n\nfunction firstSentence(s: string): string {\n return s.trim().replace(/\\s+/g, ' ').split(/(?<=\\.)\\s/)[0];\n}\n\nfunction cmdAdd(names: string[], root: string, dryRun: boolean, harnesses: Harness[], stamp: string) {\n const mods = loadAllModules(MODULES);\n const { order, missing } = resolveInstallOrder(names, mods);\n if (missing.length) {\n console.log(c.red(`\\n unknown module(s): ${missing.join(', ')}\\n`));\n return 1;\n }\n const pulled = order.filter((m) => !names.includes(m.name));\n\n // `--set module.param=value`. Without it the first real install into a repo\n // that already had a backlog would have created a second one beside it \u2014\n // `docs/backlog/` next to `docs/.ai/backlog/` \u2014 which is the \"two places to\n // look\" failure this whole tool is against, arriving through the installer.\n //\n // Values arrive already split from their flag, in either spelling. A malformed\n // key is refused rather than skipped: `--set root=x` used to be dropped in\n // silence, so the install proceeded with the default and looked successful.\n const overrides: Record<string, Record<string, unknown>> = {};\n for (const raw of flagValues['--set'] ?? []) {\n const [key, ...rhs] = raw.split('=');\n const [modName, param] = key.split('.');\n if (!modName || !param || !rhs.length) {\n console.log(c.red(`\\n --set expects module.param=value, got: ${raw}\\n`));\n return 1;\n }\n (overrides[modName] ??= {})[param] = rhs.join('=');\n }\n const params = resolveParams(mods, overrides, root);\n for (const [m, vals] of Object.entries(overrides)) {\n for (const [k, v] of Object.entries(vals)) console.log(c.dim(` set ${m}.${k} = ${v}`));\n }\n const skillsDir = harnesses.includes('claude') ? '.claude/skills' : '.agents/skills';\n\n console.log(c.bold(`\\nrungs add ${names.join(' ')} \u2192 ${root}${dryRun ? c.yellow(' (dry run)') : ''}\\n`));\n if (pulled.length) console.log(c.dim(` pulled in by dependency: ${pulled.map((m) => m.name).join(', ')}\\n`));\n\n const installed: Manifest[] = [];\n const wrote = new Map<string, Set<string>>();\n for (const mod of order) {\n if (mod.threshold?.confirm && !dryRun && !flags.has('--confirm-threshold')) {\n console.log(\n c.yellow(` ${mod.name}: requires ${mod.threshold.minimum}+ ${mod.threshold.metric}.`) +\n c.dim(' Skipped \u2014 pass --confirm-threshold to install it.\\n'),\n );\n continue;\n }\n const actions = addModule(mod, root, params, { dryRun, skillsDir });\n installed.push(mod);\n wrote.set(mod.name, new Set(actions.filter((a) => a.disposition !== 'skip-exists' && a.disposition !== 'merge' && a.disposition !== 'gate').map((a) => a.target)));\n const counts = new Map<string, number>();\n for (const a of actions) counts.set(a.disposition, (counts.get(a.disposition) ?? 0) + 1);\n console.log(` ${c.bold(mod.name.padEnd(14))} ${[...counts].map(([k, v]) => `${v} ${k}`).join(' \u00B7 ')}`);\n for (const a of actions.filter((x) => x.disposition === 'skip-exists')) {\n console.log(c.dim(` kept ${a.target}`));\n }\n }\n\n // Detect what the repo already has and register it alongside (ADR-0004).\n const repoFiles = scanRepo(root);\n const adopted = installed.flatMap((m) =>\n (m.detect.adopt_as ?? [])\n .filter((a) => a.kind === 'command')\n .flatMap((a) => adoptableGates(repoFiles, a.paths ?? [], root)),\n );\n if (adopted.length) {\n console.log(\n '\\n ' + c.cyan(`adopting ${adopted.length} existing validator(s)`) +\n ' as command gates' + c.dim(' \u2014 their scripts are untouched'),\n );\n for (const a of adopted.slice(0, 3)) console.log(c.dim(` ${a.command}`));\n if (adopted.length > 3) console.log(c.dim(` \u2026and ${adopted.length - 3} more`));\n }\n\n // Phase two: the registry's owner has created it by now.\n const gateActions = registerGates(installed, root, dryRun, adopted);\n if (gateActions.length) {\n console.log(c.dim(`\\n registered ${gateActions.reduce((n, a) => n + Number(a.note!.split(': ')[1].split(' ')[0]), 0)} gates from ${gateActions.length} module(s)`));\n }\n\n if (!dryRun) {\n writeInstallRecord(root, order, params, harnesses, stamp, skillsDir, wrote);\n const entries = render(root, harnesses);\n writeReport(root, entries, harnesses, stamp);\n console.log(\n `\\n rendered ${entries.filter((e) => e.target).length} file(s) \u00B7 ` +\n `${entries.filter((e) => e.degraded).length} degraded ` +\n c.dim('\u2192 .ai/render-report.md'),\n );\n }\n console.log();\n return 0;\n}\n\nfunction cmdRender(root: string, harnesses: Harness[], stamp: string) {\n const entries = render(root, harnesses);\n writeReport(root, entries, harnesses, stamp);\n console.log(c.bold(`\\nrungs render \u2014 ${root}\\n`));\n for (const e of entries) {\n const lost = e.degraded ?? (e.dropped?.length ? c.dim(` (dropped ${e.dropped.join(', ')})`) : '');\n console.log(` ${e.rule.padEnd(24)} ${e.harness.padEnd(10)} ${e.target ?? c.yellow('not emitted')}${lost}`);\n }\n console.log(c.dim(`\\n ${entries.length} rendering(s) \u2192 .ai/render-report.md\\n`));\n // A bare `0 rendering(s)` reads as a completed edit. It is the answer a user gets after editing a\n // parameter in `.ai/rungs.toml` and running this \u2014 the thing the record's header used to tell\n // them to do \u2014 so the zero case has to say what it did not do, not just how much of it (WI-003).\n if (entries.length === 0) {\n console.log(c.yellow(' Nothing to render.') + c.dim(' This command re-emits path-scoped rules from `.ai/rules/`.'));\n console.log(c.dim(' It does not re-substitute parameters \u2014 a changed value in `.ai/rungs.toml`'));\n console.log(c.dim(' does not rewrite a file that already exists.\\n'));\n }\n return 0;\n}\n\nfunction cmdCheck(root: string, tier: string | undefined, stamp: string) {\n const runs = runGates(root, tier);\n if (!runs.length) {\n console.log(c.yellow('\\n no gates registered \u2014 is this a rungs repo?\\n'));\n return 1;\n }\n appendLedger(root, runs, stamp);\n\n console.log(c.bold(`\\nrungs check \u2014 ${root}${tier ? ` (${tier} tier)` : ''}\\n`));\n const mark = { pass: c.green('pass'), fail: c.red('FAIL'), unimplemented: c.yellow('unimpl'), error: c.red('error') };\n for (const r of runs) {\n console.log(\n ` ${mark[r.status]} ${r.id.padEnd(34)} ${c.dim(`${r.ms}ms`)}` +\n (r.examined ? c.dim(` ${r.examined} examined`) : ''),\n );\n for (const f of r.findings.slice(0, 4)) {\n console.log(` ${c.dim(f.file ? `${f.file}: ` : '')}${f.message}`);\n }\n if (r.findings.length > 4) console.log(c.dim(` \u2026and ${r.findings.length - 4} more`));\n }\n\n const n = (s: string) => runs.filter((r) => r.status === s).length;\n console.log(\n `\\n ${c.green(`${n('pass')} pass`)} \u00B7 ${c.red(`${n('fail')} fail`)} \u00B7 ` +\n `${c.yellow(`${n('unimplemented')} unimplemented`)} \u00B7 ${n('error')} error` +\n c.dim(` (${runs.reduce((t, r) => t + r.ms, 0)}ms total)`),\n );\n\n if (n('unimplemented')) {\n console.log(\n c.yellow('\\n Unimplemented gates are not passes.') +\n c.dim(' A registry reporting green because most of its\\n gates do nothing is the worst failure this tool could have, so they block.'),\n );\n }\n\n const { gates } = loadRegistry(root);\n const q = ledgerQuestions(root, gates);\n if (q.neverFired.length || q.alwaysFires.length) {\n console.log(c.bold(`\\n Ledger questions ${c.dim(`(${q.runs} recorded runs)`)}`));\n for (const g of q.neverFired.slice(0, 3)) {\n console.log(` ${c.cyan(g.id)} has never fired. ${c.dim(firstSentence(g.why ?? ''))}`);\n console.log(c.dim(' Is that still a risk here, or is the gate scoped too narrowly?'));\n }\n for (const g of q.alwaysFires.slice(0, 3)) {\n console.log(` ${c.cyan(g.id)} fails ${g.rate}. ${c.dim('Red by default is a gate people learn to bypass.')}`);\n }\n console.log(\n c.dim('\\n These are questions, not verdicts. The ledger records whether a gate ran'),\n );\n console.log(c.dim(' and whether it fired \u2014 never whether it is valuable. Gates invoked'));\n console.log(c.dim(' directly, and CI runs, are not counted.'));\n }\n console.log();\n return n('fail') + n('unimplemented') + n('error') > 0 ? 1 : 0;\n}\n\nfunction cmdInit(root: string, profile: string, dryRun: boolean, harnesses: Harness[], stamp: string) {\n if (readRecord(root)) {\n console.log(\n c.yellow('\\n this repo is already initialised.') +\n c.dim(' Use `rungs add <module>` to install more, or `rungs upgrade`.\\n'),\n );\n return 1;\n }\n const names = PROFILES[profile];\n if (!names) {\n console.log(c.red(`\\n unknown profile '${profile}'.`) + c.dim(` Known: ${Object.keys(PROFILES).join(', ')}\\n`));\n return 1;\n }\n console.log(c.dim(`\\n profile '${profile}' \u2014 ${names.length} modules`));\n return cmdAdd(names, root, dryRun, harnesses, stamp);\n}\n\nfunction cmdUpgrade(root: string, apply: boolean) {\n const record = readRecord(root);\n if (!record) {\n console.log(c.yellow('\\n not a rungs repo \u2014 nothing to upgrade.\\n'));\n return 1;\n }\n const mods = loadAllModules(MODULES);\n const plan = planUpgrade(root, mods, record);\n console.log(c.bold(`\\nrungs upgrade \u2014 ${root}${apply ? '' : c.yellow(' (preview)')}\\n`));\n\n let stale = 0;\n let diverged = 0;\n for (const item of plan) {\n const counts = item.files.reduce<Record<string, number>>((a, f) => ({ ...a, [f.state]: (a[f.state] ?? 0) + 1 }), {});\n stale += (counts.stale ?? 0) + (counts.missing ?? 0);\n diverged += counts.diverged ?? 0;\n const moved = item.from === item.to ? c.dim(item.to) : `${item.from} \u2192 ${c.bold(item.to)}`;\n console.log(` ${item.module.padEnd(14)} ${moved} ${c.dim(Object.entries(counts).map(([k, v]) => `${v} ${k}`).join(' \u00B7 '))}`);\n for (const f of item.files.filter((x) => x.state === 'diverged')) {\n console.log(` ${c.yellow('diverged')} ${f.rel} ${c.dim('\u2014 yours, left alone')}`);\n }\n }\n\n if (apply && stale) {\n const written = applyUpgrade(root, mods, record, plan);\n console.log(c.green(`\\n updated ${written} file(s)`));\n }\n console.log(\n `\\n ${stale} to update \u00B7 ${diverged} diverged\\n` +\n c.dim(' Divergence is a decision, not an error: a file you edited is never overwritten.\\n') +\n (apply ? '' : c.dim(' Run with --apply to write.\\n')),\n );\n return 0;\n}\n\nfunction cmdEject(root: string, dryRun: boolean) {\n if (!readRecord(root)) {\n console.log(c.yellow('\\n not a rungs repo \u2014 nothing to eject.\\n'));\n return 1;\n }\n const result = eject(root, loadAllModules(MODULES), dryRun);\n console.log(c.bold(`\\nrungs eject \u2014 ${root}${dryRun ? c.yellow(' (dry run)') : ''}\\n`));\n for (const a of result.actions.slice(0, 6)) console.log(c.dim(` ${a}`));\n if (result.actions.length > 6) console.log(c.dim(` \u2026and ${result.actions.length - 6} more`));\n console.log(\n `\\n ${result.gates} declared gate(s) rewritten as commands.` +\n c.dim('\\n This repo no longer needs rungs installed to run its checks.\\n') +\n c.dim(' Engine fixes stop arriving with a version bump \u2014 these files are yours now.\\n'),\n );\n return 0;\n}\n\n/**\n * Flags that carry a value, and therefore consume the token after them unless it is attached with\n * `=`. Everything else is a bare switch.\n *\n * This exists because the split below used to be two filters \u2014 `startsWith('--')` into flags,\n * everything else into positionals \u2014 which has no concept of a value. `--set backlog.root=x` then\n * left `backlog.root=x` sitting in the positionals, `--into` took the last positional as its\n * target, and the user's actual path was reported back to them as an unknown module. Both\n * spellings now work, and the value never reaches `args` (WI-002).\n */\nconst VALUE_FLAGS = new Set(['--set']);\n\n/**\n * The command surface, defined once and rendered into `--help`.\n *\n * It was a template literal listing eight of the nine commands \u2014 `setup git` was missing entirely \u2014\n * beside a README table listing all nine, which is two hand-kept inventories of one fact. They had\n * already drifted, in both directions: help omitted a real command, and three real flags appeared\n * in neither. Keep this table beside the switch it describes, and add a row when you add a `case`.\n *\n * The README's table is still hand-kept and still a second inventory. That is a known cost, not an\n * oversight \u2014 see WI-004.\n */\nconst COMMANDS: [usage: string, blurb: string][] = [\n ['init [path] [profile]', 'scaffold a repo \u2014 minimal \u00B7 tracked \u00B7 disciplined \u00B7 hardened \u00B7 fleet'],\n ['doctor [path]', 'detect what a repo already has, installed or not'],\n ['add <module\u2026> [--into p]', 'install modules, resolving dependencies and adopting what exists'],\n ['check [path] [tier]', 'run the registered gates and record the ledger'],\n ['render [path]', 're-emit path-scoped rules per harness'],\n ['upgrade [path]', 'move to newer module versions, never touching what you edited'],\n ['eject [path]', 'materialise the engines; stop depending on rungs'],\n ['setup git [path]', 'install the merge drivers .gitattributes names'],\n ['modules', 'list the module set and audit the manifests'],\n];\n\n/** Every flag the parser honours. A flag absent here is a flag nobody can find. */\nconst FLAGS: [flag: string, blurb: string][] = [\n ['--dry-run', 'report what would happen, write nothing'],\n ['--into <path>', 'add: install into this repo instead of the working directory'],\n ['--set m.param=value', 'add/init: override a module parameter. Repeatable'],\n ['--confirm-threshold', 'add: install a module whose rung is above this repo'],\n ['--apply', 'upgrade: write the changes, rather than preview them'],\n ['--fast, --full', 'check: pick the gate tier, as the positional also does'],\n ['--params', 'modules: show every module parameter, its default and its allowed values'],\n ['--copilot', 'also emit Copilot instruction files'],\n];\n\nfunction renderHelp(): string {\n const pad = Math.max(...COMMANDS.map(([u]) => u.length)) + 2;\n const fpad = Math.max(...FLAGS.map(([f]) => f.length)) + 2;\n return [\n ``,\n `${c.bold('rungs')} \u2014 installs and maintains a repository's agentic development system`,\n ``,\n ...COMMANDS.map(([u, b]) => ` ${c.bold(`rungs ${u.split(' ')[0]}`)}${u.slice(u.split(' ')[0].length).padEnd(pad - u.split(' ')[0].length)} ${c.dim(b)}`),\n ``,\n ...FLAGS.map(([f, b]) => ` ${c.dim(f.padEnd(fpad))} ${c.dim(b)}`),\n ``,\n ].join('\\n');\n}\n\nconst [, , cmd, ...rest] = process.argv;\n\nconst flags = new Set<string>();\nconst args: string[] = [];\nconst flagValues: Record<string, string[]> = {};\n/** A value-flag left without a value. Reported by the command, so `--help` still works. */\nlet missingValue: string | null = null;\n\nfor (let i = 0; i < rest.length; i++) {\n const token = rest[i];\n if (!token.startsWith('--')) {\n args.push(token);\n continue;\n }\n const eq = token.indexOf('=');\n const name = eq === -1 ? token : token.slice(0, eq);\n if (!VALUE_FLAGS.has(name)) {\n // The bare name, not the raw token, so `--copilot=yes` still answers `flags.has('--copilot')`.\n flags.add(name);\n continue;\n }\n // Attached form first; otherwise the next token, unless that is itself a flag \u2014 `--set --dry-run`\n // is a missing value, not a value of `--dry-run`.\n const next = rest[i + 1];\n const value = eq === -1 ? (next === undefined || next.startsWith('--') ? undefined : rest[++i]) : token.slice(eq + 1);\n if (value === undefined) missingValue = name;\n else (flagValues[name] ??= []).push(value);\n}\n\n/**\n * A positional shaped like `module.param=value` was meant to be an override and was not claimed by\n * `--set`. No path, module, profile or tier has that shape, so it is unambiguously a mistake \u2014\n * refuse it by name rather than letting a command interpret it as something else.\n */\nconst strayOverride = args.find((a) => /^[a-z][a-z0-9_-]*\\.[a-z][a-z0-9_]*=/.test(a));\n\n// Dates come from the caller, never from inside a render: a timestamp baked\n// into generated output makes every run a diff.\nconst STAMP = process.env.RUNGS_DATE ?? new Date().toISOString().slice(0, 10);\nconst HARNESSES: Harness[] = flags.has('--copilot')\n ? ['claude', 'copilot', 'agents-md']\n : (['claude', 'agents-md'] as Harness[]);\n\n// Both refusals run before dispatch, because either one means the argv the user typed is not the\n// argv any command would act on. Silently proceeding is what made the original failure so opaque.\nif (missingValue) {\n console.log(c.red(`\\n ${missingValue} expects a value \u2014 ${missingValue} module.param=value\\n`));\n process.exit(1);\n}\nif (strayOverride) {\n console.log(\n c.red(`\\n stray override: ${strayOverride}`) +\n c.dim(`\\n Nothing claimed it, so it would be read as a path or a module name.`) +\n c.dim(`\\n Did you mean: --set ${strayOverride}\\n`),\n );\n process.exit(1);\n}\n\nswitch (cmd) {\n case 'modules':\n process.exit(cmdModules(flags.has('--params')));\n case 'doctor':\n process.exit(cmdDoctor(args[0] ?? process.cwd()));\n case 'check': {\n const tier = args[1] ?? (flags.has('--full') ? 'full' : flags.has('--fast') ? 'fast' : undefined);\n process.exit(cmdCheck(resolve(args[0] ?? process.cwd()), tier, STAMP));\n }\n case 'init': {\n const profile = args[1] ?? 'tracked';\n process.exit(cmdInit(resolve(args[0] ?? process.cwd()), profile, flags.has('--dry-run'), HARNESSES, STAMP));\n }\n case 'upgrade':\n process.exit(cmdUpgrade(resolve(args[0] ?? process.cwd()), flags.has('--apply')));\n case 'eject':\n process.exit(cmdEject(resolve(args[0] ?? process.cwd()), flags.has('--dry-run')));\n case 'setup': {\n const r = setupGit(resolve(args[1] ?? process.cwd()), flags.has('--dry-run'));\n console.log(\n r.drivers.length\n ? `\\n installed ${r.drivers.length} merge driver(s): ${r.drivers.join(', ')}` +\n (r.rerere ? c.dim(' \u00B7 rerere on') : '') +\n c.dim('\\n Declared drivers were inert until now \u2014 a fresh clone needs this once.\\n')\n : c.dim('\\n no rungs merge drivers declared in .gitattributes\\n'),\n );\n process.exit(0);\n }\n case 'render':\n process.exit(cmdRender(resolve(args[0] ?? process.cwd()), HARNESSES, STAMP));\n case 'add': {\n const target = flags.has('--into') ? args[args.length - 1] : process.cwd();\n const names = flags.has('--into') ? args.slice(0, -1) : args;\n process.exit(cmdAdd(names, resolve(target), flags.has('--dry-run'), HARNESSES, STAMP));\n }\n default: {\n // Help is a success, and an unknown command is not. Both used to land here and exit on\n // `cmd ? 1 : 0`, which made `rungs --help` \u2014 a command that did exactly what was asked \u2014\n // report failure to anything checking the status (WI-004).\n const wantedHelp = cmd === undefined || cmd === 'help' || cmd === '--help' || cmd === '-h';\n if (!wantedHelp) console.log(c.red(`\\n unknown command: ${cmd}`));\n console.log(renderHelp());\n process.exit(wantedHelp ? 0 : 1);\n }\n}\n", "import { readdirSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { parse } from 'smol-toml';\nimport type { Manifest, ParamSpec } from './types.ts';\nimport { walk } from './glob.ts';\n\n/** Reads one module directory into a validated manifest. Throws on anything malformed. */\nexport function loadManifest(dir: string): Manifest {\n const raw = parse(readFileSync(join(dir, 'module.toml'), 'utf8')) as Record<string, any>;\n const m = raw.module ?? {};\n const name = m.name;\n if (!name) throw new Error(`${dir}: [module].name is required`);\n\n const manifest: Manifest = {\n name,\n version: m.version ?? '0.0.0',\n rung: m.rung ?? 0,\n summary: m.summary ?? '',\n requires: raw.requires?.modules ?? [],\n conflicts: raw.conflicts?.modules ?? [],\n params: (raw.params ?? {}) as Record<string, ParamSpec>,\n gates: raw.gates ?? [],\n detect: raw.detect ?? {},\n provenance: raw.provenance,\n threshold: raw.threshold,\n dir,\n };\n\n // `[provenance]` is required and validated (ADR-0003). A module with no\n // traceable source is one somebody invented, and `doctor` cannot ask its\n // questions without the incident.\n const p = manifest.provenance;\n if (!p?.sources?.length) throw new Error(`${name}: [provenance].sources is required`);\n if (!p?.patterns?.length) throw new Error(`${name}: [provenance].patterns is required`);\n if (!p?.incident?.trim()) throw new Error(`${name}: [provenance].incident is required`);\n\n return manifest;\n}\n\nexport function loadAllModules(modulesRoot: string): Manifest[] {\n return readdirSync(modulesRoot, { withFileTypes: true })\n .filter((e) => e.isDirectory() && statSync(join(modulesRoot, e.name, 'module.toml'), { throwIfNoEntry: false }))\n .map((e) => loadManifest(join(modulesRoot, e.name)))\n .sort((a, b) => a.rung - b.rung || a.name.localeCompare(b.name));\n}\n\n/** Every `{{param}}` appearing in a module's files and path names. */\nexport function usedParams(dir: string): Set<string> {\n const used = new Set<string>();\n const add = (text: string) => {\n // `${{ \u2026 }}` is never a substitution: GitHub Actions expressions share the\n // delimiter, and without this the ci module corrupts its own workflow file.\n for (const match of text.matchAll(/(^|[^$])\\{\\{([a-z_.]+)\\}\\}/g)) used.add(match[2]);\n };\n for (const rel of walk(dir)) {\n add(rel);\n add(readFileSync(join(dir, rel), 'utf8'));\n }\n return used;\n}\n\nexport interface ManifestIssue {\n module: string;\n kind: 'dead-param' | 'undeclared-param' | 'dep-missing' | 'gate-no-table' | 'gate-no-why';\n detail: string;\n}\n\n/** The cross-module audit. Several findings were only visible with every module in hand. */\nexport function auditModules(mods: Manifest[]): ManifestIssue[] {\n const issues: ManifestIssue[] = [];\n const names = new Set(mods.map((m) => m.name));\n\n for (const mod of mods) {\n for (const dep of mod.requires) {\n if (!names.has(dep)) {\n issues.push({ module: mod.name, kind: 'dep-missing', detail: `requires unknown module '${dep}'` });\n }\n }\n\n const used = usedParams(mod.dir);\n for (const [param, spec] of Object.entries(mod.params)) {\n if (used.has(param) || spec.consumed_by) continue;\n issues.push({\n module: mod.name,\n kind: 'dead-param',\n detail: `'${param}' is declared, never substituted, and not marked consumed_by`,\n });\n }\n for (const u of used) {\n if (u.includes('.')) continue; // cross-module reference, e.g. backlog.root\n if (!(u in mod.params)) {\n issues.push({ module: mod.name, kind: 'undeclared-param', detail: `uses {{${u}}} but does not declare it` });\n }\n }\n\n for (const g of mod.gates) {\n if (g.kind === 'declared' && !g.table) {\n issues.push({ module: mod.name, kind: 'gate-no-table', detail: `gate '${g.id}' is declared with no table` });\n }\n // `doctor` quotes `why` back when a gate has never fired (ADR-0005 tier B),\n // so a gate without one cannot be asked about.\n if (!g.why?.trim()) {\n issues.push({ module: mod.name, kind: 'gate-no-why', detail: `gate '${g.id}' has no 'why'` });\n }\n }\n }\n return issues;\n}\n", "import { readdirSync, statSync } from 'node:fs';\nimport { join, relative, sep } from 'node:path';\n\n/**\n * A small glob matcher: `**`, `*`, `?`, and `{a,b}` brace groups.\n *\n * Written rather than depended on so the semantics are ours. The only rule that\n * matters is the one ADR-0004 states: when a pattern is ambiguous it must fail\n * to match. A false negative creates something visible in git; a false positive\n * makes the CLI believe wrong things about a repo and act on them later.\n */\nexport function globToRegExp(pattern: string): RegExp {\n let out = '';\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i];\n if (c === '*') {\n if (pattern[i + 1] === '*') {\n // `**/` consumes any number of segments, including none.\n if (pattern[i + 2] === '/') {\n out += '(?:[^/]+/)*';\n i += 2;\n } else {\n out += '.*';\n i += 1;\n }\n } else {\n out += '[^/]*';\n }\n } else if (c === '?') {\n out += '[^/]';\n } else if (c === '{') {\n const end = pattern.indexOf('}', i);\n if (end === -1) {\n out += '\\\\{';\n } else {\n const alts = pattern.slice(i + 1, end).split(',');\n out += `(?:${alts.map((a) => a.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})`;\n i = end;\n }\n } else if ('.+^$()|[]\\\\'.includes(c)) {\n out += `\\\\${c}`;\n } else {\n out += c;\n }\n }\n return new RegExp(`^${out}$`);\n}\n\nconst SKIP = new Set([\n '.git',\n 'node_modules',\n 'dist',\n 'build',\n 'out',\n 'bin',\n 'obj',\n '.vs',\n '.angular',\n '.next',\n 'coverage',\n 'TestResults',\n 'BenchmarkDotNet.Artifacts',\n]);\n\n/** Walk a repo once; callers match the resulting relative paths. */\nexport function walk(root: string, maxEntries = 200_000): string[] {\n const files: string[] = [];\n const stack = [root];\n while (stack.length && files.length < maxEntries) {\n const dir = stack.pop()!;\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const e of entries) {\n if (SKIP.has(e.name)) continue;\n const full = join(dir, e.name);\n if (e.isDirectory()) {\n stack.push(full);\n } else if (e.isFile()) {\n files.push(relative(root, full).split(sep).join('/'));\n }\n }\n }\n return files;\n}\n\nexport function matchAny(files: string[], pattern: string): string[] {\n const re = globToRegExp(pattern);\n return files.filter((f) => re.test(f));\n}\n\nexport function isDir(p: string): boolean {\n try {\n return statSync(p).isDirectory();\n } catch {\n return false;\n }\n}\n", "import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { DetectResult, Manifest } from './types.ts';\nimport { matchAny, walk } from './glob.ts';\nimport { contentHash, emittedFiles } from './add.ts';\nimport type { Params } from './substitute.ts';\n\nconst SAMPLE = 3;\n\n/**\n * ADR-0004. Presence is decided by `paths` and `markers` only; `infer` merely\n * *proposes* parameters, and never concludes presence \u2014 hexguard-templates has\n * 207 well-formed `FOUND-US-###` matches and no backlog, because those are spec\n * story ids.\n *\n * Signatures are biased toward false negatives throughout: a false negative\n * creates something visible in git, while a false positive makes the CLI\n * believe wrong things about a repo and act on that belief later.\n */\nexport function detect(mod: Manifest, repoRoot: string, files: string[], installed?: InstalledModule): DetectResult {\n const result: DetectResult = {\n module: mod.name,\n state: 'absent',\n matchedPaths: [],\n matchedMarkers: [],\n proposals: [],\n adoptable: [],\n };\n\n // A module the repo installed is answered from the record, not from\n // signatures. Signatures exist to recognise somebody *else's* structure;\n // running them over our own would report a healthy install as \"theirs\" and\n // lose the one thing the record knows and detection cannot \u2014 which files we\n // wrote, and whether they still say what we wrote.\n if (installed) {\n result.ours = ownedState(mod, repoRoot, installed);\n result.state = result.ours.diverged.length ? 'ours-diverged' : 'ours-current';\n return result;\n }\n\n for (const pattern of mod.detect.paths ?? []) {\n const hits = matchAny(files, pattern);\n if (hits.length) {\n result.matchedPaths.push({ pattern, count: hits.length, sample: hits.slice(0, SAMPLE) });\n }\n }\n\n const markers = mod.detect.markers ?? [];\n if (markers.length) {\n // Only files a marker could plausibly live in, and only ones we already\n // have a reason to read. Scanning a whole repo for a marker string is both\n // slow and a way to match prose that mentions one.\n //\n // `marker_paths` exists for the case where a file's *existence* is not\n // discriminating but its *content* is: nearly every repo has a\n // `.gitattributes`, and only one of the four declares a custom merge\n // driver in it \u2014 21 declarations against 0, 0, 0.\n const scanPatterns = mod.detect.marker_paths ?? result.matchedPaths.map((m) => m.pattern);\n const candidates = new Set(scanPatterns.flatMap((p) => matchAny(files, p)));\n for (const rel of candidates) {\n let text: string;\n try {\n text = readFileSync(join(repoRoot, rel), 'utf8');\n } catch {\n continue;\n }\n for (const marker of markers) {\n if (text.includes(marker) && !result.matchedMarkers.includes(marker)) {\n result.matchedMarkers.push(marker);\n }\n }\n }\n }\n\n for (const adopt of mod.detect.adopt_as ?? []) {\n const hits = (adopt.paths ?? []).flatMap((p) => matchAny(files, p));\n if (hits.length) {\n result.adoptable.push({ kind: adopt.kind, count: hits.length, sample: hits.slice(0, SAMPLE), note: adopt.note });\n }\n }\n\n // A paradigm is only consulted when nothing else matched. Checking it\n // unconditionally reported rift-forge's pulled design mirror as *both* an\n // external authority and an in-repo design system, on a theme.ts the pattern\n // was never meant to reach.\n if (result.matchedPaths.length === 0 && result.adoptable.length === 0) {\n for (const para of mod.detect.paradigm ?? []) {\n const matched = (para.paths ?? []).flatMap((p) => matchAny(files, p));\n if (matched.length) {\n result.paradigm = { id: para.id, note: para.note, compare: para.compare, matched: matched.slice(0, SAMPLE) };\n break;\n }\n }\n }\n\n // State. `ours-current` / `ours-diverged` require a rungs.toml recording a\n // prior install; a repo without one can only be absent, theirs, or paradigm.\n //\n // An `adopt_as` match is ADR-0004 state 4 \u2014 \"theirs, equivalent\": the\n // module's function exists in a shape we can map, even though our own\n // structure is absent. Treating it as absent hid the single highest-value\n // adoption in the catalogue, rift-forge's 82 registered gates.\n if (result.matchedPaths.length > 0 || result.adoptable.length > 0 || result.matchedMarkers.length > 0) {\n result.state = 'theirs';\n } else if (result.paradigm) {\n result.state = 'paradigm';\n } else {\n result.state = 'absent';\n }\n\n // Proposals run only once presence is established, and are reported as\n // proposals \u2014 never applied, never used to decide state.\n if (result.state === 'theirs') {\n result.proposals = infer(mod, repoRoot, files);\n }\n\n return result;\n}\n\nfunction infer(mod: Manifest, repoRoot: string, files: string[]) {\n const proposals: DetectResult['proposals'] = [];\n\n for (const rule of mod.detect.infer ?? []) {\n if (rule.paths) {\n // Directory-presence inference (e.g. which harnesses exist).\n const present = Object.entries(rule.paths)\n .filter(([, p]) => files.some((f) => f.startsWith(p.replace(/\\/$/, '/'))))\n .map(([key]) => key);\n if (present.length) {\n proposals.push({ param: rule.param, value: present.join(', '), evidence: 'directory present' });\n }\n continue;\n }\n if (!rule.pattern) continue;\n\n const scope = (rule.scope ?? ['**/*.md']).flatMap((p) => matchAny(files, p));\n const excluded = new Set((rule.exclude ?? []).flatMap((p) => matchAny(files, p)));\n const counts = new Map<string, number>();\n\n for (const rel of scope) {\n if (excluded.has(rel)) continue;\n let text: string;\n try {\n text = readFileSync(join(repoRoot, rel), 'utf8');\n } catch {\n continue;\n }\n for (const m of text.matchAll(new RegExp(rule.pattern, 'gm'))) {\n const key = m[1];\n if (key) counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n }\n\n // An anchor wins outright over frequency. Counting raw occurrences made\n // `findings` propose the *backlog's* prefix, because a findings register is\n // full of citations to work items \u2014 more of them than of its own ids.\n // The register's own NEXT-ID marker settles it without judgement.\n if (rule.anchor) {\n const anchored = new Map<string, number>();\n for (const rel of scope) {\n if (excluded.has(rel)) continue;\n let text: string;\n try {\n text = readFileSync(join(repoRoot, rel), 'utf8');\n } catch {\n continue;\n }\n for (const m of text.matchAll(new RegExp(rule.anchor, 'gm'))) {\n if (m[1]) anchored.set(m[1], (anchored.get(m[1]) ?? 0) + 1);\n }\n }\n const [best] = [...anchored].sort((a, b) => b[1] - a[1]);\n if (best) {\n proposals.push({ param: rule.param, value: best[0], evidence: `anchored on ${rule.anchor_name ?? 'marker'}` });\n continue;\n }\n }\n\n const banned = new Set(rule.exclude_values ?? []);\n const ranked = [...counts].filter(([k]) => !banned.has(k)).sort((a, b) => b[1] - a[1]);\n const [top] = ranked;\n if (top && top[1] >= (rule.min ?? 1)) {\n proposals.push({\n param: rule.param,\n value: top[0],\n evidence: `${top[1]} matches${ranked.length > 1 ? ` (next: ${ranked[1][0]} at ${ranked[1][1]})` : ''}`,\n });\n }\n }\n return proposals;\n}\n\nexport function scanRepo(repoRoot: string): string[] {\n return walk(repoRoot);\n}\n\nexport interface InstalledModule {\n version: string;\n params?: Record<string, unknown>;\n hashes?: Record<string, string>;\n kept?: { files: string[] };\n skillsDir?: string;\n params_all?: Params;\n}\n\n/**\n * The state of files this repo installed from a module.\n *\n * Three comparisons, and each answers a different question:\n *\n * absent from disk \u2192 missing, an upgrade restores it\n * matches what we'd emit now \u2192 current\n * matches the recorded hash \u2192 stale; ours to replace on upgrade\n * matches neither \u2192 diverged; theirs, and never touched\n */\nexport function ownedState(mod: Manifest, repoRoot: string, installed: InstalledModule) {\n const params = installed.params_all ?? {};\n const emitted = emittedFiles(mod, params, installed.skillsDir ?? '.claude/skills');\n const kept = new Set(installed.kept?.files ?? []);\n const out = {\n version: installed.version,\n current: [] as string[],\n stale: [] as string[],\n diverged: [] as string[],\n missing: [] as string[],\n kept: [] as string[],\n };\n for (const [rel, wouldEmit] of emitted) {\n // A file that already existed at install was never ours. Calling it\n // \"diverged\" implies the user broke something they never touched.\n if (kept.has(rel)) {\n out.kept.push(rel);\n continue;\n }\n const full = join(repoRoot, rel);\n if (!existsSync(full)) {\n out.missing.push(rel);\n continue;\n }\n const onDisk = contentHash(readFileSync(full, 'utf8'));\n if (onDisk === contentHash(wouldEmit)) out.current.push(rel);\n else if (installed.hashes?.[rel] && onDisk === installed.hashes[rel]) out.stale.push(rel);\n else out.diverged.push(rel);\n }\n return out;\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { Manifest } from './types.ts';\nimport { matchAny, walk } from './glob.ts';\nimport { markers, mergeBlock, substitute, type Params } from './substitute.ts';\n\nexport interface AddAction {\n disposition: 'create' | 'skip-exists' | 'rule' | 'skill' | 'merge' | 'gate';\n target: string;\n note?: string;\n}\n\n/** Where a fragment file merges to. The name is the target, not a path. */\nconst FRAGMENT_TARGET: Record<string, string> = {\n 'AGENTS.md': 'AGENTS.md',\n gitignore: '.gitignore',\n gitattributes: '.gitattributes',\n};\n\n/**\n * Install one module. Disposition is decided by which subdirectory a file is\n * in \u2014 never by per-file configuration (ADR-0003), which is why this function\n * is a switch over five directory names and nothing else.\n *\n * Never overwrites an existing file. ADR-0004: `add` on existing structure\n * reports the delta; the dangerous operation is removed rather than guarded.\n */\nexport function addModule(\n mod: Manifest,\n repoRoot: string,\n params: Params,\n opts: { dryRun?: boolean; skillsDir?: string } = {},\n): AddAction[] {\n const actions: AddAction[] = [];\n const write = (rel: string, content: string, disposition: AddAction['disposition']) => {\n const full = join(repoRoot, rel);\n if (existsSync(full)) {\n actions.push({ disposition: 'skip-exists', target: rel, note: 'already present \u2014 left alone' });\n return;\n }\n actions.push({ disposition, target: rel });\n if (opts.dryRun) return;\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, content);\n };\n\n const sub = (text: string) => substitute(text, mod.name, params);\n const has = (d: string) => existsSync(join(mod.dir, d));\n\n if (has('files')) {\n const base = join(mod.dir, 'files');\n for (const rel of walk(base)) {\n write(sub(rel), sub(readFileSync(join(base, rel), 'utf8')), 'create');\n }\n }\n\n if (has('rules')) {\n const base = join(mod.dir, 'rules');\n for (const rel of walk(base)) {\n write(join('.ai', 'rules', rel).split('\\\\').join('/'), sub(readFileSync(join(base, rel), 'utf8')), 'rule');\n }\n }\n\n if (has('skills')) {\n const base = join(mod.dir, 'skills');\n const dir = opts.skillsDir ?? '.claude/skills';\n for (const rel of walk(base)) {\n write(`${dir}/${rel}`, sub(readFileSync(join(base, rel), 'utf8')), 'skill');\n }\n }\n\n if (has('fragments')) {\n const base = join(mod.dir, 'fragments');\n for (const rel of walk(base)) {\n const target = FRAGMENT_TARGET[rel];\n if (!target) {\n actions.push({ disposition: 'merge', target: rel, note: 'unknown fragment target \u2014 skipped' });\n continue;\n }\n const full = join(repoRoot, target);\n const existing = existsSync(full) ? readFileSync(full, 'utf8') : '';\n const fragment = sub(readFileSync(join(base, rel), 'utf8'));\n const merged = mergeBlock(existing, fragment, mod.name);\n actions.push({\n disposition: 'merge',\n target,\n note: existing.includes(`rungs:begin ${mod.name}`) ? 'block replaced' : 'block appended',\n });\n if (!opts.dryRun) {\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, merged);\n }\n }\n }\n\n return actions;\n}\n\n/**\n * Gate registration is a **second phase**, run after every module's files exist.\n *\n * Done inside `addModule` it raced the `gates` module's own registry file:\n * whichever module merged an entry first created `.ai/gates.toml`, and the\n * owner then hit the never-overwrite rule and was skipped \u2014 leaving a registry\n * with entries and no `[runner]` block. Reordering the install did not fix it,\n * because `gates` depends on `instructions`, which itself ships gates. The\n * ordering was never the problem: **the owner of a shared file must create it\n * before anything merges into it, which is a phase, not a position.**\n */\nexport function registerGates(mods: Manifest[], repoRoot: string, dryRun = false, adopted: AdoptedGate[] = []): AddAction[] {\n const actions: AddAction[] = [];\n const registry = join(repoRoot, '.ai', 'gates.toml');\n\n // Adoption, in the only form ADR-0004 permits: the repo's existing validators\n // are registered as `command` gates so they gain the runner, the ledger and\n // attribution \u2014 **without a line of them being rewritten**. This is the claim\n // the whole product rests on, and it was missing: `add` created a registry of\n // rungs' own gates and left the repo's sixteen where they were.\n if (adopted.length) {\n const existing = existsSync(registry) ? readFileSync(registry, 'utf8') : '';\n const { begin, end } = markers('gates.toml', 'adopted', '1.0.0');\n const body = [\n begin,\n '# Registered from validators this repo already had. Their scripts are untouched and',\n '# stay yours; rungs only runs them and records what it observes.',\n ...adopted.map(\n (a) => `\\n[[gates]]\\nid = \"${a.id}\"\\nkind = \"command\"\\nmodule = \"adopted\"\\ntier = \"${a.tier}\"\\ncommand = \"${a.command}\"\\nwhy = \"\"\"Adopted from ${a.source}. Predates rungs and is owned by this repo.\"\"\"`,\n ),\n end,\n ].join('\\n');\n actions.push({ disposition: 'gate', target: '.ai/gates.toml', note: `adopted: ${adopted.length} entries` });\n if (!dryRun) {\n mkdirSync(dirname(registry), { recursive: true });\n writeFileSync(registry, mergeBlock(existing, body, 'adopted'));\n }\n }\n\n for (const mod of mods) {\n if (!mod.gates.length) continue;\n const existing = existsSync(registry) ? readFileSync(registry, 'utf8') : '';\n const { begin, end } = markers('gates.toml', mod.name, mod.version);\n const body = [begin, ...mod.gates.map(gateEntry(mod)), end].join('\\n');\n actions.push({ disposition: 'gate', target: '.ai/gates.toml', note: `${mod.name}: ${mod.gates.length} entries` });\n if (dryRun) continue;\n mkdirSync(dirname(registry), { recursive: true });\n writeFileSync(registry, mergeBlock(existing, body, mod.name));\n }\n return actions;\n}\n\nconst gateEntry = (mod: Manifest) => (g: Manifest['gates'][number]) => {\n const lines = ['', '[[gates]]', `id = \"${g.id}\"`, `kind = \"${g.kind}\"`, `module = \"${mod.name}\"`];\n if (g.engine) lines.push(`engine = \"${g.engine}\"`);\n if (g.table) lines.push(`table = \"${mod.name}/${g.table.replace(/^gates\\//, '')}\"`);\n if (g.command) lines.push(`command = \"${g.command}\"`);\n if (g.tier) lines.push(`tier = \"${g.tier}\"`);\n if (g.trigger) lines.push(`trigger = \"${g.trigger}\"`);\n if (g.matcher) lines.push(`matcher = \"${g.matcher}\"`);\n // `why` is carried into the repo because ADR-0005 tier B quotes it back when\n // a gate has never fired. A gate whose reason lives only in this CLI cannot\n // be asked about by a repo that has it installed.\n if (g.why) lines.push(`why = \"\"\"${g.why.trim()}\"\"\"`);\n return lines.join('\\n');\n};\n\n/** Dependency order, refusing anything unmet \u2014 naming the incident (ADR-0003). */\nexport function resolveInstallOrder(requested: string[], all: Manifest[]): { order: Manifest[]; missing: string[] } {\n const byName = new Map(all.map((m) => [m.name, m]));\n const order: Manifest[] = [];\n const missing: string[] = [];\n const seen = new Set<string>();\n const visit = (name: string) => {\n if (seen.has(name)) return;\n const mod = byName.get(name);\n if (!mod) {\n missing.push(name);\n return;\n }\n seen.add(name);\n for (const dep of mod.requires) visit(dep);\n order.push(mod);\n };\n // A module's gates are inert without the runner that executes them. Installing\n // `backlog` alone produced a `.ai/gates.toml` holding three entries and no\n // `[runner]` block \u2014 a registry nothing reads. Rather than making every\n // gate-shipping module declare the dependency (and `instructions`, which ships\n // gates and is what `gates` itself requires, could not), the runner is pulled\n // in whenever anything registers with it.\n //\n // It is visited **first**, not appended: installed last it arrived after other\n // modules had already merged entries into the registry, so its own file \u2014 the\n // one carrying `[runner]` \u2014 hit the never-overwrite rule and was skipped. The\n // owner of a shared file has to create it before anyone merges into it.\n const closure = new Set<string>();\n const collect = (n: string) => {\n if (closure.has(n)) return;\n const m = byName.get(n);\n if (!m) return;\n closure.add(n);\n m.requires.forEach(collect);\n };\n requested.forEach(collect);\n if ([...closure].some((n) => byName.get(n)!.gates.length) && byName.has('gates')) {\n visit('gates');\n }\n\n for (const r of requested) visit(r);\n return { order, missing };\n}\n\n/**\n * Content hash of what a module emitted, recorded at install.\n *\n * Without it `upgrade` cannot tell a file the user edited from one an older\n * module version wrote \u2014 and those want opposite treatment: the first is a\n * decision to respect, the second is the thing upgrade exists to replace.\n * It is also what makes ADR-0004's `ours-current` and `ours-diverged` states\n * decidable at all.\n */\nexport const contentHash = (s: string) => createHash('sha256').update(s.replace(/\\r\\n/g, '\\n')).digest('hex').slice(0, 12);\n\n/**\n * Files a module owns **outright** \u2014 not the shared ones it merges into.\n *\n * `AGENTS.md` and `.ai/gates.toml` are co-owned: a module creates them and then\n * every other module merges a block in, so their content differs from what any\n * single module emitted the moment the second module installs. Hashing them\n * reported both as diverged on a completely untouched repo. A file carrying\n * managed blocks is never whole-file upgraded \u2014 its **blocks** are, through the\n * merge path.\n */\nconst SHARED = new Set(['AGENTS.md', 'CLAUDE.md', '.gitignore', '.gitattributes', '.ai/gates.toml']);\n\nexport function emittedFiles(mod: Manifest, params: Params, skillsDir = '.claude/skills'): Map<string, string> {\n const out = new Map<string, string>();\n const sub = (t: string) => substitute(t, mod.name, params);\n for (const [dir, prefix] of [\n ['files', ''],\n ['rules', '.ai/rules/'],\n ['skills', `${skillsDir}/`],\n ] as const) {\n const base = join(mod.dir, dir);\n if (!existsSync(base)) continue;\n for (const rel of walk(base)) {\n const target = sub(prefix + rel).split('\\\\').join('/');\n if (SHARED.has(target)) continue;\n out.set(target, sub(readFileSync(join(base, rel), 'utf8')));\n }\n }\n return out;\n}\n\nexport function writeInstallRecord(\n repoRoot: string,\n mods: Manifest[],\n params: Params,\n harnesses: string[],\n stamp: string,\n skillsDir = '.claude/skills',\n /** Per module, the files rungs actually created \u2014 as opposed to kept. */\n wroteByModule?: Map<string, Set<string>>,\n) {\n const lines = [\n '# Installed by `rungs`. This is a record of what was written, not a control panel:',\n '# editing a parameter here does not rewrite a file that already exists. `rungs render`',\n '# re-emits path-scoped rules from `.ai/rules/`, and `rungs upgrade --apply` replaces',\n '# module files you have not edited \u2014 neither re-substitutes parameters. AGENTS.md,',\n '# CLAUDE.md, .gitignore, .gitattributes and .ai/gates.toml are shared between modules,',\n '# so only their `rungs:begin`/`rungs:end` blocks are ever updated; anything outside a',\n '# block, including the entry document\\'s title, is yours to edit directly.',\n '#',\n '# Hashes are what rungs emitted; a file whose hash no longer matches is a',\n '# divergence rungs reports and never overwrites.',\n '',\n '[repo]',\n `harnesses = ${JSON.stringify(harnesses)}`,\n `installed = \"${stamp}\"`,\n '',\n ];\n for (const m of mods) {\n lines.push(`[modules.${m.name}]`, `version = \"${m.version}\"`, 'state = \"managed\"');\n const p = params[m.name] ?? {};\n if (Object.keys(p).length) {\n lines.push(`params = { ${Object.entries(p).map(([k, v]) => `${k} = ${JSON.stringify(v ?? '')}`).join(', ')} }`);\n }\n // Only files rungs actually **wrote** get a hash. A file that already\n // existed was kept, and hashing it with our content would later read as a\n // divergence the user caused \u2014 implying they broke something they never\n // touched. Kept files are listed separately and stay theirs forever.\n const emitted = emittedFiles(m, params, skillsDir);\n const created = [...emitted].filter(([rel]) => (wroteByModule?.get(m.name)?.has(rel) ?? existsSync(join(repoRoot, rel))));\n const kept = [...emitted].filter(([rel]) => !created.some(([c]) => c === rel) && existsSync(join(repoRoot, rel)));\n if (created.length) {\n lines.push(`[modules.${m.name}.hashes]`);\n for (const [rel, content] of created) lines.push(`\"${rel}\" = \"${contentHash(content)}\"`);\n }\n if (kept.length) {\n lines.push('', `[modules.${m.name}]`.replace(']', '.kept]'));\n lines.push(`files = ${JSON.stringify(kept.map(([rel]) => rel))}`);\n }\n lines.push('');\n }\n writeFileSync(join(repoRoot, '.ai', 'rungs.toml'), lines.join('\\n'));\n}\n\nexport interface AdoptedGate {\n id: string;\n command: string;\n tier: string;\n source: string;\n}\n\n/**\n * Turn detected `adopt_as` matches into `command` gate entries.\n *\n * The interpreter is chosen from the extension, and an unknown one is skipped\n * rather than guessed at \u2014 a registry entry that cannot run is worse than one\n * that is absent, because it reports as a failure the owner did not cause.\n */\nexport function adoptableGates(files: string[], patterns: string[], repoRoot: string): AdoptedGate[] {\n const runner: Record<string, string> = { '.mjs': 'node', '.js': 'node', '.ps1': 'pwsh -File', '.sh': 'bash' };\n const out: AdoptedGate[] = [];\n for (const pattern of patterns) {\n for (const rel of matchAny(files, pattern)) {\n const ext = rel.slice(rel.lastIndexOf('.'));\n const exec = runner[ext];\n if (!exec) continue;\n out.push({\n id: `adopted-${rel.split('/').pop()!.replace(/\\.[^.]+$/, '')}`,\n command: `${exec} ${rel}`,\n tier: 'fast',\n source: rel,\n });\n }\n }\n return out;\n}\n", "import { basename, resolve } from 'node:path';\nimport type { Manifest } from './types.ts';\n\nexport type Params = Record<string, Record<string, unknown>>;\n\n/**\n * `{{param}}` substitution, in file contents and in path segments. No\n * conditionals, no loops \u2014 ADR-0003. A module that needs a conditional is two\n * modules, or reaches file content through a managed block.\n *\n * `${{ \u2026 }}` is never substituted: GitHub Actions expressions share the\n * delimiter, and without the passthrough the `ci` module corrupts its own\n * workflow file at install \u2014 a broken file rather than an error.\n */\nexport function substitute(text: string, module: string, params: Params): string {\n return text.replace(/(^|[^$])\\{\\{([a-z_.]+)\\}\\}/g, (whole, lead: string, ref: string) => {\n const [a, b] = ref.includes('.') ? ref.split('.') : [module, ref];\n const value = params[a]?.[b];\n if (value === undefined) return whole; // leave it visible rather than emitting an empty string\n return lead + format(value);\n });\n}\n\nfunction format(v: unknown): string {\n if (Array.isArray(v)) return `[${v.map((x) => JSON.stringify(x)).join(', ')}]`;\n if (typeof v === 'boolean' || typeof v === 'number') return String(v);\n return String(v);\n}\n\n/**\n * Facts about the target repository, addressable from a default as `{{repo.<key>}}`.\n *\n * `repo` is a **reserved namespace, not a module**, which is what keeps it clear of\n * `modules/README.md` rule 9b \u2014 referencing a module you have not declared is an undeclared\n * coupling, but every module already sits in a repository, so there is nothing to declare.\n *\n * Deliberately one key. `git_remote` and `branch` were considered and left out: nothing consumes\n * them, and rule 9e is about the knob wired to nothing that stays invisible until someone compares\n * every module at once.\n */\nfunction repoFacts(repoRoot?: string): Record<string, unknown> {\n return repoRoot ? { dirname: basename(resolve(repoRoot)) } : {};\n}\n\n/**\n * Defaults from every manifest, with explicit overrides applied on top.\n *\n * `repoRoot` is optional only so a caller with no repository in hand can still read defaults. When\n * it is absent `{{repo.dirname}}` does not resolve, and `substitute` leaves the token visible\n * rather than emitting an empty string \u2014 the same bias as every other unresolved reference, and\n * the reason a missing root shows up as a wrong-looking file instead of a silently blank heading.\n */\nexport function resolveParams(mods: Manifest[], overrides: Params = {}, repoRoot?: string): Params {\n const out: Params = { repo: repoFacts(repoRoot) };\n for (const m of mods) {\n out[m.name] = {};\n for (const [k, spec] of Object.entries(m.params)) out[m.name][k] = spec.default;\n }\n\n // **Overrides go on before cross-module references resolve.** They were\n // applied last, which meant a default referencing another module's parameter\n // had already baked in that module's *default* \u2014 so installing into hexguard\n // with `--set backlog.root=.ai/backlog` put the findings register at\n // `docs/.ai/backlog/FINDINGS.md` and left every link to it pointing at\n // `docs/backlog/FINDINGS.md`. The gate caught it on the first real install;\n // nothing in a scratch repo could have, because nothing there overrides.\n for (const [mod, vals] of Object.entries(overrides)) {\n out[mod] = { ...(out[mod] ?? {}), ...vals };\n }\n\n // A default may reference another module's parameter, e.g. findings' register\n // living at `docs/{{backlog.root}}/FINDINGS.md`. One level only \u2014 a chain\n // would be a template language arriving through the back door.\n for (const m of mods) {\n for (const [k, v] of Object.entries(out[m.name])) {\n if (typeof v === 'string' && v.includes('{{')) out[m.name][k] = substitute(v, m.name, out);\n }\n }\n return out;\n}\n\n/** Comment syntax for a managed block, chosen by the target file. */\nexport function markers(targetPath: string, module: string, version: string) {\n const hash = /\\.(toml|ya?ml|gitignore|gitattributes|sh|ps1|conf|properties)$|(^|\\/)\\.(gitignore|gitattributes)$/.test(\n targetPath,\n );\n return hash\n ? { begin: `# rungs:begin ${module}@${version}`, end: `# rungs:end ${module}` }\n : { begin: `<!-- rungs:begin ${module}@${version} -->`, end: `<!-- rungs:end ${module} -->` };\n}\n\n/**\n * Replace an existing managed block, or append one. Content outside every block\n * is the user's and is never touched \u2014 that is what makes the upgrade story\n * mechanical and divergence a decision rather than an error.\n */\nexport function mergeBlock(existing: string, fragment: string, module: string): string {\n const beginRe = new RegExp(`^[ \\\\t]*(?:<!--|#)\\\\s*rungs:begin ${module}(?:@[\\\\w.\\\\-]+)?\\\\s*(?:-->)?[ \\\\t]*$`, 'm');\n const endRe = new RegExp(`^[ \\\\t]*(?:<!--|#)\\\\s*rungs:end ${module}\\\\s*(?:-->)?[ \\\\t]*$`, 'm');\n const b = existing.match(beginRe);\n const e = existing.match(endRe);\n if (b && e && b.index !== undefined && e.index !== undefined && e.index > b.index) {\n const before = existing.slice(0, b.index);\n const after = existing.slice(e.index + e[0].length);\n return `${before}${fragment.trim()}${after}`;\n }\n const sep = existing.endsWith('\\n\\n') ? '' : existing.endsWith('\\n') ? '\\n' : '\\n\\n';\n return `${existing}${sep}${fragment.trim()}\\n`;\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { walk } from './glob.ts';\n\nexport type Harness = 'claude' | 'copilot' | 'cursor' | 'agents-md';\n\nexport interface Rule {\n file: string;\n description?: string;\n paths: string[];\n enforcement?: string;\n body: string;\n}\n\nexport interface RenderEntry {\n rule: string;\n harness: Harness;\n target?: string;\n degraded?: string;\n dropped?: string[];\n}\n\nconst DO_NOT_EDIT = (source: string) =>\n `Generated by \\`rungs render\\` from ${source}. Do not edit \u2014 your changes are overwritten.`;\n\n/** Parse `.ai/rules/*.md`: the neutral source ADR-0001 renders from. */\nexport function readRules(repoRoot: string): Rule[] {\n const dir = join(repoRoot, '.ai', 'rules');\n const rules: Rule[] = [];\n let files: string[];\n try {\n files = walk(dir).filter((f) => f.endsWith('.md') && f !== 'README.md');\n } catch {\n return rules;\n }\n for (const rel of files) {\n const raw = readFileSync(join(dir, rel), 'utf8');\n const m = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!m) continue;\n const [, fm, body] = m;\n rules.push({\n file: rel,\n description: scalar(fm, 'description'),\n paths: list(fm, 'paths'),\n enforcement: scalar(fm, 'enforcement'),\n body: body.trim(),\n });\n }\n return rules;\n}\n\nfunction scalar(fm: string, key: string): string | undefined {\n const folded = fm.match(new RegExp(`^${key}:\\\\s*>-?\\\\s*\\\\n([\\\\s\\\\S]*?)(?=\\\\n\\\\S|$)`, 'm'));\n if (folded) return folded[1].split('\\n').map((l) => l.trim()).filter(Boolean).join(' ');\n const plain = fm.match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'));\n return plain?.[1].trim().replace(/^[\"']|[\"']$/g, '');\n}\n\nfunction list(fm: string, key: string): string[] {\n const block = fm.match(new RegExp(`^${key}:\\\\s*\\\\n((?:\\\\s*-\\\\s*.+\\\\n?)+)`, 'm'));\n if (!block) return [];\n return [...block[1].matchAll(/^\\s*-\\s*(.+)$/gm)].map((m) => m[1].trim().replace(/^[\"']|[\"']$/g, ''));\n}\n\n/**\n * Emit one rule into one harness's dialect. Full bodies, never pointers: a\n * wrapper that references a shared file relies on the harness following the\n * reference, and only some do. A rule that does not load is worth nothing.\n */\nexport function renderRule(rule: Rule, harness: Harness): { target: string; content: string; dropped: string[] } | { degraded: string } {\n const stem = rule.file.replace(/\\.md$/, '');\n const source = `.ai/rules/${rule.file}`;\n const dropped: string[] = [];\n\n if (harness === 'claude') {\n // No description field in a Claude rule; the routing is done by `paths`.\n if (rule.description) dropped.push('description');\n const fm = rule.paths.length ? `paths:\\n${rule.paths.map((p) => ` - \"${p}\"`).join('\\n')}\\n` : '';\n return {\n target: `.claude/rules/${stem}.md`,\n content: `---\\n${fm}---\\n\\n<!-- ${DO_NOT_EDIT(source)} -->\\n\\n${rule.body}\\n`,\n dropped,\n };\n }\n\n if (harness === 'copilot') {\n const applyTo = rule.paths.length ? rule.paths.join(', ') : '**/*';\n const desc = rule.description ? `description: '${rule.description.replace(/'/g, \"''\")}'\\n` : '';\n return {\n target: `.github/instructions/${stem}.instructions.md`,\n content: `---\\n${desc}applyTo: '${applyTo}'\\n---\\n\\n<!-- ${DO_NOT_EDIT(source)} -->\\n\\n${rule.body}\\n`,\n dropped,\n };\n }\n\n if (harness === 'cursor') {\n // `.mdc` is required \u2014 a plain .md in .cursor/rules is ignored entirely.\n const desc = rule.description ? `description: ${rule.description}\\n` : '';\n const globs = rule.paths.length ? `globs: ${rule.paths.join(',')}\\n` : '';\n return {\n target: `.cursor/rules/${stem}.mdc`,\n content: `---\\n${desc}${globs}alwaysApply: ${rule.paths.length === 0}\\n---\\n\\n<!-- ${DO_NOT_EDIT(source)} -->\\n\\n${rule.body}\\n`,\n dropped,\n };\n }\n\n // AGENTS.md-only harnesses have no glob scoping at all. Degrade explicitly\n // and report it \u2014 never drop a rule silently.\n const prefix = commonDirPrefix(rule.paths);\n if (prefix) {\n return {\n target: `${prefix}/AGENTS.md`,\n content: `<!-- ${DO_NOT_EDIT(source)} -->\\n\\n${rule.body}\\n`,\n dropped: ['description', 'paths (directory-scoped instead of glob)'],\n };\n }\n return {\n degraded: `routing-only: globs do not share a directory prefix, so root AGENTS.md gets a pointer to ${source}`,\n };\n}\n\nfunction commonDirPrefix(paths: string[]): string | null {\n if (!paths.length) return null;\n const dirs = paths.map((p) => p.split('/').filter((s) => !s.includes('*')).join('/')).filter(Boolean);\n if (dirs.length !== paths.length) return null;\n const first = dirs[0];\n return dirs.every((d) => d === first) && first.includes('/') ? first : null;\n}\n\nexport function render(repoRoot: string, harnesses: Harness[]): RenderEntry[] {\n const rules = readRules(repoRoot);\n const entries: RenderEntry[] = [];\n const routingOnly: Rule[] = [];\n\n for (const rule of rules) {\n for (const harness of harnesses) {\n const out = renderRule(rule, harness);\n if ('degraded' in out) {\n entries.push({ rule: rule.file, harness, degraded: out.degraded });\n if (harness === 'agents-md') routingOnly.push(rule);\n continue;\n }\n const full = join(repoRoot, out.target);\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, out.content);\n entries.push({ rule: rule.file, harness, target: out.target, dropped: out.dropped });\n }\n }\n\n // The report said root AGENTS.md \"gets a pointer\" and nothing wrote one \u2014 a\n // degradation notice that was itself a silent drop, in the function whose\n // whole job is not to have those. Written now, as a managed block.\n writeRoutingBlock(repoRoot, routingOnly, harnesses);\n return entries;\n}\n\nfunction writeRoutingBlock(repoRoot: string, rules: Rule[], harnesses: Harness[]) {\n if (!harnesses.includes('agents-md')) return;\n const target = join(repoRoot, 'AGENTS.md');\n if (!existsSync(target)) return;\n const begin = '<!-- rungs:begin rules-routing -->';\n const end = '<!-- rungs:end rules-routing -->';\n\n const body = rules.length\n ? [\n begin,\n '## Rules for specific paths',\n '',\n 'This harness has no glob scoping, so these load only if you open them. **Read the one that',\n 'matches what you are editing before editing broadly.**',\n '',\n ...rules.map((r) => `- \\`${r.paths.join('\\`, \\`')}\\` \u2192 [\\`.ai/rules/${r.file}\\`](.ai/rules/${r.file})`),\n end,\n ].join('\\n')\n : '';\n\n const existing = readFileSync(target, 'utf8');\n const beginRe = /^[ \\t]*<!--\\s*rungs:begin rules-routing\\s*-->[ \\t]*$/m;\n const endRe = /^[ \\t]*<!--\\s*rungs:end rules-routing\\s*-->[ \\t]*$/m;\n const b = existing.match(beginRe);\n const e = existing.match(endRe);\n if (b && e && b.index !== undefined && e.index !== undefined) {\n const next = existing.slice(0, b.index) + body.trim() + existing.slice(e.index + e[0].length);\n writeFileSync(target, body ? next : next.replace(/\\n{3,}/g, '\\n\\n'));\n return;\n }\n if (body) writeFileSync(target, `${existing.replace(/\\n+$/, '\\n')}\\n${body}\\n`);\n}\n\n/**\n * ADR-0001: a render that quietly dropped a rule reads identically to one that\n * had nothing to drop, so every degradation lands here.\n */\nexport function writeReport(repoRoot: string, entries: RenderEntry[], harnesses: Harness[], stamp: string): string {\n const lines = [\n '# Render report',\n '',\n `> Generated by \\`rungs render\\` on ${stamp}. Do not edit.`,\n '',\n `Harnesses: ${harnesses.join(', ')}`,\n '',\n '| Rule | Harness | Emitted | Dropped / degraded |',\n '| --- | --- | --- | --- |',\n ];\n for (const e of entries) {\n const lost = e.degraded ?? (e.dropped?.length ? e.dropped.join(', ') : '\u2014');\n lines.push(`| \\`${e.rule}\\` | ${e.harness} | ${e.target ? `\\`${e.target}\\`` : '**not emitted**'} | ${lost} |`);\n }\n const degraded = entries.filter((e) => e.degraded).length;\n const lossy = entries.filter((e) => e.dropped?.length).length;\n lines.push(\n '',\n `${entries.length} renderings \u00B7 ${lossy} lost a field \u00B7 ${degraded} degraded.`,\n '',\n 'A field listed as dropped is one the target harness has no way to express. It is recorded',\n 'here rather than silently discarded, so a repo can see what its harness choice costs it.',\n '',\n );\n const content = lines.join('\\n');\n writeFileSync(join(repoRoot, '.ai', 'render-report.md'), content);\n return content;\n}\n", "import { appendFileSync, existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { parse } from 'smol-toml';\nimport { ENGINES, isImplemented, type Finding } from './engines.ts';\nimport { walk } from './glob.ts';\nimport { resolveParams, substitute, type Params } from './substitute.ts';\nimport { loadAllModules } from './manifest.ts';\n\nconst MODULES = join(dirname(fileURLToPath(import.meta.url)), '..', 'modules');\n\nexport type Status = 'pass' | 'fail' | 'unimplemented' | 'error';\n\nexport interface GateRun {\n id: string;\n module?: string;\n kind: string;\n engine?: string;\n tier: string;\n status: Status;\n ms: number;\n examined: number;\n findings: Finding[];\n why?: string;\n}\n\ninterface RegistryGate {\n id: string;\n kind: string;\n module?: string;\n engine?: string;\n table?: string;\n command?: string;\n tier?: string;\n trigger?: string;\n why?: string;\n}\n\nexport function loadRegistry(repoRoot: string): { runner: any; gates: RegistryGate[] } {\n const path = join(repoRoot, '.ai', 'gates.toml');\n if (!existsSync(path)) return { runner: {}, gates: [] };\n const raw = parse(readFileSync(path, 'utf8')) as any;\n return { runner: raw.runner ?? {}, gates: raw.gates ?? [] };\n}\n\nexport function runGates(repoRoot: string, tier?: string, now = () => Date.now()): GateRun[] {\n const { gates } = loadRegistry(repoRoot);\n const files = walk(repoRoot);\n const runs: GateRun[] = [];\n\n for (const g of gates) {\n // A hook fires on a tool call, not in the runner. Skipping it here is\n // correct; counting it as a pass would not be.\n if (g.trigger) continue;\n if (tier && g.tier && g.tier !== tier) continue;\n\n const started = now();\n let status: Status = 'pass';\n let findings: Finding[] = [];\n let examined = 0;\n\n if (g.kind === 'command' && g.command) {\n try {\n execSync(g.command, { cwd: repoRoot, stdio: 'pipe' });\n } catch (e: any) {\n status = 'fail';\n findings = [{ message: String(e.stderr ?? e.stdout ?? e.message).trim().split('\\n').slice(-3).join(' ') }];\n }\n } else if (!g.engine || !isImplemented(g.engine)) {\n // Never green. An engine named in a table and missing from the CLI is an\n // unknown, and a registry reporting green because most of its gates do\n // nothing is the worst failure this tool could have.\n status = 'unimplemented';\n findings = [{ message: `engine '${g.engine ?? '(none)'}' is not implemented` }];\n } else {\n const table = loadTable(g.table, repoRoot);\n if (!table) {\n status = 'error';\n findings = [{ message: `table '${g.table}' not found` }];\n } else {\n try {\n const key = tableKey(g.engine);\n let section = table[key] ?? table;\n // An array table holds one entry per gate; select by trailing id.\n if (Array.isArray(section) && section.some((s: any) => s?.id)) {\n const mine = section.filter((s: any) => !s.id || g.id.includes(s.id));\n if (mine.length) section = mine;\n }\n const r = ENGINES[g.engine](section, repoRoot, files);\n findings = r.findings;\n examined = r.examined;\n status = r.findings.length ? 'fail' : 'pass';\n } catch (e: any) {\n status = 'error';\n findings = [{ message: e.message }];\n }\n }\n }\n\n runs.push({\n id: g.id,\n module: g.module,\n kind: g.kind,\n engine: g.engine,\n tier: g.tier ?? 'fast',\n status,\n ms: now() - started,\n examined,\n findings,\n why: g.why,\n });\n }\n return runs;\n}\n\n/**\n * A table lives in the CLI's module set, not in the repo (ADR-0002) \u2014 but it is\n * authored with `{{param}}` placeholders, so it is **not valid TOML until\n * substituted**: `max_lines = {{core_budget}}` parses as nothing.\n *\n * Found by running the runner, which reported `table not found` for a file\n * plainly on disk. Tables are substituted against the repo's own installed\n * parameters before parsing \u2014 which is also what makes a gate honour the\n * prefix, root and budget that repo actually chose.\n */\nfunction loadTable(ref: string | undefined, repoRoot: string): any | null {\n if (!ref) return null;\n const [mod, file] = ref.split('/');\n const path = join(MODULES, mod, 'gates', file);\n if (!existsSync(path)) return null;\n try {\n return parse(substitute(readFileSync(path, 'utf8'), mod, installedParams(repoRoot)));\n } catch {\n return null;\n }\n}\n\nlet paramCache: { root: string; params: Params } | null = null;\n\n/** Parameters as the repo installed them, falling back to module defaults. */\nfunction installedParams(repoRoot: string): Params {\n if (paramCache?.root === repoRoot) return paramCache.params;\n const defaults = resolveParams(loadAllModules(MODULES), {}, repoRoot);\n const recordPath = join(repoRoot, '.ai', 'rungs.toml');\n if (existsSync(recordPath)) {\n try {\n const rec = parse(readFileSync(recordPath, 'utf8')) as any;\n for (const [name, entry] of Object.entries<any>(rec.modules ?? {})) {\n if (entry?.params) defaults[name] = { ...(defaults[name] ?? {}), ...entry.params };\n }\n } catch {\n /* a malformed record falls back to defaults rather than failing every gate */\n }\n }\n paramCache = { root: repoRoot, params: defaults };\n return defaults;\n}\n\nconst tableKey = (engine: string) =>\n ({\n 'file-budget': 'file_budget',\n sections: 'sections',\n 'frontmatter-schema': 'frontmatter_schema',\n 'link-integrity': 'link_integrity',\n 'file-population': 'file_population',\n 'gate-meta': 'gate_meta',\n 'id-integrity': '__whole__',\n 'render-freshness': 'render_freshness',\n 'register-schema': 'register_schema',\n 'self-declared-closure': 'self_declared_closure',\n 'filename-schema': 'filename_schema',\n 'cross-reference': 'cross_reference',\n 'git-status-reconcile': 'merged_status',\n 'computed-claim': 'computed_claim',\n 'term-ownership': 'term_ownership',\n 'rule-propagation': 'rule_propagation',\n 'git-state': 'git_state',\n 'merge-driver-check': 'merge_driver_check',\n })[engine] ?? engine;\n\n/**\n * ADR-0005 tier A. One line per gate per run: what the runner directly observes\n * and nothing that needs interpretation. Local, gitignored, never transmitted.\n */\nexport function appendLedger(repoRoot: string, runs: GateRun[], stamp: string) {\n const { runner } = loadRegistry(repoRoot);\n if (runner.ledger === false) return;\n const path = join(repoRoot, '.ai', '.gate-ledger.jsonl');\n const lines = runs\n .map((r) => JSON.stringify({ at: stamp, id: r.id, status: r.status, ms: r.ms, examined: r.examined }))\n .join('\\n');\n appendFileSync(path, lines + '\\n');\n}\n\n/** The two questions ADR-0005 tier B allows, both binary facts. */\nexport function ledgerQuestions(repoRoot: string, gates: RegistryGate[]) {\n const path = join(repoRoot, '.ai', '.gate-ledger.jsonl');\n if (!existsSync(path)) return { neverFired: [], alwaysFires: [], runs: 0 };\n const rows = readFileSync(path, 'utf8')\n .split('\\n')\n .filter(Boolean)\n .map((l) => JSON.parse(l) as { id: string; status: Status });\n const by = new Map<string, { total: number; failed: number }>();\n for (const r of rows) {\n const e = by.get(r.id) ?? { total: 0, failed: 0 };\n e.total++;\n if (r.status === 'fail') e.failed++;\n by.set(r.id, e);\n }\n const whyOf = (id: string) => gates.find((g) => g.id === id)?.why;\n const neverFired = [...by].filter(([, e]) => e.total >= 3 && e.failed === 0).map(([id]) => ({ id, why: whyOf(id) }));\n const alwaysFires = [...by]\n .filter(([, e]) => e.total >= 3 && e.failed / e.total > 0.9)\n .map(([id, e]) => ({ id, why: whyOf(id), rate: `${e.failed}/${e.total}` }));\n return { neverFired, alwaysFires, runs: rows.length };\n}\n", "import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { matchAny, walk } from './glob.ts';\nimport {\n computedClaim,\n crossReference,\n filenameSchema,\n gitStatusReconcile,\n idIntegrity,\n registerSchema,\n renderFreshness,\n selfDeclaredClosure,\n} from './engines2.ts';\nimport { gitState, mergeDriverCheck, rulePropagation, termOwnership } from './engines3.ts';\n\nexport interface Finding {\n file?: string;\n message: string;\n}\nexport interface EngineResult {\n findings: Finding[];\n /** What the engine looked at. A gate that examined nothing is not a passing gate. */\n examined: number;\n}\nexport type Engine = (table: any, repoRoot: string, files: string[]) => EngineResult;\n\nconst read = (root: string, rel: string) => {\n try {\n return readFileSync(join(root, rel), 'utf8');\n } catch {\n return '';\n }\n};\n\n/**\n * `expand` also drops anything the CLI generated.\n *\n * Without it a gate fires on its own tool's output: `render` degrades a\n * path-scoped rule into a nested `docs/plans/AGENTS.md` for harnesses with no\n * glob scoping, and the `workflows` gate \u2014 which scans `docs/plans/**` for plan\n * documents \u2014 then reported that file for having no plan frontmatter. The\n * render pipeline and the gate scopes collide by construction, so the exclusion\n * is global rather than per-table: **a gate must never fire on a file rungs\n * wrote.**\n */\nconst GENERATED = 'Generated by `rungs';\n\nconst expand = (files: string[], patterns: string[] | undefined, fallback: string[] = []) =>\n [...new Set((patterns ?? fallback).flatMap((p) => matchAny(files, p)))];\n\nfunction dropGenerated(root: string, rels: string[]): string[] {\n return rels.filter((rel) => !read(root, rel).slice(0, 600).includes(GENERATED));\n}\n\n/** Lines that actually load: HTML comments are stripped by at least one harness. */\nfunction loadedLines(text: string): number {\n return text\n .replace(/^---\\n[\\s\\S]*?\\n---\\n/, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .split('\\n')\n .filter((l) => l.trim()).length;\n}\n\nconst fileBudget: Engine = (t, root, files) => {\n const targets = dropGenerated(root, t.file ? [t.file] : expand(files, t.scan));\n const excluded = new Set(expand(files, t.exclude, []));\n const findings: Finding[] = [];\n let examined = 0;\n for (const rel of targets) {\n if (excluded.has(rel) || !existsSync(join(root, rel))) continue;\n examined++;\n const n = loadedLines(read(root, rel));\n if (n > t.max_lines) findings.push({ file: rel, message: `${n} lines, budget ${t.max_lines}` });\n }\n return { findings, examined };\n};\n\nconst sections: Engine = (t, root, files) => {\n const specs = Array.isArray(t) ? t : [t];\n const findings: Finding[] = [];\n let examined = 0;\n for (const spec of specs) {\n const targets = dropGenerated(root, spec.file ? [spec.file] : expand(files, spec.scan));\n const excluded = new Set(expand(files, spec.exclude, []));\n for (const rel of targets) {\n if (excluded.has(rel) || !existsSync(join(root, rel))) continue;\n examined++;\n const text = read(root, rel);\n const heads = [...text.matchAll(/^#{1,6}\\s+(.+?)\\s*$/gm)].map((m) => m[1]);\n for (const want of spec.required ?? []) {\n const idx = heads.findIndex((h) => h.toLowerCase().startsWith(String(want).toLowerCase()));\n if (idx === -1) {\n findings.push({ file: rel, message: `missing section '${want}'` });\n continue;\n }\n if (spec.non_empty) {\n const after = text.split(new RegExp(`^#{1,6}\\\\s+${escapeRe(heads[idx])}\\\\s*$`, 'm'))[1] ?? '';\n const body = after.split(/^#{1,6}\\s+/m)[0].replace(/<!--[\\s\\S]*?-->/g, '').trim();\n if (!body) findings.push({ file: rel, message: `section '${want}' is empty` });\n }\n }\n for (const open of spec.requires_opening ?? []) {\n if (!text.slice(0, 400).includes(open)) findings.push({ file: rel, message: `does not open with ${open}` });\n }\n }\n }\n return { findings, examined };\n};\n\nconst frontmatterSchema: Engine = (t, root, files) => {\n const specs = Array.isArray(t) ? t : [t];\n const findings: Finding[] = [];\n let examined = 0;\n for (const spec of specs) {\n for (const rel of dropGenerated(root, expand(files, spec.scan))) {\n if (new Set(expand(files, spec.exclude, [])).has(rel)) continue;\n const text = read(root, rel);\n const m = text.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!m) {\n findings.push({ file: rel, message: 'no frontmatter' });\n continue;\n }\n examined++;\n const keys = [...m[1].matchAll(/^([a-zA-Z0-9_-]+):/gm)].map((k) => k[1]);\n for (const req of spec.required ?? []) {\n if (!keys.includes(req)) findings.push({ file: rel, message: `missing '${req}'` });\n }\n if (spec.allowed) {\n for (const k of keys) {\n if (!spec.allowed.includes(k)) findings.push({ file: rel, message: `non-spec key '${k}'` });\n }\n }\n for (const [key, values] of Object.entries(spec.enum ?? {})) {\n const v = m[1].match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'))?.[1].trim().replace(/^[\"']|[\"']$/g, '');\n if (v && !(values as string[]).map(String).includes(v)) {\n findings.push({ file: rel, message: `${key}='${v}' not one of ${(values as string[]).join(', ')}` });\n }\n }\n }\n }\n return { findings, examined };\n};\n\nconst linkIntegrity: Engine = (t, root, files) => {\n const scan = expand(files, t.scan, ['**/*.md']); // link checks DO cover generated files\n const excluded = new Set(expand(files, t.exclude, []));\n const findings: Finding[] = [];\n let examined = 0;\n for (const rel of scan) {\n if (excluded.has(rel)) continue;\n const text = read(root, rel);\n examined++;\n if (/path-ok:\\s*\\S/.test(text)) continue;\n // A link written inside a code span is prose *quoting* a link \u2014 most often a document\n // explaining that some link is wrong. Blanked rather than removed, so every offset after it\n // is unchanged and the reported text still matches what the author sees.\n const scannable = text.replace(/`+[^`\\n]*`+/g, (s) => ' '.repeat(s.length));\n for (const m of scannable.matchAll(/\\]\\((?!https?:|#|mailto:)([^)\\s#]+)/g)) {\n // An unsubstituted placeholder makes a **template** link, which resolves only once\n // installed. This test used to sit on the whole file, and one token anywhere in a document\n // exempted every link in it: 16 non-excluded files, including eight that ship to consumer\n // repos, silently stopped being checked. A green gate and a skipped file looked identical.\n // The case the file-level skip was written for \u2014 `modules/*/fragments/AGENTS.md` linking\n // `{{path}}/README.md` \u2014 is already excluded by path in `link_integrity.exclude` (WI-008).\n if (/\\{\\{[a-z_.]+\\}\\}/.test(m[1])) continue;\n const target = resolve(root, dirname(rel), decodeURIComponent(m[1]));\n if (!existsSync(target)) findings.push({ file: rel, message: `broken link \u2192 ${m[1]}` });\n }\n }\n return { findings, examined };\n};\n\nconst filePopulation: Engine = (t, root, files) => {\n let hits = dropGenerated(root, expand(files, t.scan)).filter((f) => !new Set(expand(files, t.exclude, [])).has(f));\n\n // A `detect` narrows the population to files matching a shape. Without it the\n // gate counted *every scanned file* \u2014 so the redirect-stub check reported\n // \"12 matching files, threshold 1\" against a repo with no stubs at all, which\n // is a confidently wrong number rather than a finding.\n if (t.detect === 'body_is_only_a_pointer') {\n hits = hits.filter((rel) => {\n const body = read(root, rel)\n .replace(/^---\\n[\\s\\S]*?\\n---\\n/, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .replace(/^#.*$/gm, '')\n .trim();\n const words = body.split(/\\s+/).filter(Boolean).length;\n const links = (body.match(/\\]\\(/g) ?? []).length;\n // Short *and* mostly a link. Short alone is a stub-shaped index page.\n return words > 0 && words <= (t.max_body_words ?? 40) && links >= 1;\n });\n }\n\n const findings: Finding[] = [];\n const failAt = t.fail_at ?? Infinity;\n if (hits.length >= failAt) {\n findings.push({ message: `${hits.length} matching file(s), threshold ${failAt} (e.g. ${hits[0]})` });\n }\n return { findings, examined: hits.length };\n};\n\n/**\n * The meta-gate: every declared gate must carry a self-test expecting `pass`\n * and one expecting `fail`. A gate whose rules are all currently satisfied is\n * indistinguishable from a gate that matches nothing.\n */\nconst gateMeta: Engine = (_t, root) => {\n const findings: Finding[] = [];\n const registry = join(root, '.ai', 'gates.toml');\n if (!existsSync(registry)) return { findings, examined: 0 };\n const text = readFileSync(registry, 'utf8');\n const entries = [...text.matchAll(/\\[\\[gates\\]\\][\\s\\S]*?(?=\\n\\[\\[gates\\]\\]|\\n# rungs:end|$)/g)].map((m) => m[0]);\n let examined = 0;\n for (const entry of entries) {\n const id = entry.match(/^id\\s*=\\s*\"(.+)\"/m)?.[1];\n const kind = entry.match(/^kind\\s*=\\s*\"(.+)\"/m)?.[1];\n const table = entry.match(/^table\\s*=\\s*\"(.+)\"/m)?.[1];\n if (!id || kind !== 'declared' || !table) continue;\n examined++;\n // Tables live in the CLI, not the repo, so read them from the module set.\n const tablePath = join(dirname(new URL(import.meta.url).pathname.slice(1)), '..', 'modules', dirname(table), 'gates', table.split('/').pop()!);\n const src = existsSync(tablePath) ? readFileSync(tablePath, 'utf8') : '';\n const forGate = [...src.matchAll(/\\[\\[self_test\\]\\][\\s\\S]*?(?=\\n\\[\\[|\\n\\[|$)/g)]\n .map((m) => m[0])\n .filter((b) => b.includes(`gate = \"${id}\"`) || b.includes(`gate = \"${id}\"`) || b.includes(`gate = \"${id}\"`));\n for (const direction of ['pass', 'fail']) {\n if (!forGate.some((b) => new RegExp(`expect\\\\s*=\\\\s*\"${direction}\"`).test(b))) {\n findings.push({ message: `gate '${id}' has no self-test expecting '${direction}'` });\n }\n }\n }\n return { findings, examined };\n};\n\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\nexport const ENGINES: Record<string, Engine> = {\n 'file-budget': fileBudget,\n sections,\n 'frontmatter-schema': frontmatterSchema,\n 'link-integrity': linkIntegrity,\n 'file-population': filePopulation,\n 'gate-meta': gateMeta,\n 'id-integrity': idIntegrity,\n 'render-freshness': renderFreshness,\n 'register-schema': registerSchema,\n 'self-declared-closure': selfDeclaredClosure,\n 'filename-schema': filenameSchema,\n 'cross-reference': crossReference,\n 'git-status-reconcile': gitStatusReconcile,\n 'computed-claim': computedClaim,\n 'term-ownership': termOwnership,\n 'rule-propagation': rulePropagation,\n 'git-state': gitState,\n 'merge-driver-check': mergeDriverCheck,\n};\n\n/**\n * Engines named in a gate table but not implemented here. Reported by name and\n * treated as blocking \u2014 never as a pass.\n *\n * This is the single most dangerous failure this tool could have: a registry of\n * 31 gates reporting green because 25 of them do nothing. rift-forge's rule\n * generalises exactly \u2014 *we do not land on an unknown.*\n */\nexport function isImplemented(engine: string): boolean {\n return engine in ENGINES;\n}\n", "import { existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { matchAny } from './glob.ts';\nimport type { Engine, Finding } from './engines.ts';\n\nconst read = (root: string, rel: string) => {\n try {\n return readFileSync(join(root, rel), 'utf8');\n } catch {\n return '';\n }\n};\nconst expand = (files: string[], p: string[] | undefined, f: string[] = []) =>\n [...new Set((p ?? f).flatMap((x) => matchAny(files, x)))];\n\n/** An exemption marker is ignored unless it states a reason. */\nconst exempted = (text: string, marker?: string) =>\n !!marker && new RegExp(`${marker.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}\\\\s*\\\\S`).test(text);\n\n/**\n * Ids: uniqueness across the declared sources, citations that resolve, and the\n * stale-blocker rule \u2014 a document may not say it waits on work that has finished.\n */\nexport const idIntegrity: Engine = (t, root, files) => {\n const findings: Finding[] = [];\n let examined = 0;\n const known = new Set<string>();\n\n for (const [, kind] of Object.entries<any>(t.kinds ?? {})) {\n const re = new RegExp(`^\\\\s*id:\\\\s*(${kind.format})`, 'm');\n const seen = new Map<string, string>();\n for (const rel of expand(files, kind.sources)) {\n examined++;\n const text = read(root, rel);\n const id = text.match(re)?.[1] ?? rel.match(new RegExp(kind.format))?.[0];\n if (!id) continue;\n known.add(id);\n const prior = seen.get(id);\n if (prior) findings.push({ file: rel, message: `id ${id} also claimed by ${prior}` });\n else seen.set(id, rel);\n }\n // The marker must not name an id that is already spent.\n if (kind.marker?.file) {\n const m = read(root, kind.marker.file).match(new RegExp(kind.marker.pattern));\n if (m?.[1] && seen.has(m[1])) {\n findings.push({ file: kind.marker.file, message: `NEXT marker points at ${m[1]}, already taken` });\n }\n }\n }\n\n // Stale blockers. Vocabulary is narrow on purpose: a first draft that matched\n // `until <id>` hit 29 lines of true history in one repo's own voice.\n const sb = t.stale_blocker;\n if (sb?.phrases?.length && known.size) {\n const scope = expand(files, ['docs/**/*.md', 'AGENTS.md', 'CLAUDE.md']).filter(\n (f) => !expand(files, sb.scope_exclude, []).includes(f),\n );\n const past = (sb.past_tense_ok ?? []).map((p: string) => p.toLowerCase());\n for (const rel of scope) {\n const text = read(root, rel);\n if (exempted(text, sb.exempt_marker)) continue;\n for (const phrase of sb.phrases) {\n const re = new RegExp(`(.{0,${sb.negation_window ?? 60}})\\\\b${phrase}\\\\b\\\\s+([A-Z]{1,6}-\\\\d{1,4})`, 'gi');\n for (const m of text.matchAll(re)) {\n const lead = m[1].toLowerCase();\n if (past.some((p: string) => lead.includes(p.split(' ')[0]) && lead.includes('was'))) continue;\n if (/\\bnot\\b|\\bnever\\b|\\bno longer\\b/.test(lead.slice(-30))) continue;\n if (isDone(root, m[2], files)) {\n findings.push({ file: rel, message: `claims to be ${phrase} ${m[2]}, which is done` });\n }\n }\n }\n }\n }\n return { findings, examined };\n};\n\nfunction isDone(root: string, id: string, files: string[]): boolean {\n const hit = files.find((f) => f.includes(id) && f.endsWith('.md'));\n if (!hit) return false;\n const s = read(root, hit).match(/^status:\\s*(\\S+)/m)?.[1];\n return s === 'done' || hit.includes('/archive/');\n}\n\n/** Generated output that no longer matches what its producer would emit now. */\nexport const renderFreshness: Engine = (t, root, files) => {\n const specs = Array.isArray(t) ? t : [t];\n const findings: Finding[] = [];\n let examined = 0;\n for (const spec of specs) {\n if (spec.block?.file) {\n examined++;\n const text = read(root, spec.block.file);\n const re = new RegExp(`rungs:begin ${spec.block.marker}[\\\\s\\\\S]*?rungs:end ${spec.block.marker}`);\n if (!re.test(text)) {\n findings.push({ file: spec.block.file, message: `no '${spec.block.marker}' block \u2014 run \\`${spec.command}\\`` });\n }\n continue;\n }\n const excluded = new Set(expand(files, spec.exclude, []));\n const sources = expand(files, spec.sources).filter((s) => !excluded.has(s));\n const targets = expand(files, spec.targets);\n // Only harnesses this repo actually emits for are checked; a missing\n // `.cursor/rules` in a repo that never asked for Cursor is not staleness.\n const live = new Set(targets.map((x) => x.split('/')[0]));\n for (const src of sources) {\n examined++;\n const stem = src.split('/').pop()!.replace(/\\.md$/, '');\n for (const dir of live) {\n if (!targets.some((x) => x.startsWith(dir) && x.includes(stem))) {\n findings.push({ file: src, message: `no rendering under ${dir}/ \u2014 run \\`${spec.command}\\`` });\n }\n }\n }\n }\n return { findings, examined };\n};\n\n/** Markdown-table registers: required columns, enums, and conditional rules. */\nexport const registerSchema: Engine = (t, root, files) => {\n const findings: Finding[] = [];\n let examined = 0;\n const targets = t.file ? [t.file] : expand(files, t.scan);\n for (const rel of targets) {\n const text = read(root, rel);\n if (!text) continue;\n for (const table of parseTables(text)) {\n if (t.table && !sectionOf(text, table.headerLine).toLowerCase().includes(String(t.table).toLowerCase())) continue;\n const cols = t.required_cols ?? t.table_columns ?? [];\n const present = cols.filter((c: string) =>\n table.headers.some((h) => h.toLowerCase() === String(c).toLowerCase()),\n );\n // Recognition before validation: a file may hold several tables and only\n // some are registers. Demanding every one carry the columns reported a\n // spec index for not being a story table.\n if (cols.length && present.length < Math.max(2, Math.ceil(cols.length / 2))) continue;\n for (const c of cols) {\n if (!present.includes(c)) findings.push({ file: rel, message: `register table missing column '${c}'` });\n }\n for (const row of table.rows) {\n if (Object.values(row).every((v) => !v || v === '\u2014')) continue;\n examined++;\n for (const [key, values] of Object.entries<any>(t.enum ?? {})) {\n const v = strip(row[key]);\n if (v && !values.map(String).includes(v)) {\n findings.push({ file: rel, message: `${key}='${v}' not one of ${values.join(', ')}` });\n }\n }\n for (const c of t.non_empty ?? []) {\n if (!strip(row[c])) findings.push({ file: rel, message: `row ${firstCell(row)}: '${c}' is empty` });\n }\n for (const cond of t.conditional ?? []) {\n const matches = Object.entries<any>(cond.when ?? {}).every(([k, v]) => strip(row[k]) === String(v));\n if (!matches) continue;\n for (const c of cond.non_empty ?? []) {\n const v = strip(row[c]);\n if (!v) findings.push({ file: rel, message: `row ${firstCell(row)}: '${c}' required when ${JSON.stringify(cond.when)}` });\n else if (cond.min_words?.[c] && v.split(/\\s+/).length < cond.min_words[c]) {\n findings.push({ file: rel, message: `row ${firstCell(row)}: '${c}' is too thin to be a reason` });\n }\n }\n }\n }\n }\n }\n return { findings, examined };\n};\n\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * An open finding must not declare itself fixed in its own detail section.\n *\n * This is deliberately a text-only contradiction check. It does not inspect\n * code or infer that a fix really shipped; those questions are repository-\n * specific and a guessed probe would be confidently wrong. A section may\n * contain a reasoned `closure-ok:` marker when only a part of the observation\n * was addressed. The table owns the headings, id shape, and verdict phrases so\n * the engine remains useful for registers that use a different prefix or\n * detail heading.\n */\nexport const selfDeclaredClosure: Engine = (t, root, files) => {\n const findings: Finding[] = [];\n let examined = 0;\n const targets = t.file ? [t.file] : expand(files, t.scan ?? ['docs/**/FINDINGS.md']);\n const idPattern = t.id_pattern ?? '[A-Z]{1,6}-\\\\d{1,4}';\n const openRow = new RegExp(t.open_row_pattern ?? `^\\\\|\\\\s*\\\\[?(${idPattern})\\\\]`, 'gmu');\n const detailHeading = new RegExp(t.detail_heading_pattern ?? `^###\\\\s+(${idPattern})\\\\s+\u2014\\\\s+`, 'gmu');\n const verdicts = (t.declares_fixed ?? [\n '\\\\*\\\\*Fixed[.,)*]',\n '\\\\*\\\\*Fixed\\\\s+(?:in|by|the\\\\s+same\\\\s+day|\\\\d{4}-\\\\d{2}-\\\\d{2})',\n '\\\\*\\\\*Implemented in this change\\\\.?\\\\*\\\\*',\n '\\\\*\\\\*fixed in the pass that found it\\\\*\\\\*',\n ]).map((p: string) => new RegExp(p, 'iu'));\n\n for (const rel of targets) {\n const text = read(root, rel);\n if (!text) continue;\n const openStart = headingIndex(text, t.open_heading ?? 'Open');\n const closedStart = headingIndex(text, t.closed_heading ?? 'Closed');\n const detailStart = headingIndex(text, t.detail_heading ?? 'Detail');\n if (openStart < 0 || closedStart < 0 || detailStart < 0 || closedStart <= openStart || detailStart < closedStart) continue;\n\n const open = new Set<string>();\n for (const match of text.slice(openStart, closedStart).matchAll(openRow)) open.add(match[1]);\n if (!open.size) continue;\n\n const detail = text.slice(detailStart);\n const headings = [...detail.matchAll(detailHeading)];\n for (let i = 0; i < headings.length; i++) {\n const id = headings[i][1];\n if (!open.has(id)) continue;\n examined++;\n const start = headings[i].index ?? 0;\n const end = headings[i + 1]?.index ?? detail.length;\n const section = detail.slice(start, end);\n const marker = t.exempt_marker ?? 'closure-ok:';\n if (new RegExp(`<!--\\\\s*${escapeRe(marker)}\\\\s*\\\\S`, 'u').test(section)) continue;\n const body = section.slice(section.indexOf('\\n') + 1);\n for (const verdict of verdicts) {\n const match = verdict.exec(body);\n if (!match) continue;\n const before = body.slice(Math.max(0, match.index - (t.citation_window ?? 120)), match.index);\n const cited = [...before.matchAll(new RegExp(`(${idPattern})[^.]{0,${t.citation_window ?? 120}}$`, 'gu'))].at(-1)?.[1];\n if (cited && cited !== id) continue;\n findings.push({ file: rel, message: `${id} is open but its detail declares it fixed: ${body.slice(match.index, match.index + 60).split('\\n')[0].trim()}` });\n break;\n }\n }\n }\n return { findings, examined };\n};\n\nfunction headingIndex(text: string, heading: string): number {\n const re = new RegExp(`^#{1,6}\\\\s+${escapeRe(heading)}\\\\s*$`, 'imu');\n return text.search(re);\n}\n\nconst strip = (v?: string) => (v ?? '').replace(/[`*\\[\\]]/g, '').split('(')[0].trim();\nconst firstCell = (row: Record<string, string>) => strip(Object.values(row)[0]) || '?';\n\nfunction parseTables(text: string) {\n const out: { headers: string[]; rows: Record<string, string>[]; headerLine: number }[] = [];\n const lines = text.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (!/^\\s*\\|/.test(lines[i]) || !/^\\s*\\|[\\s:|-]+\\|/.test(lines[i + 1] ?? '')) continue;\n const headers = cells(lines[i]);\n const rows: Record<string, string>[] = [];\n let j = i + 2;\n for (; j < lines.length && /^\\s*\\|/.test(lines[j]); j++) {\n const c = cells(lines[j]);\n rows.push(Object.fromEntries(headers.map((h, k) => [h, c[k] ?? ''])));\n }\n out.push({ headers, rows, headerLine: i });\n i = j;\n }\n return out;\n}\nconst cells = (line: string) => line.trim().replace(/^\\||\\|$/g, '').split('|').map((s) => s.trim());\nconst sectionOf = (text: string, line: number) => {\n const before = text.split('\\n').slice(0, line);\n for (let i = before.length - 1; i >= 0; i--) if (/^#{1,6}\\s/.test(before[i])) return before[i];\n return '';\n};\n\nexport const filenameSchema: Engine = (t, root, files) => {\n const re = new RegExp(t.pattern);\n const excluded = new Set(expand(files, t.exclude, []));\n const findings: Finding[] = [];\n let examined = 0;\n for (const rel of expand(files, t.scan)) {\n if (excluded.has(rel)) continue;\n examined++;\n const base = rel.split('/').pop()!;\n if (!re.test(base)) findings.push({ file: rel, message: 'filename does not say what closed and what came next' });\n }\n return { findings, examined };\n};\n\n/** Skills naming their neighbours \u2014 only past the threshold where it matters. */\nexport const crossReference: Engine = (t, root, files) => {\n const skills = expand(files, t.scan);\n if (skills.length < (t.min_skills ?? 6)) return { findings: [], examined: skills.length };\n const names = skills.map((s) => s.split('/').slice(-2)[0]);\n const findings: Finding[] = [];\n for (const rel of skills) {\n const text = read(root, rel);\n if (exempted(text, t.exempt_marker)) continue;\n const desc = text.match(/^---\\n([\\s\\S]*?)\\n---/)?.[1] ?? '';\n const self = rel.split('/').slice(-2)[0];\n if (!names.some((n) => n !== self && desc.includes(n))) {\n findings.push({ file: rel, message: `names no neighbouring skill (${skills.length} in this repo)` });\n }\n }\n return { findings, examined: skills.length };\n};\n\n/** A merged branch cannot still sit at a pre-review status. One-directional. */\nexport const gitStatusReconcile: Engine = (t, root, files) => {\n const findings: Finding[] = [];\n let merged: Set<string>;\n try {\n merged = new Set(\n execSync(`git branch --merged ${t.integration_branch ?? 'main'} --format=%(refname:short)`, {\n cwd: root,\n stdio: 'pipe',\n })\n .toString()\n .split('\\n')\n .map((s) => s.trim())\n .filter(Boolean),\n );\n } catch {\n // No git, or no such branch. Not a pass and not a failure \u2014 an unknown.\n return { findings: [{ message: 'cannot read git branches; status not reconciled' }], examined: 0 };\n }\n let examined = 0;\n for (const rel of expand(files, ['docs/**/items/**/*.md'])) {\n const text = read(root, rel);\n if (exempted(text, t.exempt_marker)) continue;\n const branch = text.match(new RegExp(`^${t.branch_field ?? 'branch'}:\\\\s*(\\\\S+)`, 'm'))?.[1];\n const status = text.match(new RegExp(`^${t.status_field ?? 'status'}:\\\\s*(\\\\S+)`, 'm'))?.[1];\n if (!branch || !status) continue;\n examined++;\n if (merged.has(branch) && (t.pre_review_statuses ?? []).includes(status)) {\n findings.push({ file: rel, message: `branch ${branch} is merged but status is '${status}'` });\n }\n }\n return { findings, examined };\n};\n\n/** A number a machine can compute is never typed by a human. */\nexport const computedClaim: Engine = (t, root, files) => {\n const specs = Array.isArray(t) ? t : [t];\n const findings: Finding[] = [];\n let examined = 0;\n for (const spec of specs) {\n const values = new Map<string, string>();\n for (const src of spec.sources ?? []) {\n for (const rel of matchAny(files, src.file)) {\n const text = read(root, rel);\n let v: string | undefined;\n if (src.path && rel.endsWith('.json')) {\n try {\n v = src.path.split('.').reduce((o: any, k: string) => o?.[k], JSON.parse(text));\n } catch {\n /* unparseable is not a disagreement */\n }\n } else if (src.xpath) {\n v = text.match(new RegExp(`<${src.xpath.split('//')[1]}>(.*?)<`))?.[1];\n }\n if (v) {\n examined++;\n values.set(rel, String(v));\n }\n }\n }\n const distinct = new Set(values.values());\n if (spec.rule === 'all-agree' && distinct.size > 1) {\n findings.push({\n message: `${spec.id} disagrees across ${values.size} locations: ${[...distinct].join(', ')} \u2014 run \\`${spec.autofix}\\``,\n });\n }\n }\n return { findings, examined };\n};\n", "import { existsSync, readFileSync } from 'node:fs';\nimport { execSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { matchAny } from './glob.ts';\nimport type { Engine, Finding } from './engines.ts';\n\nconst read = (root: string, rel: string) => {\n try {\n return readFileSync(join(root, rel), 'utf8');\n } catch {\n return '';\n }\n};\nconst expand = (files: string[], p: string[] | undefined, f: string[] = []) =>\n [...new Set((p ?? f).flatMap((x) => matchAny(files, x)))];\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** An exemption marker is ignored unless it states a reason. */\nconst exempted = (text: string, marker?: string) =>\n !!marker && new RegExp(`${escapeRe(marker)}\\\\s*\\\\S`).test(text);\n\n/** Rows of the first markdown table under a heading containing `near`. */\nfunction tableRows(text: string, near?: string): Record<string, string>[] {\n const lines = text.split('\\n');\n const rows: Record<string, string>[] = [];\n let heading = '';\n for (let i = 0; i < lines.length; i++) {\n if (/^#{1,6}\\s/.test(lines[i])) heading = lines[i];\n if (!/^\\s*\\|/.test(lines[i]) || !/^\\s*\\|[\\s:|-]+\\|/.test(lines[i + 1] ?? '')) continue;\n if (near && !heading.toLowerCase().includes(near.toLowerCase())) continue;\n const cells = (l: string) => l.trim().replace(/^\\||\\|$/g, '').split('|').map((s) => s.trim());\n const headers = cells(lines[i]);\n for (let j = i + 2; j < lines.length && /^\\s*\\|/.test(lines[j]); j++) {\n const c = cells(lines[j]);\n rows.push(Object.fromEntries(headers.map((h, k) => [h, c[k] ?? ''])));\n }\n i = lines.length;\n }\n return rows;\n}\n\nconst clean = (v = '') => v.replace(/[`*\\[\\]]/g, '').trim();\n\n/** Words distinctive enough to indicate a topic is being restated, not mentioned. */\nfunction terms(topic: string): string[] {\n const stop = new Set(['the', 'and', 'for', 'with', 'per', 'its', 'a', 'an', 'of', 'to', 'in', 'on', 'is', 'are']);\n return clean(topic)\n .toLowerCase()\n .split(/[^a-z0-9_-]+/)\n .filter((w) => w.length > 3 && !stop.has(w));\n}\n\n/**\n * One owner per topic, checked by vocabulary.\n *\n * The registry's third column \u2014 where a topic must NOT appear \u2014 is what turns\n * \"one source of truth\" from a principle into a lookup. Approximate by\n * construction: it catches a section that restates a topic, not one that\n * restates it in different words. That ceiling is pinned in the message rather\n * than hidden, so a green run never reads as \"verified\".\n */\nexport const termOwnership: Engine = (t, root, files) => {\n const registry = read(root, t.registry ?? 'docs/doc-ownership.md');\n if (!registry) return { findings: [{ message: `ownership registry '${t.registry}' not found` }], examined: 0 };\n\n const cols = t.columns ?? {};\n const findings: Finding[] = [];\n let examined = 0;\n\n for (const row of tableRows(registry)) {\n const topic = clean(row[cols.topic ?? 'Topic']);\n const owner = clean(row[cols.owner ?? 'Owner']);\n const forbidden = clean(row[cols.forbidden ?? 'Must NOT appear in']);\n if (!topic || !forbidden || forbidden === '\u2014' || topic.startsWith('(example)')) continue;\n\n const want = terms(topic);\n if (want.length < 2) continue; // too vague to test without guessing\n const patterns = forbidden.split(/[,\u00B7]/).map((s) => s.trim()).filter(Boolean);\n\n for (const rel of expand(files, patterns)) {\n if (rel === owner) continue;\n const text = read(root, rel);\n if (exempted(text, t.exempt_marker)) continue;\n examined++;\n // Per section, not per file: a passing mention is a cross-reference, a\n // section carrying several of the topic's terms is a restatement.\n for (const section of text.split(/^#{1,6}\\s+/m)) {\n const lower = section.toLowerCase();\n const hits = want.filter((w) => lower.includes(w));\n if (hits.length >= (t.engage_min_terms ?? 3)) {\n findings.push({ file: rel, message: `restates \"${topic}\", owned by ${owner} (${hits.length} terms)` });\n break;\n }\n }\n }\n }\n return { findings, examined };\n};\n\n/**\n * A working rule lives in more surfaces than its authority, and fixing the\n * authority does not reach them. Each declared rule names the surfaces that\n * restate it; a surface carrying the retired wording is reported.\n *\n * `forbids` is matched against a preceding-context negation window, because a\n * retired phrase inside \"do NOT <retired>\" is the fix, not the violation \u2014 and\n * a guard that refuses its own fix is one people disable.\n */\nexport const rulePropagation: Engine = (t, root, files) => {\n const registry = read(root, t.registry ?? 'docs/working-rules.md');\n if (!registry) return { findings: [{ message: `rules registry '${t.registry}' not found` }], examined: 0 };\n\n const cols = t.columns ?? {};\n const findings: Finding[] = [];\n let examined = 0;\n const window = t.negation_window ?? 60;\n\n for (const row of tableRows(registry)) {\n const rule = clean(row[cols.rule ?? 'Rule']);\n const retired = clean(row[cols.retired ?? 'Retired wording']);\n const surfaces = clean(row[cols.surfaces ?? 'Surfaces that restate it']);\n if (!rule || !retired || retired === '\u2014' || rule.startsWith('(example)')) continue;\n\n for (const rel of expand(files, surfaces.split(/[,\u00B7]/).map((s) => s.trim()).filter(Boolean))) {\n const text = read(root, rel);\n if (exempted(text, t.exempt_marker)) continue;\n examined++;\n const re = new RegExp(`(.{0,${window}})${escapeRe(retired)}`, 'gis');\n for (const m of text.matchAll(re)) {\n const lead = m[1].toLowerCase();\n if (/\\bnot\\b|\\bnever\\b|\\bno longer\\b|\\bused to\\b|\\bformerly\\b|\\bretired\\b/.test(lead)) continue;\n findings.push({ file: rel, message: `carries the retired wording for \"${rule}\"` });\n break;\n }\n }\n }\n return { findings, examined };\n};\n\n/**\n * The integration branch must be checked out nowhere.\n *\n * Recorded as a correction rather than a preference: holding it checked out\n * blocked every other session *and* did not prevent concurrent landing anyway,\n * because switching to the scratch ref releases it mid-run.\n */\nexport const gitState: Engine = (t, root) => {\n let out: string;\n try {\n out = execSync('git worktree list --porcelain', { cwd: root, stdio: 'pipe' }).toString();\n } catch {\n // Not a git repo, or git unavailable. An unattributable result blocks:\n // we do not land on an unknown.\n return { findings: [{ message: 'cannot read git worktrees; checkout state unknown' }], examined: 0 };\n }\n const findings: Finding[] = [];\n const blocks = out.split('\\n\\n').filter(Boolean);\n for (const b of blocks) {\n const dir = b.match(/^worktree (.+)$/m)?.[1];\n const branch = b.match(/^branch refs\\/heads\\/(.+)$/m)?.[1];\n if (branch && (t.refuse_checked_out ?? []).includes(branch)) {\n findings.push({ message: `'${branch}' is checked out in ${dir} \u2014 nothing should hold it` });\n }\n }\n return { findings, examined: blocks.length };\n};\n\n/**\n * Merge drivers named in `.gitattributes` are **inert until installed**, so a\n * fresh clone silently falls back to git's default merge on files that must\n * never be text-merged. Declaring them is not the same as having them.\n */\nexport const mergeDriverCheck: Engine = (t, root) => {\n const attrs = read(root, t.attributes_file ?? '.gitattributes');\n if (!attrs) return { findings: [], examined: 0 };\n\n const declared = [...new Set([...attrs.matchAll(/merge=([\\w-]+)/g)].map((m) => m[1]))];\n const required = (t.required_drivers ?? []).filter((d: string) => declared.includes(d));\n if (!required.length) return { findings: [], examined: declared.length };\n\n const findings: Finding[] = [];\n for (const driver of required) {\n let configured = '';\n try {\n configured = execSync(`git config --get merge.${driver}.driver`, { cwd: root, stdio: 'pipe' }).toString().trim();\n } catch {\n /* absent config exits non-zero, which is the finding */\n }\n if (!configured) {\n findings.push({ message: `driver '${driver}' is declared but not installed \u2014 run \\`${t.install_command}\\`` });\n }\n }\n return { findings, examined: declared.length };\n};\n", "import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { execSync } from 'node:child_process';\nimport { parse } from 'smol-toml';\nimport type { Manifest } from './types.ts';\nimport { contentHash, emittedFiles } from './add.ts';\nimport { resolveParams, substitute, type Params } from './substitute.ts';\nimport { loadRegistry } from './check.ts';\n\nconst SRC = dirname(fileURLToPath(import.meta.url));\n\n/** Bundles from the module catalogue. `init` offers these, not a list of fifteen. */\nexport const PROFILES: Record<string, string[]> = {\n minimal: ['instructions'],\n tracked: ['instructions', 'gates', 'backlog', 'findings', 'adr', 'session'],\n disciplined: ['instructions', 'gates', 'backlog', 'findings', 'adr', 'session', 'ci', 'specs', 'workflows', 'skills', 'audit'],\n hardened: ['instructions', 'gates', 'backlog', 'findings', 'adr', 'session', 'ci', 'specs', 'workflows', 'skills', 'audit', 'release', 'doc-authority'],\n fleet: ['instructions', 'gates', 'backlog', 'findings', 'adr', 'session', 'ci', 'specs', 'workflows', 'skills', 'audit', 'release', 'doc-authority', 'concurrency', 'design-sync'],\n};\n\nexport interface InstallRecord {\n harnesses: string[];\n modules: Record<string, { version: string; params?: Record<string, unknown>; hashes?: Record<string, string>; kept?: { files: string[] } }>;\n}\n\nexport function readRecord(repoRoot: string): InstallRecord | null {\n const p = join(repoRoot, '.ai', 'rungs.toml');\n if (!existsSync(p)) return null;\n try {\n const raw = parse(readFileSync(p, 'utf8')) as any;\n return { harnesses: raw.repo?.harnesses ?? [], modules: raw.modules ?? {} };\n } catch {\n return null;\n }\n}\n\nexport type FileState = 'current' | 'diverged' | 'stale' | 'missing';\n\nexport interface UpgradeItem {\n module: string;\n from: string;\n to: string;\n files: { rel: string; state: FileState }[];\n}\n\n/**\n * Compare what is on disk against both the recorded hash and what the module\n * would emit now. Those two comparisons answer different questions:\n *\n * matches recorded, matches current \u2192 current, nothing to do\n * matches recorded, differs current \u2192 **stale**, ours to replace\n * differs recorded \u2192 **diverged**, theirs; never touched\n *\n * Without the recorded hash the middle two collapse, and upgrade would either\n * clobber deliberate edits or refuse to move anything.\n */\nexport function planUpgrade(repoRoot: string, mods: Manifest[], record: InstallRecord): UpgradeItem[] {\n const params = resolveParams(mods, paramsFrom(record), repoRoot);\n const skillsDir = record.harnesses.includes('claude') ? '.claude/skills' : '.agents/skills';\n const items: UpgradeItem[] = [];\n\n for (const mod of mods) {\n const installed = record.modules[mod.name];\n if (!installed) continue;\n const emitted = emittedFiles(mod, params, skillsDir);\n const files: UpgradeItem['files'] = [];\n const kept = new Set(installed.kept?.files ?? []);\n for (const [rel, wouldEmit] of emitted) {\n if (kept.has(rel)) continue; // never ours; upgrade does not touch it\n const full = join(repoRoot, rel);\n if (!existsSync(full)) {\n files.push({ rel, state: 'missing' });\n continue;\n }\n const onDisk = contentHash(readFileSync(full, 'utf8'));\n const recorded = installed.hashes?.[rel];\n if (onDisk === contentHash(wouldEmit)) files.push({ rel, state: 'current' });\n else if (recorded && onDisk === recorded) files.push({ rel, state: 'stale' });\n else files.push({ rel, state: 'diverged' });\n }\n items.push({ module: mod.name, from: installed.version, to: mod.version, files });\n }\n return items;\n}\n\n/** Applies only `stale` and `missing`. Divergence is a decision, not an error. */\nexport function applyUpgrade(repoRoot: string, mods: Manifest[], record: InstallRecord, plan: UpgradeItem[]) {\n const params = resolveParams(mods, paramsFrom(record), repoRoot);\n const skillsDir = record.harnesses.includes('claude') ? '.claude/skills' : '.agents/skills';\n let written = 0;\n for (const item of plan) {\n const mod = mods.find((m) => m.name === item.module)!;\n const emitted = emittedFiles(mod, params, skillsDir);\n for (const f of item.files) {\n if (f.state !== 'stale' && f.state !== 'missing') continue;\n const full = join(repoRoot, f.rel);\n mkdirSync(dirname(full), { recursive: true });\n writeFileSync(full, emitted.get(f.rel)!);\n written++;\n }\n }\n return written;\n}\n\nfunction paramsFrom(record: InstallRecord): Params {\n const out: Params = {};\n for (const [name, entry] of Object.entries(record.modules)) {\n if (entry.params) out[name] = { ...entry.params };\n }\n return out;\n}\n\n/**\n * ADR-0002's promised exit. Materialises the engines and their tables into the\n * repo and rewrites every declared gate to a `command` gate that runs them.\n *\n * This is a stated obligation, not a nicety: a tool whose checks disappear when\n * you uninstall it is one nobody should adopt, and promising the exit is what\n * makes the no-scripts-in-your-repo default acceptable.\n */\nexport function eject(repoRoot: string, mods: Manifest[], dryRun = false) {\n const dest = join(repoRoot, '.rungs');\n // Only what the runner actually needs, and nothing that imports a package.\n // The first version copied `check.ts` and `manifest.ts` too, which pull in the\n // TOML parser \u2014 so an ejected repo crashed on a module it could not resolve.\n // An exit that does not work is not an exit.\n const engines = ['glob.ts', 'engines.ts', 'engines2.ts'];\n const { gates } = loadRegistry(repoRoot);\n const declared = gates.filter((g) => g.kind === 'declared' && g.table);\n const tables = [...new Set(declared.map((g) => g.table!))];\n\n const actions: string[] = [];\n for (const f of engines) actions.push(`.rungs/${f}`);\n for (const t of tables) actions.push(`.rungs/tables/${t.replace('/', '-').replace(/.toml$/, '.json')}`);\n actions.push('.rungs/run-gate.mjs', '.ai/gates.toml (rewritten to command gates)');\n\n if (dryRun) return { actions, gates: declared.length };\n\n mkdirSync(join(dest, 'tables'), { recursive: true });\n for (const f of engines) copyFileSync(join(SRC, f), join(dest, f));\n\n // Tables are **converted to JSON at eject time**, parsed here with the parser\n // this CLI already has. The ejected repo then needs no TOML dependency at all\n // \u2014 which is the same promise ADR-0002 makes about installation, kept on the\n // way out. Parameters are substituted now, for the same reason.\n const record = readRecord(repoRoot);\n const params = resolveParams(mods, record ? paramsFrom(record) : {}, repoRoot);\n for (const t of tables) {\n const [mod, file] = t.split('/');\n const src = join(SRC, '..', 'modules', mod, 'gates', file);\n if (!existsSync(src)) continue;\n try {\n const parsed = parse(substitute(readFileSync(src, 'utf8'), mod, params));\n writeFileSync(join(dest, 'tables', `${mod}-${file.replace(/\\.toml$/, '.json')}`), JSON.stringify(parsed, null, 2));\n } catch {\n /* an unparseable table is dropped, and its gate will say so when run */\n }\n }\n\n writeFileSync(join(dest, 'run-gate.mjs'), RUNNER);\n writeFileSync(join(dest, 'README.md'), EJECT_README);\n\n const registry = join(repoRoot, '.ai', 'gates.toml');\n let text = readFileSync(registry, 'utf8');\n for (const g of declared) {\n text = text.replace(\n new RegExp(`(id\\\\s*=\\\\s*\"${g.id}\"[\\\\s\\\\S]*?)kind\\\\s*=\\\\s*\"declared\"`),\n `$1kind = \"command\"\\ncommand = \"node .rungs/run-gate.mjs ${g.id}\"`,\n );\n }\n writeFileSync(registry, `${text}\\n# Ejected: gates above run from .rungs/ and no longer need rungs installed.\\n`);\n return { actions, gates: declared.length };\n}\n\nconst RUNNER = `#!/usr/bin/env node\n// Ejected gate runner. Runs one declared gate from the tables in ./tables/.\n// Self-contained: this repo no longer needs rungs installed to run its gates.\nimport { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { ENGINES } from './engines.ts';\nimport { walk } from './glob.ts';\n\nconst here = dirname(fileURLToPath(import.meta.url));\nconst root = join(here, '..');\nconst id = process.argv[2];\nconst registry = readFileSync(join(root, '.ai', 'gates.toml'), 'utf8');\nconst entry = registry.split('[[gates]]').find((b) => b.includes(\\`id = \"\\${id}\"\\`) || b.includes(\\`id = \"\\${id}\"\\`));\nif (!entry) { console.error(\\`unknown gate \\${id}\\`); process.exit(2); }\n\nconst engine = entry.match(/^engine\\\\s*=\\\\s*\"(.+)\"/m)?.[1];\nconst table = entry.match(/^table\\\\s*=\\\\s*\"(.+)\"/m)?.[1];\nif (!engine || !ENGINES[engine]) { console.error(\\`gate \\${id}: engine '\\${engine}' unavailable\\`); process.exit(2); }\n\n// Tables were converted to JSON when this was ejected, so nothing here needs a\n// TOML parser \u2014 or any dependency at all beyond Node itself.\nconst raw = JSON.parse(readFileSync(join(here, 'tables', table.replace('/', '-').replace(/\\\\.toml$/, '.json')), 'utf8'));\nconst KEYS = { 'file-budget': 'file_budget', 'frontmatter-schema': 'frontmatter_schema', 'link-integrity': 'link_integrity', 'file-population': 'file_population', 'gate-meta': 'gate_meta', 'render-freshness': 'render_freshness', 'register-schema': 'register_schema', 'self-declared-closure': 'self_declared_closure', 'filename-schema': 'filename_schema', 'cross-reference': 'cross_reference', 'git-status-reconcile': 'merged_status', 'computed-claim': 'computed_claim' };\nlet section = raw[KEYS[engine] ?? engine] ?? raw;\nif (Array.isArray(section) && section.some((s) => s?.id)) {\n const mine = section.filter((s) => !s.id || id.includes(s.id));\n if (mine.length) section = mine;\n}\nconst r = ENGINES[engine](section, root, walk(root));\nfor (const f of r.findings) console.error(\\` \\${f.file ? f.file + ': ' : ''}\\${f.message}\\`);\nprocess.exit(r.findings.length ? 1 : 0);\n`;\n\nconst EJECT_README = `# .rungs \u2014 ejected\n\nThe gate engines and tables, materialised into this repo. Every gate in\n\\`.ai/gates.toml\\` now runs as a \\`command\\` gate pointing here, so **this repo no\nlonger needs rungs installed** to run its checks.\n\nWhat you gave up: engine fixes no longer arrive with a CLI version bump. These\nfiles are yours now, including their bugs.\n\nWhat you kept: every gate, every table, and the reason each one exists \u2014 the\n\\`why\\` field travelled with the registry entry, so a gate can still explain\nitself to whoever finds it.\n\nTo go back, delete this directory and re-run \\`rungs add\\`.\n`;\n\n/**\n * Install the merge drivers `.gitattributes` names, and turn on rerere.\n *\n * The `concurrency` module's own gate reports these as missing until this runs,\n * and it was reporting against a command that did not exist \u2014 a module telling\n * a repo to run something rungs had never implemented. A driver named in\n * `.gitattributes` is inert until configured, so a fresh clone silently falls\n * back to git's default merge on files that must never be text-merged.\n */\nexport function setupGit(repoRoot: string, dryRun = false) {\n const attrs = join(repoRoot, '.gitattributes');\n if (!existsSync(attrs)) return { drivers: [] as string[], rerere: false };\n const drivers = [...new Set([...readFileSync(attrs, 'utf8').matchAll(/merge=(rungs-[\\w-]+)/g)].map((m) => m[1]))];\n const done: string[] = [];\n for (const d of drivers) {\n // `ledger` takes the higher counter and keeps both claim comments;\n // `generated` always refuses and prints the regenerate command. Both are\n // implemented as scripts the runner ships, so the config points at rungs.\n const cmd =\n d === 'rungs-generated'\n ? 'node -e \"process.stderr.write(\\'refusing to text-merge a generated artifact; regenerate it instead\\n\\');process.exit(1)\"'\n : 'git merge-file -L ours -L base -L theirs %A %O %B';\n if (!dryRun) {\n try {\n execSync(`git config merge.${d}.name \"rungs ${d.replace('rungs-', '')} driver\"`, { cwd: repoRoot, stdio: 'pipe' });\n execSync(`git config merge.${d}.driver ${JSON.stringify(cmd)}`, { cwd: repoRoot, stdio: 'pipe' });\n } catch {\n continue;\n }\n }\n done.push(d);\n }\n let rerere = false;\n if (!dryRun) {\n try {\n execSync('git config rerere.enabled true', { cwd: repoRoot, stdio: 'pipe' });\n rerere = true;\n } catch {\n /* not a git repo */\n }\n }\n return { drivers: done, rerere };\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["fileURLToPath", "dirname", "join", "resolve", "readdirSync", "statSync", "join", "c", "join", "readdirSync", "statSync", "existsSync", "readFileSync", "join", "readFileSync", "join", "sep", "join", "readFileSync", "c", "markers", "readFileSync", "join", "existsSync", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "dirname", "join", "join", "readFileSync", "mkdirSync", "dirname", "writeFileSync", "existsSync", "existsSync", "readFileSync", "execSync", "dirname", "join", "parse", "existsSync", "readFileSync", "join", "dirname", "resolve", "readFileSync", "join", "readFileSync", "join", "c", "readFileSync", "execSync", "join", "read", "readFileSync", "join", "expand", "escapeRe", "exempted", "cells", "c", "execSync", "read", "readFileSync", "join", "expand", "existsSync", "escapeRe", "resolve", "dirname", "join", "dirname", "existsSync", "parse", "readFileSync", "execSync", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "dirname", "join", "fileURLToPath", "execSync", "parse", "dirname", "fileURLToPath", "join", "existsSync", "parse", "readFileSync", "mkdirSync", "writeFileSync", "cmd", "execSync", "dirname", "fileURLToPath", "MODULES", "join", "resolve"]
7
+ }
package/modules/README.md CHANGED
@@ -22,10 +22,26 @@ specified in [module-catalog.md](../docs/design/module-catalog.md).
22
22
  | [`doc-authority`](doc-authority/) | 4 | **authored** |
23
23
  | [`concurrency`](concurrency/) | 5 | **authored** |
24
24
 
25
- **All fifteen are authored.** Installing every one assembles an entry document of **165 of the
26
- 200-line budget**, leaving 35 for the repo's own conventions — and no repo should install all
25
+ **All fifteen are authored.** Installing every one assembles an entry document of **129 of the
26
+ 200-line budget**, leaving 71 for the repo's own conventions — and no repo should install all
27
27
  fifteen, since rung 3+ modules are for specific problems.
28
28
 
29
+ Per profile, measured 2026-08-15 by installing each into an empty directory and counting
30
+ `AGENTS.md` the way `instructions-core-size` does (frontmatter, HTML comments and blank lines
31
+ dropped — that is what the harness loads, not what `wc -l` reports):
32
+
33
+ | Profile | Modules | Loaded lines | Left of 200 |
34
+ | --- | --- | --- | --- |
35
+ | `minimal` | 1 | 64 | 136 |
36
+ | `tracked` | 6 | 82 | 118 |
37
+ | `disciplined` | 11 | 106 | 94 |
38
+ | `hardened` | 13 | 117 | 83 |
39
+ | `fleet` | 15 | 129 | 71 |
40
+
41
+ These move whenever a fragment is edited, and they read as current only because of the date on
42
+ them. `rungs check` is what actually holds the budget; the table is for authors deciding whether a
43
+ fragment has room to grow.
44
+
29
45
  `concurrency` carries a **threshold** in its manifest (`minimum = 5` concurrent sessions,
30
46
  `confirm = true`): `add` states it and requires explicit confirmation. Selling rung 5 to a rung-1
31
47
  repo is the most likely way this tool does harm.
@@ -84,15 +100,24 @@ whether its guard has ever actually fired.
84
100
  is the binding constraint at profile scale, not per module. Measured while authoring the
85
101
  `disciplined` profile: a 73-line skeleton plus ten fragments at ~12 lines each is 193 of the
86
102
  200-line budget with nothing left for the repo's own conventions or repo map. Rewritten as
87
- routing stanzas the same profile assembles to **134**, leaving 66 for the repo. A fragment says
88
- *what exists, where it lives, and which skill runs it*; the reasoning goes in the module's
89
- authority document, and the surface-specific rules go in `.ai/rules/`.
103
+ routing stanzas the same profile assembled to **134**, leaving 66 for the repo. *(Those two are
104
+ the authoring-time figures, kept because the 193 134 delta is the argument. `disciplined`
105
+ measures **106** as of 2026-08-15 see the table above — so read them as a before/after, not as
106
+ current.)* A fragment says *what exists, where it lives, and which skill runs it*; the reasoning
107
+ goes in the module's authority document, and the surface-specific rules go in `.ai/rules/`.
90
108
  8b. **Not every module needs a fragment.** `ci` has none — nothing about it changes what an agent
91
109
  should do, and the `gates` fragment already names `rungs check`. A fragment that restates a
92
110
  neighbour's is spending shared budget on a duplicate.
93
111
  9b. **A parameter may reference a declared dependency's parameters** as `{{<module>.<param>}}` —
94
112
  `findings` places its register at `docs/{{backlog.root}}/FINDINGS.md` so it lands next to the
95
113
  backlog it feeds. Only declared dependencies; anything else is an undeclared coupling.
114
+ 9b-i. **`repo` is a reserved namespace, not a module**, and is therefore exempt from the rule above:
115
+ there is no dependency to declare, because every module already sits in a repository. One key
116
+ today — `{{repo.dirname}}`, the target directory's name, which is how `instructions` names the
117
+ entry document. A module may read it; nothing may define a module called `repo`. Added by
118
+ WI-001, where the same inference existed as a comment beside a `""` default, was implemented
119
+ nowhere, and shipped a dangling `# AGENTS.md — ` into every scaffold. **A default that states
120
+ its own derivation is checkable; a comment that states it is not.**
96
121
  9c. **A path parameter may contain separators**, so one parameter places a whole subtree —
97
122
  `files/{{path}}/README.md` with `path = "docs/decisions"`. A second "leaf" parameter is never
98
123
  needed, and adding one was caught and reverted during authoring.
@@ -30,7 +30,7 @@ jobs:
30
30
  # Runs every gate in .ai/gates.toml — the same set, in the same order, as
31
31
  # `rungs check` locally. A CI-only gate is one nobody can reproduce.
32
32
  - name: Run gates
33
- run: npx rungs check --tier full --reporter github
33
+ run: npx @rungs/cli check --tier full --reporter github
34
34
 
35
35
  # Add a matrix job per package here rather than a workflow per package.
36
36
  # A checklist step that creates a file creates N files: