@descent-vtt/spec-harness 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The command line: arguments, dispatch, output and exit codes.\n *\n * Exit 0: done, nothing refused. Exit 1: something refused or found. Exit 2:\n * the answer cannot be trusted - a bad flag, an option, an argument or a\n * value that names nothing, a configuration that does not load, a sibling\n * that is missing or printed something unreadable, a git command that\n * failed, an output its reader closed, an error nothing here expected. A run\n * that could not look must never exit as though it looked and found nothing\n * (spec-core ADR-0005).\n *\n * A command loads what it runs. This module imports what every run needs,\n * the hook's before a write among them, and a module that only some\n * commands run is imported where one of them is the command: the hook\n * runs before and after every write an agent makes, and what it loaded of\n * the other commands was a wait before each (ADR-0002). A module that\n * cannot be loaded is thrown where it was asked for, and ends the run in a\n * line and exit 2, as every error does.\n */\n\nimport { SiblingOutputError } from './briefs.js';\nimport { ConfigError, SIBLINGS } from './config.js';\nimport type { ClaudeCodeWiring } from './configure.js';\nimport { isDirectory } from './fs.js';\nimport { GitError, show, stagedChanges } from './git.js';\nimport type { DocumentReader } from './document.js';\nimport type { Decision } from './guard.js';\nimport { claudeResponse, gitResponse, parseClaudeHook, type HookRequest } from './hooks.js';\nimport type { Base } from './round.js';\nimport { SiblingError } from './siblings.js';\nimport { emptyValue, heldHookLine, isBlank, isClaudeHook, readHookLine, refusal, unreadHookLine, type Command, type LineFault } from './usage.js';\nimport { CLAUDE_CODE_MINIMUM, MINIMUM_VERSIONS, type ClaudeCodeCheck } from './versions.js';\nimport {\n activeBrief,\n answerOf,\n describeActive,\n EXIT_ERROR,\n EXIT_FAILED,\n EXIT_OK,\n json,\n openWorkspace,\n parseOptions,\n UsageError,\n version,\n type CliIO,\n type Options,\n type UnreadableLine,\n type Workspace,\n} from './workspace.js';\n\nexport { EXIT_ERROR, EXIT_FAILED, EXIT_OK, UsageError, version, type CliIO } from './workspace.js';\n\nexport const HELP = `spec-harness - context, guards, audits and rulings for rounds of agent work\n\nUsage:\n spec-harness <command> [options]\n\nCommands:\n context [brief] What an agent needs to start a round: the brief, its scope,\n rulings, dependencies, the rules in force, the cited documents.\n guard <path...> May the round write these paths? Exit 1 if one is refused.\n hook claude Answer a Claude Code PreToolUse or PostToolUse hook (stdin).\n hook git Answer git's pre-commit hook for the staged files.\n escalate Ask a person to rule: --path <file> (repeatable) --reason <why>\n [--option \"<label>: <cost>\"]... [--recommend <text>].\n --list shows what waits; --show <id> prints one memo. Neither\n raises a request: beside one, only --root and --format are read.\n rule <id> Record a person's ruling in the brief: --allow or --deny, with\n --note <text>. It counts once committed signed.\n rulings [brief] The brief's rulings, and whether each one's signature verifies.\n audit [brief] Did the round stay inside the lines: what the archive would say,\n the brief's assertions, unverified rulings, new dependencies\n and the install scripts it allowed.\n probe [brief] Run the brief's probes: red at the base, green at the head.\n --at <base|head|both>, --id <probe>.\n premises Do the live briefs' premises still hold? For CI: exit 1 when one\n is stale, or, with --strict, when spec-guard cannot read one.\n init Configure the spec-* tools to agree. Prints the plan; --write\n applies it; --git-hook adds a pre-commit hook.\n mcp Serve start_round, check_path, request_escalation, audit_round,\n list_rounds and the workflow prompts over MCP on stdio.\n doctor Which siblings are installed, at which versions, which brief is\n named, how Claude Code runs the guard, and git's hook. Exit 1\n when a sibling is older than this release needs, the guard is\n installed twice, its hook's line turns it off or holds every\n write, disableAllHooks or an array for a matcher switches it\n off, the plugin that is turned on is not on this machine and\n nothing else guards, Claude Code is too old to run its hooks,\n or git stops every commit at what stands for its hook.\n\nOptions:\n --brief <id> The brief the round works on. Otherwise SPEC_BRIEF, then the branch.\n For context, guard, hook, escalate, rulings, audit, probe, premises\n and doctor.\n --base <ref> What the round is measured from. Otherwise \"base\" in\n .spec-harness.json, then the remote's default branch. For context,\n guard, hook, rulings, audit, probe and doctor.\n --root <dir> Run from another directory, which must exist. For every command.\n --format <fmt> pretty or json; audit and premises also gitlab, sarif or github.\n For every command but hook and mcp.\n --strict Warnings fail the run. For guard, audit, premises and doctor.\n --help, --version\n\nAn option a command does not read, an argument it does not take, an option or an\nargument given an empty value, and a brief given both as the argument and as --brief\nare refused, exit 2, not read as if they were not there. doctor says an empty --brief\nor --base in its report. hook claude reads its line as every release has, and says a\nline it cannot read, and a --root that is not a directory, with exit 1: it refuses\nnothing for either.\n\nExit codes: 0 clean, 1 refused or found something, 2 the answer cannot be trusted.\n`;\n\n\n/* ------------------------------------------------------------------- guard */\n\n/**\n * The reader of a brief's rulings, loaded where a ruling is read: a write\n * to a file no brief protects reads none.\n */\nconst reader = async (): Promise<DocumentReader> => (await import('./reader.js')).createReader();\n\nasync function decisionsFor(\n workspace: Workspace,\n options: Options,\n io: CliIO,\n given: readonly string[],\n cwd: string,\n): Promise<{ readonly decisions: Decision[] } | { readonly problem: string }> {\n const active = await activeBrief(workspace, options, io.env);\n const { brief, note, problem } = describeActive(active);\n if (problem !== null) return { problem };\n const { checkPaths } = await import('./round.js');\n return { decisions: await checkPaths(workspace, brief, note, given, cwd, reader, options.base) };\n}\n\nconst SYMBOL: Record<Decision['verdict'], string> = { allow: 'ok ', warn: 'warning', ask: 'ask ', deny: 'refused' };\n\nasync function guardCommand(options: Options, io: CliIO): Promise<number> {\n if (options.positionals.length === 0) throw new UsageError('guard needs at least one path');\n const workspace = await openWorkspace(options, io);\n const decided = await decisionsFor(workspace, options, io, options.positionals, io.cwd);\n if ('problem' in decided) {\n io.stderr.write(`spec-harness: ${decided.problem}\\n`);\n return EXIT_ERROR;\n }\n const { decisions } = decided;\n if (options.format === 'json') {\n io.stdout.write(json('guard', { decisions }));\n } else {\n for (const decision of decisions) {\n io.stdout.write(`${SYMBOL[decision.verdict]} ${decision.message}\\n`);\n if (decision.verdict !== 'allow') io.stdout.write(` ${decision.hint}\\n`);\n }\n }\n const refused = decisions.some((d) => d.verdict === 'deny' || d.verdict === 'ask');\n const warned = decisions.some((d) => d.verdict === 'warn');\n return refused || (options.strict && warned) ? EXIT_FAILED : EXIT_OK;\n}\n\n/* -------------------------------------------------------------------- hook */\n\nasync function readStdin(io: CliIO): Promise<string> {\n // Only the built command line reads process.stdin, and the suite spawns it\n // from dist/, outside the sweep (tests/integration/claude-code.test.ts): the\n // lines below survive it untested in-process.\n if (io.stdin !== undefined) return io.stdin();\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf8');\n}\n\n/**\n * The write Claude Code asks the hook about, or the exit code that answers\n * already: 1 for a question that cannot be read, 0 for a tool that writes\n * no file. Asked before anything on the hook's own line is, so that a line\n * that is wrong is said where there is a write it leaves unchecked.\n */\nasync function writeAsked(io: CliIO): Promise<HookRequest | number> {\n let question: string;\n try {\n question = await readStdin(io);\n } catch (error) {\n // A question that could not be read is one the hook cannot see, as one\n // it cannot parse is, below: it has no event to hold a write by.\n io.stderr.write(`spec-harness: the hook input could not be read: ${(error as Error).message}\\n`);\n return EXIT_FAILED;\n }\n const request = parseClaudeHook(question);\n if ('error' in request) {\n // A hook that cannot read its question refuses nothing it cannot see,\n // but says so where the person reads it: a non-blocking error.\n io.stderr.write(`spec-harness: ${request.error}\\n`);\n return EXIT_FAILED;\n }\n return request.paths.length === 0 ? EXIT_OK : request;\n}\n\n/**\n * What is wrong with the hook's own line, said and nothing refused for it:\n * one line, since Claude Code shows the first line of the stderr of a hook\n * that exits 1 and goes on with the write, where exit 2 would hold every\n * write of the session, the one that mends the line among them (ADR-0005).\n */\nfunction guardOff(io: CliIO, { wrong, mend }: LineFault): number {\n io.stderr.write(`spec-harness: ${wrong}, so the guard is off and this write is not checked; ${mend}\\n`);\n return EXIT_FAILED;\n}\n\n/**\n * Claude Code's hook on a line the parser refused: an option no command has,\n * an option left without its value, a --format or an --at that is none. It\n * was exit 2 before the question was read, for the line a settings file\n * holds as for one typed at a terminal. What is said of it is `doctor`'s\n * to say as well, of a line it finds in a settings file (usage.ts).\n */\nasync function unreadLine(said: string, io: CliIO): Promise<number> {\n const request = await writeAsked(io);\n if (typeof request === 'number') return request;\n return guardOff(io, unreadHookLine(said).fault);\n}\n\nasync function hookCommand(options: Options, io: CliIO): Promise<number> {\n const kind = options.positionals[0];\n if (kind === 'claude') {\n const request = await writeAsked(io);\n if (typeof request === 'number') return request;\n // The root the line gives, or what is wrong with it: read as `doctor`\n // reads the line where it finds it in a settings file (usage.ts).\n const line = readHookLine(options.root, io.cwd, isDirectory);\n if (line.state === 'off') return guardOff(io, line.fault);\n const cwd = request.cwd ?? io.cwd;\n let workspace: Workspace;\n try {\n workspace = await openWorkspace({ ...options, root: line.root ?? io.env['CLAUDE_PROJECT_DIR'] ?? cwd }, io);\n } catch (error) {\n if (error instanceof UsageError) return EXIT_OK;\n throw error;\n }\n try {\n const decided = await decisionsFor(workspace, options, io, request.paths, cwd);\n if ('problem' in decided) {\n // Exit 2 blocks the tool call, and its stderr reaches the model. Where\n // the name stands on the hook's own line, what is wrong with it is\n // `doctor`'s to say as well, in the same words (usage.ts).\n io.stderr.write(`spec-harness: ${heldHookLine(decided.problem).wrong}. Fix the brief or the branch before writing.\\n`);\n return EXIT_ERROR;\n }\n const response = claudeResponse(request.event, decided.decisions);\n io.stdout.write(response.stdout);\n return response.exitCode;\n } catch (error) {\n if (request.event !== 'PreToolUse') throw error;\n // A round is named and its briefs cannot be read: the guard cannot\n // tell a protected file from any other, so the write waits.\n io.stderr.write(`spec-harness: cannot check this write: ${(error as Error).message}\\n`);\n return EXIT_ERROR;\n }\n }\n if (kind === 'git') {\n const workspace = await openWorkspace(options, io);\n const staged = await stagedChanges(workspace.root);\n const paths = staged.flatMap((change) => (change.from === undefined ? [change.path] : [change.from, change.path]));\n if (paths.length === 0) return EXIT_OK;\n const decided = await decisionsFor(workspace, options, io, paths, workspace.root);\n if ('problem' in decided) {\n io.stderr.write(`spec-harness: ${decided.problem}\\n`);\n return EXIT_ERROR;\n }\n const response = gitResponse(decided.decisions);\n io.stderr.write(response.text);\n return response.exitCode;\n }\n throw new UsageError('hook takes \"claude\" or \"git\"');\n}\n\n/* ------------------------------------------------------------------ doctor */\n\n/**\n * The base, and the allowed-signers file as it is on it: the file waits on\n * the base, and the two on nothing else doctor asks. A --base given nothing\n * is no base, said as the brief's is, in the report.\n */\nasync function baseAndSigners(\n { resolveBase }: Pick<typeof import('./round.js'), 'resolveBase'>,\n workspace: Workspace,\n flag: string | undefined,\n signersFile: string,\n): Promise<{ readonly base: Base; readonly signersText: string | null }> {\n // Nothing in doctor asks what kind a base is but whether it is resolved, so\n // the mutant that names this one otherwise is equivalent.\n const base: Base = flag !== undefined && isBlank(flag) ? { kind: 'unresolved', reason: emptyValue('--base', 'base', flag) } : await resolveBase(workspace, flag);\n // An unresolved base has no commit: git shows nothing for one, so asking\n // anyway reads as no file, and that mutant is equivalent.\n const signersText = base.kind === 'resolved' ? await show(base.sha, signersFile, workspace.root) : null;\n return { base, signersText };\n}\n\n/**\n * How Claude Code is wired to the guard, and the release of the one on\n * `PATH`, which waits on the wiring: only a Claude Code that runs the guard\n * is asked its release, since one older than the hooks need lets every\n * write through unguarded. `null` where it was not asked. The wiring asks\n * it itself, since which writes a line is started for can turn on the\n * release as well (round.ts); the two are told apart here for the report,\n * which has a place of its own for the release.\n */\nasync function wiringAndRelease(\n { claudeCodeWiring }: Pick<typeof import('./round.js'), 'claudeCodeWiring'>,\n root: string,\n io: CliIO,\n): Promise<{ readonly wiring: Omit<ClaudeCodeWiring, 'release'>; readonly release: ClaudeCodeCheck | null }> {\n const { release, ...wiring } = await claudeCodeWiring(root, io);\n return { wiring, release };\n}\n\nasync function doctorCommand(options: Options, io: CliIO): Promise<number> {\n // What doctor alone runs of them, loaded before anything is asked: the\n // five things below are asked at once, and none waits on a module.\n const [configure, round, setup, signing] = await Promise.all([import('./configure.js'), import('./round.js'), import('./setup.js'), import('./signers.js')]);\n const { describeBase, describeClaudeCode, describeClaudeRelease, describeGitHook, describeHooksOff, describePlugin, describePresence, describeSignerKeys, describeSignerProblem, describeSigners, guardSwitchedOff, wiringState } = configure;\n const { diagnoseBrief, specBriefPlugin } = round;\n const { gitHook } = setup;\n const { notFido2, readAllowedSigners } = signing;\n const workspace = await openWorkspace(options, io);\n const rows = SIBLINGS.map((name) => {\n const sibling = workspace.siblings.locate(name);\n const row = { tool: name, state: sibling.kind, minimum: MINIMUM_VERSIONS[name] };\n if (sibling.kind === 'absent') return { ...row, version: null, detail: sibling.reason };\n if (sibling.kind === 'outdated') return { ...row, version: sibling.version, detail: sibling.reason };\n const command = sibling.command.join(' ');\n const detail = sibling.version === null ? `${command} (named in .spec-harness.json; its version is not checked)` : `${command} (${sibling.version})`;\n return { ...row, version: sibling.version, detail };\n });\n const signersFile = workspace.config.rulings.allowedSigners;\n // Five things that wait on the work tree and on nothing of one another,\n // each a process or a chain of them. Asked one after another, Claude\n // Code's release, the longest wait of a doctor on Windows, was asked for\n // only when every answer of git's before it was in. So they are asked at\n // once, and read below in the order they were asked in before: where more\n // than one fails, the first of that order is the one thrown, whichever\n // failed first by the clock (ADR-0002).\n const [briefAsked, baseAsked, pluginAsked, claudeAsked, hookAsked] = await Promise.allSettled([\n diagnoseBrief(workspace, options, io.env),\n baseAndSigners(round, workspace, options.base, signersFile),\n specBriefPlugin(workspace.root),\n wiringAndRelease(round, workspace.root, io),\n gitHook(workspace.root),\n ]);\n const named = answerOf(briefAsked);\n // A ruling counts only by a signature checked against the allowed signers\n // on the base, and only once spec-brief's archive asks the plugin about it.\n const { base, signersText } = answerOf(baseAsked);\n const onBase = base.kind === 'resolved' ? signersText !== null : null;\n const signers = describeSigners(signersFile, base.kind === 'resolved' ? base.ref : null, onBase === true);\n // Which keys sign, as notes: a key that is not FIDO2 can still be one the\n // agent cannot use, and a PIV key reads as a plain one (ADR-0006).\n const read = readAllowedSigners(signersText ?? '');\n const plain = notFido2(read.signers);\n const signerNotes = [describeSignerKeys(plain), ...read.problems.map(describeSignerProblem)].filter((note): note is string => note !== null);\n const plugin = answerOf(pluginAsked);\n // The plugin and init's entries both on: Claude Code runs every guard twice\n // and registers the server twice (ADR-0012).\n const { wiring, release } = answerOf(claudeAsked);\n const claude = wiringState(wiring);\n // What the hook does with each line the settings hold for it, where there\n // is something to say: more on it than init writes, a line that turns the\n // guard off or holds every write, one only a shell can read, the writes\n // Claude Code starts it for where they are not all of them, and what\n // onFailure changes.\n const lineNotes = wiring.lines.flatMap((line) => [line.detail, line.cover, line.note]).filter((note): note is string => note !== null);\n // What stands over every line: a plugin that is turned on and is not on\n // this machine, or cannot be told to be, and disableAllHooks, which\n // switches off whatever hooks there are.\n const switchedOff = guardSwitchedOff(wiring);\n const wiringNotes = [describePresence(wiring), wiring.hooksOff === null ? null : describeHooksOff(wiring.hooksOff, switchedOff)].filter((note): note is string => note !== null);\n // How the hook runs the harness is a note: one that goes through npx guards\n // as well as one that does not, and fails nothing, --strict or not.\n const { hook, note: hookNote } = answerOf(hookAsked);\n const branch = workspace.branch === null ? '(detached)' : `${workspace.branch}${workspace.branchSource === undefined ? '' : ` (detached; ${workspace.branchSource} names it)`}`;\n if (options.format === 'json') {\n io.stdout.write(\n json('doctor', {\n root: workspace.root,\n branch: workspace.branch,\n branchSource: workspace.branchSource ?? null,\n brief: named.id,\n briefProblem: named.problem,\n base: base.kind === 'resolved' ? { ref: base.ref, source: base.source, mergeBase: base.mergeBase } : { unresolved: base.reason },\n allowedSigners: {\n file: signersFile,\n onBase,\n detail: signers,\n notFido2: plain.map(({ line, principals, keyType }) => ({ line, principals, keyType })),\n problems: read.problems,\n },\n plugin: { state: plugin.kind, file: 'file' in plugin ? plugin.file : null, detail: describePlugin(plugin) },\n claudeCode: {\n state: claude,\n ...wiring,\n detail: describeClaudeCode(wiring),\n notes: wiringNotes,\n release:\n release === null\n ? { state: 'unchecked', version: null, minimum: CLAUDE_CODE_MINIMUM, detail: 'not asked: nothing wires Claude Code to the guard here' }\n : { state: release.state, version: 'version' in release ? release.version : null, minimum: CLAUDE_CODE_MINIMUM, detail: describeClaudeRelease(release) },\n },\n gitHook: { state: hook.state, file: 'file' in hook ? hook.file : null, detail: describeGitHook(hook), note: hookNote },\n siblings: rows,\n }),\n );\n } else {\n const more = (notes: readonly string[]): string[] => notes.map((note) => ` ${note}`);\n io.stdout.write(\n [\n `root ${workspace.root}`,\n `branch ${branch}`,\n `brief ${named.problem === null ? (named.id ?? '(none named)') : `none: ${named.problem}`}`,\n `base ${describeBase(base)}`,\n `signers ${signers}`,\n ...more(signerNotes),\n `plugin ${describePlugin(plugin)}`,\n `claude ${describeClaudeCode(wiring)}`,\n ...more(wiringNotes),\n ...more(lineNotes),\n ...more(release === null ? [] : [describeClaudeRelease(release)]),\n `git ${describeGitHook(hook)}`,\n ...more(hookNote === null ? [] : [hookNote]),\n '',\n '',\n ].join('\\n'),\n );\n for (const row of rows) io.stdout.write(`${row.state.padEnd(8)} ${row.tool.padEnd(10)} ${row.detail}\\n`);\n }\n // An outdated sibling is a problem to fix, where a missing optional one is\n // a choice; with none installed, the harness can check nothing. A double\n // install is a problem too, where no Claude Code wiring at all is a choice,\n // and so are a hook whose own line turns the guard off or holds every\n // write, guard hooks that disableAllHooks switches off, a plugin that is\n // turned on and is not on this machine where no hook of init's stands in\n // for it, a Claude Code too old to run the hooks, and something at the\n // path of git's pre-commit hook that git cannot run and stops every\n // commit at. A release that cannot be told is not fine either, nor a\n // line whose reading cannot be, nor a plugin that cannot be told to be on\n // this machine: --strict fails the three.\n const outdated = rows.some((row) => row.state === 'outdated');\n const usable = rows.some((row) => row.state === 'found');\n const off = wiring.lines.some((line) => line.state === 'off' || line.state === 'held');\n const missing = wiring.presence?.state === 'absent' && wiring.hooks.length === 0;\n const tooOld = release?.state === 'outdated';\n const stopped = hook.state === 'stops';\n const untold = options.strict && (release?.state === 'unknown' || wiring.lines.some((line) => line.state === 'unknown') || wiring.presence?.state === 'unknown');\n return outdated || !usable || claude === 'both' || off || switchedOff || missing || tooOld || stopped || untold ? EXIT_FAILED : EXIT_OK;\n}\n\n/* ---------------------------------------------------------------- dispatch */\n\n/**\n * A map, because the command is the first word a person types and an object\n * answers to more names than it was given: `spec-harness constructor` ran\n * `Object` as a command and ended on a stack trace, where `spec-harness\n * construct` is an unknown command with exit 2.\n */\nconst COMMANDS: ReadonlyMap<string, (options: Options, io: CliIO) => Promise<number>> = new Map(\n // One for every command that has a shape (usage.ts), which the compiler\n // holds. A command of another module loads its module when it is the one\n // typed, and no other command's.\n Object.entries({\n guard: guardCommand,\n hook: hookCommand,\n context: async (options, io) => (await import('./commands.js')).contextCommand(options, io),\n audit: async (options, io) => (await import('./commands.js')).auditCommand(options, io),\n escalate: async (options, io) => (await import('./commands.js')).escalateCommand(options, io),\n rule: async (options, io) => (await import('./commands.js')).ruleCommand(options, io),\n rulings: async (options, io) => (await import('./commands.js')).rulingsCommand(options, io),\n probe: async (options, io) => (await import('./commands.js')).probeCommand(options, io),\n premises: async (options, io) => (await import('./premises.js')).premisesCommand(options, io),\n init: async (options, io) => (await import('./setup.js')).initCommand(options, io),\n mcp: async (options, io) => (await import('./server.js')).mcpCommand(options, io),\n doctor: doctorCommand,\n } satisfies Record<Command, (options: Options, io: CliIO) => Promise<number>>),\n);\n\nasync function dispatch(argv: readonly string[], io: CliIO): Promise<number> {\n let options: Options;\n try {\n options = parseOptions(argv);\n } catch (error) {\n // The parser throws nothing but its refusal of the line, which holds\n // whose line it was. Claude Code's hook says its own, and holds no\n // write for it.\n const refused = error as UnreadableLine;\n if (isClaudeHook(refused.words[0], refused.words[1])) return unreadLine(refused.message, io);\n io.stderr.write(`spec-harness: ${refused.message}\\n`);\n return EXIT_ERROR;\n }\n if (options.version) {\n io.stdout.write(`${version()}\\n`);\n return EXIT_OK;\n }\n if (options.help || options.command === undefined) {\n io.stdout.write(HELP);\n return options.help ? EXIT_OK : EXIT_ERROR;\n }\n const command = COMMANDS.get(options.command);\n if (command === undefined) {\n io.stderr.write(`spec-harness: unknown command \"${options.command}\"; see spec-harness --help\\n`);\n return EXIT_ERROR;\n }\n // What parsed and names nothing, before anything is read or written for it.\n const refused = refusal(options, isDirectory);\n if (refused !== null) {\n io.stderr.write(`spec-harness: ${refused}\\n`);\n return EXIT_ERROR;\n }\n return command(options, io);\n}\n\n/**\n * Runs the command line and resolves to the exit code, for an error nothing\n * below expected too.\n *\n * Such an error is neither a refusal nor a finding: the answer cannot be\n * trusted, which is exit 2 (spec-core ADR-0005). Rejected instead, it reached\n * the launcher as Node's uncaught error, exit 1, \"refused or found something\"\n * to a script, and to Claude Code a hook that failed without blocking: the\n * write the guard could not check went ahead. The stack is what makes a\n * report of it something to act on, and it goes to stderr alone: a script\n * that reads a document from stdout is handed no part of one.\n *\n * A write its reader had closed the pipe for is not such an error: the answer\n * was not delivered, which is still 2, and nothing in the harness is at\n * fault, so it is said in a line and no stack sends a person looking for a\n * defect. The process's own streams report it as an event, which the\n * launcher answers in the same words; here it is a caller's stream that\n * throws it. It is read by its code: stdout and stderr are the only pipes\n * the harness writes to.\n *\n * Nor is a module of the build that is not there. The launcher says a build\n * without its command line in a line, and a module a command asks for where\n * it runs is said in the same line: a build with a file missing is not a\n * defect a stack leads to. It is read by its code too: the harness imports\n * nothing but its own modules and Node's.\n */\nexport async function run(argv: readonly string[], io: CliIO): Promise<number> {\n try {\n return await dispatch(argv, io);\n } catch (error) {\n // A sibling's document of a shape the harness does not read is a sibling\n // that printed something it cannot read (answers.ts): exit 2. A git\n // command that failed is what git said, and no line of the harness's.\n if (\n error instanceof UsageError ||\n error instanceof ConfigError ||\n error instanceof SiblingError ||\n error instanceof SiblingOutputError ||\n error instanceof GitError\n ) {\n io.stderr.write(`spec-harness: ${error.message}\\n`);\n return EXIT_ERROR;\n }\n if (!(error instanceof Error)) io.stderr.write(`spec-harness: unexpected error: ${String(error)}\\n`);\n else if ((error as NodeJS.ErrnoException).code === 'EPIPE') io.stderr.write('spec-harness: stdout was closed before all of the output was written\\n');\n else if ((error as NodeJS.ErrnoException).code === 'ERR_MODULE_NOT_FOUND') io.stderr.write('spec-harness: build output is missing; run \"npm run build\" first, or install the published package.\\n');\n else io.stderr.write(`spec-harness: unexpected error: ${error.stack ?? error.message}\\n`);\n return EXIT_ERROR;\n }\n}\n\n// What bin/spec-harness.js runs; the suite spawns the built one, from dist/,\n// outside the sweep (tests/integration/cli.test.ts), so it survives untested\n// in-process.\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n return run(argv, { stdout: process.stdout, stderr: process.stderr, cwd: process.cwd(), env: process.env });\n}\n\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The command line: arguments, dispatch, output and exit codes.\n *\n * Exit 0: done, nothing refused. Exit 1: something refused or found. Exit 2:\n * the answer cannot be trusted - a bad flag, an option, an argument or a\n * value that names nothing, a configuration that does not load, a sibling\n * that is missing or printed something unreadable, a git command that\n * failed, an output its reader closed, an error nothing here expected. A run\n * that could not look must never exit as though it looked and found nothing\n * (spec-core ADR-0005).\n *\n * A command loads what it runs. This module imports what every run needs,\n * the hook's before a write among them, and a module that only some\n * commands run is imported where one of them is the command: the hook\n * runs before and after every write an agent makes, and what it loaded of\n * the other commands was a wait before each (ADR-0002). A module that\n * cannot be loaded is thrown where it was asked for, and ends the run in a\n * line and exit 2, as every error does.\n */\n\nimport { SiblingOutputError } from './briefs.js';\nimport { CONFIG_FILE, ConfigError, SIBLINGS, SPEC_BRIEF_CONFIGS } from './config.js';\nimport type { ClaudeCodeWiring } from './configure.js';\nimport { dirname, join } from 'node:path';\n\nimport { gitDirectories, holdsGit, isDirectory, keepCall, loadConfig, realSpelling, repositoryPath, StateError, takeCall } from './fs.js';\nimport { GitError, show, stagedChanges } from './git.js';\nimport type { DocumentReader } from './document.js';\nimport type { Decision } from './guard.js';\nimport { afterResponse, callFile, callRecord, claudeResponse, gitResponse, keptCall, parseClaudeHook, SESSION_START, sessionResponse, warningsKept, warningsOf, type CallRecord, type HookRequest, type HookResponse } from './hooks.js';\nimport type { Base } from './round.js';\nimport type { BriefRow } from './types.js';\nimport { SiblingError } from './siblings.js';\nimport { emptyValue, heldHookLine, isBlank, isClaudeHook, readHookLine, refusal, twoValues, unreadHookLine, type Command, type LineFault } from './usage.js';\nimport { CLAUDE_CODE_MINIMUM, MINIMUM_VERSIONS, type ClaudeCodeCheck } from './versions.js';\nimport {\n activeBrief,\n answerOf,\n describeActive,\n EXIT_ERROR,\n EXIT_FAILED,\n EXIT_OK,\n findTree,\n foundCommonDir,\n json,\n MAIN_INSTALL,\n openFound,\n openWorkspace,\n parseOptions,\n UsageError,\n version,\n type CliIO,\n type FoundTree,\n type Options,\n type UnreadableLine,\n type Workspace,\n} from './workspace.js';\n\nexport { EXIT_ERROR, EXIT_FAILED, EXIT_OK, UsageError, version, type CliIO } from './workspace.js';\n\nexport const HELP = `spec-harness - context, guards, audits and rulings for rounds of agent work\n\nUsage:\n spec-harness <command> [options]\n\nCommands:\n context [brief] What an agent needs to start a round: the brief, its scope,\n rulings, dependencies, the rules in force, the cited documents.\n guard <path...> May the round write these paths? Exit 1 if one is refused.\n hook claude Answer a Claude Code PreToolUse, PostToolUse or SessionStart hook\n (stdin). At session start it says what would hold every write.\n hook git Answer git's pre-commit hook for the staged files.\n escalate Ask a person to rule: --path <file> (repeatable) --reason <why>\n [--option \"<label>: <cost>\"]... [--recommend <text>].\n --list shows what waits; --show <id> prints one memo. Neither\n raises a request: beside one, only --root and --format are read.\n rule <id> Record a person's ruling in the brief: --allow or --deny, with\n --note <text>. It counts once committed signed.\n rulings [brief] The brief's rulings, and whether each one's signature verifies.\n audit [brief] Did the round stay inside the lines: what the archive would say,\n the brief's assertions, unverified rulings, new dependencies\n and the install scripts it allowed.\n probe [brief] Run the brief's probes: red at the base, green at the head.\n --at <base|head|both>, --id <probe>.\n premises Do the live briefs' premises still hold? For CI: exit 1 when one\n is stale, or, with --strict, when spec-guard cannot read one.\n init Configure the spec-* tools to agree. Prints the plan; --write\n applies it; --git-hook adds a pre-commit hook.\n mcp Serve start_round, check_path, request_escalation, audit_round,\n list_rounds and the workflow prompts over MCP on stdio.\n doctor Which siblings are installed, at which versions, which brief is\n named, how Claude Code runs the guard, and git's hook. Exit 1\n when a sibling is older than this release needs, the guard is\n installed twice, its hook's line turns it off or holds every\n write, disableAllHooks or an array for a matcher switches it\n off, the plugin that is turned on is not on this machine and\n nothing else guards, Claude Code is too old to run its hooks,\n or git stops every commit at what stands for its hook.\n\nOptions:\n --brief <id> The brief the round works on. Otherwise SPEC_BRIEF, then the branch.\n For context, guard, hook, escalate, rulings, audit, probe, premises\n and doctor.\n --base <ref> What the round is measured from. Otherwise \"base\" in\n .spec-harness.json, then the remote's default branch. For context,\n guard, hook, rulings, audit, probe and doctor.\n --root <dir> Run from another directory, which must exist. For every command.\n --format <fmt> pretty or json; audit and premises also gitlab, sarif or github.\n For every command but hook and mcp.\n --strict Warnings fail the run. For guard, audit, premises and doctor.\n --help, --version One of the two: both on one line are refused.\n\nAn option a command does not read, an argument it does not take, an option or an\nargument given an empty value, a brief given both as the argument and as --brief,\nand an option that takes one value given two that name two things are refused, exit 2,\nnot read as if they were not there, and so with --help or --version on the line. The\nsame value twice, as --root . --root ./, is read once. doctor says an empty --brief or\n--base in its report. hook claude reads its line as every release has, and says a line\nit cannot read, two values for one option among them, and a --root that is not a\ndirectory, with exit 1: it refuses nothing for either.\n\nExit codes: 0 clean, 1 refused or found something, 2 the answer cannot be trusted.\n`;\n\n\n/* ------------------------------------------------------------------- guard */\n\n/**\n * The reader of a brief's rulings, loaded where a ruling is read: a write\n * to a file no brief protects reads none.\n */\nconst reader = async (): Promise<DocumentReader> => (await import('./reader.js')).createReader();\n\nasync function decisionsFor(\n workspace: Workspace,\n options: Options,\n io: CliIO,\n given: readonly string[],\n cwd: string,\n): Promise<{ readonly decisions: Decision[]; readonly brief: BriefRow | null } | { readonly problem: string }> {\n const active = await activeBrief(workspace, options, io.env);\n const { brief, note, problem } = describeActive(active);\n if (problem !== null) return { problem };\n const { checkPaths } = await import('./round.js');\n return { decisions: await checkPaths(workspace, brief, note, given, cwd, reader, options.base), brief };\n}\n\n/**\n * Whether a decision is of a file the answer after the write is made from:\n * the configuration, spec-brief's, the brief, or a file beside it in the\n * briefs' directory, which spec-brief reads too. A call that writes one is\n * decided again after the write, so that what the write changed is read\n * (ADR-0002).\n */\nfunction decidesAnswers(decision: Decision, brief: BriefRow | null): boolean {\n if (decision.path === CONFIG_FILE || SPEC_BRIEF_CONFIGS.includes(decision.path)) return true;\n if (brief === null) return false;\n return decision.path === brief.file || decision.path.startsWith(`${dirname(brief.file)}/`);\n}\n\nconst SYMBOL: Record<Decision['verdict'], string> = { allow: 'ok ', warn: 'warning', ask: 'ask ', deny: 'refused' };\n\nasync function guardCommand(options: Options, io: CliIO): Promise<number> {\n if (options.positionals.length === 0) throw new UsageError('guard needs at least one path');\n const workspace = await openWorkspace(options, io);\n const decided = await decisionsFor(workspace, options, io, options.positionals, io.cwd);\n if ('problem' in decided) {\n io.stderr.write(`spec-harness: ${decided.problem}\\n`);\n return EXIT_ERROR;\n }\n const { decisions } = decided;\n if (options.format === 'json') {\n io.stdout.write(json('guard', { decisions }));\n } else {\n for (const decision of decisions) {\n io.stdout.write(`${SYMBOL[decision.verdict]} ${decision.message}\\n`);\n if (decision.verdict !== 'allow') io.stdout.write(` ${decision.hint}\\n`);\n }\n }\n const refused = decisions.some((d) => d.verdict === 'deny' || d.verdict === 'ask');\n const warned = decisions.some((d) => d.verdict === 'warn');\n return refused || (options.strict && warned) ? EXIT_FAILED : EXIT_OK;\n}\n\n/* -------------------------------------------------------------------- hook */\n\nasync function readStdin(io: CliIO): Promise<string> {\n // Only the built command line reads process.stdin, and the suite spawns it\n // from dist/, outside the sweep (tests/integration/claude-code.test.ts): the\n // lines below survive it untested in-process.\n if (io.stdin !== undefined) return io.stdin();\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString('utf8');\n}\n\n/**\n * The write Claude Code asks the hook about, or the session that starts, or\n * the exit code that answers already: 1 for a question that cannot be read,\n * 0 for a tool that writes no file. Asked before anything on the hook's own\n * line is, so that a line that is wrong is said where there is a write it\n * leaves unchecked, or a session whose every write it leaves so.\n */\nasync function writeAsked(io: CliIO): Promise<HookRequest | number> {\n let question: string;\n try {\n question = await readStdin(io);\n } catch (error) {\n // A question that could not be read is one the hook cannot see, as one\n // it cannot parse is, below: it has no event to hold a write by.\n io.stderr.write(`spec-harness: the hook input could not be read: ${(error as Error).message}\\n`);\n return EXIT_FAILED;\n }\n const request = parseClaudeHook(question);\n if ('error' in request) {\n // A hook that cannot read its question refuses nothing it cannot see,\n // but says so where the person reads it: a non-blocking error.\n io.stderr.write(`spec-harness: ${request.error}\\n`);\n return EXIT_FAILED;\n }\n return request.paths.length === 0 && request.event !== SESSION_START ? EXIT_OK : request;\n}\n\n/**\n * What is wrong with the hook's own line, said and nothing refused for it:\n * one line, since Claude Code shows the first line of the stderr of a hook\n * that exits 1 and goes on with the write, where exit 2 would hold every\n * write of the session, the one that mends the line among them (ADR-0005).\n */\nfunction guardOff(io: CliIO, { wrong, mend }: LineFault, event: string): number {\n if (event === SESSION_START) return answer(io, sessionResponse(`${wrong}, so the guard is off and no write of this session is checked; ${mend}`));\n io.stderr.write(`spec-harness: ${wrong}, so the guard is off and this write is not checked; ${mend}\\n`);\n return EXIT_FAILED;\n}\n\nfunction answer(io: CliIO, response: { readonly stdout: string; readonly exitCode: number }): number {\n io.stdout.write(response.stdout);\n return response.exitCode;\n}\n\n/**\n * What would hold every write of the session that starts, said once as it\n * starts and no write waits on it (ADR-0005): a configuration that does not\n * load, a brief named that spec-brief does not list or has archived, and\n * spec-brief itself, where a brief is named, missing, too old or unable to\n * list the briefs. Each in the words a write would be held with, and\n * `doctor` says, and with what mends it. `null` where nothing does. The\n * check never ends the session's start: whatever it meets is said.\n */\nasync function sessionProblem(options: Options, io: CliIO, root: string, cwd: string | null): Promise<string | null> {\n const held = 'so every write of this session is held until it is mended';\n try {\n const named = await openWorkspace({ ...options, root }, io);\n // A session in another work tree of the project has its writes decided\n // there, and so is the check (ADR-0005).\n const found = cwd === null ? null : await otherTree(named, cwd);\n const workspace = found === null ? named : await openFound(found, io, () => [named.root]);\n const { problem } = describeActive(await activeBrief(workspace, options, io.env));\n return problem === null ? null : `${heldHookLine(problem).wrong}, ${held}: fix the brief or the branch before writing; spec-harness doctor says more`;\n } catch (error) {\n // A session in no work tree has nothing to guard, as a write there has\n // not. Anything else that stops the check stops a write's as well, which\n // is then held as one the hook cannot check: a configuration that does\n // not load, a spec-brief that is missing, too old or cannot list the\n // briefs, and whatever a defect throws.\n if (error instanceof UsageError) return null;\n return `${(error as Error).message}, ${held}; spec-harness doctor says more`;\n }\n}\n\n/**\n * Claude Code's hook on a line the parser refused: an option no command has,\n * an option left without its value, a --format or an --at that is none. It\n * was exit 2 before the question was read, for the line a settings file\n * holds as for one typed at a terminal. What is said of it is `doctor`'s\n * to say as well, of a line it finds in a settings file (usage.ts).\n */\nasync function unreadLine(said: string, io: CliIO): Promise<number> {\n const request = await writeAsked(io);\n if (typeof request === 'number') return request;\n return guardOff(io, unreadHookLine(said).fault, request.event);\n}\n\n/**\n * Whether a work tree other than the one whose top is `top` may hold `cwd`:\n * `cwd` is outside it, or a `.git` stands in a directory between the two,\n * where a linked worktree, a submodule or a repository of its own starts.\n * Where neither is so, `cwd` is in that work tree, and git is asked nothing\n * more: a session works at its project's top, or below it, for nearly every\n * write. Answering that one may is what git is then asked, so the mutant\n * that always answers so is equivalent, at the cost of a process, and so\n * is each that only answers so more often: a slice one short reaches the\n * top itself, which holds a `.git`, and a part named in place of none is\n * a directory no top holds.\n */\nfunction mayBeElsewhere(cwd: string, top: string): boolean {\n const path = repositoryPath(cwd, top, cwd);\n if (path === null) return true;\n const parts = path === '' ? [] : path.split('/');\n return parts.some((_, index) => holdsGit(join(top, ...parts.slice(0, index + 1))));\n}\n\n/**\n * The work tree that holds `cwd`, where it is another work tree of the\n * repository the hook's root names, by the git directory the two share;\n * `null` where `cwd` is in the root's own, in another repository, or in\n * none (ADR-0005).\n */\nasync function otherTree(named: Workspace, cwd: string): Promise<FoundTree | null> {\n if (!mayBeElsewhere(cwd, named.root)) return null;\n const found = await findTree(cwd);\n // The project's own work tree, found again, would decide every path the\n // same way once more: the check saves reading its configuration twice, and\n // its mutant is equivalent.\n if (found === null || found.root === named.root) return null;\n const common = await foundCommonDir(found);\n // git names a common directory wherever it names a top, so `null` is\n // there for the type.\n if (common === null || realSpelling(common) !== realSpelling(named.commonDir)) return null;\n return found;\n}\n\n/**\n * The work trees a write is decided in, each with the paths it decides\n * (ADR-0005). The repository is the one the hook's root names, as before,\n * and so is the work tree, but where the question's `cwd` is in another\n * work tree of that repository, linked or main, by the git directory the\n * two share: there a session works in a worktree while Claude Code names\n * the project it started in, and the hook decided by the project's branch,\n * which named no brief, so a protected write passed with no word. That work\n * tree decides the paths it holds, by its branch, its briefs and its\n * configuration, with its siblings looked for in its install and then the\n * project's. A path it does not hold is decided as before, by the work tree\n * the root names: a write to the project's own file from a worktree is\n * refused where it was. Where both hold a path, one is inside the other,\n * and the inner one holds it as git reads it. A `cwd` in another\n * repository, or in none, leaves every path where it was.\n */\nasync function writesBy(named: Workspace, cwd: string | null, paths: readonly string[], io: CliIO): Promise<{ readonly workspace: Workspace; readonly paths: readonly string[] }[]> {\n const asBefore = [{ workspace: named, paths }];\n if (cwd === null) return asBefore;\n const found = await otherTree(named, cwd);\n if (found === null) return asBefore;\n const inner = repositoryPath(found.root, named.root, cwd) !== null;\n const holds = (path: string): boolean => repositoryPath(path, found.root, cwd) !== null && (inner || repositoryPath(path, named.root, cwd) === null);\n const own = paths.filter(holds);\n if (own.length === 0) return asBefore;\n const workspace = await openFound(found, io, () => [named.root]);\n const rest = paths.filter((path) => !holds(path));\n return [{ workspace, paths: own }, ...(rest.length === 0 ? [] : [{ workspace: named, paths: rest }])];\n}\n\n/**\n * The answer after a write, where it can be given with no process started,\n * or `null` where it is to be decided as before (ADR-0002, ADR-0003).\n *\n * The git directory is the one the files at the hook's root name. What the\n * run before the write kept for this call, if anything, is taken away as it\n * is read, and answered from where it is this call's: the same release,\n * session, call, tool, paths, directories, line and variables. And where\n * nothing is kept, a run after a write says nothing but a warning outside\n * the scope, which only `outOfScope: \"warn\"` decides: under `ask` or\n * `deny` there is nothing to say, where the configuration read is the one\n * git would have the hook read, of the work tree the session is in.\n */\nasync function answeredAfter(root: string, record: CallRecord | null, cwd: string | null, io: CliIO): Promise<HookResponse | null> {\n const found = gitDirectories(root, io.env);\n if (found === null) return null;\n if (record !== null) {\n const kept = await takeCall(found.common, callFile(record));\n // warningsKept reads no text as no record as well: the test is there for\n // the type, and its mutant is equivalent.\n const warnings = kept === null ? null : warningsKept(kept, record);\n if (warnings !== null) return afterResponse(warnings);\n }\n if (!found.exact || (cwd !== null && mayBeElsewhere(cwd, found.top))) return null;\n try {\n return (await loadConfig(found.top)).config.outOfScope === 'warn' ? null : afterResponse([]);\n } catch {\n // A configuration that does not load is said as it was, by the run.\n return null;\n }\n}\n\nasync function hookCommand(options: Options, io: CliIO): Promise<number> {\n const kind = options.positionals[0];\n if (kind === 'claude') {\n const request = await writeAsked(io);\n if (typeof request === 'number') return request;\n // The root the line gives, or what is wrong with it: read as `doctor`\n // reads the line where it finds it in a settings file (usage.ts).\n const line = readHookLine(options.root, io.cwd, isDirectory);\n if (line.state === 'off') return guardOff(io, line.fault, request.event);\n const cwd = request.cwd ?? io.cwd;\n const root = line.root ?? io.env['CLAUDE_PROJECT_DIR'] ?? cwd;\n if (request.event === SESSION_START) return answer(io, sessionResponse(await sessionProblem(options, io, root, request.cwd)));\n const record = callRecord(request, { root: line.root, brief: options.brief, base: options.base }, io.cwd, io.env, version());\n if (request.event === 'PostToolUse') {\n const answered = await answeredAfter(root, record, request.cwd, io);\n if (answered !== null) {\n io.stdout.write(answered.stdout);\n return answered.exitCode;\n }\n }\n let workspace: Workspace;\n try {\n workspace = await openWorkspace({ ...options, root }, io);\n } catch (error) {\n if (error instanceof UsageError) return EXIT_OK;\n throw error;\n }\n try {\n // The answer reads a decision by its verdict, which a mutant's text\n // put first on this list has none of: that mutant is equivalent.\n const decisions: Decision[] = [];\n // Whether the run after the write may answer from what this one keeps:\n // not where a decision refuses, nor where the write is to what the\n // answer is made from, in any work tree that decides it.\n let keeps = true;\n for (const part of await writesBy(workspace, request.cwd, request.paths, io)) {\n const decided = await decisionsFor(part.workspace, options, io, part.paths, cwd);\n if ('problem' in decided) {\n // Exit 2 blocks the tool call, and its stderr reaches the model. Where\n // the name stands on the hook's own line, what is wrong with it is\n // `doctor`'s to say as well, in the same words (usage.ts).\n io.stderr.write(`spec-harness: ${heldHookLine(decided.problem).wrong}. Fix the brief or the branch before writing.\\n`);\n return EXIT_ERROR;\n }\n // A line of the answer for each path, by the work tree that decided it.\n decisions.push(...decided.decisions);\n if (decided.decisions.some((decision) => decision.verdict === 'deny' || decidesAnswers(decision, decided.brief))) keeps = false;\n }\n const response = claudeResponse(request.event, decisions);\n io.stdout.write(response.stdout);\n // What the run after the write will say, kept for it where the call\n // goes ahead: a refused call has none. It changes nothing of the\n // answer, which is made before it is kept.\n if (request.event === 'PreToolUse' && record !== null && keeps) {\n await keepCall(workspace.commonDir, callFile(record), keptCall(record, warningsOf(decisions)));\n }\n return response.exitCode;\n } catch (error) {\n if (request.event !== 'PreToolUse') throw error;\n // A round is named and its briefs cannot be read: the guard cannot\n // tell a protected file from any other, so the write waits.\n io.stderr.write(`spec-harness: cannot check this write: ${(error as Error).message}\\n`);\n return EXIT_ERROR;\n }\n }\n if (kind === 'git') {\n // git starts its hook at the top of the work tree it commits in, a\n // linked worktree's own, whose install may be none: it is then checked\n // with the main work tree's (ADR-0005).\n const workspace = await openWorkspace(options, io, MAIN_INSTALL);\n const staged = await stagedChanges(workspace.root);\n const paths = staged.flatMap((change) => (change.from === undefined ? [change.path] : [change.from, change.path]));\n if (paths.length === 0) return EXIT_OK;\n const decided = await decisionsFor(workspace, options, io, paths, workspace.root);\n if ('problem' in decided) {\n io.stderr.write(`spec-harness: ${decided.problem}\\n`);\n return EXIT_ERROR;\n }\n const response = gitResponse(decided.decisions);\n io.stderr.write(response.text);\n return response.exitCode;\n }\n throw new UsageError('hook takes \"claude\" or \"git\"');\n}\n\n/* ------------------------------------------------------------------ doctor */\n\n/**\n * The base, and the allowed-signers file as it is on it: the file waits on\n * the base, and the two on nothing else doctor asks. A --base given nothing\n * is no base, said as the brief's is, in the report.\n */\nasync function baseAndSigners(\n { resolveBase }: Pick<typeof import('./round.js'), 'resolveBase'>,\n workspace: Workspace,\n flag: string | undefined,\n signersFile: string,\n): Promise<{ readonly base: Base; readonly signersText: string | null }> {\n // Nothing in doctor asks what kind a base is but whether it is resolved, so\n // the mutant that names this one otherwise is equivalent.\n const base: Base = flag !== undefined && isBlank(flag) ? { kind: 'unresolved', reason: emptyValue('--base', 'base', flag) } : await resolveBase(workspace, flag);\n // An unresolved base has no commit: git shows nothing for one, so asking\n // anyway reads as no file, and that mutant is equivalent.\n const signersText = base.kind === 'resolved' ? await show(base.sha, signersFile, workspace.root) : null;\n return { base, signersText };\n}\n\n/**\n * How Claude Code is wired to the guard, and the release of the one on\n * `PATH`, which waits on the wiring: only a Claude Code that runs the guard\n * is asked its release, since one older than the hooks need lets every\n * write through unguarded. `null` where it was not asked. The wiring asks\n * it itself, since which writes a line is started for can turn on the\n * release as well (round.ts); the two are told apart here for the report,\n * which has a place of its own for the release.\n */\nasync function wiringAndRelease(\n { claudeCodeWiring }: Pick<typeof import('./round.js'), 'claudeCodeWiring'>,\n root: string,\n io: CliIO,\n): Promise<{ readonly wiring: Omit<ClaudeCodeWiring, 'release'>; readonly release: ClaudeCodeCheck | null }> {\n const { release, ...wiring } = await claudeCodeWiring(root, io);\n return { wiring, release };\n}\n\nasync function doctorCommand(options: Options, io: CliIO): Promise<number> {\n // What doctor alone runs of them, loaded before anything is asked: the\n // five things below are asked at once, and none waits on a module.\n const [configure, round, setup, signing] = await Promise.all([import('./configure.js'), import('./round.js'), import('./setup.js'), import('./signers.js')]);\n const { describeBase, describeClaudeCode, describeClaudeRelease, describeGitHook, describeHooksOff, describePlugin, describePresence, describeSignerKeys, describeSignerProblem, describeSigners, guardSwitchedOff, NO_SESSION_START, wiringState } = configure;\n const { diagnoseBrief, specBriefPlugin } = round;\n const { gitHook } = setup;\n const { notFido2, readAllowedSigners } = signing;\n // The siblings as git's hook finds them in this work tree: its own\n // install, and in a linked worktree with none the main work tree's.\n const workspace = await openWorkspace(options, io, MAIN_INSTALL);\n const rows = SIBLINGS.map((name) => {\n const sibling = workspace.siblings.locate(name);\n const row = { tool: name, state: sibling.kind, minimum: MINIMUM_VERSIONS[name] };\n if (sibling.kind === 'absent') return { ...row, version: null, elsewhere: null, detail: sibling.reason };\n const elsewhere = sibling.elsewhere ?? null;\n const whose = elsewhere === null ? '' : `, the install of ${elsewhere}: this work tree has none of its own`;\n if (sibling.kind === 'outdated') return { ...row, version: sibling.version, elsewhere, detail: `${sibling.reason}${whose}` };\n const command = sibling.command.join(' ');\n const detail = sibling.version === null ? `${command} (named in .spec-harness.json; its version is not checked)` : `${command} (${sibling.version}${whose})`;\n return { ...row, version: sibling.version, elsewhere, detail };\n });\n const signersFile = workspace.config.rulings.allowedSigners;\n // Five things that wait on the work tree and on nothing of one another,\n // each a process or a chain of them. Asked one after another, Claude\n // Code's release, the longest wait of a doctor on Windows, was asked for\n // only when every answer of git's before it was in. So they are asked at\n // once, and read below in the order they were asked in before: where more\n // than one fails, the first of that order is the one thrown, whichever\n // failed first by the clock (ADR-0002).\n const [briefAsked, baseAsked, pluginAsked, claudeAsked, hookAsked] = await Promise.allSettled([\n diagnoseBrief(workspace, options, io.env),\n baseAndSigners(round, workspace, options.base, signersFile),\n specBriefPlugin(workspace.root),\n wiringAndRelease(round, workspace.root, io),\n gitHook(workspace.root),\n ]);\n const named = answerOf(briefAsked);\n // A ruling counts only by a signature checked against the allowed signers\n // on the base, and only once spec-brief's archive asks the plugin about it.\n const { base, signersText } = answerOf(baseAsked);\n const onBase = base.kind === 'resolved' ? signersText !== null : null;\n const signers = describeSigners(signersFile, base.kind === 'resolved' ? base.ref : null, onBase === true);\n // Which keys sign, as notes: a key that is not FIDO2 can still be one the\n // agent cannot use, and a PIV key reads as a plain one (ADR-0006).\n const read = readAllowedSigners(signersText ?? '');\n const plain = notFido2(read.signers);\n const signerNotes = [describeSignerKeys(plain), ...read.problems.map(describeSignerProblem)].filter((note): note is string => note !== null);\n const plugin = answerOf(pluginAsked);\n // The plugin and init's entries both on: Claude Code runs every guard twice\n // and registers the server twice (ADR-0012).\n const { wiring, release } = answerOf(claudeAsked);\n const claude = wiringState(wiring);\n // What the hook does with each line the settings hold for it, where there\n // is something to say: more on it than init writes, a line that turns the\n // guard off or holds every write, one only a shell can read, the writes\n // Claude Code starts it for where they are not all of them, and what\n // onFailure changes.\n const lineNotes = wiring.lines.flatMap((line) => [line.detail, line.cover, line.note]).filter((note): note is string => note !== null);\n // What stands over every line: a plugin that is turned on and is not on\n // this machine, or cannot be told to be, and disableAllHooks, which\n // switches off whatever hooks there are.\n const switchedOff = guardSwitchedOff(wiring);\n // And whether the hook is started as a session starts, where settings hold\n // the guard: a note, failing nothing, and `sessionStart` in the document.\n const atStart = wiring.hooks.length > 0 && !wiring.sessionStart ? NO_SESSION_START : null;\n const wiringNotes = [describePresence(wiring), wiring.hooksOff === null ? null : describeHooksOff(wiring.hooksOff, switchedOff)].filter((note): note is string => note !== null);\n // How the hook runs the harness is a note: one that goes through npx guards\n // as well as one that does not, and fails nothing, --strict or not.\n const { hook, note: hookNote } = answerOf(hookAsked);\n const branch = workspace.branch === null ? '(detached)' : `${workspace.branch}${workspace.branchSource === undefined ? '' : ` (detached; ${workspace.branchSource} names it)`}`;\n if (options.format === 'json') {\n io.stdout.write(\n json('doctor', {\n root: workspace.root,\n branch: workspace.branch,\n branchSource: workspace.branchSource ?? null,\n brief: named.id,\n briefProblem: named.problem,\n base: base.kind === 'resolved' ? { ref: base.ref, source: base.source, mergeBase: base.mergeBase } : { unresolved: base.reason },\n allowedSigners: {\n file: signersFile,\n onBase,\n detail: signers,\n notFido2: plain.map(({ line, principals, keyType }) => ({ line, principals, keyType })),\n problems: read.problems,\n },\n plugin: { state: plugin.kind, file: 'file' in plugin ? plugin.file : null, detail: describePlugin(plugin) },\n claudeCode: {\n state: claude,\n ...wiring,\n detail: describeClaudeCode(wiring),\n notes: wiringNotes,\n release:\n release === null\n ? { state: 'unchecked', version: null, minimum: CLAUDE_CODE_MINIMUM, detail: 'not asked: nothing wires Claude Code to the guard here' }\n : { state: release.state, version: 'version' in release ? release.version : null, minimum: CLAUDE_CODE_MINIMUM, detail: describeClaudeRelease(release) },\n },\n gitHook: { state: hook.state, file: 'file' in hook ? hook.file : null, detail: describeGitHook(hook), note: hookNote },\n siblings: rows,\n }),\n );\n } else {\n const more = (notes: readonly string[]): string[] => notes.map((note) => ` ${note}`);\n io.stdout.write(\n [\n `root ${workspace.root}`,\n `branch ${branch}`,\n `brief ${named.problem === null ? (named.id ?? '(none named)') : `none: ${named.problem}`}`,\n `base ${describeBase(base)}`,\n `signers ${signers}`,\n ...more(signerNotes),\n `plugin ${describePlugin(plugin)}`,\n `claude ${describeClaudeCode(wiring)}`,\n ...more(wiringNotes),\n ...more(lineNotes),\n ...more(release === null ? [] : [describeClaudeRelease(release)]),\n ...more(atStart === null ? [] : [atStart]),\n `git ${describeGitHook(hook)}`,\n ...more(hookNote === null ? [] : [hookNote]),\n '',\n '',\n ].join('\\n'),\n );\n for (const row of rows) io.stdout.write(`${row.state.padEnd(8)} ${row.tool.padEnd(10)} ${row.detail}\\n`);\n }\n // An outdated sibling is a problem to fix, where a missing optional one is\n // a choice; with none installed, the harness can check nothing. A double\n // install is a problem too, where no Claude Code wiring at all is a choice,\n // and so are a hook whose own line turns the guard off or holds every\n // write, guard hooks that disableAllHooks switches off, a plugin that is\n // turned on and is not on this machine where no hook of init's stands in\n // for it, a Claude Code too old to run the hooks, and something at the\n // path of git's pre-commit hook that git cannot run and stops every\n // commit at. A release that cannot be told is not fine either, nor a\n // line whose reading cannot be, nor a plugin that cannot be told to be on\n // this machine, nor a hook git runs that cannot be read, which stops every\n // commit as a script and runs as a program: --strict fails the four.\n const outdated = rows.some((row) => row.state === 'outdated');\n const usable = rows.some((row) => row.state === 'found');\n const off = wiring.lines.some((line) => line.state === 'off' || line.state === 'held');\n const missing = wiring.presence?.state === 'absent' && wiring.hooks.length === 0;\n const tooOld = release?.state === 'outdated';\n const stopped = hook.state === 'stops';\n // Only an unreadable hook has `runs`, so the test of its state is the\n // compiler's, and its mutant is equivalent.\n const untold =\n options.strict && (release?.state === 'unknown' || wiring.lines.some((line) => line.state === 'unknown') || wiring.presence?.state === 'unknown' || (hook.state === 'unreadable' && hook.runs));\n return outdated || !usable || claude === 'both' || off || switchedOff || missing || tooOld || stopped || untold ? EXIT_FAILED : EXIT_OK;\n}\n\n/* ---------------------------------------------------------------- dispatch */\n\n/**\n * A map, because the command is the first word a person types and an object\n * answers to more names than it was given: `spec-harness constructor` ran\n * `Object` as a command and ended on a stack trace, where `spec-harness\n * construct` is an unknown command with exit 2.\n */\nconst COMMANDS: ReadonlyMap<string, (options: Options, io: CliIO) => Promise<number>> = new Map(\n // One for every command that has a shape (usage.ts), which the compiler\n // holds. A command of another module loads its module when it is the one\n // typed, and no other command's.\n Object.entries({\n guard: guardCommand,\n hook: hookCommand,\n context: async (options, io) => (await import('./commands.js')).contextCommand(options, io),\n audit: async (options, io) => (await import('./commands.js')).auditCommand(options, io),\n escalate: async (options, io) => (await import('./commands.js')).escalateCommand(options, io),\n rule: async (options, io) => (await import('./commands.js')).ruleCommand(options, io),\n rulings: async (options, io) => (await import('./commands.js')).rulingsCommand(options, io),\n probe: async (options, io) => (await import('./commands.js')).probeCommand(options, io),\n premises: async (options, io) => (await import('./premises.js')).premisesCommand(options, io),\n init: async (options, io) => (await import('./setup.js')).initCommand(options, io),\n mcp: async (options, io) => (await import('./server.js')).mcpCommand(options, io),\n doctor: doctorCommand,\n } satisfies Record<Command, (options: Options, io: CliIO) => Promise<number>>),\n);\n\nasync function dispatch(argv: readonly string[], io: CliIO): Promise<number> {\n let options: Options;\n try {\n options = parseOptions(argv);\n } catch (error) {\n // The parser throws nothing but its refusal of the line, which holds\n // whose line it was. Claude Code's hook says its own, and holds no\n // write for it.\n const refused = error as UnreadableLine;\n if (isClaudeHook(refused.words[0], refused.words[1])) return unreadLine(refused.message, io);\n io.stderr.write(`spec-harness: ${refused.message}\\n`);\n return EXIT_ERROR;\n }\n // Two values for an option that takes one: the parser kept the last, and\n // which was meant cannot be told from the line, so it is refused as a line\n // the parser cannot read is, and Claude Code's hook says it of its own.\n const twice = twoValues(options, io.cwd);\n if (twice !== null) {\n if (isClaudeHook(options.command, options.positionals[0])) return unreadLine(twice, io);\n io.stderr.write(`spec-harness: ${twice}; give it one\\n`);\n return EXIT_ERROR;\n }\n // A line that is wrong is refused before --help or --version answers: an\n // answer beside it said nothing of what was wrong, exit 0, as an option no\n // command has never was (spec-core ADR-0005).\n if (options.command !== undefined && !COMMANDS.has(options.command)) {\n io.stderr.write(`spec-harness: unknown command \"${options.command}\"; see spec-harness --help\\n`);\n return EXIT_ERROR;\n }\n // What parsed and names nothing, before anything is read or written for it.\n const refused = refusal(options, isDirectory);\n if (refused !== null) {\n io.stderr.write(`spec-harness: ${refused}\\n`);\n return EXIT_ERROR;\n }\n if (options.version) {\n io.stdout.write(`${version()}\\n`);\n return EXIT_OK;\n }\n if (options.help || options.command === undefined) {\n io.stdout.write(HELP);\n return options.help ? EXIT_OK : EXIT_ERROR;\n }\n return COMMANDS.get(options.command)!(options, io);\n}\n\n/**\n * Runs the command line and resolves to the exit code, for an error nothing\n * below expected too.\n *\n * Such an error is neither a refusal nor a finding: the answer cannot be\n * trusted, which is exit 2 (spec-core ADR-0005). Rejected instead, it reached\n * the launcher as Node's uncaught error, exit 1, \"refused or found something\"\n * to a script, and to Claude Code a hook that failed without blocking: the\n * write the guard could not check went ahead. The stack is what makes a\n * report of it something to act on, and it goes to stderr alone: a script\n * that reads a document from stdout is handed no part of one.\n *\n * A write its reader had closed the pipe for is not such an error: the answer\n * was not delivered, which is still 2, and nothing in the harness is at\n * fault, so it is said in a line and no stack sends a person looking for a\n * defect. The process's own streams report it as an event, which the\n * launcher answers in the same words; here it is a caller's stream that\n * throws it. It is read by its code: stdout and stderr are the only pipes\n * the harness writes to.\n *\n * Nor is a module of the build that is not there. The launcher says a build\n * without its command line in a line, and a module a command asks for where\n * it runs is said in the same line: a build with a file missing is not a\n * defect a stack leads to. It is read by its code too: the harness imports\n * nothing but its own modules and Node's.\n */\nexport async function run(argv: readonly string[], io: CliIO): Promise<number> {\n try {\n return await dispatch(argv, io);\n } catch (error) {\n // A sibling's document of a shape the harness does not read is a sibling\n // that printed something it cannot read (answers.ts): exit 2. A git\n // command that failed is what git said, and no line of the harness's;\n // and a path under git's directory where the harness keeps its state,\n // which holds something else, is said in a line of its own (fs.ts).\n if (\n error instanceof UsageError ||\n error instanceof ConfigError ||\n error instanceof SiblingError ||\n error instanceof SiblingOutputError ||\n error instanceof GitError ||\n error instanceof StateError\n ) {\n io.stderr.write(`spec-harness: ${error.message}\\n`);\n return EXIT_ERROR;\n }\n if (!(error instanceof Error)) io.stderr.write(`spec-harness: unexpected error: ${String(error)}\\n`);\n else if ((error as NodeJS.ErrnoException).code === 'EPIPE') io.stderr.write('spec-harness: stdout was closed before all of the output was written\\n');\n else if ((error as NodeJS.ErrnoException).code === 'ERR_MODULE_NOT_FOUND') io.stderr.write('spec-harness: build output is missing; run \"npm run build\" first, or install the published package.\\n');\n else io.stderr.write(`spec-harness: unexpected error: ${error.stack ?? error.message}\\n`);\n return EXIT_ERROR;\n }\n}\n\n// What bin/spec-harness.js runs; the suite spawns the built one, from dist/,\n// outside the sweep (tests/integration/cli.test.ts), so it survives untested\n// in-process.\nexport async function main(argv: readonly string[] = process.argv.slice(2)): Promise<number> {\n return run(argv, { stdout: process.stdout, stderr: process.stderr, cwd: process.cwd(), env: process.env });\n}\n\n"]}
package/dist/config.d.ts CHANGED
@@ -48,6 +48,8 @@ export interface HarnessConfig {
48
48
  export type SiblingName = 'spec-brief' | 'spec-graph' | 'spec-guard';
49
49
  export declare const SIBLINGS: readonly SiblingName[];
50
50
  export declare const CONFIG_FILE = ".spec-harness.json";
51
+ /** spec-brief's configuration files, in the order spec-brief looks for them in a directory. */
52
+ export declare const SPEC_BRIEF_CONFIGS: readonly string[];
51
53
  export declare const DEFAULT_MANIFESTS: readonly string[];
52
54
  export declare const DEFAULT_CONFIG: HarnessConfig;
53
55
  export declare class ConfigError extends Error {
package/dist/config.js CHANGED
@@ -9,6 +9,8 @@
9
9
  import { templateError } from './branch.js';
10
10
  export const SIBLINGS = ['spec-brief', 'spec-graph', 'spec-guard'];
11
11
  export const CONFIG_FILE = '.spec-harness.json';
12
+ /** spec-brief's configuration files, in the order spec-brief looks for them in a directory. */
13
+ export const SPEC_BRIEF_CONFIGS = ['.spec-brief.json', 'spec-brief.json'];
12
14
  export const DEFAULT_MANIFESTS = [
13
15
  'package.json',
14
16
  'Cargo.toml',
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What `.spec-harness.json` may say, the defaults, and validation.\n *\n * Every key has a default, so a repository without the file works; a file\n * that says something this version does not understand stops the run with\n * exit 2, because a guard that silently ignored a misspelt key would be\n * guarding something other than what its owner wrote.\n */\n\nimport { templateError } from './branch.js';\n\nexport type OutOfScope = 'warn' | 'ask' | 'deny';\n\nexport interface HarnessConfig {\n /** Branch-name templates that carry the active brief's id (ADR-0004). */\n readonly branches: readonly string[];\n /** What a write outside the brief's `affectedFiles` gets: a warning, a question to the person, or a refusal. */\n readonly outOfScope: OutOfScope;\n /** The branch rounds merge into, which audits and rulings are measured against. `null`: the remote's default branch. */\n readonly base: string | null;\n readonly rulings: {\n /** The brief section whose table holds the rulings. */\n readonly section: string;\n /** The allowed-signers file, read from the base branch, never from the round's own tree. */\n readonly allowedSigners: string;\n };\n readonly dependencies: {\n /** Manifest file names whose added dependencies an audit reports. */\n readonly manifests: readonly string[];\n };\n readonly context: {\n /** The most a context packet may hold, in characters. Cited documents fill what the rest leaves; those that do not fit are named by path. */\n readonly budget: number;\n };\n readonly assertions: {\n /**\n * Brief sections whose assertions state what was true before the round -\n * the defect, measured - and are expected to stop holding when it ends.\n * Every other assertion in a brief is a goal.\n */\n readonly premises: readonly string[];\n };\n readonly probes: {\n /** How many times a probe runs; every run must agree. */\n readonly runs: number;\n /** Seconds one run may take. */\n readonly timeout: number;\n };\n /** The command for each sibling tool, or `null` to find it (ADR-0002). */\n readonly tools: Readonly<Record<SiblingName, readonly string[] | null>>;\n}\n\nexport type SiblingName = 'spec-brief' | 'spec-graph' | 'spec-guard';\nexport const SIBLINGS: readonly SiblingName[] = ['spec-brief', 'spec-graph', 'spec-guard'];\n\nexport const CONFIG_FILE = '.spec-harness.json';\n\nexport const DEFAULT_MANIFESTS: readonly string[] = [\n 'package.json',\n 'Cargo.toml',\n 'go.mod',\n 'pyproject.toml',\n 'requirements*.txt',\n 'Directory.Packages.props',\n '*.csproj',\n '*.fsproj',\n '*.vbproj',\n 'Gemfile',\n];\n\nexport const DEFAULT_CONFIG: HarnessConfig = {\n branches: ['brief/{id}', 'brief-{id}', '*/brief/{id}', '*/brief-{id}'],\n outOfScope: 'warn',\n base: null,\n rulings: { section: 'Rulings', allowedSigners: '.github/allowed_signers' },\n dependencies: { manifests: DEFAULT_MANIFESTS },\n context: { budget: 60_000 },\n assertions: { premises: ['The Defect, Measured', 'Premises', 'Preconditions'] },\n probes: { runs: 2, timeout: 600 },\n tools: { 'spec-brief': null, 'spec-graph': null, 'spec-guard': null },\n};\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\ntype Json = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Json {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isStringList(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction checkKeys(value: Json, allowed: readonly string[], where: string): void {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) {\n throw new ConfigError(`${where}: unknown key \"${key}\"; the keys are ${allowed.join(', ')}`);\n }\n }\n}\n\nfunction positive(value: unknown, where: string): number {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < 1) {\n throw new ConfigError(`${where} must be a whole number of at least 1`);\n }\n return value;\n}\n\nfunction nonEmpty(value: unknown, where: string): string {\n if (typeof value !== 'string' || value.trim() === '') throw new ConfigError(`${where} must be a non-empty string`);\n return value;\n}\n\n/** Validates a parsed configuration and fills in every default. */\nexport function parseConfig(raw: unknown, file = CONFIG_FILE): HarnessConfig {\n if (!isObject(raw)) throw new ConfigError(`${file} must hold a JSON object`);\n checkKeys(raw, ['$schema', 'branches', 'outOfScope', 'base', 'rulings', 'dependencies', 'context', 'assertions', 'probes', 'tools'], file);\n\n let branches = DEFAULT_CONFIG.branches;\n if (raw['branches'] !== undefined) {\n if (!isStringList(raw['branches']) || raw['branches'].length === 0) {\n throw new ConfigError(`${file}: \"branches\" must be a non-empty list of templates`);\n }\n for (const template of raw['branches']) {\n const error = templateError(template);\n if (error !== null) throw new ConfigError(`${file}: \"branches\": ${error}`);\n }\n branches = raw['branches'];\n }\n\n let outOfScope = DEFAULT_CONFIG.outOfScope;\n if (raw['outOfScope'] !== undefined) {\n if (raw['outOfScope'] !== 'warn' && raw['outOfScope'] !== 'ask' && raw['outOfScope'] !== 'deny') {\n throw new ConfigError(`${file}: \"outOfScope\" must be \"warn\", \"ask\" or \"deny\"`);\n }\n outOfScope = raw['outOfScope'];\n }\n\n let base = DEFAULT_CONFIG.base;\n if (raw['base'] !== undefined && raw['base'] !== null) base = nonEmpty(raw['base'], `${file}: \"base\"`);\n\n let rulings = DEFAULT_CONFIG.rulings;\n if (raw['rulings'] !== undefined) {\n const value = raw['rulings'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"rulings\" must be an object`);\n checkKeys(value, ['section', 'allowedSigners'], `${file}: \"rulings\"`);\n rulings = {\n section: value['section'] === undefined ? rulings.section : nonEmpty(value['section'], `${file}: \"rulings.section\"`),\n allowedSigners:\n value['allowedSigners'] === undefined\n ? rulings.allowedSigners\n : nonEmpty(value['allowedSigners'], `${file}: \"rulings.allowedSigners\"`),\n };\n }\n\n let dependencies = DEFAULT_CONFIG.dependencies;\n if (raw['dependencies'] !== undefined) {\n const value = raw['dependencies'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"dependencies\" must be an object`);\n checkKeys(value, ['manifests'], `${file}: \"dependencies\"`);\n if (value['manifests'] !== undefined) {\n if (!isStringList(value['manifests'])) throw new ConfigError(`${file}: \"dependencies.manifests\" must be a list of file names`);\n dependencies = { manifests: value['manifests'] };\n }\n }\n\n let context = DEFAULT_CONFIG.context;\n if (raw['context'] !== undefined) {\n const value = raw['context'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"context\" must be an object`);\n checkKeys(value, ['budget'], `${file}: \"context\"`);\n if (value['budget'] !== undefined) context = { budget: positive(value['budget'], `${file}: \"context.budget\"`) };\n }\n\n let assertions = DEFAULT_CONFIG.assertions;\n if (raw['assertions'] !== undefined) {\n const value = raw['assertions'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"assertions\" must be an object`);\n checkKeys(value, ['premises'], `${file}: \"assertions\"`);\n if (value['premises'] !== undefined) {\n if (!isStringList(value['premises'])) throw new ConfigError(`${file}: \"assertions.premises\" must be a list of section names`);\n assertions = { premises: value['premises'] };\n }\n }\n\n let probes = DEFAULT_CONFIG.probes;\n if (raw['probes'] !== undefined) {\n const value = raw['probes'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"probes\" must be an object`);\n checkKeys(value, ['runs', 'timeout'], `${file}: \"probes\"`);\n probes = {\n runs: value['runs'] === undefined ? probes.runs : positive(value['runs'], `${file}: \"probes.runs\"`),\n timeout: value['timeout'] === undefined ? probes.timeout : positive(value['timeout'], `${file}: \"probes.timeout\"`),\n };\n }\n\n const tools: Record<SiblingName, readonly string[] | null> = { ...DEFAULT_CONFIG.tools };\n if (raw['tools'] !== undefined) {\n const value = raw['tools'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"tools\" must be an object`);\n checkKeys(value, SIBLINGS, `${file}: \"tools\"`);\n for (const name of SIBLINGS) {\n const command = value[name];\n if (command === undefined || command === null) continue;\n // A list that is not empty has a first entry: the `?.` is the\n // compiler's, and the mutant without it is equivalent.\n if (!isStringList(command) || command.length === 0 || command[0]?.trim() === '') {\n // A sibling runs without a shell, so the example is node and the\n // script: npx is a shim Windows cannot start without one.\n throw new ConfigError(`${file}: \"tools.${name}\" must be a command as a list, such as [\"node\", \"node_modules/@descent-vtt/${name}/bin/${name}.js\"], or null`);\n }\n tools[name] = command;\n }\n }\n\n return { branches, outOfScope, base, rulings, dependencies, context, assertions, probes, tools };\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What `.spec-harness.json` may say, the defaults, and validation.\n *\n * Every key has a default, so a repository without the file works; a file\n * that says something this version does not understand stops the run with\n * exit 2, because a guard that silently ignored a misspelt key would be\n * guarding something other than what its owner wrote.\n */\n\nimport { templateError } from './branch.js';\n\nexport type OutOfScope = 'warn' | 'ask' | 'deny';\n\nexport interface HarnessConfig {\n /** Branch-name templates that carry the active brief's id (ADR-0004). */\n readonly branches: readonly string[];\n /** What a write outside the brief's `affectedFiles` gets: a warning, a question to the person, or a refusal. */\n readonly outOfScope: OutOfScope;\n /** The branch rounds merge into, which audits and rulings are measured against. `null`: the remote's default branch. */\n readonly base: string | null;\n readonly rulings: {\n /** The brief section whose table holds the rulings. */\n readonly section: string;\n /** The allowed-signers file, read from the base branch, never from the round's own tree. */\n readonly allowedSigners: string;\n };\n readonly dependencies: {\n /** Manifest file names whose added dependencies an audit reports. */\n readonly manifests: readonly string[];\n };\n readonly context: {\n /** The most a context packet may hold, in characters. Cited documents fill what the rest leaves; those that do not fit are named by path. */\n readonly budget: number;\n };\n readonly assertions: {\n /**\n * Brief sections whose assertions state what was true before the round -\n * the defect, measured - and are expected to stop holding when it ends.\n * Every other assertion in a brief is a goal.\n */\n readonly premises: readonly string[];\n };\n readonly probes: {\n /** How many times a probe runs; every run must agree. */\n readonly runs: number;\n /** Seconds one run may take. */\n readonly timeout: number;\n };\n /** The command for each sibling tool, or `null` to find it (ADR-0002). */\n readonly tools: Readonly<Record<SiblingName, readonly string[] | null>>;\n}\n\nexport type SiblingName = 'spec-brief' | 'spec-graph' | 'spec-guard';\nexport const SIBLINGS: readonly SiblingName[] = ['spec-brief', 'spec-graph', 'spec-guard'];\n\nexport const CONFIG_FILE = '.spec-harness.json';\n\n/** spec-brief's configuration files, in the order spec-brief looks for them in a directory. */\nexport const SPEC_BRIEF_CONFIGS: readonly string[] = ['.spec-brief.json', 'spec-brief.json'];\n\nexport const DEFAULT_MANIFESTS: readonly string[] = [\n 'package.json',\n 'Cargo.toml',\n 'go.mod',\n 'pyproject.toml',\n 'requirements*.txt',\n 'Directory.Packages.props',\n '*.csproj',\n '*.fsproj',\n '*.vbproj',\n 'Gemfile',\n];\n\nexport const DEFAULT_CONFIG: HarnessConfig = {\n branches: ['brief/{id}', 'brief-{id}', '*/brief/{id}', '*/brief-{id}'],\n outOfScope: 'warn',\n base: null,\n rulings: { section: 'Rulings', allowedSigners: '.github/allowed_signers' },\n dependencies: { manifests: DEFAULT_MANIFESTS },\n context: { budget: 60_000 },\n assertions: { premises: ['The Defect, Measured', 'Premises', 'Preconditions'] },\n probes: { runs: 2, timeout: 600 },\n tools: { 'spec-brief': null, 'spec-graph': null, 'spec-guard': null },\n};\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\ntype Json = Record<string, unknown>;\n\nfunction isObject(value: unknown): value is Json {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isStringList(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction checkKeys(value: Json, allowed: readonly string[], where: string): void {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) {\n throw new ConfigError(`${where}: unknown key \"${key}\"; the keys are ${allowed.join(', ')}`);\n }\n }\n}\n\nfunction positive(value: unknown, where: string): number {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < 1) {\n throw new ConfigError(`${where} must be a whole number of at least 1`);\n }\n return value;\n}\n\nfunction nonEmpty(value: unknown, where: string): string {\n if (typeof value !== 'string' || value.trim() === '') throw new ConfigError(`${where} must be a non-empty string`);\n return value;\n}\n\n/** Validates a parsed configuration and fills in every default. */\nexport function parseConfig(raw: unknown, file = CONFIG_FILE): HarnessConfig {\n if (!isObject(raw)) throw new ConfigError(`${file} must hold a JSON object`);\n checkKeys(raw, ['$schema', 'branches', 'outOfScope', 'base', 'rulings', 'dependencies', 'context', 'assertions', 'probes', 'tools'], file);\n\n let branches = DEFAULT_CONFIG.branches;\n if (raw['branches'] !== undefined) {\n if (!isStringList(raw['branches']) || raw['branches'].length === 0) {\n throw new ConfigError(`${file}: \"branches\" must be a non-empty list of templates`);\n }\n for (const template of raw['branches']) {\n const error = templateError(template);\n if (error !== null) throw new ConfigError(`${file}: \"branches\": ${error}`);\n }\n branches = raw['branches'];\n }\n\n let outOfScope = DEFAULT_CONFIG.outOfScope;\n if (raw['outOfScope'] !== undefined) {\n if (raw['outOfScope'] !== 'warn' && raw['outOfScope'] !== 'ask' && raw['outOfScope'] !== 'deny') {\n throw new ConfigError(`${file}: \"outOfScope\" must be \"warn\", \"ask\" or \"deny\"`);\n }\n outOfScope = raw['outOfScope'];\n }\n\n let base = DEFAULT_CONFIG.base;\n if (raw['base'] !== undefined && raw['base'] !== null) base = nonEmpty(raw['base'], `${file}: \"base\"`);\n\n let rulings = DEFAULT_CONFIG.rulings;\n if (raw['rulings'] !== undefined) {\n const value = raw['rulings'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"rulings\" must be an object`);\n checkKeys(value, ['section', 'allowedSigners'], `${file}: \"rulings\"`);\n rulings = {\n section: value['section'] === undefined ? rulings.section : nonEmpty(value['section'], `${file}: \"rulings.section\"`),\n allowedSigners:\n value['allowedSigners'] === undefined\n ? rulings.allowedSigners\n : nonEmpty(value['allowedSigners'], `${file}: \"rulings.allowedSigners\"`),\n };\n }\n\n let dependencies = DEFAULT_CONFIG.dependencies;\n if (raw['dependencies'] !== undefined) {\n const value = raw['dependencies'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"dependencies\" must be an object`);\n checkKeys(value, ['manifests'], `${file}: \"dependencies\"`);\n if (value['manifests'] !== undefined) {\n if (!isStringList(value['manifests'])) throw new ConfigError(`${file}: \"dependencies.manifests\" must be a list of file names`);\n dependencies = { manifests: value['manifests'] };\n }\n }\n\n let context = DEFAULT_CONFIG.context;\n if (raw['context'] !== undefined) {\n const value = raw['context'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"context\" must be an object`);\n checkKeys(value, ['budget'], `${file}: \"context\"`);\n if (value['budget'] !== undefined) context = { budget: positive(value['budget'], `${file}: \"context.budget\"`) };\n }\n\n let assertions = DEFAULT_CONFIG.assertions;\n if (raw['assertions'] !== undefined) {\n const value = raw['assertions'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"assertions\" must be an object`);\n checkKeys(value, ['premises'], `${file}: \"assertions\"`);\n if (value['premises'] !== undefined) {\n if (!isStringList(value['premises'])) throw new ConfigError(`${file}: \"assertions.premises\" must be a list of section names`);\n assertions = { premises: value['premises'] };\n }\n }\n\n let probes = DEFAULT_CONFIG.probes;\n if (raw['probes'] !== undefined) {\n const value = raw['probes'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"probes\" must be an object`);\n checkKeys(value, ['runs', 'timeout'], `${file}: \"probes\"`);\n probes = {\n runs: value['runs'] === undefined ? probes.runs : positive(value['runs'], `${file}: \"probes.runs\"`),\n timeout: value['timeout'] === undefined ? probes.timeout : positive(value['timeout'], `${file}: \"probes.timeout\"`),\n };\n }\n\n const tools: Record<SiblingName, readonly string[] | null> = { ...DEFAULT_CONFIG.tools };\n if (raw['tools'] !== undefined) {\n const value = raw['tools'];\n if (!isObject(value)) throw new ConfigError(`${file}: \"tools\" must be an object`);\n checkKeys(value, SIBLINGS, `${file}: \"tools\"`);\n for (const name of SIBLINGS) {\n const command = value[name];\n if (command === undefined || command === null) continue;\n // A list that is not empty has a first entry: the `?.` is the\n // compiler's, and the mutant without it is equivalent.\n if (!isStringList(command) || command.length === 0 || command[0]?.trim() === '') {\n // A sibling runs without a shell, so the example is node and the\n // script: npx is a shim Windows cannot start without one.\n throw new ConfigError(`${file}: \"tools.${name}\" must be a command as a list, such as [\"node\", \"node_modules/@descent-vtt/${name}/bin/${name}.js\"], or null`);\n }\n tools[name] = command;\n }\n }\n\n return { branches, outOfScope, base, rulings, dependencies, context, assertions, probes, tools };\n}\n"]}