cohorte 3.0.0-dev.0 → 3.0.0-dev.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.
Files changed (53) hide show
  1. package/assets/manifest.json +4 -4
  2. package/assets/schemas/reconcile-plan.schema.json +1 -2
  3. package/dist/agent-host.mjs +2142 -5
  4. package/dist/agent-host.mjs.map +1 -1
  5. package/dist/bundle-manifest.json +38 -36
  6. package/dist/chunks/{auth-D8rCVY33.mjs → auth-ybswxUPK.mjs} +54 -2
  7. package/dist/chunks/auth-ybswxUPK.mjs.map +1 -0
  8. package/dist/chunks/{brainstorm-CU10T1tm.mjs → brainstorm-BwKA6yZP.mjs} +2 -2
  9. package/dist/chunks/{brainstorm-CU10T1tm.mjs.map → brainstorm-BwKA6yZP.mjs.map} +1 -1
  10. package/dist/chunks/{catalogue-BvwSrM_j.mjs → catalogue-B5uFqfzJ.mjs} +2 -2
  11. package/dist/chunks/{catalogue-BvwSrM_j.mjs.map → catalogue-B5uFqfzJ.mjs.map} +1 -1
  12. package/dist/chunks/{compose-Cr0hP0qm.mjs → compose-C0rEh5wB.mjs} +3354 -3343
  13. package/dist/chunks/compose-C0rEh5wB.mjs.map +1 -0
  14. package/dist/chunks/{contract-B0ra2-bm.mjs → contract-BkMjU1kR.mjs} +2 -2
  15. package/dist/chunks/{contract-B0ra2-bm.mjs.map → contract-BkMjU1kR.mjs.map} +1 -1
  16. package/dist/chunks/{contract-vYbwYr0Y.mjs → contract-bQ9FJl4N.mjs} +2 -2
  17. package/dist/chunks/contract-bQ9FJl4N.mjs.map +1 -0
  18. package/dist/chunks/{diff-Qw0II0sj.mjs → diff-D_0hBwHl.mjs} +2 -2
  19. package/dist/chunks/{diff-Qw0II0sj.mjs.map → diff-D_0hBwHl.mjs.map} +1 -1
  20. package/dist/chunks/{discover-30Ciya_0.mjs → discover-eS01-me1.mjs} +3 -2
  21. package/dist/chunks/{discover-30Ciya_0.mjs.map → discover-eS01-me1.mjs.map} +1 -1
  22. package/dist/chunks/{doctor-DfCrKpfT.mjs → doctor-CginW8y8.mjs} +5 -5
  23. package/dist/chunks/{doctor-DfCrKpfT.mjs.map → doctor-CginW8y8.mjs.map} +1 -1
  24. package/dist/chunks/init-BUnzIkeE.mjs +63 -0
  25. package/dist/chunks/init-BUnzIkeE.mjs.map +1 -0
  26. package/dist/chunks/migrate-DybihKzZ.mjs +33 -0
  27. package/dist/chunks/migrate-DybihKzZ.mjs.map +1 -0
  28. package/dist/chunks/{policy-DUIgzF3W.mjs → policy-Clypo20s.mjs} +3 -3
  29. package/dist/chunks/{policy-DUIgzF3W.mjs.map → policy-Clypo20s.mjs.map} +1 -1
  30. package/dist/chunks/reconcile-Bhy3IIYo.mjs +50 -0
  31. package/dist/chunks/reconcile-Bhy3IIYo.mjs.map +1 -0
  32. package/dist/chunks/scan-8Gy_B6kI.mjs +122 -0
  33. package/dist/chunks/scan-8Gy_B6kI.mjs.map +1 -0
  34. package/dist/chunks/src-CmFjh4M0.mjs +928 -0
  35. package/dist/chunks/src-CmFjh4M0.mjs.map +1 -0
  36. package/dist/chunks/{src-CfAOde7C.mjs → src-DZazJCp1.mjs} +2 -2
  37. package/dist/chunks/{src-CfAOde7C.mjs.map → src-DZazJCp1.mjs.map} +1 -1
  38. package/dist/chunks/{src-CId6kMsY.mjs → src-r0ECB1UJ.mjs} +2 -2
  39. package/dist/chunks/{src-CId6kMsY.mjs.map → src-r0ECB1UJ.mjs.map} +1 -1
  40. package/dist/cli.mjs +12 -12
  41. package/dist/cli.mjs.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunks/auth-D8rCVY33.mjs.map +0 -1
  44. package/dist/chunks/compose-Cr0hP0qm.mjs.map +0 -1
  45. package/dist/chunks/contract-vYbwYr0Y.mjs.map +0 -1
  46. package/dist/chunks/init-Okz4mlhW.mjs +0 -30
  47. package/dist/chunks/init-Okz4mlhW.mjs.map +0 -1
  48. package/dist/chunks/migrate-DRoFUg53.mjs +0 -19
  49. package/dist/chunks/migrate-DRoFUg53.mjs.map +0 -1
  50. package/dist/chunks/reconcile-BfD785gd.mjs +0 -26
  51. package/dist/chunks/reconcile-BfD785gd.mjs.map +0 -1
  52. package/dist/chunks/src-JxawBQBn.mjs +0 -446
  53. package/dist/chunks/src-JxawBQBn.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"catalogue-BvwSrM_j.mjs","names":["resolvePath","metadata","fail","row","result","fail","requiredPath","make","rowByName","ToolGrantSchema"],"sources":["../../../../packages/security/src/decide/commands/profiles.ts","../../../../packages/security/src/decide/commands/resolver.ts","../../../../packages/security/src/decide/commands/index.ts","../../../../packages/security/src/decide/gate/index.ts","../../../../packages/security/src/decide/paths/glob.ts","../../../../packages/security/src/decide/paths/resolve.ts","../../../../packages/tools/src/catalogue/schemas.ts","../../../../packages/tools/src/impl/exec/index.ts","../../../../packages/tools/src/impl/read/index.ts","../../../../packages/tools/src/catalogue/stub.ts","../../../../packages/tools/src/impl/state/index.ts","../../../../packages/tools/src/impl/write/index.ts","../../../../packages/tools/src/catalogue/index.ts"],"sourcesContent":["// ProgramProfiles for git, pnpm, npm, yarn, node, docker (DESIGN 2.6.4, ADR-0024 item 4).\n//\n// A profile parses argv[1..] into { globals, subcommand, flags, positionals } (`ParsedCommand`), or returns a\n// `CommandDenial` when a GLOBAL option would re-target the command onto a directory or repository the agent does not\n// own (`git -C`, `node --require`, ...). Everything else that looks like a flag before the first non-flag token is a\n// benign global (`git --no-pager push` still parses `push` as the subcommand: DESIGN 7.4 EV-08/09).\n//\n// Deviation (recorded, not a defect in a dependency): DESIGN's interface comment for `ProgramProfile.parse` is the\n// fullest listing of the re-targeting option sets (git: -C/-c/--git-dir/--work-tree/--exec-path/--namespace; pnpm:\n// -C/--dir/--prefix; npm: --prefix; node: -e/-p/-r/--require/--import/--loader/--eval); the unit pack's prose\n// summary drops a few of these in its compression. This file follows the fuller DESIGN interface comment, which is\n// normative for behaviour (RULES pack §0). That per-program listing is ILLUSTRATIVE, not closed: the normative\n// sentence is \"Returns a denial for any global option that re-targets the command\", so `yarn --cwd` and\n// `docker -H/--host/--context/--config` are denied too — they are the EV-08/09 mechanism `git -C` is denied for.\n//\n// Deviation: DESIGN's `ParsedCommand` splits the LEADING run of option tokens into `globals`; npm, pnpm, yarn and\n// docker all accept their config options AFTER the subcommand as well (`pnpm install --dir=/elsewhere`), so a\n// re-targeting option is rejected wherever it appears in argv, not only while it leads.\n\nimport type { CommandDenial, ParsedCommand, ProgramProfile } from '../../contract/index.ts';\n\n/** True for a token that starts a run of leading options, e.g. `-C`, `--dir=x`, `-e\"code\"`. */\nconst isFlagToken = (token: string): boolean => token.startsWith('-') && token !== '-';\n\n/** True when `token` invokes `flag`, whether joined by `=` (long options) or directly attached (short options). */\nfunction matchesFlag(token: string, flag: string): boolean {\n if (token === flag) return true;\n if (flag.startsWith('--')) return token.startsWith(`${flag}=`);\n return flag.length === 2 && token.length > flag.length && token.startsWith(flag);\n}\n\nexport interface ProfileSpec {\n program: string;\n aliases: readonly string[];\n /** global options that re-target the command; matched against every leading flag token (DESIGN 2.6.4 step 1-4). */\n retargeting: readonly string[];\n}\n\n/**\n * One shared structural parser for every built-in profile: walk leading flag tokens (denying a re-targeting one on\n * sight), the first non-flag token is the subcommand, everything after it splits into `flags` / `positionals` by\n * whether it starts with `-`. This is a STRUCTURAL split, not a full CLI grammar: it does not know which flags of\n * `git commit -m <msg>` consume a value, because the callers that need that (CommandRule matching) work in terms of\n * flag NAMES and positional VALUES declared by policy data, never by re-deriving one CLI's full option grammar here.\n */\nfunction createProfile(spec: ProfileSpec): ProgramProfile {\n return {\n program: spec.program,\n aliases: spec.aliases,\n parse(args: readonly string[]): ParsedCommand | CommandDenial {\n const retargeted = (token: string): CommandDenial | undefined => {\n const denied = spec.retargeting.find((flag) => matchesFlag(token, flag));\n if (denied === undefined) return undefined;\n return {\n kind: 'denied',\n code: 'security/command-global-option',\n token,\n reason: `${spec.program}: \\`${denied}\\` re-targets the command onto a different directory or repository`,\n };\n };\n\n const globals: string[] = [];\n let index = 0;\n while (index < args.length) {\n const token = args[index];\n if (token === undefined || !isFlagToken(token)) break;\n const denial = retargeted(token);\n if (denial !== undefined) return denial;\n globals.push(token);\n index += 1;\n }\n const subcommandToken = args[index];\n const subcommand = subcommandToken === undefined ? [] : [subcommandToken];\n const rest = subcommandToken === undefined ? [] : args.slice(index + 1);\n const flags: string[] = [];\n const positionals: string[] = [];\n for (const token of rest) (isFlagToken(token) ? flags : positionals).push(token);\n // A re-targeting option placed after the subcommand re-targets just as well: `pnpm install --dir=/elsewhere`.\n for (const token of flags) {\n const denial = retargeted(token);\n if (denial !== undefined) return denial;\n }\n return { kind: 'parsed', globals, subcommand, flags, positionals };\n },\n };\n}\n\n// The sets include the exact functional SYNONYMS of the options DESIGN 2.6.4 names — `--config-env` is `-c` read\n// from the environment, `--experimental-loader` is Node's own documented alias of `--loader` — and the remaining\n// value-taking git globals (`--super-prefix`, `--attr-source`), which would otherwise parse as benign globals and\n// shift the subcommand out from under the D9 check. DESIGN's per-program listing is illustrative, not closed\n// (request R3); the normative sentence is \"a denial for ANY global option that re-targets the command\".\nconst GIT_RETARGETING = [\n '-C',\n '-c',\n '--config-env',\n '--git-dir',\n '--work-tree',\n '--exec-path',\n '--namespace',\n '--super-prefix',\n '--attr-source',\n];\nconst PNPM_RETARGETING = ['-C', '--dir', '--prefix'];\nconst NPM_RETARGETING = ['--prefix'];\nconst NODE_RETARGETING = [\n '-e',\n '-p',\n '-r',\n '--require',\n '--import',\n '--loader',\n '--experimental-loader',\n '--eval',\n '--env-file',\n '--env-file-if-exists',\n];\n/** `yarn --cwd <dir>` runs the whole command in another directory: `git -C` under another name. */\nconst YARN_RETARGETING = ['--cwd'];\n/** `docker -H`/`--host`/`--context` re-target the DAEMON (a remote one included); `--config` the credential store. */\nconst DOCKER_RETARGETING = ['-H', '--host', '--context', '--config'];\n\nexport const GIT_PROFILE: ProgramProfile = createProfile({ program: 'git', aliases: [], retargeting: GIT_RETARGETING });\nexport const PNPM_PROFILE: ProgramProfile = createProfile({\n program: 'pnpm',\n aliases: [],\n retargeting: PNPM_RETARGETING,\n});\nexport const NPM_PROFILE: ProgramProfile = createProfile({ program: 'npm', aliases: [], retargeting: NPM_RETARGETING });\nexport const YARN_PROFILE: ProgramProfile = createProfile({\n program: 'yarn',\n aliases: [],\n retargeting: YARN_RETARGETING,\n});\nexport const NODE_PROFILE: ProgramProfile = createProfile({\n program: 'node',\n aliases: [],\n retargeting: NODE_RETARGETING,\n});\n/** `docker-compose up` normalises to `docker compose up`: EV-10. */\nexport const DOCKER_PROFILE: ProgramProfile = createProfile({\n program: 'docker',\n aliases: ['docker-compose'],\n retargeting: DOCKER_RETARGETING,\n});\n\nexport const BUILTIN_PROFILES: readonly ProgramProfile[] = Object.freeze([\n GIT_PROFILE,\n PNPM_PROFILE,\n NPM_PROFILE,\n YARN_PROFILE,\n NODE_PROFILE,\n DOCKER_PROFILE,\n]);\n\n/**\n * Subcommand tokens an alias implies, prepended to argv[1..] before the matched profile parses it: `docker-compose`\n * behaves as `docker compose`. No other built-in alias carries an implied subcommand.\n */\nconst ALIAS_SUBCOMMAND_PREFIX: Readonly<Record<string, readonly string[]>> = Object.freeze({\n 'docker-compose': Object.freeze(['compose']),\n});\n\nexport interface ProfileMatch {\n profile: ProgramProfile;\n /** subcommand tokens the alias implies, to prepend to argv[1..] before calling `profile.parse`. */\n prefix: readonly string[];\n}\n\n/** `bareName` is argv[0] as typed (already checked to be a bare name with no path separator). */\nexport function findProfile(bareName: string, profiles: readonly ProgramProfile[]): ProfileMatch | undefined {\n for (const profile of profiles) {\n if (profile.program === bareName) return { profile, prefix: [] };\n if (profile.aliases.includes(bareName)) return { profile, prefix: ALIAS_SUBCOMMAND_PREFIX[bareName] ?? [] };\n }\n return undefined;\n}\n\n/** The CANONICAL program name of `bareName` for trampoline / rule-matching purposes: `docker-compose` -> `docker`. */\nexport function canonicalProgramName(bareName: string, profiles: readonly ProgramProfile[]): string {\n return findProfile(bareName, profiles)?.profile.program ?? bareName;\n}\n","// ProgramResolver: `argv[0]` through the PATH pinned at run start, then realpath (DESIGN 2.6.4). A repo-local shim,\n// a `./node`, or a program planted in a directory outside the pinned list can never stand in for the real program:\n// this resolver only ever looks inside the directories it was given, in order, and returns the on-disk realpath of\n// whatever it finds there — never the raw candidate path (EV-07).\nimport { accessSync, constants, realpathSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CanonicalPath, ProgramResolver } from '../../contract/index.ts';\n\nexport interface ProgramResolverFs {\n accessSync(path: string, mode?: number): void;\n realpathSync(path: string): string;\n}\n\nconst NODE_FS: ProgramResolverFs = { accessSync, realpathSync };\n\nexport interface ProgramResolverOptions {\n /** the PATH pinned at run start, as directories, in search order. Never Pi's or Cohorte's own bin directory. */\n pathDirs: readonly string[];\n /** injected for tests; defaults to `node:fs`. */\n fs?: ProgramResolverFs;\n}\n\n/**\n * `bareName` SHOULD already be a bare name (no path separator): that is checked one layer up, as the very first\n * thing `evaluate()` does (DESIGN 2.6.4 step 1). This resolver enforces it too, defensively: `node:path.join`\n * normalises a segment like `./node` or `../x` away, so without this guard a relative-looking name would silently\n * resolve through directory-list normalisation rather than being rejected outright, for any OTHER caller of this\n * port that does not repeat the step-1 check.\n */\nexport function createProgramResolver(options: ProgramResolverOptions): ProgramResolver {\n const dirs = [...options.pathDirs];\n const fs = options.fs ?? NODE_FS;\n const cache = new Map<string, CanonicalPath | undefined>();\n return {\n resolve(bareName: string): CanonicalPath | undefined {\n if (bareName === '' || bareName.includes('/') || bareName.includes('\\\\')) return undefined;\n const cached = cache.get(bareName);\n if (cached !== undefined || cache.has(bareName)) return cached;\n let found: CanonicalPath | undefined;\n for (const dir of dirs) {\n const candidate = join(dir, bareName);\n try {\n fs.accessSync(candidate, constants.X_OK);\n found = fs.realpathSync(candidate) as CanonicalPath;\n break;\n } catch {\n // not in this directory, or not executable: keep searching the pinned PATH\n }\n }\n cache.set(bareName, found);\n return found;\n },\n };\n}\n","// Command policy evaluation (DESIGN 2.6.4, ADR-0024, ADR-0007): a parsed-argv allowlist, never a shell-string\n// matcher. `createCommandPolicy` implements the six evaluation steps verbatim:\n//\n// 1. `argv[0]` is a bare name, resolved to an absolute realpath through the PATH pinned at run start.\n// 2. Trampolines (`sh`, `python*`, `pi`, `cohorte`, ...) are denied, `overridable: false`. The single escape hatch\n// is an exact-argv rule under `policy.dangerousCommands`, and ADR-0024 item 3 is categorical about it: a\n// trampoline \"cannot be allowlisted\" and \"every use is `ask`\". A `CommandRule` carries no marker telling a\n// `dangerousCommands` rule from a `policy.commands.allow` one (both are `origin: 'project-config'`), so this\n// evaluator RE-ASSERTS the coercion itself: a matching rule that says `deny` denies, anything else asks.\n// 3. Agents have a built-in, non-overridable deny on `git commit|push|merge|...` (D9 / ADR-0007), independent of\n// any rule.\n// 4. A program WITH a `ProgramProfile` is parsed structurally and matched by `(program, subcommand, flags,\n// positionals)`; a program without one can only be matched by an `exact`-argv rule (used by both\n// `dangerousCommands` and `config.checks`, via `checksToCommandRules`).\n// 5. No rule matches => deny; among several matches, deny beats ask beats allow.\n// 6. `cwd` must canonicalise inside the agent's own worktree; a rule's `when.branch: 'unprotected-only'` treats a\n// detached/unknown branch as protected (never matches).\n//\n// Deviation (recorded, does not affect any test in this unit's own scope): this evaluator checks `cwd` containment\n// EARLY, as a precondition, rather than as literally the last of the six steps — nothing downstream can matter once\n// `cwd` has escaped the agent's own worktree, and evaluating it early means `when.branch` matching always has a\n// resolved branch to work with. The set of calls this denies is identical either way.\n//\n// Deviation: DESIGN's parenthetical for EV-01 says the node profile \"canonicalises the script positional to a\n// worktree-relative realpath\". `CommandPolicyOptions` carries no `PathResolver` (only `programs` and `branches`),\n// so this unit does not perform that canonicalisation itself: a positional that does not literally match a rule is\n// denied by the plain \"no rule matches\" default (§5), which is the same security outcome. Full realpath\n// canonicalisation of `run_command` POSITIONAL arguments, if ever wanted, needs a `PathResolver` threaded into\n// this contract — filed as an FYI in docs/v3/requests/U1.03.md, not a blocker.\nimport type { CohorteConfig, CommandRule } from '@cohorte/config/schema';\nimport { type TSchema, Type } from 'typebox';\nimport type {\n BranchResolver,\n CanonicalPath,\n CommandPolicy,\n CommandRequest,\n NormalizedCall,\n ParsedCommand,\n ProgramProfile,\n ProgramResolver,\n} from '../../contract/index.ts';\nimport { AGENT_GIT_DENIED_SUBCOMMANDS, isTrampoline } from '../../contract/index.ts';\nimport { BUILTIN_PROFILES, canonicalProgramName, findProfile } from './profiles.ts';\n\nexport { createProgramResolver, type ProgramResolverFs, type ProgramResolverOptions } from './resolver.ts';\nexport { BUILTIN_PROFILES, canonicalProgramName, findProfile };\n\nexport interface CommandContext {\n /** the agent's own worktree: `cwd` must canonicalise inside it */\n worktree: CanonicalPath;\n /** `CommandRequest.cwd`, already resolved by stage 3 */\n cwd: CanonicalPath;\n role: string;\n phase: string;\n /** under L0 a rule flagged `network` is denied */\n sandboxLevel: 'L0-process' | 'L1-os';\n defaultTimeoutMs: number;\n}\n\n/** Stage 4 for `run_command`: deny over ask over allow; no rule => deny. */\nexport interface CommandEvaluation {\n decision: 'allow' | 'ask' | 'deny';\n ruleId: string;\n /** the error code of a deny, e.g. 'security/command-trampoline' */\n code?: string;\n reason: string;\n overridable: boolean;\n securityViolation: boolean;\n evaluatedRules: string[];\n /** present unless denied: what will actually execute */\n command?: NonNullable<NormalizedCall['command']>;\n}\n\nexport interface CommandPolicyEvaluator {\n evaluate(request: CommandRequest, policy: CommandPolicy, context: CommandContext): CommandEvaluation;\n}\n\nexport interface CommandPolicyOptions {\n programs: ProgramResolver;\n branches: BranchResolver;\n /** default: the built-in profiles (git, pnpm, npm, yarn, node, docker) */\n profiles?: readonly ProgramProfile[];\n}\n\ntype BranchInfo = ReturnType<BranchResolver['branchOf']>;\n\n// ── structural helpers ────────────────────────────────────────────────────────────────────────\n\nconst tokensEqual = (a: readonly string[], b: readonly string[]): boolean =>\n a.length === b.length && a.every((value, index) => value === b[index]);\n\n/** `path` inside `root`, by path SEGMENTS (never `startsWith` alone: `/w/api` must not contain `/w/api-gateway`). */\nconst isContainedIn = (path: string, root: string): boolean => path === root || path.startsWith(`${root}/`);\n\n/**\n * \"Anything not allowed is denied\" (DESIGN 2.6.4) is a rule about what may be PERMITTED, so the allowlist only ever\n * narrows an `allow` rule — where narrowing fails closed. Applied to a `deny` or an `ask` rule it narrows in the\n * other direction: the restrictive rule stops matching as soon as a flag it did not declare is present, while a\n * broader `allow` rule that DOES list that flag keeps matching, and `deny > ask > allow` (step 5) is defeated by one\n * token (`pnpm --silent run build`). A restrictive rule therefore matches on program + subcommand + positionals\n * alone. Recorded in docs/v3/requests/U1.03.md R4 item 3.\n */\nfunction flagsMatch(flags: readonly string[], rule: CommandRule): boolean {\n if (flags.length === 0 || rule.decision !== 'allow') return true;\n const spec = rule.flags;\n if (spec === undefined) return false; // \"anything not allowed is denied\": no allowlist => no flag may be present\n return flags.every((flag) => !spec.deny?.includes(flag) && spec.allow.includes(flag));\n}\n\n/** Structural, not filesystem-aware: real containment/symlink checks of path-typed arguments are stage 3's job. */\nconst looksLikeWorktreeRelativePath = (value: string): boolean =>\n !value.startsWith('-') && !value.startsWith('/') && !value.startsWith('~') && !value.split(/[/\\\\]/).includes('..');\n\nfunction positionalsMatch(positionals: readonly string[], spec: CommandRule['positionals']): boolean {\n if (spec === undefined) return positionals.length === 0;\n switch (spec.kind) {\n case 'none':\n return positionals.length === 0;\n case 'exact':\n return tokensEqual(positionals, spec.values);\n // Both value-bearing kinds have a LOWER bound too: `every()` over an empty array is vacuously true, so without\n // it a rule written for `pnpm run test` also matched the bare `pnpm run`, and one for `git add <paths>` the\n // argument-less `git add` — every such rule silently wider than its author wrote it.\n case 'enum':\n return (\n positionals.length > 0 &&\n positionals.length <= spec.max &&\n positionals.every((value) => spec.values.includes(value))\n );\n case 'paths-in-worktree':\n return (\n positionals.length > 0 && positionals.length <= spec.max && positionals.every(looksLikeWorktreeRelativePath)\n );\n }\n}\n\n/** A rule with no `subcommand`, no `flags` and `positionals.kind: 'exact'` matches the WHOLE rest of argv, whether\n * or not the program has a profile: this is how `dangerousCommands` and `checksToCommandRules` rules match. */\nfunction matchesExactArgv(rule: CommandRule, rest: readonly string[]): boolean {\n if (rule.subcommand !== undefined || rule.flags !== undefined) return false;\n const positionals = rule.positionals;\n return positionals !== undefined && positionals.kind === 'exact' && tokensEqual(rest, positionals.values);\n}\n\n/**\n * Only reachable for a profiled program: `(subcommand, flags, positionals)`, per DESIGN 2.6.4 step 4.\n *\n * The profile's structural split is deliberately shallow — the FIRST non-flag token is `subcommand`, every later\n * non-flag token is a positional — so a rule's `subcommand` is matched as a PREFIX of the whole non-flag token\n * stream. That is what makes DESIGN 2.6.4's own example (`subcommand: ['run','test']`) and `['compose','up']`\n * reachable, and it keeps `docker-compose up` ≡ `docker compose up`. The tokens the prefix consumes are removed\n * before the positional check; an absent or empty `subcommand` is \"no subcommand constraint\", not \"never matches\".\n *\n * Deviation (recorded): a rule's `flags` allowlist is matched against `globals` TOO, not only against the flags\n * that follow the subcommand. DESIGN 2.6.4 says of `flags` \"anything not allowed is denied\"; leaving the leading\n * globals unchecked would let `pnpm --silent run test` satisfy a rule written for `pnpm run test`, which fails\n * OPEN. Benign globals are still parsed as globals (EV-08/09: `git --no-pager push` still has subcommand `push`);\n * a policy that wants to permit one lists it in `flags.allow`.\n */\nfunction matchesStructurally(rule: CommandRule, parsed: ParsedCommand): boolean {\n const tokens = [...parsed.subcommand, ...parsed.positionals];\n const required = rule.subcommand ?? [];\n if (required.length > tokens.length) return false;\n if (!required.every((token, index) => token === tokens[index])) return false;\n return (\n flagsMatch([...parsed.globals, ...parsed.flags], rule) &&\n positionalsMatch(tokens.slice(required.length), rule.positionals)\n );\n}\n\n/**\n * The D9 subcommand of a `git` call, if it is one of the denied ones (ADR-0007 item 2).\n *\n * With a structural parse in hand the subcommand is exact, and the profile has already denied every value-taking\n * re-targeting global. Without one — a caller passed `profiles` without git — nothing can tell a subcommand from a\n * global option's VALUE (`git --super-prefix x commit`), so every token is held against the set: conservative in\n * the only safe direction for an invariant that must not be switchable off.\n */\nfunction deniedGitSubcommand(parsed: ParsedCommand | undefined, rest: readonly string[]): string | undefined {\n const denied = AGENT_GIT_DENIED_SUBCOMMANDS as readonly string[];\n if (parsed === undefined) return rest.find((token) => denied.includes(token));\n const subcommand = parsed.subcommand[0];\n return subcommand !== undefined && denied.includes(subcommand) ? subcommand : undefined;\n}\n\nfunction branchAllows(rule: CommandRule, branch: BranchInfo): boolean {\n const required = rule.when?.branch ?? 'any';\n return required === 'any' || (branch.kind === 'branch' && !branch.protected);\n}\n\nfunction whenMatches(rule: CommandRule, context: CommandContext, branch: BranchInfo): boolean {\n if (!branchAllows(rule, branch)) return false;\n if (rule.when?.roles && !rule.when.roles.includes(context.role)) return false;\n if (rule.when?.phases && !rule.when.phases.includes(context.phase)) return false;\n return true;\n}\n\nconst DECISION_RANK: Record<CommandRule['decision'], number> = { deny: 0, ask: 1, allow: 2 };\n\n/** deny beats ask beats allow (DESIGN 2.6.4 step 5, 2.6.2 precedence). `matches` must be non-empty. */\nfunction pickWinner(matches: readonly CommandRule[]): CommandRule {\n return matches.reduce((best, rule) => (DECISION_RANK[rule.decision] < DECISION_RANK[best.decision] ? rule : best));\n}\n\n/** Every rule of `program`, structurally or exactly matching, whose `when` is satisfied. Records every rule id it\n * looked at in `evaluatedRules`, matched or not (`PolicyVerdict.evaluatedRules`, \"for `cohorte policy explain`\"). */\nfunction matchRules(\n rules: readonly CommandRule[],\n program: string,\n rest: readonly string[],\n parsed: ParsedCommand | undefined,\n context: CommandContext,\n branch: BranchInfo,\n evaluatedRules: string[],\n): CommandRule[] {\n const matches: CommandRule[] = [];\n for (const rule of rules) {\n if (rule.program !== program) continue;\n evaluatedRules.push(rule.id);\n const structurallyOk = parsed !== undefined && matchesStructurally(rule, parsed);\n const exactlyOk = matchesExactArgv(rule, rest);\n if ((structurallyOk || exactlyOk) && whenMatches(rule, context, branch)) matches.push(rule);\n }\n return matches;\n}\n\n// ── building the result ───────────────────────────────────────────────────────────────────────\n\ninterface DenyArgs {\n ruleId: string;\n code?: string;\n reason: string;\n overridable: boolean;\n securityViolation: boolean;\n evaluatedRules: string[];\n}\n\nfunction denyEval(args: DenyArgs): CommandEvaluation {\n const { ruleId, code, reason, overridable, securityViolation, evaluatedRules } = args;\n return {\n decision: 'deny',\n ruleId,\n reason,\n overridable,\n securityViolation,\n evaluatedRules,\n ...(code === undefined ? {} : { code }),\n };\n}\n\nfunction applyRule(\n rule: CommandRule,\n args: {\n resolvedFile: CanonicalPath;\n rest: readonly string[];\n context: CommandContext;\n timeoutMs: number | undefined;\n evaluatedRules: string[];\n },\n): CommandEvaluation {\n const { resolvedFile, rest, context, timeoutMs, evaluatedRules } = args;\n // An explicit deny is reported as its own verdict, BEFORE the network guard: a `deny` rule that also carries\n // `network: true` is denied by policy, and saying `permission/network-denied` would misattribute it in the audit\n // event and in `cohorte policy explain`. Only an `allow`/`ask` rule can become a network denial.\n const overridable = rule.origin !== 'builtin';\n if (rule.decision === 'deny') {\n return denyEval({\n ruleId: rule.id,\n code: 'permission/command-not-allowed',\n reason: `denied by rule ${rule.id}`,\n overridable,\n securityViolation: false,\n evaluatedRules,\n });\n }\n // \"network: true => denied under L0 (nothing enforces the deny); under L1 it fails closed in the sandbox.\"\n if (rule.network && context.sandboxLevel === 'L0-process') {\n return denyEval({\n ruleId: rule.id,\n code: 'permission/network-denied',\n reason: `rule ${rule.id} needs network access, which the L0 process sandbox cannot enforce a deny for`,\n overridable: false,\n securityViolation: false,\n evaluatedRules,\n });\n }\n const command: NonNullable<NormalizedCall['command']> = {\n file: resolvedFile,\n args: [...rest],\n cwd: context.cwd,\n ruleId: rule.id,\n replay: rule.replay,\n network: rule.network,\n timeoutMs: timeoutMs ?? context.defaultTimeoutMs,\n };\n return {\n decision: rule.decision === 'ask' ? 'ask' : 'allow',\n ruleId: rule.id,\n reason: rule.decision === 'ask' ? `rule ${rule.id} requires confirmation` : `allowed by rule ${rule.id}`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n command,\n };\n}\n\n// ── the evaluator ─────────────────────────────────────────────────────────────────────────────\n\nexport function createCommandPolicy(options: CommandPolicyOptions): CommandPolicyEvaluator {\n const profiles = options.profiles ?? BUILTIN_PROFILES;\n return {\n evaluate(request: CommandRequest, policy: CommandPolicy, context: CommandContext): CommandEvaluation {\n const evaluatedRules: string[] = [];\n const argv = request.argv;\n const bareName = argv[0];\n\n if (bareName === undefined || bareName === '') {\n return denyEval({\n ruleId: 'builtin/argv-empty',\n code: 'permission/command-not-allowed',\n reason: 'argv is empty: there is no program to run',\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n if (bareName.includes('/') || bareName.includes('\\\\')) {\n return denyEval({\n ruleId: 'builtin/bare-name',\n code: 'permission/command-not-allowed',\n reason: `argv[0] \"${bareName}\" is not a bare program name (DESIGN 2.6.4 step 1)`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n evaluatedRules.push('builtin/resolve');\n const resolvedFile = options.programs.resolve(bareName);\n if (resolvedFile === undefined) {\n return denyEval({\n ruleId: 'builtin/resolve',\n code: 'permission/command-not-allowed',\n reason: `\"${bareName}\" does not resolve to a program on the PATH pinned at run start`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n });\n }\n\n evaluatedRules.push('builtin/cwd-containment');\n if (!isContainedIn(context.cwd, context.worktree)) {\n return denyEval({\n ruleId: 'builtin/cwd-containment',\n code: 'permission/command-not-allowed',\n reason: `cwd \"${context.cwd}\" is outside the agent's own worktree \"${context.worktree}\"`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n const branch = options.branches.branchOf(context.cwd);\n const match = findProfile(bareName, profiles);\n const canonicalName = match?.profile.program ?? bareName;\n const rest = argv.slice(1);\n\n // Step 2: trampolines. A trampoline is NEVER allowlisted (ADR-0024 item 3): the only escape hatch is an\n // exact-argv `dangerousCommands` rule, and \"every use is `ask`\". Since a `CommandRule` carries no marker\n // distinguishing such a rule from an ordinary `policy.commands` allow (both are `origin: 'project-config'`,\n // and `checksToCommandRules` mints rules from `.cohorte/config.yaml` too), the coercion the `PolicySnapshot`\n // contract promises is re-asserted here rather than trusted to the rule list: deny stays deny, everything\n // else becomes `ask`.\n evaluatedRules.push('builtin/trampolines');\n if (isTrampoline(bareName) || isTrampoline(canonicalName)) {\n const matches = matchRules(policy.rules, canonicalName, rest, undefined, context, branch, evaluatedRules);\n const winner = matches.length > 0 ? pickWinner(matches) : undefined;\n if (winner !== undefined) {\n const coerced: CommandRule = winner.decision === 'deny' ? winner : { ...winner, decision: 'ask' };\n const evaluation = applyRule(coerced, {\n resolvedFile,\n rest,\n context,\n timeoutMs: request.timeoutMs,\n evaluatedRules,\n });\n if (evaluation.decision !== 'ask') return evaluation;\n return {\n ...evaluation,\n reason: `\"${bareName}\" launches another program on behalf of the agent: rule ${winner.id} matches, but every use of a trampoline is \\`ask\\` (ADR-0024)`,\n };\n }\n return denyEval({\n ruleId: 'builtin/trampolines',\n code: 'security/command-trampoline',\n reason: `\"${bareName}\" would launch another program on behalf of the agent`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n // Step 4: structural parse for a profiled program (denies a re-targeting global option on sight).\n let parsed: ParsedCommand | undefined;\n if (match !== undefined) {\n evaluatedRules.push('builtin/profile-parse');\n const outcome = match.profile.parse([...match.prefix, ...rest]);\n if (outcome.kind === 'denied') {\n return denyEval({\n ruleId: 'builtin/global-option',\n code: outcome.code,\n reason: outcome.reason,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n parsed = outcome;\n }\n\n // Step 3: agents have no commit capability (D9 / ADR-0007 item 2), unconditionally — including when the\n // caller's `profiles` list carries no git profile at all. `profiles` is a public option of this API, so\n // nesting this inside \"a git profile was found\" would let a caller switch a NON-OVERRIDABLE invariant off.\n if (canonicalName === 'git') {\n const subcommand = deniedGitSubcommand(parsed, rest);\n if (subcommand !== undefined) {\n evaluatedRules.push('builtin/agent-git-deny');\n return denyEval({\n ruleId: 'builtin/agent-git-deny',\n code: 'permission/command-not-allowed',\n reason: `agents may not run \\`git ${subcommand}\\`: Cohorte creates every commit (ADR-0007)`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n }\n\n // Steps 4-5: structural (profiled) or exact-argv (unprofiled, or a profiled program's exact rule) matching.\n const matches = matchRules(policy.rules, canonicalName, rest, parsed, context, branch, evaluatedRules);\n if (matches.length === 0) {\n return denyEval({\n ruleId: 'builtin/no-rule',\n code: 'permission/command-not-allowed',\n reason: `no command rule matches \"${[bareName, ...rest].join(' ')}\"; the default is deny`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n });\n }\n return applyRule(pickWinner(matches), {\n resolvedFile,\n rest,\n context,\n timeoutMs: request.timeoutMs,\n evaluatedRules,\n });\n },\n };\n}\n\n// ── `config.checks` -> CommandRule (DESIGN 2.6.4: \"package.json scripts are reachable only as `pnpm run <name>`\n// with `<name>` in an `enum`\"; a check's own argv array becomes one `exact` rule instead) ──────────────────────\n\n/** `config.checks.{typecheck,lint,test}` (argv arrays) become `exact`, `idempotent`, allowed rules: they are the\n * project's own, human-authored commands (`.cohorte/config.yaml` `checks:`), not something an approval gates.\n *\n * The one exception is a check whose `argv[0]` is a TRAMPOLINE (`checks.test: ['npx', 'vitest']`,\n * `['sh', '-c', …]`): `.cohorte/config.yaml` is project-controlled, so minting `decision: 'allow'` from it would\n * re-open the shell that ADR-0024 item 3 closes. Such a check becomes an `ask` rule — the same verdict the\n * evaluator's trampoline step would coerce it to, said honestly in the rule DATA so `cohorte policy explain`\n * shows it. */\nexport function checksToCommandRules(checks: CohorteConfig['checks']): CommandRule[] {\n const named: readonly (readonly [string, readonly string[] | undefined])[] = [\n ['typecheck', checks.typecheck],\n ['lint', checks.lint],\n ['test', checks.test],\n ];\n const rules: CommandRule[] = [];\n for (const [name, argv] of named) {\n if (argv === undefined || argv.length === 0) continue;\n const declared = argv[0];\n if (declared === undefined) continue;\n // `evaluate()` matches rules against the ALIAS-NORMALISED program name (EV-10), so a check declared with an\n // alias (`checks.test: ['docker-compose', 'up']`) must mint the canonical one or the rule is dead on arrival\n // and the project's own check command is denied. `exact` positionals stay `argv.slice(1)`: that is what is\n // compared against the literal `argv[1..]` of the request.\n const program = canonicalProgramName(declared, BUILTIN_PROFILES);\n rules.push({\n id: `checks/${name}`,\n program,\n positionals: { kind: 'exact', values: argv.slice(1) },\n decision: isTrampoline(declared) || isTrampoline(program) ? 'ask' : 'allow',\n replay: 'idempotent',\n network: false,\n origin: 'project-checks',\n });\n }\n return rules;\n}\n\n// ── schema, for \"every returned verdict fragment is schema-valid\" ────────────────────────────────────────────\n\nconst closed = { additionalProperties: false } as const;\n\n/** [S] Mirrors `CommandEvaluation`; `command` mirrors `NormalizedCall['command']` of ../../contract/decisions.ts. */\nexport const CommandEvaluationSchema: TSchema = Type.Object(\n {\n decision: Type.Union([Type.Literal('allow'), Type.Literal('ask'), Type.Literal('deny')]),\n ruleId: Type.String({ minLength: 1 }),\n code: Type.Optional(Type.String({ minLength: 1 })),\n reason: Type.String(),\n overridable: Type.Boolean(),\n securityViolation: Type.Boolean(),\n evaluatedRules: Type.Array(Type.String()),\n command: Type.Optional(\n Type.Object(\n {\n file: Type.String({ minLength: 1 }),\n args: Type.Array(Type.String()),\n cwd: Type.String({ minLength: 1 }),\n ruleId: Type.String({ minLength: 1 }),\n replay: Type.Union([Type.Literal('idempotent'), Type.Literal('at-most-once')]),\n network: Type.Boolean(),\n timeoutMs: Type.Integer({ minimum: 0 }),\n },\n closed,\n ),\n ),\n },\n closed,\n);\n","// Five pure gate stages and policy explanation (PLAN U2.01).\n\nimport type { JsonValue } from '@cohorte/base';\nimport { canonicalJson, sha256Hex } from '@cohorte/base';\nimport { type CohorteConfig, DEFAULT_NETWORK_POLICY, type Ownership } from '@cohorte/config/schema';\nimport type { TSchema } from 'typebox';\nimport { Compile } from 'typebox/compile';\nimport type {\n AgentGrant,\n GateCall,\n GlobMatcher,\n PolicyEngine,\n PolicyPorts,\n PolicySnapshot,\n PolicyVerdict,\n ToolIntrospection,\n} from '../../contract/index.ts';\nimport type { CommandPolicyEvaluator } from '../commands/index.ts';\n\nconst deny = (\n stage: PolicyVerdict['stage'],\n ruleId: string,\n reason: string,\n code = 'permission/tool-not-granted',\n securityViolation = false,\n): PolicyVerdict => ({\n decision: 'deny',\n stage,\n ruleId,\n reason: `${code}: ${reason}`,\n modelFacingReason: `${reason}. Do not retry.`,\n overridable: !securityViolation,\n securityViolation,\n asks: [],\n evaluatedRules: [ruleId],\n normalized: null,\n});\n\nconst invalidPolicy = (message: string): never => {\n throw new Error(`configuration/policy-invalid: ${message}`);\n};\n\nconst cloneFreeze = <T>(value: T): T => {\n if (value && typeof value === 'object') {\n Object.freeze(value);\n for (const child of Object.values(value as Record<string, unknown>)) cloneFreeze(child);\n }\n return value;\n};\n\nexport interface PolicyEngineOptions {\n tools: ToolIntrospection;\n globs: GlobMatcher;\n commands: CommandPolicyEvaluator;\n}\n\nexport function createPolicyEngine(options: PolicyEngineOptions): PolicyEngine {\n if (!options?.tools || !options.globs || !options.commands) invalidPolicy('policy engine ports are incomplete');\n return {\n evaluate(call, grant, policy, ports) {\n try {\n const schema = options.tools.schemaOf(call.tool);\n if (schema === undefined)\n return deny('schema', 'builtin/unknown-tool', `unknown tool \"${call.tool}\"`, 'validation/tool-input', true);\n const validation = Compile(schema as TSchema);\n if (!validation.Check(call.input))\n return deny(\n 'schema',\n 'builtin/tool-schema',\n `input for \"${call.tool}\" does not match its strict schema`,\n 'validation/tool-input',\n );\n\n const evaluatedRules: string[] = ['builtin/tool-schema'];\n if (!grant.tools.includes(call.tool))\n return {\n ...deny('capability', 'grant/tool-not-granted', `tool \"${call.tool}\" is not granted to this agent`),\n evaluatedRules,\n };\n\n const normalizedPaths: NonNullable<PolicyVerdict['normalized']>['paths'] = [];\n const base = grant.roots.workspace ?? grant.roots.readOnly[0];\n if (base === undefined)\n return deny(\n 'path',\n 'grant/no-root',\n 'the agent has no workspace or read-only root',\n 'permission/path-outside-grant',\n );\n for (const arg of options.tools.pathArgsOf(call.tool, call.input)) {\n const resolved = ports.paths.resolve(arg.value, base, arg.intent);\n if (!resolved.ok)\n return deny(\n 'path',\n `path/${resolved.error.code}`,\n `path argument \"${arg.arg}\" was refused: ${resolved.error.detail}`,\n resolved.error.security ? `security/${resolved.error.code}` : 'permission/path-outside-grant',\n resolved.error.security,\n );\n if (\n options.globs.isDenied(\n resolved.value.relative,\n grant,\n arg.intent === 'read' || arg.intent === 'list' ? 'read' : 'write',\n )\n )\n return deny('path', 'grant/deny-glob', `path argument \"${arg.arg}\" is denied by the grant`);\n normalizedPaths.push({ arg: arg.arg, resolved: resolved.value, intent: arg.intent });\n }\n\n let command: NonNullable<NonNullable<PolicyVerdict['normalized']>['command']> | undefined;\n if (call.tool === 'network_request')\n return deny(\n 'network',\n 'builtin/network-denied',\n 'network requests are disabled in V3.0',\n 'permission/network-denied',\n );\n if (call.tool === 'run_command') {\n const input = call.input as { argv?: JsonValue; cwd?: JsonValue };\n const argv =\n Array.isArray(input.argv) && input.argv.every((v) => typeof v === 'string') ? (input.argv as string[]) : [];\n const cwd = typeof input.cwd === 'string' ? input.cwd : '';\n const cwdResult = ports.paths.resolve(cwd, base, 'exec-cwd');\n if (!cwdResult.ok)\n return deny(\n 'command',\n 'command/cwd',\n 'command cwd is outside the grant',\n 'permission/command-not-allowed',\n true,\n );\n const evaluation = options.commands.evaluate({ argv, cwd }, grant.commands, {\n worktree: grant.roots.workspace ?? cwdResult.value.root,\n cwd: cwdResult.value.canonical,\n role: grant.role,\n phase: call.phase,\n sandboxLevel: policy.sandboxLevel,\n defaultTimeoutMs: grant.limits.perTool.run_command?.timeoutMs ?? 60_000,\n });\n evaluatedRules.push(...evaluation.evaluatedRules);\n if (evaluation.decision === 'deny' || evaluation.command === undefined)\n return deny('command', evaluation.ruleId, evaluation.reason, evaluation.code, evaluation.securityViolation);\n command = evaluation.command;\n }\n\n const limit = grant.limits.perTool[call.tool];\n const levels = [\n ['run', call.runId],\n ['phase', call.phase],\n ['agent', call.agentId],\n ['tool', call.tool],\n ] as const;\n for (const [level, id] of levels) {\n const remaining = ports.budgets.remaining(level, id);\n if ((remaining.toolCalls ?? 1) <= 0 || (remaining.wallClockMs ?? 1) <= 0)\n return deny('budget', `budget/${level}`, `${level} budget is exhausted`, 'budget/exhausted');\n }\n if (ports.budgets.callsInLastMinute(call.agentId, call.tool) >= grant.limits.maxCallsPerMinute)\n return deny('budget', 'budget/rate-limit', 'tool rate limit is exhausted', 'budget/rate-limit');\n const timeoutMs = Math.max(\n 1,\n Math.min(\n limit?.timeoutMs ?? 60_000,\n command?.timeoutMs ?? Number.MAX_SAFE_INTEGER,\n ports.budgets.remaining('agent', call.agentId).wallClockMs ?? Number.MAX_SAFE_INTEGER,\n ),\n );\n return {\n decision: 'allow',\n stage: 'budget',\n ruleId: command?.ruleId ?? 'grant/tool',\n reason: 'allowed by the policy',\n modelFacingReason: '',\n overridable: true,\n securityViolation: false,\n asks: [],\n evaluatedRules,\n normalized: {\n tool: call.tool,\n paths: normalizedPaths,\n ...(command ? { command: { ...command, timeoutMs } } : {}),\n input: call.input,\n grantKeyMaterial: { tool: call.tool, input: call.input },\n },\n };\n } catch (error) {\n return deny(\n 'schema',\n 'security/gate-internal-error',\n error instanceof Error ? error.message : 'gate failed closed',\n 'security/gate-internal-error',\n true,\n );\n }\n },\n };\n}\n\n/** Missing, unparseable or empty policy => `configuration/policy-invalid`: no tool ever executes. */\nexport function buildPolicySnapshot(\n config: CohorteConfig,\n ownership: Ownership,\n options: { sandboxLevel: PolicySnapshot['sandboxLevel'] },\n): PolicySnapshot {\n if (!config || config.policy === undefined || !ownership || options?.sandboxLevel === undefined)\n invalidPolicy('missing policy or ownership');\n const commands = [\n ...config.policy.commands.deny,\n ...config.policy.commands.ask,\n ...config.policy.commands.allow,\n ...config.policy.dangerousCommands,\n ];\n if (commands.some((rule) => rule.origin !== 'project-config' && rule.origin !== 'project-checks'))\n invalidPolicy('policy command origin is invalid');\n const snapshot = {\n commands: Object.freeze({ default: 'deny' as const, rules: commands.map((rule) => ({ ...rule })) }),\n symlinks: { ...config.policy.symlinks },\n network: { ...DEFAULT_NETWORK_POLICY },\n protectedBranches: [...config.project.protectedBranches],\n ownership: cloneFreeze(structuredClone(ownership)),\n sandboxLevel: options.sandboxLevel,\n } satisfies Omit<PolicySnapshot, 'digest'>;\n return Object.freeze({ ...snapshot, digest: sha256Hex(canonicalJson(snapshot as unknown as JsonValue)) });\n}\n\n/** `cohorte policy explain -- <argv…>`: stages 1-5, offline, nothing executes. */\nexport function explainPolicy(\n engine: PolicyEngine,\n call: GateCall,\n grant: AgentGrant,\n policy: PolicySnapshot,\n ports: PolicyPorts,\n): PolicyVerdict {\n if (!engine || !call || !grant || !policy || !ports)\n invalidPolicy('policy explain requires a complete call, grant, snapshot and ports');\n return engine.evaluate(call, grant, policy, ports);\n}\n","// The ONE glob implementation of DESIGN 2.6.3 step 7, exported as `GlobMatcher` (DESIGN 2.6.1) so that `tools`\n// (list_files, search, git_diff output filtering, WorkspaceReader) and `core` (grants, zones) never configure\n// picomatch themselves.\nimport picomatch from 'picomatch';\nimport type { AgentGrant, GlobMatcher, GlobSet } from '../../contract/index.ts';\n\n/** Locked once, here: deny sets and allow sets alike are matched with the SAME options. */\nconst PICOMATCH_OPTIONS = { dot: true, nocase: false } as const;\n\ntype Predicate = (relativePosixPath: string) => boolean;\n\nconst NEVER: Predicate = () => false;\n\n// A slash-less pattern means \"at any depth\" (gitignore-style): `.env*` becomes a double-star prefixed pattern,\n// so it matches `config/.env` and not only a root-level `.env` (DESIGN 2.6.3 step 7; the spec's own example is\n// unsafe as written without this rule, per the toolchain research). A trailing-double-star directory pattern\n// matching the bare directory name is picomatch's own behaviour with these options and needs no help here\n// (locked by a table test).\nfunction normalizePattern(pattern: string): string {\n return pattern.includes('/') ? pattern : `**/${pattern}`;\n}\n\n// Compiling a pattern list costs ~25 µs; `isDenied` runs once per RESULT LINE of `search` / `list_files` /\n// `git_diff` (I11 output filtering, U2.03), which is thousands of calls over the same two or three sets. Two\n// caches, because both shapes occur: the same long-lived `GlobSet` object (a grant is immutable for the life of\n// a run) and an equal set rebuilt from literals on every call. The key covers BOTH lists, so two sets that\n// share an `include` and differ in `exclude` never share a predicate.\nconst PATTERN_CACHE_LIMIT = 512;\nconst patternCache = new Map<string, Predicate>();\nconst globSetCache = new WeakMap<GlobSet, Predicate>();\n\nfunction cacheKey(patterns: readonly string[]): string {\n return patterns.join('\u0000');\n}\n\nfunction memoize(key: string, compile: () => Predicate): Predicate {\n const cached = patternCache.get(key);\n if (cached !== undefined) return cached;\n const compiled = compile();\n // Pattern lists come from grants and project policy, never from model input, so the cache is bounded in\n // practice; the limit is there so a long-lived host cannot grow one without end.\n if (patternCache.size >= PATTERN_CACHE_LIMIT) patternCache.clear();\n patternCache.set(key, compiled);\n return compiled;\n}\n\n/**\n * Compiled once per pattern list and memoized, so every consumer of this module shares the exact same semantics\n * at the same cost. An empty pattern list matches nothing (picomatch(`[]`) would otherwise match everything).\n */\nexport function compilePatterns(patterns: readonly string[]): Predicate {\n if (patterns.length === 0) return NEVER;\n return memoize(`p\u0001${cacheKey(patterns)}`, () => picomatch(patterns.map(normalizePattern), PICOMATCH_OPTIONS));\n}\n\nfunction compileGlobSet(set: GlobSet): Predicate {\n const cached = globSetCache.get(set);\n if (cached !== undefined) return cached;\n const compiled = memoize(`s\u0001${cacheKey(set.include)}\u0002${cacheKey(set.exclude)}`, () => {\n const included = compilePatterns(set.include);\n if (set.exclude.length === 0) return included;\n const excluded = compilePatterns(set.exclude);\n return (relativePosixPath: string) => included(relativePosixPath) && !excluded(relativePosixPath);\n });\n globSetCache.set(set, compiled);\n return compiled;\n}\n\n/**\n * Neither dialect can express a RE-INCLUDE, so `toExcludeArgs` renders the exclusions alone:\n *\n * - `rg --glob` reads its list in order, later entries overriding earlier matches — but a POSITIVE glob turns\n * ripgrep's override set into a whitelist (the `ignore` crate ignores every file that matches no positive\n * glob), which would silently empty the listing. Unprovable on this machine anyway (PLAN F-1: no `rg`).\n * - git pathspec is NOT order-dependent: `:(exclude,…)` magic is subtractive and applied AFTER the union of\n * every positive pathspec. A rendered `:(glob)<re-include>` therefore cannot bring back what the exclusion\n * removed, and when the caller passes no positive pathspec of its own it narrows the enumeration to the\n * re-include, which the exclusion then empties: `git ls-files`/`git grep` return NOTHING, exit 0 (measured).\n *\n * The consequence is deliberate and fail-closed (I2): for a deny set with a non-empty `exclude` the external\n * enumerator drops MORE than the matcher denies — never less. `matches()` / `isDenied` stay the authority, and\n * a caller that needs the re-included paths in its output must enumerate without the args and post-filter.\n */\nfunction toExcludePatterns(set: GlobSet): string[] {\n return set.include.map(normalizePattern);\n}\n\nexport function createGlobMatcher(): GlobMatcher {\n function deniedBySet(relativePosixPath: string, grant: AgentGrant, intent: 'read' | 'write'): boolean {\n const denySet = intent === 'read' ? grant.denyRead : grant.denyWrite;\n return compileGlobSet(denySet)(relativePosixPath);\n }\n\n return {\n matches(relativePosixPath, set) {\n return compileGlobSet(set)(relativePosixPath);\n },\n /**\n * \"Not permitted for this intent\" — the whole of step 7 in one call, which is why the contract takes an\n * `AgentGrant` and not a `GlobSet`: the deny set wins over the allow set, and a path that no allow pattern\n * matches is denied too (fail closed, I2). That second half is what keeps the I11 ownership boundary in tool\n * OUTPUT filtering (`search`, `list_files`, `git_diff`), where the gate's own allow stage never runs.\n *\n * The empty relative path is the WORKSPACE ROOT itself — what `resolve('.', root, 'list')` returns — and no\n * picomatch pattern matches the empty string, `**` and `**​/*` included. The root is not \"outside the\n * surface\": it IS the surface, so an allow set that has any pattern at all covers it, and only a deny\n * pattern (or a grant that permits nothing for this intent) can forbid it.\n */\n isDenied(relativePosixPath, grant, intent) {\n if (deniedBySet(relativePosixPath, grant, intent)) return true;\n const allowSet = intent === 'read' ? grant.read : grant.write;\n if (relativePosixPath === '') return allowSet.include.length === 0;\n return !compileGlobSet(allowSet)(relativePosixPath);\n },\n toExcludeArgs(set, dialect) {\n const patterns = toExcludePatterns(set);\n return dialect === 'rg-glob'\n ? patterns.map((pattern) => `!${pattern}`)\n : patterns.map((pattern) => `:(exclude,glob)${pattern}`);\n },\n };\n}\n","// The canonical PathResolver (DESIGN 2.6.3 steps 1-7, spec 23): one implementation shared by the gate,\n// `WorkspaceReader`, `WorktreeService` and `tools`. Never throws — every failure mode, expected or not, comes\n// back as a `PathViolation` (I2: fail closed).\nimport { lstatSync, readdirSync, realpathSync } from 'node:fs';\nimport { resolve as resolvePath } from 'node:path';\nimport { err, ok, type Result } from '@cohorte/base';\nimport type {\n CanonicalPath,\n PathIntent,\n PathResolver,\n PathResolverOptions,\n PathViolation,\n ResolvedPath,\n} from '../../contract/index.ts';\nimport { PROTECTED_REPO_GLOBS } from '../../contract/index.ts';\nimport { compilePatterns } from './glob.ts';\n\nconst MAX_INPUT_LENGTH = 4096;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: the whole point is to catch a NUL byte or control character.\nconst CONTROL_OR_NUL = /[\\x00-\\x1f\\x7f]/;\nconst ENV_SYNTAX = /\\$\\{[^}]*\\}|\\$[A-Za-z_][A-Za-z0-9_]*|%[A-Za-z_][A-Za-z0-9_]*%/;\n// The home-directory shorthand is a whole SEGMENT — `~` or `~user` — never a tilde anywhere in a name: refusing\n// every `~` made `notes.txt~`, `a~b.ts` and `~$report.docx` (an Office lock file) unaddressable.\nconst HOME_SHORTHAND_SEGMENT = /^~([A-Za-z0-9_][A-Za-z0-9_-]*)?$/;\nconst WINDOWS_DRIVE = /^[A-Za-z]:[\\\\/]/;\nconst UNC_PREFIX = /^\\\\\\\\/;\nconst WRITE_LIKE = new Set<PathIntent>(['write', 'create']);\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction violation(code: PathViolation['code'], security: boolean, detail: string): Result<never, PathViolation> {\n return err({ code, security, detail });\n}\n\nfunction segmentsOf(absolutePosixPath: string): string[] {\n return absolutePosixPath.split('/').filter((part) => part.length > 0);\n}\n\n/** Containment by path SEGMENTS, never `startsWith`: `apps/api` must not contain `apps/api-gateway`. */\nfunction segmentsContain(longer: readonly string[], shorter: readonly string[]): boolean {\n if (longer.length < shorter.length) return false;\n for (let index = 0; index < shorter.length; index += 1) {\n if (longer[index] !== shorter[index]) return false;\n }\n return true;\n}\n\nfunction findRoot(absolutePosixPath: string, roots: readonly string[]): string | undefined {\n const target = segmentsOf(absolutePosixPath);\n return roots.find((root) => segmentsContain(target, segmentsOf(root)));\n}\n\nfunction isWithinAny(absolutePosixPath: string, candidates: readonly string[]): boolean {\n const target = segmentsOf(absolutePosixPath);\n return candidates.some((candidate) => segmentsContain(target, segmentsOf(candidate)));\n}\n\n/**\n * POSIX-relative form of `absolutePosixPath` to `root`, which always CONTAINS it: the caller picks `root` with\n * `findRoot` on the CANONICAL path. It can therefore never climb with `..` — and it must not, because the deny\n * globs and the protected-repository patterns are matched against this string, and a `..` segment matches no\n * double-star pattern (a relative form with `..` silently disabled both layers).\n */\nfunction relativeTo(root: string, absolutePosixPath: string): string {\n return segmentsOf(absolutePosixPath).slice(segmentsOf(root).length).join('/');\n}\n\ninterface Lstat {\n isSymbolicLink(): boolean;\n isFile(): boolean;\n isFIFO(): boolean;\n isSocket(): boolean;\n isBlockDevice(): boolean;\n isCharacterDevice(): boolean;\n dev: number;\n ino: number;\n nlink: number;\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && 'code' in error;\n}\n\n/** `null` for \"does not exist\" (ENOENT — or ENOTDIR, an ancestor turned out not to be a directory). */\nfunction lstatOrNull(absolutePath: string): Lstat | null {\n try {\n return lstatSync(absolutePath);\n } catch (error) {\n if (isErrnoException(error) && (error.code === 'ENOENT' || error.code === 'ENOTDIR')) return null;\n throw error;\n }\n}\n\nfunction isSpecialFile(stat: Lstat): boolean {\n return stat.isFIFO() || stat.isSocket() || stat.isBlockDevice() || stat.isCharacterDevice();\n}\n\n/**\n * The one point a blind create could alias an existing entry that `realpath` cannot fix for us, because the\n * requested name does not exist yet: a case-insensitive volume already holds a differently-cased sibling.\n */\nfunction caseInsensitiveSiblingExists(dir: string, requestedName: string): boolean {\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return false;\n }\n const lower = requestedName.toLowerCase();\n return entries.some((entry) => entry !== requestedName && entry.toLowerCase() === lower);\n}\n\ninterface WalkOutcome {\n /** on-disk case, absolute POSIX, no trailing slash: the deepest existing position of the walk. */\n canonicalDir: string;\n /** the requested-case segments beyond `canonicalDir` that do not exist yet; empty once fully resolved. */\n tailSegments: string[];\n exists: boolean;\n viaSymlink: boolean;\n}\n\nexport function createPathResolver(options: PathResolverOptions): PathResolver {\n const roots = options.roots.map((root): string => root);\n const protectedRoots = options.protectedRoots.map((root): string => root);\n const protectedRepoPath = compilePatterns(PROTECTED_REPO_GLOBS);\n const { mode: symlinkMode, hardlinksOnWrite } = options.symlinks;\n\n /** DESIGN 2.6.3 steps 3-4: one component at a time, from `root` to the leaf. */\n function walk(root: string, target: string, intent: PathIntent): Result<WalkOutcome, PathViolation> {\n const remaining = segmentsOf(target).slice(segmentsOf(root).length);\n let current = root;\n let viaSymlink = false;\n\n for (let index = 0; index < remaining.length; index += 1) {\n const name = remaining[index];\n if (name === undefined) break; // unreachable: index ranges over remaining.length\n const candidate = `${current}/${name}`;\n const isFinal = index === remaining.length - 1;\n const stat = lstatOrNull(candidate);\n\n if (stat === null) {\n const canonicalDir = realpathSync.native(current);\n if (WRITE_LIKE.has(intent) && caseInsensitiveSiblingExists(canonicalDir, name)) {\n return violation(\n 'case-collision',\n true,\n `${candidate} collides, case-insensitively, with an existing entry of ${canonicalDir}`,\n );\n }\n return ok({ canonicalDir, tailSegments: remaining.slice(index), exists: false, viaSymlink });\n }\n\n if (stat.isSymbolicLink()) {\n if (isFinal && WRITE_LIKE.has(intent)) {\n return violation(\n 'symlink-final-write',\n true,\n `${candidate} is a symlink; a write never follows the final path component`,\n );\n }\n if (symlinkMode === 'deny-all') {\n return violation('symlink-denied', true, `${candidate} is a symlink; policy is deny-all`);\n }\n let linkTarget: string;\n try {\n linkTarget = realpathSync.native(candidate);\n } catch (error) {\n return violation('symlink-escape', true, `${candidate} could not be resolved: ${describeError(error)}`);\n }\n if (symlinkMode === 'deny-outgoing' && findRoot(linkTarget, roots) === undefined) {\n return violation('symlink-escape', true, `${candidate} -> ${linkTarget} leaves every root`);\n }\n current = linkTarget;\n viaSymlink = true;\n continue;\n }\n\n if (isSpecialFile(stat) && !isFinal) {\n return violation('special-file', true, `${candidate} is a FIFO, socket or device: cannot descend into it`);\n }\n current = candidate;\n }\n\n return ok({ canonicalDir: realpathSync.native(current), tailSegments: [], exists: true, viaSymlink });\n }\n\n function resolveOnce(input: string, base: CanonicalPath, intent: PathIntent): Result<ResolvedPath, PathViolation> {\n if (CONTROL_OR_NUL.test(input)) return violation('nul-byte', true, 'control character or NUL byte in path');\n if (Buffer.byteLength(input, 'utf8') > MAX_INPUT_LENGTH) {\n return violation('too-long', true, `path exceeds ${MAX_INPUT_LENGTH} bytes`);\n }\n if (input.split('/').some((segment) => HOME_SHORTHAND_SEGMENT.test(segment))) {\n return violation('outside-roots', true, 'home-directory shorthand (~) is never expanded');\n }\n if (ENV_SYNTAX.test(input))\n return violation('outside-roots', true, 'environment-variable syntax is never expanded');\n if (WINDOWS_DRIVE.test(input) || UNC_PREFIX.test(input)) {\n return violation('outside-roots', true, 'Windows drive/UNC path forms are not supported');\n }\n\n const target = resolvePath(base, input.normalize('NFC'));\n // The LEXICAL root only says where to start the walk; it decides nothing.\n const lexicalRoot = findRoot(target, roots);\n if (lexicalRoot === undefined) return violation('outside-roots', true, `${target} is outside every root`);\n\n const walked = walk(lexicalRoot, target, intent);\n if (!walked.ok) return walked;\n const { canonicalDir, tailSegments, exists, viaSymlink } = walked.value;\n const canonical = tailSegments.length === 0 ? canonicalDir : `${canonicalDir}/${tailSegments.join('/')}`;\n\n // Step 4, AFTER the walk: containment is decided on the canonical path, never on the lexical one. With more\n // than one root — the normal grant shape, a workspace plus read-only roots — a symlink (or a realpath'd\n // ancestor) can land in a root OTHER than the one the input pointed at, and `root` / `relative` must name\n // where the bytes really are: step 5 and every relative deny-glob below match on `relative`.\n const root = findRoot(canonical, roots);\n if (root === undefined) return violation('outside-roots', true, `${canonical} resolves outside every root`);\n\n // Step 5: built-in protected roots — never overridable by config or approval.\n if (isWithinAny(canonical, protectedRoots))\n return violation('protected-root', true, `${canonical} is a protected root`);\n const relative = relativeTo(root, canonical);\n if (protectedRepoPath(relative))\n return violation('protected-root', true, `${relative} is a protected repository path`);\n\n // Step 6: hardlink / special-file, on the resolved target.\n let identity: ResolvedPath['identity'];\n if (exists) {\n const stat = lstatSync(canonical);\n if (isSpecialFile(stat)) return violation('special-file', true, `${canonical} is a FIFO, socket or device`);\n if (WRITE_LIKE.has(intent) && stat.isFile() && stat.nlink > 1 && hardlinksOnWrite === 'deny') {\n return violation('hardlink-multiply-linked', true, `${canonical} has ${stat.nlink} hard links`);\n }\n identity = { dev: stat.dev, ino: stat.ino, nlink: stat.nlink };\n }\n\n return ok({\n canonical: canonical as CanonicalPath,\n relative,\n root: root as CanonicalPath,\n exists,\n viaSymlink,\n ...(identity ? { identity } : {}),\n });\n }\n\n return {\n resolve(input, base, intent) {\n try {\n return resolveOnce(input, base, intent);\n } catch (error) {\n // Fail closed (I2): a symlink loop `realpath` cannot follow, a permission error walking a component,\n // anything unforeseen — never an uncaught throw.\n const detail = `unexpected error resolving ${JSON.stringify(input)}: ${describeError(error)}`;\n return violation('outside-roots', true, detail);\n }\n },\n };\n}\n","// DESIGN 2.7 — the 9 V3.0 tools + the 3 seams, as DATA: name, model-facing description, input schema, effect,\n// terminal, and the path-argument annotations `pathArgsOf` reads. Every input schema is authored UNCLOSED (as every\n// TypeBox schema in this repo is) and closed once, uniformly, by `toStrictSchema` in `./index.ts` — the same\n// generator `@cohorte/protocol` uses for commands and events (DESIGN 0.1 C3), so \"additionalProperties: false\" is\n// never something an author can forget.\nimport type { JsonValue } from '@cohorte/base';\nimport { AgentOutput, ClosedEnum } from '@cohorte/protocol';\n// The ONE closed union of path intents (DESIGN 2.6.3): re-exported, never re-declared, so `toolIntrospection`'s\n// `PathArg[]` IS a `ToolIntrospection` result and no cast bridges two copies of the same union.\nimport type { PathIntent } from '@cohorte/security/contract';\nimport { type Static, type TSchema, Type } from 'typebox';\n\nexport type { PathIntent };\nexport interface PathArg {\n arg: string;\n value: string;\n intent: PathIntent;\n}\n\nconst ReadFileInput = Type.Object({\n path: Type.String(),\n offset: Type.Optional(Type.Integer({ minimum: 0 })),\n limit: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst ListFilesInput = Type.Object({\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n maxEntries: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst SearchInput = Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n caseInsensitive: Type.Optional(Type.Boolean()),\n maxMatches: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst WriteFileInput = Type.Object({ path: Type.String(), content: Type.String() });\nconst PatchFileInput = Type.Object({\n path: Type.String(),\n edits: Type.Array(Type.Object({ oldText: Type.String(), newText: Type.String() }), { minItems: 1 }),\n});\nconst RunCommandInput = Type.Object({\n argv: Type.Array(Type.String(), { minItems: 1 }),\n cwd: Type.Optional(Type.String()),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nexport const GIT_DIFF_BASES = ['run-base', 'integration', 'checkpoint'] as const;\nconst GitDiffInput = Type.Object({\n base: Type.Optional(ClosedEnum(GIT_DIFF_BASES)),\n paths: Type.Optional(Type.Array(Type.String())),\n stat: Type.Optional(Type.Boolean()),\n});\nconst ApprovalRequestInput = Type.Object({\n question: Type.String(),\n options: Type.Optional(Type.Array(Type.String())),\n});\nconst GitCommitInput = Type.Object({ message: Type.String() });\nconst NetworkRequestInput = Type.Object({ url: Type.String(), method: Type.Optional(Type.String()) });\nconst SecretReadInput = Type.Object({ id: Type.String() });\n\nexport type ReadFileInput = Static<typeof ReadFileInput>;\nexport type ListFilesInput = Static<typeof ListFilesInput>;\nexport type SearchInput = Static<typeof SearchInput>;\nexport type WriteFileInput = Static<typeof WriteFileInput>;\nexport type PatchFileInput = Static<typeof PatchFileInput>;\nexport type RunCommandInput = Static<typeof RunCommandInput>;\nexport type GitDiffInput = Static<typeof GitDiffInput>;\nexport type ApprovalRequestInput = Static<typeof ApprovalRequestInput>;\nexport type GitCommitInput = Static<typeof GitCommitInput>;\nexport type NetworkRequestInput = Static<typeof NetworkRequestInput>;\nexport type SecretReadInput = Static<typeof SecretReadInput>;\n\nexport interface CatalogueRow {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: TSchema;\n readonly effect: 'read' | 'write' | 'execute' | 'network' | 'control';\n readonly terminal: boolean;\n readonly pathArgsOf: (input: JsonValue) => PathArg[];\n}\n\nconst noPaths = (): PathArg[] => [];\nconst stringField = (input: JsonValue, key: string): string | undefined => {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return undefined;\n const value = (input as Record<string, JsonValue>)[key];\n return typeof value === 'string' ? value : undefined;\n};\nconst arrayField = (input: JsonValue, key: string): JsonValue[] | undefined => {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return undefined;\n const value = (input as Record<string, JsonValue>)[key];\n return Array.isArray(value) ? value : undefined;\n};\n\n/** DESIGN 2.7, in table order. `submit_result.inputSchema` is `AgentOutput` itself — closed by the same\n * `toStrictSchema` every other row goes through in `./index.ts`, so the two are deep-equal by construction. */\nexport const CATALOGUE_ROWS: readonly CatalogueRow[] = [\n {\n name: 'read_file',\n description:\n 'Read a file as sealed text with line numbers. offset/limit page through it; binary files error; capped at 256 KiB per call.',\n inputSchema: ReadFileInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'read' }];\n },\n },\n {\n name: 'list_files',\n description:\n 'List files under a path (default the workspace root), filtered by glob. Deny sets are filtered out; outgoing symlinks are never followed.',\n inputSchema: ListFilesInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'list' }];\n },\n },\n {\n name: 'search',\n description:\n 'Search file contents for a pattern (a literal argv element, never a shell string). Every hit is filtered against the deny sets and the grant before it is returned.',\n inputSchema: SearchInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'list' }];\n },\n },\n {\n name: 'write_file',\n description: 'Write the complete content of a file, creating it if it does not exist. The whole file is replaced.',\n inputSchema: WriteFileInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'write' }];\n },\n },\n {\n name: 'patch_file',\n description:\n 'Apply exact-match text edits to a file: each oldText must occur exactly once in the current content, or the call fails without writing anything.',\n inputSchema: PatchFileInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'write' }];\n },\n },\n {\n name: 'run_command',\n description: 'Run one allow-listed command (argv only, never a shell line) and return its output.',\n inputSchema: RunCommandInput,\n effect: 'execute',\n terminal: false,\n pathArgsOf: (input) => {\n const cwd = stringField(input, 'cwd');\n return cwd === undefined ? [] : [{ arg: 'cwd', value: cwd, intent: 'exec-cwd' }];\n },\n },\n {\n name: 'git_diff',\n description:\n \"Show a diff of the worktree against 'run-base' (the run's pinned base, the default on a read-only review ref), 'integration' (the default in a slot) or 'checkpoint'.\",\n inputSchema: GitDiffInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const paths = arrayField(input, 'paths');\n if (!paths) return [];\n const out: PathArg[] = [];\n paths.forEach((value, index) => {\n if (typeof value === 'string') out.push({ arg: `paths[${index}]`, value, intent: 'read' });\n });\n return out;\n },\n },\n {\n name: 'approval_request',\n description:\n 'Ask a human a question before proceeding, optionally offering a fixed set of answers. Waits for a decision.',\n inputSchema: ApprovalRequestInput,\n effect: 'control',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'submit_result',\n description:\n 'Submit the final structured result for this task. Call submit_result alone, last: no other tool call may follow it in the same batch.',\n inputSchema: AgentOutput,\n effect: 'control',\n terminal: true,\n pathArgsOf: (input) => {\n const artifacts = arrayField(input, 'artifacts');\n if (!artifacts) return [];\n const out: PathArg[] = [];\n artifacts.forEach((artifact, index) => {\n const path = stringField(artifact, 'path');\n if (path !== undefined) out.push({ arg: `artifacts[${index}].path`, value: path, intent: 'read' });\n });\n return out;\n },\n },\n {\n name: 'git_commit',\n description: 'Reserved: granted to nobody in V3.0. Cohorte alone commits agent work.',\n inputSchema: GitCommitInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'network_request',\n description: 'Reserved: granted to nobody in V3.0. Agents have no network access.',\n inputSchema: NetworkRequestInput,\n effect: 'network',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'secret_read',\n description: 'Reserved: granted to nobody in V3.0.',\n inputSchema: SecretReadInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: noPaths,\n },\n];\n\n/** Tools registered but granted to nobody in V3.0 (DESIGN 2.7): the default policy denies every call, on principle. */\nexport const SEAM_TOOL_NAMES = ['git_commit', 'network_request', 'secret_read'] as const;\n\nexport const TOOL_NAMES = CATALOGUE_ROWS.map((row) => row.name);\n","import type { JsonValue } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type { ToolExecContext, ToolExecuteResult, ToolImplementation, ToolPlan } from '../../catalogue/types.ts';\n\nexport const EXEC_TOOL_NAMES = ['run_command'] as const;\nconst metadata = CATALOGUE_ROWS.find((row) => row.name === 'run_command');\nif (!metadata) throw new Error('missing catalogue row: run_command');\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\n\nconst runCommand: ToolImplementation = {\n ...metadata,\n plan(input, n): ToolPlan {\n return {\n kind: 'tool.run_command',\n replayClass: n.command?.replay ?? 'at-most-once',\n verify: { tool: 'run_command', input, normalized: JSON.parse(JSON.stringify(n)) as JsonValue },\n };\n },\n async execute(input, n, ctx: ToolExecContext, signal): Promise<ToolExecuteResult<JsonValue>> {\n if (signal.aborted) fail('tool-transient/cancelled', 'command was cancelled');\n const command = n.command ?? fail('permission/command-not-allowed', 'run_command has no normalized command');\n const value = input as { argv: string[]; timeoutMs?: number };\n const result = await ctx.executor.run(\n {\n file: command.file,\n args: command.args,\n cwd: command.cwd,\n env: {},\n fs: { readWrite: [ctx.workspaceRoot], readOnly: [], denyRead: [] },\n network: 'none',\n timeoutMs: value.timeoutMs ?? command.timeoutMs,\n maxOutputBytes: 1024 * 1024,\n stdin: 'ignore',\n limits: {},\n require: 'best-effort',\n },\n signal,\n );\n const text = String(result.tail);\n return {\n output: {\n argv: value.argv,\n exitCode: result.exitCode,\n ...(result.signal === undefined ? {} : { signal: result.signal }),\n outcome: result.outcome,\n text,\n outputSha256: result.outputSha256,\n outputBytes: result.outputBytes,\n truncated: result.truncated,\n },\n modelText: text,\n filesTouched: [],\n };\n },\n verifyAfterCrash: async (_record: EffectRecord) => 'in-doubt',\n describeForNote: (record) => `run_command ${record.idempotencyKey}`,\n};\n\nexport const EXEC_TOOLS: Readonly<Record<(typeof EXEC_TOOL_NAMES)[number], ToolImplementation>> = Object.freeze({\n run_command: runCommand,\n});\n","import { createHash } from 'node:crypto';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { JsonValue } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type {\n NormalizedCall,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from '../../catalogue/types.ts';\n\nexport const READ_TOOL_NAMES = ['read_file', 'list_files', 'search', 'git_diff'] as const;\ntype ReadName = (typeof READ_TOOL_NAMES)[number];\nconst row = (name: ReadName) => {\n const entry = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (entry === undefined) throw new Error(`missing catalogue row: ${name}`);\n return entry;\n};\nconst sha256 = (bytes: Uint8Array): string => createHash('sha256').update(bytes).digest('hex');\nconst result = (output: JsonValue, modelText: string): ToolExecuteResult<JsonValue> => ({\n output,\n modelText,\n filesTouched: [],\n});\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\nconst requiredPath = (value: string | undefined, message: string): string =>\n value ?? fail('permission/path-outside-grant', message);\nconst make = (\n name: ReadName,\n execute: (\n input: JsonValue,\n n: NormalizedCall,\n ctx: ToolExecContext,\n signal: AbortSignal,\n ) => Promise<ToolExecuteResult<JsonValue>>,\n): ToolImplementation => {\n const metadata = row(name);\n return {\n ...metadata,\n plan: (input, n): ToolPlan => ({\n kind: 'tool.read',\n replayClass: 'idempotent',\n verify: { tool: name, input, normalized: JSON.parse(JSON.stringify(n)) as JsonValue },\n }),\n execute,\n verifyAfterCrash: async (_record: EffectRecord) => 'done',\n describeForNote: (record) => `${name} ${record.idempotencyKey}`,\n };\n};\n\nconst readFileTool = make('read_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'read was cancelled');\n const target = requiredPath(n.paths[0]?.resolved.canonical, 'read_file has no resolved path');\n const bytes = await readFile(target);\n if (bytes.byteLength > 256 * 1024) fail('tool-terminal/output-too-large', 'file exceeds the 256 KiB read limit');\n if (bytes.includes(0)) fail('tool-terminal/binary-file', 'binary files are not returned as text');\n const value = input as { path: string; offset?: number; limit?: number };\n const offset = value.offset ?? 0;\n const selected = bytes\n .toString('utf8')\n .split(/\\r?\\n/)\n .slice(offset, value.limit === undefined ? undefined : offset + value.limit);\n const text = selected.map((line, index) => `${offset + index + 1}: ${line}`).join('\\n');\n return result(\n { path: n.paths[0]?.resolved.relative ?? value.path, text, sha256: sha256(bytes), offset, lines: selected.length },\n text,\n );\n});\n\nconst walk = async (root: string, current: string, output: string[], max: number): Promise<void> => {\n if (output.length >= max) return;\n for (const entry of await readdir(current, { withFileTypes: true })) {\n if (entry.name === '.git' || entry.name === '.cohorte' || entry.name === '.pi' || entry.isSymbolicLink()) continue;\n const absolute = join(current, entry.name);\n if (entry.isDirectory()) await walk(root, absolute, output, max);\n else output.push(relative(root, absolute).split('\\\\').join('/'));\n if (output.length >= max) return;\n }\n};\nconst globMatch = (value: string, pattern?: string): boolean => {\n if (!pattern || pattern === '**') return true;\n const escaped = pattern\n .replace(/[.*+?^()|[\\]\\\\]/g, '\\\\$&')\n .replaceAll('\\\\*\\\\*', '.*')\n .replaceAll('\\\\*', '[^/]*')\n .replaceAll('\\\\?', '[^/]');\n return new RegExp(`^${escaped}$`).test(value);\n};\n\nconst listFilesTool = make('list_files', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'listing was cancelled');\n const root = requiredPath(n.paths[0]?.resolved.canonical, 'list_files has no resolved root');\n const value = input as { glob?: string; maxEntries?: number };\n const files: string[] = [];\n await walk(root, root, files, value.maxEntries ?? 1000);\n const filtered = files.filter((file) => globMatch(file, value.glob));\n return result({ files: filtered, truncated: files.length >= (value.maxEntries ?? 1000) }, filtered.join('\\n'));\n});\n\nconst searchTool = make('search', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'search was cancelled');\n const root = requiredPath(n.paths[0]?.resolved.canonical, 'search has no resolved root');\n const value = input as { pattern: string; caseInsensitive?: boolean; glob?: string; maxMatches?: number };\n const expression = new RegExp(value.pattern, value.caseInsensitive ? 'i' : '');\n const files: string[] = [];\n await walk(root, root, files, 10_000);\n const matches: { path: string; line: number; text: string }[] = [];\n for (const file of files.filter((candidate) => globMatch(candidate, value.glob))) {\n if (matches.length >= (value.maxMatches ?? 100)) break;\n const text = await readFile(join(root, file), 'utf8').catch(() => undefined);\n if (text === undefined) continue;\n text.split(/\\r?\\n/).forEach((line, index) => {\n if (matches.length < (value.maxMatches ?? 100) && expression.test(line))\n matches.push({ path: file, line: index + 1, text: line });\n });\n }\n return result(\n { matches, filteredPaths: 0 },\n matches.map((match) => `${match.path}:${match.line}:${match.text}`).join('\\n'),\n );\n});\n\nconst gitDiffTool = make('git_diff', async (input, _n, ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'diff was cancelled');\n const value = input as { base?: 'run-base' | 'integration' | 'checkpoint'; stat?: boolean };\n const output = await ctx.git.diffBySurface({\n repo: ctx.workspaceRoot,\n base: value.base ?? 'integration',\n head: 'HEAD',\n surfaces: { surfaceOf: () => 'shared' },\n });\n const text = output.map((item) => new TextDecoder().decode(item.patch.bytes)).join('\\\\n');\n return result(\n {\n base: value.base ?? 'integration',\n stat: value.stat ?? false,\n files: output.flatMap((item) => item.files),\n diff: text,\n },\n text,\n );\n});\n\nexport const READ_TOOLS: Readonly<Record<ReadName, ToolImplementation>> = Object.freeze({\n read_file: readFileTool,\n list_files: listFilesTool,\n search: searchTool,\n git_diff: gitDiffTool,\n});\n","// The Wave-0 seam of every catalogue tool. It lives in its own module — not in `./index.ts` — so that `./index.ts`\n// can assemble `TOOL_CATALOGUE` from `impl/**` (DESIGN 2.7) while `impl/**` keeps importing the stub: the edge runs\n// `index.ts -> impl/** -> stub.ts` in one direction only.\nimport type { JsonValue } from '@cohorte/base';\nimport { NotImplemented } from '@cohorte/base';\nimport { CATALOGUE_ROWS } from './schemas.ts';\nimport type { ToolExecuteResult, ToolImplementation, ToolPlan } from './types.ts';\n\nconst rowByName = new Map(CATALOGUE_ROWS.map((row) => [row.name, row]));\n\n/**\n * Every deliverable of THIS unit (U0.08) ends here: a `ToolImplementation` whose `plan`/`execute`/`verifyAfterCrash`\n * /`describeForNote` throw. The metadata (`name`, `inputSchema`, `description`, `effect`, `terminal`) is real —\n * `impl/read`, `impl/write`, `impl/exec` and `impl/state` (Wave 2: `U2.03`, `U2.04`) call this for every tool they\n * do not yet implement, and REPLACE the body, never the metadata, one tool at a time.\n */\nexport function stubImplementation(name: string): ToolImplementation {\n const row = rowByName.get(name);\n if (!row) throw new RangeError(`stubImplementation: unknown tool ${JSON.stringify(name)}`);\n const notImplemented = (member: string): never => {\n throw new NotImplemented(`tools/${name}.${member} (Wave 2 fills packages/tools/src/impl/**)`);\n };\n return {\n name: row.name,\n inputSchema: row.inputSchema,\n description: row.description,\n effect: row.effect,\n terminal: row.terminal,\n plan(): ToolPlan | null {\n return notImplemented('plan');\n },\n execute(): Promise<ToolExecuteResult<JsonValue>> {\n return notImplemented('execute');\n },\n verifyAfterCrash(): Promise<'done' | 'not-done' | 'in-doubt'> {\n return notImplemented('verifyAfterCrash');\n },\n describeForNote(): string {\n return notImplemented('describeForNote');\n },\n };\n}\n","import type { JsonValue } from '@cohorte/base';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport { stubImplementation } from '../../catalogue/stub.ts';\nimport type { ToolImplementation } from '../../catalogue/types.ts';\n\nexport const STATE_TOOL_NAMES = [\n 'approval_request',\n 'submit_result',\n 'git_commit',\n 'network_request',\n 'secret_read',\n] as const;\n\nconst metadata = (name: (typeof STATE_TOOL_NAMES)[number]) => {\n const row = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (row === undefined) throw new Error(`missing catalogue row: ${name}`);\n return row;\n};\n\nconst approvalRequest: ToolImplementation = {\n ...metadata('approval_request'),\n plan: () => null,\n execute: async (input, _normalized, ctx) => {\n const value = input as { question: string; options?: string[] };\n const decision = await ctx.requestApproval(value.question, value.options);\n return {\n output: decision as unknown as JsonValue,\n modelText: decision.answer ?? decision.decision,\n filesTouched: [],\n };\n },\n verifyAfterCrash: async () => 'done',\n describeForNote: () => 'approval request',\n};\n\nconst submitResult: ToolImplementation = {\n ...metadata('submit_result'),\n plan: () => null,\n execute: async (input, _normalized, ctx) => {\n const accepted = await ctx.acceptResult(input as never);\n if (!accepted.accepted) throw new Error(`validation/agent-output: ${accepted.reason ?? 'result was rejected'}`);\n return { output: { accepted: true }, modelText: 'result submitted', filesTouched: [] };\n },\n verifyAfterCrash: async () => 'done',\n describeForNote: () => 'submit result',\n};\n\nexport const STATE_TOOLS: Readonly<Record<(typeof STATE_TOOL_NAMES)[number], ToolImplementation>> = Object.freeze({\n approval_request: approvalRequest,\n submit_result: submitResult,\n git_commit: stubImplementation('git_commit'),\n network_request: stubImplementation('network_request'),\n secret_read: stubImplementation('secret_read'),\n});\n","import { createHash } from 'node:crypto';\nimport { readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { type JsonValue, type Sha256, sha256Hex } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type {\n NormalizedCall,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from '../../catalogue/types.ts';\n\nexport const WRITE_TOOL_NAMES = ['write_file', 'patch_file'] as const;\ntype WriteName = (typeof WRITE_TOOL_NAMES)[number];\nconst row = (name: WriteName) => {\n const entry = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (entry === undefined) throw new Error(`missing catalogue row: ${name}`);\n return entry;\n};\nconst digest = (value: Uint8Array | string): Sha256 => sha256Hex(createHash('sha256').update(value).digest());\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\nconst requiredPath = (n: NormalizedCall): string =>\n n.paths[0]?.resolved.canonical ?? fail('permission/path-outside-grant', 'write tool has no resolved path');\nconst result = (\n output: JsonValue,\n modelText: string,\n filesTouched: ToolExecuteResult<JsonValue>['filesTouched'],\n): ToolExecuteResult<JsonValue> => ({ output, modelText, filesTouched });\n\nconst make = (\n name: WriteName,\n execute: (\n input: JsonValue,\n n: NormalizedCall,\n ctx: ToolExecContext,\n signal: AbortSignal,\n ) => Promise<ToolExecuteResult<JsonValue>>,\n): ToolImplementation => {\n const metadata = row(name);\n return {\n ...metadata,\n plan: (input, _n): ToolPlan => ({\n kind: name === 'write_file' ? 'tool.write_file' : 'tool.patch_file',\n replayClass: 'verifiable',\n verify: { tool: name, input },\n }),\n execute,\n verifyAfterCrash: async (record: EffectRecord, ctx: ToolExecContext) => {\n const request = record.request as unknown as { path?: string; content?: string };\n if (!request.path) return 'in-doubt';\n try {\n const path = ctx.paths.resolve(request.path, ctx.workspaceRoot, 'read');\n if (!path.ok) return 'in-doubt';\n const bytes = await readFile(path.value.canonical);\n return request.content !== undefined && digest(bytes) === digest(request.content) ? 'done' : 'not-done';\n } catch {\n return 'not-done';\n }\n },\n describeForNote: (record) => `${name} ${record.idempotencyKey}`,\n };\n};\n\nconst atomicWrite = async (target: string, content: string): Promise<void> => {\n const temporary = join(dirname(target), `.cohorte-write-${process.pid}-${Date.now()}`);\n await writeFile(temporary, content, { encoding: 'utf8', flag: 'wx' });\n await rename(temporary, target);\n};\n\nconst writeFileTool = make('write_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'write was cancelled');\n const target = requiredPath(n);\n const value = input as { path: string; content: string };\n let before: Uint8Array | undefined;\n try {\n before = await readFile(target);\n } catch {\n /* create */\n }\n await atomicWrite(target, value.content);\n const after = Buffer.from(value.content);\n const path = n.paths[0]?.resolved.relative ?? value.path;\n return result({ path, bytes: after.byteLength, sha256: digest(after) }, `wrote ${after.byteLength} bytes`, [\n {\n path,\n op: before === undefined ? 'create' : 'modify',\n ...(before === undefined ? {} : { beforeSha256: digest(before) }),\n afterSha256: digest(after),\n bytes: after.byteLength,\n },\n ]);\n});\n\nconst patchFileTool = make('patch_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'patch was cancelled');\n const target = requiredPath(n);\n const value = input as { path: string; edits: { oldText: string; newText: string }[] };\n const before = await readFile(target, 'utf8');\n let next = before;\n for (const edit of value.edits) {\n const count = next.split(edit.oldText).length - 1;\n if (count !== 1) fail('tool-terminal/patch-mismatch', `expected one occurrence, found ${count}`);\n next = next.replace(edit.oldText, edit.newText);\n }\n await atomicWrite(target, next);\n const after = Buffer.from(next);\n const path = n.paths[0]?.resolved.relative ?? value.path;\n return result(\n { path, bytes: after.byteLength, sha256: digest(after), edits: value.edits.length },\n `patched ${path}`,\n [\n {\n path,\n op: 'modify',\n beforeSha256: digest(Buffer.from(before)),\n afterSha256: digest(after),\n bytes: after.byteLength,\n },\n ],\n );\n});\n\nexport const WRITE_TOOLS: Readonly<Record<WriteName, ToolImplementation>> = Object.freeze({\n write_file: writeFileTool,\n patch_file: patchFileTool,\n});\n","// @cohorte/tools/catalogue — DESIGN 2.7, frozen in Wave 0: both the prompts and the fake scripts meet on these\n// shapes. `toToolGrant` is the ONLY place a `ToolGrant` (what the brain sees) is minted from the catalogue's own\n// data, and it is where the flat-schema rule is ASSERTED, not merely hoped for.\n\nimport type { JsonValue } from '@cohorte/base';\nimport { toStrictSchema } from '@cohorte/protocol';\nimport {\n TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS,\n type ToolGrant,\n ToolGrant as ToolGrantSchema,\n toolGrantProblems,\n} from '@cohorte/runtime-contract';\nimport type { ToolIntrospection } from '@cohorte/security/contract';\nimport { Compile } from 'typebox/compile';\nimport { EXEC_TOOLS } from '../impl/exec/index.ts';\nimport { READ_TOOLS } from '../impl/read/index.ts';\nimport { STATE_TOOLS } from '../impl/state/index.ts';\nimport { WRITE_TOOLS } from '../impl/write/index.ts';\nimport { CATALOGUE_ROWS } from './schemas.ts';\nimport type { ToolImplementation } from './types.ts';\n\nexport type {\n ApprovalRequestInput,\n CatalogueRow,\n GitCommitInput,\n GitDiffInput,\n ListFilesInput,\n NetworkRequestInput,\n PatchFileInput,\n PathArg,\n PathIntent,\n ReadFileInput,\n RunCommandInput,\n SearchInput,\n SecretReadInput,\n WriteFileInput,\n} from './schemas.ts';\nexport { CATALOGUE_ROWS, GIT_DIFF_BASES, SEAM_TOOL_NAMES, TOOL_NAMES } from './schemas.ts';\nexport { stubImplementation } from './stub.ts';\nexport type {\n EffectIntent,\n EffectKind,\n EffectRecord,\n NormalizedCall,\n ReplayClass,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from './types.ts';\n\nconst rowByName = new Map(CATALOGUE_ROWS.map((row) => [row.name, row]));\n\n/** `ToolIntrospection` is on the per-tool-call path (PLAN PC-4: the gate validates a call's shape without importing\n * `tools`), so the strict schema of every row is built ONCE, here: `schemaOf` returns the same object identity on\n * every call and a validator cache keyed by schema identity in the gate (U2.01/U2.02) keeps working. */\nconst strictSchemaByName = new Map<string, JsonValue>(\n CATALOGUE_ROWS.map((row) => [row.name, toStrictSchema(row.inputSchema) as JsonValue]),\n);\n\n/** One TypeBox compilation for the whole process, not one per minted grant. */\nconst GRANT_CHECK = Compile(ToolGrantSchema);\n\nconst isFlatObjectSchema = (schema: JsonValue): boolean => {\n if (typeof schema !== 'object' || schema === null || Array.isArray(schema)) return false;\n const record = schema as Record<string, JsonValue>;\n if (record.type !== 'object') return false;\n return TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS.every((key) => !(key in record));\n};\n\n/**\n * Mints the `ToolGrant` (what the brain sees) of one catalogue tool: the closed, strict form of its schema\n * (`toStrictSchema`, the same generator `@cohorte/protocol` uses everywhere else — DESIGN 0.1 C3), asserted to be\n * ONE flat top-level object with no `$ref`/`$defs`/`oneOf`/`anyOf`/`allOf` at the root (DESIGN 2.7).\n */\nexport function toToolGrant(name: string): ToolGrant {\n const row = rowByName.get(name);\n if (!row) throw new RangeError(`toToolGrant: unknown tool ${JSON.stringify(name)}`);\n const inputSchema = strictSchemaByName.get(name);\n if (inputSchema === undefined || !isFlatObjectSchema(inputSchema)) {\n throw new TypeError(`toToolGrant: ${name}'s input schema is not one flat top-level object`);\n }\n const grant: ToolGrant = {\n tool: row.name,\n description: row.description,\n inputSchema,\n effect: row.effect,\n terminal: row.terminal,\n };\n const problems = GRANT_CHECK.Errors(grant);\n const first = problems[0];\n if (first) throw new TypeError(`toToolGrant: ${name} does not validate against ToolGrant: ${first.message}`);\n return grant;\n}\n\nconst namingProblems = toolGrantProblems(CATALOGUE_ROWS.map((row) => ({ tool: row.name })));\nif (namingProblems.length > 0) throw new TypeError(`tool catalogue: ${namingProblems.join('; ')}`);\n\n/** Catalogue-derived: never a second, hand-written copy of what a tool's input schema says (PLAN PC-4: `security`\n * validates a call's shape and path arguments without importing `tools`). */\nexport const toolIntrospection: ToolIntrospection = {\n schemaOf(tool) {\n return strictSchemaByName.get(tool);\n },\n pathArgsOf(tool, input) {\n const row = rowByName.get(tool);\n if (!row) return [];\n return row.pathArgsOf(input);\n },\n};\n\n/** The 9 V3.0 tools + the 3 seams, by name (DESIGN 2.7). Every value is `stubImplementation(name)` until Wave 2\n * replaces the bodies in `impl/**`; the metadata is already the catalogue's own. */\nexport const TOOL_CATALOGUE: Readonly<Record<string, ToolImplementation>> = Object.freeze({\n ...READ_TOOLS,\n ...WRITE_TOOLS,\n ...EXEC_TOOLS,\n ...STATE_TOOLS,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"catalogue-B5uFqfzJ.mjs","names":["resolvePath","metadata","fail","row","result","fail","requiredPath","make","rowByName","ToolGrantSchema"],"sources":["../../../../packages/security/src/decide/commands/profiles.ts","../../../../packages/security/src/decide/commands/resolver.ts","../../../../packages/security/src/decide/commands/index.ts","../../../../packages/security/src/decide/gate/index.ts","../../../../packages/security/src/decide/paths/glob.ts","../../../../packages/security/src/decide/paths/resolve.ts","../../../../packages/tools/src/catalogue/schemas.ts","../../../../packages/tools/src/impl/exec/index.ts","../../../../packages/tools/src/impl/read/index.ts","../../../../packages/tools/src/catalogue/stub.ts","../../../../packages/tools/src/impl/state/index.ts","../../../../packages/tools/src/impl/write/index.ts","../../../../packages/tools/src/catalogue/index.ts"],"sourcesContent":["// ProgramProfiles for git, pnpm, npm, yarn, node, docker (DESIGN 2.6.4, ADR-0024 item 4).\n//\n// A profile parses argv[1..] into { globals, subcommand, flags, positionals } (`ParsedCommand`), or returns a\n// `CommandDenial` when a GLOBAL option would re-target the command onto a directory or repository the agent does not\n// own (`git -C`, `node --require`, ...). Everything else that looks like a flag before the first non-flag token is a\n// benign global (`git --no-pager push` still parses `push` as the subcommand: DESIGN 7.4 EV-08/09).\n//\n// Deviation (recorded, not a defect in a dependency): DESIGN's interface comment for `ProgramProfile.parse` is the\n// fullest listing of the re-targeting option sets (git: -C/-c/--git-dir/--work-tree/--exec-path/--namespace; pnpm:\n// -C/--dir/--prefix; npm: --prefix; node: -e/-p/-r/--require/--import/--loader/--eval); the unit pack's prose\n// summary drops a few of these in its compression. This file follows the fuller DESIGN interface comment, which is\n// normative for behaviour (RULES pack §0). That per-program listing is ILLUSTRATIVE, not closed: the normative\n// sentence is \"Returns a denial for any global option that re-targets the command\", so `yarn --cwd` and\n// `docker -H/--host/--context/--config` are denied too — they are the EV-08/09 mechanism `git -C` is denied for.\n//\n// Deviation: DESIGN's `ParsedCommand` splits the LEADING run of option tokens into `globals`; npm, pnpm, yarn and\n// docker all accept their config options AFTER the subcommand as well (`pnpm install --dir=/elsewhere`), so a\n// re-targeting option is rejected wherever it appears in argv, not only while it leads.\n\nimport type { CommandDenial, ParsedCommand, ProgramProfile } from '../../contract/index.ts';\n\n/** True for a token that starts a run of leading options, e.g. `-C`, `--dir=x`, `-e\"code\"`. */\nconst isFlagToken = (token: string): boolean => token.startsWith('-') && token !== '-';\n\n/** True when `token` invokes `flag`, whether joined by `=` (long options) or directly attached (short options). */\nfunction matchesFlag(token: string, flag: string): boolean {\n if (token === flag) return true;\n if (flag.startsWith('--')) return token.startsWith(`${flag}=`);\n return flag.length === 2 && token.length > flag.length && token.startsWith(flag);\n}\n\nexport interface ProfileSpec {\n program: string;\n aliases: readonly string[];\n /** global options that re-target the command; matched against every leading flag token (DESIGN 2.6.4 step 1-4). */\n retargeting: readonly string[];\n}\n\n/**\n * One shared structural parser for every built-in profile: walk leading flag tokens (denying a re-targeting one on\n * sight), the first non-flag token is the subcommand, everything after it splits into `flags` / `positionals` by\n * whether it starts with `-`. This is a STRUCTURAL split, not a full CLI grammar: it does not know which flags of\n * `git commit -m <msg>` consume a value, because the callers that need that (CommandRule matching) work in terms of\n * flag NAMES and positional VALUES declared by policy data, never by re-deriving one CLI's full option grammar here.\n */\nfunction createProfile(spec: ProfileSpec): ProgramProfile {\n return {\n program: spec.program,\n aliases: spec.aliases,\n parse(args: readonly string[]): ParsedCommand | CommandDenial {\n const retargeted = (token: string): CommandDenial | undefined => {\n const denied = spec.retargeting.find((flag) => matchesFlag(token, flag));\n if (denied === undefined) return undefined;\n return {\n kind: 'denied',\n code: 'security/command-global-option',\n token,\n reason: `${spec.program}: \\`${denied}\\` re-targets the command onto a different directory or repository`,\n };\n };\n\n const globals: string[] = [];\n let index = 0;\n while (index < args.length) {\n const token = args[index];\n if (token === undefined || !isFlagToken(token)) break;\n const denial = retargeted(token);\n if (denial !== undefined) return denial;\n globals.push(token);\n index += 1;\n }\n const subcommandToken = args[index];\n const subcommand = subcommandToken === undefined ? [] : [subcommandToken];\n const rest = subcommandToken === undefined ? [] : args.slice(index + 1);\n const flags: string[] = [];\n const positionals: string[] = [];\n for (const token of rest) (isFlagToken(token) ? flags : positionals).push(token);\n // A re-targeting option placed after the subcommand re-targets just as well: `pnpm install --dir=/elsewhere`.\n for (const token of flags) {\n const denial = retargeted(token);\n if (denial !== undefined) return denial;\n }\n return { kind: 'parsed', globals, subcommand, flags, positionals };\n },\n };\n}\n\n// The sets include the exact functional SYNONYMS of the options DESIGN 2.6.4 names — `--config-env` is `-c` read\n// from the environment, `--experimental-loader` is Node's own documented alias of `--loader` — and the remaining\n// value-taking git globals (`--super-prefix`, `--attr-source`), which would otherwise parse as benign globals and\n// shift the subcommand out from under the D9 check. DESIGN's per-program listing is illustrative, not closed\n// (request R3); the normative sentence is \"a denial for ANY global option that re-targets the command\".\nconst GIT_RETARGETING = [\n '-C',\n '-c',\n '--config-env',\n '--git-dir',\n '--work-tree',\n '--exec-path',\n '--namespace',\n '--super-prefix',\n '--attr-source',\n];\nconst PNPM_RETARGETING = ['-C', '--dir', '--prefix'];\nconst NPM_RETARGETING = ['--prefix'];\nconst NODE_RETARGETING = [\n '-e',\n '-p',\n '-r',\n '--require',\n '--import',\n '--loader',\n '--experimental-loader',\n '--eval',\n '--env-file',\n '--env-file-if-exists',\n];\n/** `yarn --cwd <dir>` runs the whole command in another directory: `git -C` under another name. */\nconst YARN_RETARGETING = ['--cwd'];\n/** `docker -H`/`--host`/`--context` re-target the DAEMON (a remote one included); `--config` the credential store. */\nconst DOCKER_RETARGETING = ['-H', '--host', '--context', '--config'];\n\nexport const GIT_PROFILE: ProgramProfile = createProfile({ program: 'git', aliases: [], retargeting: GIT_RETARGETING });\nexport const PNPM_PROFILE: ProgramProfile = createProfile({\n program: 'pnpm',\n aliases: [],\n retargeting: PNPM_RETARGETING,\n});\nexport const NPM_PROFILE: ProgramProfile = createProfile({ program: 'npm', aliases: [], retargeting: NPM_RETARGETING });\nexport const YARN_PROFILE: ProgramProfile = createProfile({\n program: 'yarn',\n aliases: [],\n retargeting: YARN_RETARGETING,\n});\nexport const NODE_PROFILE: ProgramProfile = createProfile({\n program: 'node',\n aliases: [],\n retargeting: NODE_RETARGETING,\n});\n/** `docker-compose up` normalises to `docker compose up`: EV-10. */\nexport const DOCKER_PROFILE: ProgramProfile = createProfile({\n program: 'docker',\n aliases: ['docker-compose'],\n retargeting: DOCKER_RETARGETING,\n});\n\nexport const BUILTIN_PROFILES: readonly ProgramProfile[] = Object.freeze([\n GIT_PROFILE,\n PNPM_PROFILE,\n NPM_PROFILE,\n YARN_PROFILE,\n NODE_PROFILE,\n DOCKER_PROFILE,\n]);\n\n/**\n * Subcommand tokens an alias implies, prepended to argv[1..] before the matched profile parses it: `docker-compose`\n * behaves as `docker compose`. No other built-in alias carries an implied subcommand.\n */\nconst ALIAS_SUBCOMMAND_PREFIX: Readonly<Record<string, readonly string[]>> = Object.freeze({\n 'docker-compose': Object.freeze(['compose']),\n});\n\nexport interface ProfileMatch {\n profile: ProgramProfile;\n /** subcommand tokens the alias implies, to prepend to argv[1..] before calling `profile.parse`. */\n prefix: readonly string[];\n}\n\n/** `bareName` is argv[0] as typed (already checked to be a bare name with no path separator). */\nexport function findProfile(bareName: string, profiles: readonly ProgramProfile[]): ProfileMatch | undefined {\n for (const profile of profiles) {\n if (profile.program === bareName) return { profile, prefix: [] };\n if (profile.aliases.includes(bareName)) return { profile, prefix: ALIAS_SUBCOMMAND_PREFIX[bareName] ?? [] };\n }\n return undefined;\n}\n\n/** The CANONICAL program name of `bareName` for trampoline / rule-matching purposes: `docker-compose` -> `docker`. */\nexport function canonicalProgramName(bareName: string, profiles: readonly ProgramProfile[]): string {\n return findProfile(bareName, profiles)?.profile.program ?? bareName;\n}\n","// ProgramResolver: `argv[0]` through the PATH pinned at run start, then realpath (DESIGN 2.6.4). A repo-local shim,\n// a `./node`, or a program planted in a directory outside the pinned list can never stand in for the real program:\n// this resolver only ever looks inside the directories it was given, in order, and returns the on-disk realpath of\n// whatever it finds there — never the raw candidate path (EV-07).\nimport { accessSync, constants, realpathSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { CanonicalPath, ProgramResolver } from '../../contract/index.ts';\n\nexport interface ProgramResolverFs {\n accessSync(path: string, mode?: number): void;\n realpathSync(path: string): string;\n}\n\nconst NODE_FS: ProgramResolverFs = { accessSync, realpathSync };\n\nexport interface ProgramResolverOptions {\n /** the PATH pinned at run start, as directories, in search order. Never Pi's or Cohorte's own bin directory. */\n pathDirs: readonly string[];\n /** injected for tests; defaults to `node:fs`. */\n fs?: ProgramResolverFs;\n}\n\n/**\n * `bareName` SHOULD already be a bare name (no path separator): that is checked one layer up, as the very first\n * thing `evaluate()` does (DESIGN 2.6.4 step 1). This resolver enforces it too, defensively: `node:path.join`\n * normalises a segment like `./node` or `../x` away, so without this guard a relative-looking name would silently\n * resolve through directory-list normalisation rather than being rejected outright, for any OTHER caller of this\n * port that does not repeat the step-1 check.\n */\nexport function createProgramResolver(options: ProgramResolverOptions): ProgramResolver {\n const dirs = [...options.pathDirs];\n const fs = options.fs ?? NODE_FS;\n const cache = new Map<string, CanonicalPath | undefined>();\n return {\n resolve(bareName: string): CanonicalPath | undefined {\n if (bareName === '' || bareName.includes('/') || bareName.includes('\\\\')) return undefined;\n const cached = cache.get(bareName);\n if (cached !== undefined || cache.has(bareName)) return cached;\n let found: CanonicalPath | undefined;\n for (const dir of dirs) {\n const candidate = join(dir, bareName);\n try {\n fs.accessSync(candidate, constants.X_OK);\n found = fs.realpathSync(candidate) as CanonicalPath;\n break;\n } catch {\n // not in this directory, or not executable: keep searching the pinned PATH\n }\n }\n cache.set(bareName, found);\n return found;\n },\n };\n}\n","// Command policy evaluation (DESIGN 2.6.4, ADR-0024, ADR-0007): a parsed-argv allowlist, never a shell-string\n// matcher. `createCommandPolicy` implements the six evaluation steps verbatim:\n//\n// 1. `argv[0]` is a bare name, resolved to an absolute realpath through the PATH pinned at run start.\n// 2. Trampolines (`sh`, `python*`, `pi`, `cohorte`, ...) are denied, `overridable: false`. The single escape hatch\n// is an exact-argv rule under `policy.dangerousCommands`, and ADR-0024 item 3 is categorical about it: a\n// trampoline \"cannot be allowlisted\" and \"every use is `ask`\". A `CommandRule` carries no marker telling a\n// `dangerousCommands` rule from a `policy.commands.allow` one (both are `origin: 'project-config'`), so this\n// evaluator RE-ASSERTS the coercion itself: a matching rule that says `deny` denies, anything else asks.\n// 3. Agents have a built-in, non-overridable deny on `git commit|push|merge|...` (D9 / ADR-0007), independent of\n// any rule.\n// 4. A program WITH a `ProgramProfile` is parsed structurally and matched by `(program, subcommand, flags,\n// positionals)`; a program without one can only be matched by an `exact`-argv rule (used by both\n// `dangerousCommands` and `config.checks`, via `checksToCommandRules`).\n// 5. No rule matches => deny; among several matches, deny beats ask beats allow.\n// 6. `cwd` must canonicalise inside the agent's own worktree; a rule's `when.branch: 'unprotected-only'` treats a\n// detached/unknown branch as protected (never matches).\n//\n// Deviation (recorded, does not affect any test in this unit's own scope): this evaluator checks `cwd` containment\n// EARLY, as a precondition, rather than as literally the last of the six steps — nothing downstream can matter once\n// `cwd` has escaped the agent's own worktree, and evaluating it early means `when.branch` matching always has a\n// resolved branch to work with. The set of calls this denies is identical either way.\n//\n// Deviation: DESIGN's parenthetical for EV-01 says the node profile \"canonicalises the script positional to a\n// worktree-relative realpath\". `CommandPolicyOptions` carries no `PathResolver` (only `programs` and `branches`),\n// so this unit does not perform that canonicalisation itself: a positional that does not literally match a rule is\n// denied by the plain \"no rule matches\" default (§5), which is the same security outcome. Full realpath\n// canonicalisation of `run_command` POSITIONAL arguments, if ever wanted, needs a `PathResolver` threaded into\n// this contract — filed as an FYI in docs/v3/requests/U1.03.md, not a blocker.\nimport type { CohorteConfig, CommandRule } from '@cohorte/config/schema';\nimport { type TSchema, Type } from 'typebox';\nimport type {\n BranchResolver,\n CanonicalPath,\n CommandPolicy,\n CommandRequest,\n NormalizedCall,\n ParsedCommand,\n ProgramProfile,\n ProgramResolver,\n} from '../../contract/index.ts';\nimport { AGENT_GIT_DENIED_SUBCOMMANDS, isTrampoline } from '../../contract/index.ts';\nimport { BUILTIN_PROFILES, canonicalProgramName, findProfile } from './profiles.ts';\n\nexport { createProgramResolver, type ProgramResolverFs, type ProgramResolverOptions } from './resolver.ts';\nexport { BUILTIN_PROFILES, canonicalProgramName, findProfile };\n\nexport interface CommandContext {\n /** the agent's own worktree: `cwd` must canonicalise inside it */\n worktree: CanonicalPath;\n /** `CommandRequest.cwd`, already resolved by stage 3 */\n cwd: CanonicalPath;\n role: string;\n phase: string;\n /** under L0 a rule flagged `network` is denied */\n sandboxLevel: 'L0-process' | 'L1-os';\n defaultTimeoutMs: number;\n}\n\n/** Stage 4 for `run_command`: deny over ask over allow; no rule => deny. */\nexport interface CommandEvaluation {\n decision: 'allow' | 'ask' | 'deny';\n ruleId: string;\n /** the error code of a deny, e.g. 'security/command-trampoline' */\n code?: string;\n reason: string;\n overridable: boolean;\n securityViolation: boolean;\n evaluatedRules: string[];\n /** present unless denied: what will actually execute */\n command?: NonNullable<NormalizedCall['command']>;\n}\n\nexport interface CommandPolicyEvaluator {\n evaluate(request: CommandRequest, policy: CommandPolicy, context: CommandContext): CommandEvaluation;\n}\n\nexport interface CommandPolicyOptions {\n programs: ProgramResolver;\n branches: BranchResolver;\n /** default: the built-in profiles (git, pnpm, npm, yarn, node, docker) */\n profiles?: readonly ProgramProfile[];\n}\n\ntype BranchInfo = ReturnType<BranchResolver['branchOf']>;\n\n// ── structural helpers ────────────────────────────────────────────────────────────────────────\n\nconst tokensEqual = (a: readonly string[], b: readonly string[]): boolean =>\n a.length === b.length && a.every((value, index) => value === b[index]);\n\n/** `path` inside `root`, by path SEGMENTS (never `startsWith` alone: `/w/api` must not contain `/w/api-gateway`). */\nconst isContainedIn = (path: string, root: string): boolean => path === root || path.startsWith(`${root}/`);\n\n/**\n * \"Anything not allowed is denied\" (DESIGN 2.6.4) is a rule about what may be PERMITTED, so the allowlist only ever\n * narrows an `allow` rule — where narrowing fails closed. Applied to a `deny` or an `ask` rule it narrows in the\n * other direction: the restrictive rule stops matching as soon as a flag it did not declare is present, while a\n * broader `allow` rule that DOES list that flag keeps matching, and `deny > ask > allow` (step 5) is defeated by one\n * token (`pnpm --silent run build`). A restrictive rule therefore matches on program + subcommand + positionals\n * alone. Recorded in docs/v3/requests/U1.03.md R4 item 3.\n */\nfunction flagsMatch(flags: readonly string[], rule: CommandRule): boolean {\n if (flags.length === 0 || rule.decision !== 'allow') return true;\n const spec = rule.flags;\n if (spec === undefined) return false; // \"anything not allowed is denied\": no allowlist => no flag may be present\n return flags.every((flag) => !spec.deny?.includes(flag) && spec.allow.includes(flag));\n}\n\n/** Structural, not filesystem-aware: real containment/symlink checks of path-typed arguments are stage 3's job. */\nconst looksLikeWorktreeRelativePath = (value: string): boolean =>\n !value.startsWith('-') && !value.startsWith('/') && !value.startsWith('~') && !value.split(/[/\\\\]/).includes('..');\n\nfunction positionalsMatch(positionals: readonly string[], spec: CommandRule['positionals']): boolean {\n if (spec === undefined) return positionals.length === 0;\n switch (spec.kind) {\n case 'none':\n return positionals.length === 0;\n case 'exact':\n return tokensEqual(positionals, spec.values);\n // Both value-bearing kinds have a LOWER bound too: `every()` over an empty array is vacuously true, so without\n // it a rule written for `pnpm run test` also matched the bare `pnpm run`, and one for `git add <paths>` the\n // argument-less `git add` — every such rule silently wider than its author wrote it.\n case 'enum':\n return (\n positionals.length > 0 &&\n positionals.length <= spec.max &&\n positionals.every((value) => spec.values.includes(value))\n );\n case 'paths-in-worktree':\n return (\n positionals.length > 0 && positionals.length <= spec.max && positionals.every(looksLikeWorktreeRelativePath)\n );\n }\n}\n\n/** A rule with no `subcommand`, no `flags` and `positionals.kind: 'exact'` matches the WHOLE rest of argv, whether\n * or not the program has a profile: this is how `dangerousCommands` and `checksToCommandRules` rules match. */\nfunction matchesExactArgv(rule: CommandRule, rest: readonly string[]): boolean {\n if (rule.subcommand !== undefined || rule.flags !== undefined) return false;\n const positionals = rule.positionals;\n return positionals !== undefined && positionals.kind === 'exact' && tokensEqual(rest, positionals.values);\n}\n\n/**\n * Only reachable for a profiled program: `(subcommand, flags, positionals)`, per DESIGN 2.6.4 step 4.\n *\n * The profile's structural split is deliberately shallow — the FIRST non-flag token is `subcommand`, every later\n * non-flag token is a positional — so a rule's `subcommand` is matched as a PREFIX of the whole non-flag token\n * stream. That is what makes DESIGN 2.6.4's own example (`subcommand: ['run','test']`) and `['compose','up']`\n * reachable, and it keeps `docker-compose up` ≡ `docker compose up`. The tokens the prefix consumes are removed\n * before the positional check; an absent or empty `subcommand` is \"no subcommand constraint\", not \"never matches\".\n *\n * Deviation (recorded): a rule's `flags` allowlist is matched against `globals` TOO, not only against the flags\n * that follow the subcommand. DESIGN 2.6.4 says of `flags` \"anything not allowed is denied\"; leaving the leading\n * globals unchecked would let `pnpm --silent run test` satisfy a rule written for `pnpm run test`, which fails\n * OPEN. Benign globals are still parsed as globals (EV-08/09: `git --no-pager push` still has subcommand `push`);\n * a policy that wants to permit one lists it in `flags.allow`.\n */\nfunction matchesStructurally(rule: CommandRule, parsed: ParsedCommand): boolean {\n const tokens = [...parsed.subcommand, ...parsed.positionals];\n const required = rule.subcommand ?? [];\n if (required.length > tokens.length) return false;\n if (!required.every((token, index) => token === tokens[index])) return false;\n return (\n flagsMatch([...parsed.globals, ...parsed.flags], rule) &&\n positionalsMatch(tokens.slice(required.length), rule.positionals)\n );\n}\n\n/**\n * The D9 subcommand of a `git` call, if it is one of the denied ones (ADR-0007 item 2).\n *\n * With a structural parse in hand the subcommand is exact, and the profile has already denied every value-taking\n * re-targeting global. Without one — a caller passed `profiles` without git — nothing can tell a subcommand from a\n * global option's VALUE (`git --super-prefix x commit`), so every token is held against the set: conservative in\n * the only safe direction for an invariant that must not be switchable off.\n */\nfunction deniedGitSubcommand(parsed: ParsedCommand | undefined, rest: readonly string[]): string | undefined {\n const denied = AGENT_GIT_DENIED_SUBCOMMANDS as readonly string[];\n if (parsed === undefined) return rest.find((token) => denied.includes(token));\n const subcommand = parsed.subcommand[0];\n return subcommand !== undefined && denied.includes(subcommand) ? subcommand : undefined;\n}\n\nfunction branchAllows(rule: CommandRule, branch: BranchInfo): boolean {\n const required = rule.when?.branch ?? 'any';\n return required === 'any' || (branch.kind === 'branch' && !branch.protected);\n}\n\nfunction whenMatches(rule: CommandRule, context: CommandContext, branch: BranchInfo): boolean {\n if (!branchAllows(rule, branch)) return false;\n if (rule.when?.roles && !rule.when.roles.includes(context.role)) return false;\n if (rule.when?.phases && !rule.when.phases.includes(context.phase)) return false;\n return true;\n}\n\nconst DECISION_RANK: Record<CommandRule['decision'], number> = { deny: 0, ask: 1, allow: 2 };\n\n/** deny beats ask beats allow (DESIGN 2.6.4 step 5, 2.6.2 precedence). `matches` must be non-empty. */\nfunction pickWinner(matches: readonly CommandRule[]): CommandRule {\n return matches.reduce((best, rule) => (DECISION_RANK[rule.decision] < DECISION_RANK[best.decision] ? rule : best));\n}\n\n/** Every rule of `program`, structurally or exactly matching, whose `when` is satisfied. Records every rule id it\n * looked at in `evaluatedRules`, matched or not (`PolicyVerdict.evaluatedRules`, \"for `cohorte policy explain`\"). */\nfunction matchRules(\n rules: readonly CommandRule[],\n program: string,\n rest: readonly string[],\n parsed: ParsedCommand | undefined,\n context: CommandContext,\n branch: BranchInfo,\n evaluatedRules: string[],\n): CommandRule[] {\n const matches: CommandRule[] = [];\n for (const rule of rules) {\n if (rule.program !== program) continue;\n evaluatedRules.push(rule.id);\n const structurallyOk = parsed !== undefined && matchesStructurally(rule, parsed);\n const exactlyOk = matchesExactArgv(rule, rest);\n if ((structurallyOk || exactlyOk) && whenMatches(rule, context, branch)) matches.push(rule);\n }\n return matches;\n}\n\n// ── building the result ───────────────────────────────────────────────────────────────────────\n\ninterface DenyArgs {\n ruleId: string;\n code?: string;\n reason: string;\n overridable: boolean;\n securityViolation: boolean;\n evaluatedRules: string[];\n}\n\nfunction denyEval(args: DenyArgs): CommandEvaluation {\n const { ruleId, code, reason, overridable, securityViolation, evaluatedRules } = args;\n return {\n decision: 'deny',\n ruleId,\n reason,\n overridable,\n securityViolation,\n evaluatedRules,\n ...(code === undefined ? {} : { code }),\n };\n}\n\nfunction applyRule(\n rule: CommandRule,\n args: {\n resolvedFile: CanonicalPath;\n rest: readonly string[];\n context: CommandContext;\n timeoutMs: number | undefined;\n evaluatedRules: string[];\n },\n): CommandEvaluation {\n const { resolvedFile, rest, context, timeoutMs, evaluatedRules } = args;\n // An explicit deny is reported as its own verdict, BEFORE the network guard: a `deny` rule that also carries\n // `network: true` is denied by policy, and saying `permission/network-denied` would misattribute it in the audit\n // event and in `cohorte policy explain`. Only an `allow`/`ask` rule can become a network denial.\n const overridable = rule.origin !== 'builtin';\n if (rule.decision === 'deny') {\n return denyEval({\n ruleId: rule.id,\n code: 'permission/command-not-allowed',\n reason: `denied by rule ${rule.id}`,\n overridable,\n securityViolation: false,\n evaluatedRules,\n });\n }\n // \"network: true => denied under L0 (nothing enforces the deny); under L1 it fails closed in the sandbox.\"\n if (rule.network && context.sandboxLevel === 'L0-process') {\n return denyEval({\n ruleId: rule.id,\n code: 'permission/network-denied',\n reason: `rule ${rule.id} needs network access, which the L0 process sandbox cannot enforce a deny for`,\n overridable: false,\n securityViolation: false,\n evaluatedRules,\n });\n }\n const command: NonNullable<NormalizedCall['command']> = {\n file: resolvedFile,\n args: [...rest],\n cwd: context.cwd,\n ruleId: rule.id,\n replay: rule.replay,\n network: rule.network,\n timeoutMs: timeoutMs ?? context.defaultTimeoutMs,\n };\n return {\n decision: rule.decision === 'ask' ? 'ask' : 'allow',\n ruleId: rule.id,\n reason: rule.decision === 'ask' ? `rule ${rule.id} requires confirmation` : `allowed by rule ${rule.id}`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n command,\n };\n}\n\n// ── the evaluator ─────────────────────────────────────────────────────────────────────────────\n\nexport function createCommandPolicy(options: CommandPolicyOptions): CommandPolicyEvaluator {\n const profiles = options.profiles ?? BUILTIN_PROFILES;\n return {\n evaluate(request: CommandRequest, policy: CommandPolicy, context: CommandContext): CommandEvaluation {\n const evaluatedRules: string[] = [];\n const argv = request.argv;\n const bareName = argv[0];\n\n if (bareName === undefined || bareName === '') {\n return denyEval({\n ruleId: 'builtin/argv-empty',\n code: 'permission/command-not-allowed',\n reason: 'argv is empty: there is no program to run',\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n if (bareName.includes('/') || bareName.includes('\\\\')) {\n return denyEval({\n ruleId: 'builtin/bare-name',\n code: 'permission/command-not-allowed',\n reason: `argv[0] \"${bareName}\" is not a bare program name (DESIGN 2.6.4 step 1)`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n evaluatedRules.push('builtin/resolve');\n const resolvedFile = options.programs.resolve(bareName);\n if (resolvedFile === undefined) {\n return denyEval({\n ruleId: 'builtin/resolve',\n code: 'permission/command-not-allowed',\n reason: `\"${bareName}\" does not resolve to a program on the PATH pinned at run start`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n });\n }\n\n evaluatedRules.push('builtin/cwd-containment');\n if (!isContainedIn(context.cwd, context.worktree)) {\n return denyEval({\n ruleId: 'builtin/cwd-containment',\n code: 'permission/command-not-allowed',\n reason: `cwd \"${context.cwd}\" is outside the agent's own worktree \"${context.worktree}\"`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n const branch = options.branches.branchOf(context.cwd);\n const match = findProfile(bareName, profiles);\n const canonicalName = match?.profile.program ?? bareName;\n const rest = argv.slice(1);\n\n // Step 2: trampolines. A trampoline is NEVER allowlisted (ADR-0024 item 3): the only escape hatch is an\n // exact-argv `dangerousCommands` rule, and \"every use is `ask`\". Since a `CommandRule` carries no marker\n // distinguishing such a rule from an ordinary `policy.commands` allow (both are `origin: 'project-config'`,\n // and `checksToCommandRules` mints rules from `.cohorte/config.yaml` too), the coercion the `PolicySnapshot`\n // contract promises is re-asserted here rather than trusted to the rule list: deny stays deny, everything\n // else becomes `ask`.\n evaluatedRules.push('builtin/trampolines');\n if (isTrampoline(bareName) || isTrampoline(canonicalName)) {\n const matches = matchRules(policy.rules, canonicalName, rest, undefined, context, branch, evaluatedRules);\n const winner = matches.length > 0 ? pickWinner(matches) : undefined;\n if (winner !== undefined) {\n const coerced: CommandRule = winner.decision === 'deny' ? winner : { ...winner, decision: 'ask' };\n const evaluation = applyRule(coerced, {\n resolvedFile,\n rest,\n context,\n timeoutMs: request.timeoutMs,\n evaluatedRules,\n });\n if (evaluation.decision !== 'ask') return evaluation;\n return {\n ...evaluation,\n reason: `\"${bareName}\" launches another program on behalf of the agent: rule ${winner.id} matches, but every use of a trampoline is \\`ask\\` (ADR-0024)`,\n };\n }\n return denyEval({\n ruleId: 'builtin/trampolines',\n code: 'security/command-trampoline',\n reason: `\"${bareName}\" would launch another program on behalf of the agent`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n\n // Step 4: structural parse for a profiled program (denies a re-targeting global option on sight).\n let parsed: ParsedCommand | undefined;\n if (match !== undefined) {\n evaluatedRules.push('builtin/profile-parse');\n const outcome = match.profile.parse([...match.prefix, ...rest]);\n if (outcome.kind === 'denied') {\n return denyEval({\n ruleId: 'builtin/global-option',\n code: outcome.code,\n reason: outcome.reason,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n parsed = outcome;\n }\n\n // Step 3: agents have no commit capability (D9 / ADR-0007 item 2), unconditionally — including when the\n // caller's `profiles` list carries no git profile at all. `profiles` is a public option of this API, so\n // nesting this inside \"a git profile was found\" would let a caller switch a NON-OVERRIDABLE invariant off.\n if (canonicalName === 'git') {\n const subcommand = deniedGitSubcommand(parsed, rest);\n if (subcommand !== undefined) {\n evaluatedRules.push('builtin/agent-git-deny');\n return denyEval({\n ruleId: 'builtin/agent-git-deny',\n code: 'permission/command-not-allowed',\n reason: `agents may not run \\`git ${subcommand}\\`: Cohorte creates every commit (ADR-0007)`,\n overridable: false,\n securityViolation: true,\n evaluatedRules,\n });\n }\n }\n\n // Steps 4-5: structural (profiled) or exact-argv (unprofiled, or a profiled program's exact rule) matching.\n const matches = matchRules(policy.rules, canonicalName, rest, parsed, context, branch, evaluatedRules);\n if (matches.length === 0) {\n return denyEval({\n ruleId: 'builtin/no-rule',\n code: 'permission/command-not-allowed',\n reason: `no command rule matches \"${[bareName, ...rest].join(' ')}\"; the default is deny`,\n overridable: true,\n securityViolation: false,\n evaluatedRules,\n });\n }\n return applyRule(pickWinner(matches), {\n resolvedFile,\n rest,\n context,\n timeoutMs: request.timeoutMs,\n evaluatedRules,\n });\n },\n };\n}\n\n// ── `config.checks` -> CommandRule (DESIGN 2.6.4: \"package.json scripts are reachable only as `pnpm run <name>`\n// with `<name>` in an `enum`\"; a check's own argv array becomes one `exact` rule instead) ──────────────────────\n\n/** `config.checks.{typecheck,lint,test}` (argv arrays) become `exact`, `idempotent`, allowed rules: they are the\n * project's own, human-authored commands (`.cohorte/config.yaml` `checks:`), not something an approval gates.\n *\n * The one exception is a check whose `argv[0]` is a TRAMPOLINE (`checks.test: ['npx', 'vitest']`,\n * `['sh', '-c', …]`): `.cohorte/config.yaml` is project-controlled, so minting `decision: 'allow'` from it would\n * re-open the shell that ADR-0024 item 3 closes. Such a check becomes an `ask` rule — the same verdict the\n * evaluator's trampoline step would coerce it to, said honestly in the rule DATA so `cohorte policy explain`\n * shows it. */\nexport function checksToCommandRules(checks: CohorteConfig['checks']): CommandRule[] {\n const named: readonly (readonly [string, readonly string[] | undefined])[] = [\n ['typecheck', checks.typecheck],\n ['lint', checks.lint],\n ['test', checks.test],\n ];\n const rules: CommandRule[] = [];\n for (const [name, argv] of named) {\n if (argv === undefined || argv.length === 0) continue;\n const declared = argv[0];\n if (declared === undefined) continue;\n // `evaluate()` matches rules against the ALIAS-NORMALISED program name (EV-10), so a check declared with an\n // alias (`checks.test: ['docker-compose', 'up']`) must mint the canonical one or the rule is dead on arrival\n // and the project's own check command is denied. `exact` positionals stay `argv.slice(1)`: that is what is\n // compared against the literal `argv[1..]` of the request.\n const program = canonicalProgramName(declared, BUILTIN_PROFILES);\n rules.push({\n id: `checks/${name}`,\n program,\n positionals: { kind: 'exact', values: argv.slice(1) },\n decision: isTrampoline(declared) || isTrampoline(program) ? 'ask' : 'allow',\n replay: 'idempotent',\n network: false,\n origin: 'project-checks',\n });\n }\n return rules;\n}\n\n// ── schema, for \"every returned verdict fragment is schema-valid\" ────────────────────────────────────────────\n\nconst closed = { additionalProperties: false } as const;\n\n/** [S] Mirrors `CommandEvaluation`; `command` mirrors `NormalizedCall['command']` of ../../contract/decisions.ts. */\nexport const CommandEvaluationSchema: TSchema = Type.Object(\n {\n decision: Type.Union([Type.Literal('allow'), Type.Literal('ask'), Type.Literal('deny')]),\n ruleId: Type.String({ minLength: 1 }),\n code: Type.Optional(Type.String({ minLength: 1 })),\n reason: Type.String(),\n overridable: Type.Boolean(),\n securityViolation: Type.Boolean(),\n evaluatedRules: Type.Array(Type.String()),\n command: Type.Optional(\n Type.Object(\n {\n file: Type.String({ minLength: 1 }),\n args: Type.Array(Type.String()),\n cwd: Type.String({ minLength: 1 }),\n ruleId: Type.String({ minLength: 1 }),\n replay: Type.Union([Type.Literal('idempotent'), Type.Literal('at-most-once')]),\n network: Type.Boolean(),\n timeoutMs: Type.Integer({ minimum: 0 }),\n },\n closed,\n ),\n ),\n },\n closed,\n);\n","// Five pure gate stages and policy explanation (PLAN U2.01).\n\nimport type { JsonValue } from '@cohorte/base';\nimport { canonicalJson, sha256Hex } from '@cohorte/base';\nimport { type CohorteConfig, DEFAULT_NETWORK_POLICY, type Ownership } from '@cohorte/config/schema';\nimport type { TSchema } from 'typebox';\nimport { Compile } from 'typebox/compile';\nimport type {\n AgentGrant,\n GateCall,\n GlobMatcher,\n PolicyEngine,\n PolicyPorts,\n PolicySnapshot,\n PolicyVerdict,\n ToolIntrospection,\n} from '../../contract/index.ts';\nimport type { CommandPolicyEvaluator } from '../commands/index.ts';\n\nconst deny = (\n stage: PolicyVerdict['stage'],\n ruleId: string,\n reason: string,\n code = 'permission/tool-not-granted',\n securityViolation = false,\n): PolicyVerdict => ({\n decision: 'deny',\n stage,\n ruleId,\n reason: `${code}: ${reason}`,\n modelFacingReason: `${reason}. Do not retry.`,\n overridable: !securityViolation,\n securityViolation,\n asks: [],\n evaluatedRules: [ruleId],\n normalized: null,\n});\n\nconst invalidPolicy = (message: string): never => {\n throw new Error(`configuration/policy-invalid: ${message}`);\n};\n\nconst cloneFreeze = <T>(value: T): T => {\n if (value && typeof value === 'object') {\n Object.freeze(value);\n for (const child of Object.values(value as Record<string, unknown>)) cloneFreeze(child);\n }\n return value;\n};\n\nexport interface PolicyEngineOptions {\n tools: ToolIntrospection;\n globs: GlobMatcher;\n commands: CommandPolicyEvaluator;\n}\n\nexport function createPolicyEngine(options: PolicyEngineOptions): PolicyEngine {\n if (!options?.tools || !options.globs || !options.commands) invalidPolicy('policy engine ports are incomplete');\n return {\n evaluate(call, grant, policy, ports) {\n try {\n const schema = options.tools.schemaOf(call.tool);\n if (schema === undefined)\n return deny('schema', 'builtin/unknown-tool', `unknown tool \"${call.tool}\"`, 'validation/tool-input', true);\n const validation = Compile(schema as TSchema);\n if (!validation.Check(call.input))\n return deny(\n 'schema',\n 'builtin/tool-schema',\n `input for \"${call.tool}\" does not match its strict schema`,\n 'validation/tool-input',\n );\n\n const evaluatedRules: string[] = ['builtin/tool-schema'];\n if (!grant.tools.includes(call.tool))\n return {\n ...deny('capability', 'grant/tool-not-granted', `tool \"${call.tool}\" is not granted to this agent`),\n evaluatedRules,\n };\n\n const normalizedPaths: NonNullable<PolicyVerdict['normalized']>['paths'] = [];\n const base = grant.roots.workspace ?? grant.roots.readOnly[0];\n if (base === undefined)\n return deny(\n 'path',\n 'grant/no-root',\n 'the agent has no workspace or read-only root',\n 'permission/path-outside-grant',\n );\n for (const arg of options.tools.pathArgsOf(call.tool, call.input)) {\n const resolved = ports.paths.resolve(arg.value, base, arg.intent);\n if (!resolved.ok)\n return deny(\n 'path',\n `path/${resolved.error.code}`,\n `path argument \"${arg.arg}\" was refused: ${resolved.error.detail}`,\n resolved.error.security ? `security/${resolved.error.code}` : 'permission/path-outside-grant',\n resolved.error.security,\n );\n if (\n options.globs.isDenied(\n resolved.value.relative,\n grant,\n arg.intent === 'read' || arg.intent === 'list' ? 'read' : 'write',\n )\n )\n return deny('path', 'grant/deny-glob', `path argument \"${arg.arg}\" is denied by the grant`);\n normalizedPaths.push({ arg: arg.arg, resolved: resolved.value, intent: arg.intent });\n }\n\n let command: NonNullable<NonNullable<PolicyVerdict['normalized']>['command']> | undefined;\n if (call.tool === 'network_request')\n return deny(\n 'network',\n 'builtin/network-denied',\n 'network requests are disabled in V3.0',\n 'permission/network-denied',\n );\n if (call.tool === 'run_command') {\n const input = call.input as { argv?: JsonValue; cwd?: JsonValue };\n const argv =\n Array.isArray(input.argv) && input.argv.every((v) => typeof v === 'string') ? (input.argv as string[]) : [];\n const cwd = typeof input.cwd === 'string' ? input.cwd : '';\n const cwdResult = ports.paths.resolve(cwd, base, 'exec-cwd');\n if (!cwdResult.ok)\n return deny(\n 'command',\n 'command/cwd',\n 'command cwd is outside the grant',\n 'permission/command-not-allowed',\n true,\n );\n const evaluation = options.commands.evaluate({ argv, cwd }, grant.commands, {\n worktree: grant.roots.workspace ?? cwdResult.value.root,\n cwd: cwdResult.value.canonical,\n role: grant.role,\n phase: call.phase,\n sandboxLevel: policy.sandboxLevel,\n defaultTimeoutMs: grant.limits.perTool.run_command?.timeoutMs ?? 60_000,\n });\n evaluatedRules.push(...evaluation.evaluatedRules);\n if (evaluation.decision === 'deny' || evaluation.command === undefined)\n return deny('command', evaluation.ruleId, evaluation.reason, evaluation.code, evaluation.securityViolation);\n command = evaluation.command;\n }\n\n const limit = grant.limits.perTool[call.tool];\n const levels = [\n ['run', call.runId],\n ['phase', call.phase],\n ['agent', call.agentId],\n ['tool', call.tool],\n ] as const;\n for (const [level, id] of levels) {\n const remaining = ports.budgets.remaining(level, id);\n if ((remaining.toolCalls ?? 1) <= 0 || (remaining.wallClockMs ?? 1) <= 0)\n return deny('budget', `budget/${level}`, `${level} budget is exhausted`, 'budget/exhausted');\n }\n if (ports.budgets.callsInLastMinute(call.agentId, call.tool) >= grant.limits.maxCallsPerMinute)\n return deny('budget', 'budget/rate-limit', 'tool rate limit is exhausted', 'budget/rate-limit');\n const timeoutMs = Math.max(\n 1,\n Math.min(\n limit?.timeoutMs ?? 60_000,\n command?.timeoutMs ?? Number.MAX_SAFE_INTEGER,\n ports.budgets.remaining('agent', call.agentId).wallClockMs ?? Number.MAX_SAFE_INTEGER,\n ),\n );\n return {\n decision: 'allow',\n stage: 'budget',\n ruleId: command?.ruleId ?? 'grant/tool',\n reason: 'allowed by the policy',\n modelFacingReason: '',\n overridable: true,\n securityViolation: false,\n asks: [],\n evaluatedRules,\n normalized: {\n tool: call.tool,\n paths: normalizedPaths,\n ...(command ? { command: { ...command, timeoutMs } } : {}),\n input: call.input,\n grantKeyMaterial: { tool: call.tool, input: call.input },\n },\n };\n } catch (error) {\n return deny(\n 'schema',\n 'security/gate-internal-error',\n error instanceof Error ? error.message : 'gate failed closed',\n 'security/gate-internal-error',\n true,\n );\n }\n },\n };\n}\n\n/** Missing, unparseable or empty policy => `configuration/policy-invalid`: no tool ever executes. */\nexport function buildPolicySnapshot(\n config: CohorteConfig,\n ownership: Ownership,\n options: { sandboxLevel: PolicySnapshot['sandboxLevel'] },\n): PolicySnapshot {\n if (!config || config.policy === undefined || !ownership || options?.sandboxLevel === undefined)\n invalidPolicy('missing policy or ownership');\n const commands = [\n ...config.policy.commands.deny,\n ...config.policy.commands.ask,\n ...config.policy.commands.allow,\n ...config.policy.dangerousCommands,\n ];\n if (commands.some((rule) => rule.origin !== 'project-config' && rule.origin !== 'project-checks'))\n invalidPolicy('policy command origin is invalid');\n const snapshot = {\n commands: Object.freeze({ default: 'deny' as const, rules: commands.map((rule) => ({ ...rule })) }),\n symlinks: { ...config.policy.symlinks },\n network: { ...DEFAULT_NETWORK_POLICY },\n protectedBranches: [...config.project.protectedBranches],\n ownership: cloneFreeze(structuredClone(ownership)),\n sandboxLevel: options.sandboxLevel,\n } satisfies Omit<PolicySnapshot, 'digest'>;\n return Object.freeze({ ...snapshot, digest: sha256Hex(canonicalJson(snapshot as unknown as JsonValue)) });\n}\n\n/** `cohorte policy explain -- <argv…>`: stages 1-5, offline, nothing executes. */\nexport function explainPolicy(\n engine: PolicyEngine,\n call: GateCall,\n grant: AgentGrant,\n policy: PolicySnapshot,\n ports: PolicyPorts,\n): PolicyVerdict {\n if (!engine || !call || !grant || !policy || !ports)\n invalidPolicy('policy explain requires a complete call, grant, snapshot and ports');\n return engine.evaluate(call, grant, policy, ports);\n}\n","// The ONE glob implementation of DESIGN 2.6.3 step 7, exported as `GlobMatcher` (DESIGN 2.6.1) so that `tools`\n// (list_files, search, git_diff output filtering, WorkspaceReader) and `core` (grants, zones) never configure\n// picomatch themselves.\nimport picomatch from 'picomatch';\nimport type { AgentGrant, GlobMatcher, GlobSet } from '../../contract/index.ts';\n\n/** Locked once, here: deny sets and allow sets alike are matched with the SAME options. */\nconst PICOMATCH_OPTIONS = { dot: true, nocase: false } as const;\n\ntype Predicate = (relativePosixPath: string) => boolean;\n\nconst NEVER: Predicate = () => false;\n\n// A slash-less pattern means \"at any depth\" (gitignore-style): `.env*` becomes a double-star prefixed pattern,\n// so it matches `config/.env` and not only a root-level `.env` (DESIGN 2.6.3 step 7; the spec's own example is\n// unsafe as written without this rule, per the toolchain research). A trailing-double-star directory pattern\n// matching the bare directory name is picomatch's own behaviour with these options and needs no help here\n// (locked by a table test).\nfunction normalizePattern(pattern: string): string {\n return pattern.includes('/') ? pattern : `**/${pattern}`;\n}\n\n// Compiling a pattern list costs ~25 µs; `isDenied` runs once per RESULT LINE of `search` / `list_files` /\n// `git_diff` (I11 output filtering, U2.03), which is thousands of calls over the same two or three sets. Two\n// caches, because both shapes occur: the same long-lived `GlobSet` object (a grant is immutable for the life of\n// a run) and an equal set rebuilt from literals on every call. The key covers BOTH lists, so two sets that\n// share an `include` and differ in `exclude` never share a predicate.\nconst PATTERN_CACHE_LIMIT = 512;\nconst patternCache = new Map<string, Predicate>();\nconst globSetCache = new WeakMap<GlobSet, Predicate>();\n\nfunction cacheKey(patterns: readonly string[]): string {\n return patterns.join('\u0000');\n}\n\nfunction memoize(key: string, compile: () => Predicate): Predicate {\n const cached = patternCache.get(key);\n if (cached !== undefined) return cached;\n const compiled = compile();\n // Pattern lists come from grants and project policy, never from model input, so the cache is bounded in\n // practice; the limit is there so a long-lived host cannot grow one without end.\n if (patternCache.size >= PATTERN_CACHE_LIMIT) patternCache.clear();\n patternCache.set(key, compiled);\n return compiled;\n}\n\n/**\n * Compiled once per pattern list and memoized, so every consumer of this module shares the exact same semantics\n * at the same cost. An empty pattern list matches nothing (picomatch(`[]`) would otherwise match everything).\n */\nexport function compilePatterns(patterns: readonly string[]): Predicate {\n if (patterns.length === 0) return NEVER;\n return memoize(`p\u0001${cacheKey(patterns)}`, () => picomatch(patterns.map(normalizePattern), PICOMATCH_OPTIONS));\n}\n\nfunction compileGlobSet(set: GlobSet): Predicate {\n const cached = globSetCache.get(set);\n if (cached !== undefined) return cached;\n const compiled = memoize(`s\u0001${cacheKey(set.include)}\u0002${cacheKey(set.exclude)}`, () => {\n const included = compilePatterns(set.include);\n if (set.exclude.length === 0) return included;\n const excluded = compilePatterns(set.exclude);\n return (relativePosixPath: string) => included(relativePosixPath) && !excluded(relativePosixPath);\n });\n globSetCache.set(set, compiled);\n return compiled;\n}\n\n/**\n * Neither dialect can express a RE-INCLUDE, so `toExcludeArgs` renders the exclusions alone:\n *\n * - `rg --glob` reads its list in order, later entries overriding earlier matches — but a POSITIVE glob turns\n * ripgrep's override set into a whitelist (the `ignore` crate ignores every file that matches no positive\n * glob), which would silently empty the listing. Unprovable on this machine anyway (PLAN F-1: no `rg`).\n * - git pathspec is NOT order-dependent: `:(exclude,…)` magic is subtractive and applied AFTER the union of\n * every positive pathspec. A rendered `:(glob)<re-include>` therefore cannot bring back what the exclusion\n * removed, and when the caller passes no positive pathspec of its own it narrows the enumeration to the\n * re-include, which the exclusion then empties: `git ls-files`/`git grep` return NOTHING, exit 0 (measured).\n *\n * The consequence is deliberate and fail-closed (I2): for a deny set with a non-empty `exclude` the external\n * enumerator drops MORE than the matcher denies — never less. `matches()` / `isDenied` stay the authority, and\n * a caller that needs the re-included paths in its output must enumerate without the args and post-filter.\n */\nfunction toExcludePatterns(set: GlobSet): string[] {\n return set.include.map(normalizePattern);\n}\n\nexport function createGlobMatcher(): GlobMatcher {\n function deniedBySet(relativePosixPath: string, grant: AgentGrant, intent: 'read' | 'write'): boolean {\n const denySet = intent === 'read' ? grant.denyRead : grant.denyWrite;\n return compileGlobSet(denySet)(relativePosixPath);\n }\n\n return {\n matches(relativePosixPath, set) {\n return compileGlobSet(set)(relativePosixPath);\n },\n /**\n * \"Not permitted for this intent\" — the whole of step 7 in one call, which is why the contract takes an\n * `AgentGrant` and not a `GlobSet`: the deny set wins over the allow set, and a path that no allow pattern\n * matches is denied too (fail closed, I2). That second half is what keeps the I11 ownership boundary in tool\n * OUTPUT filtering (`search`, `list_files`, `git_diff`), where the gate's own allow stage never runs.\n *\n * The empty relative path is the WORKSPACE ROOT itself — what `resolve('.', root, 'list')` returns — and no\n * picomatch pattern matches the empty string, `**` and `**​/*` included. The root is not \"outside the\n * surface\": it IS the surface, so an allow set that has any pattern at all covers it, and only a deny\n * pattern (or a grant that permits nothing for this intent) can forbid it.\n */\n isDenied(relativePosixPath, grant, intent) {\n if (deniedBySet(relativePosixPath, grant, intent)) return true;\n const allowSet = intent === 'read' ? grant.read : grant.write;\n if (relativePosixPath === '') return allowSet.include.length === 0;\n return !compileGlobSet(allowSet)(relativePosixPath);\n },\n toExcludeArgs(set, dialect) {\n const patterns = toExcludePatterns(set);\n return dialect === 'rg-glob'\n ? patterns.map((pattern) => `!${pattern}`)\n : patterns.map((pattern) => `:(exclude,glob)${pattern}`);\n },\n };\n}\n","// The canonical PathResolver (DESIGN 2.6.3 steps 1-7, spec 23): one implementation shared by the gate,\n// `WorkspaceReader`, `WorktreeService` and `tools`. Never throws — every failure mode, expected or not, comes\n// back as a `PathViolation` (I2: fail closed).\nimport { lstatSync, readdirSync, realpathSync } from 'node:fs';\nimport { resolve as resolvePath } from 'node:path';\nimport { err, ok, type Result } from '@cohorte/base';\nimport type {\n CanonicalPath,\n PathIntent,\n PathResolver,\n PathResolverOptions,\n PathViolation,\n ResolvedPath,\n} from '../../contract/index.ts';\nimport { PROTECTED_REPO_GLOBS } from '../../contract/index.ts';\nimport { compilePatterns } from './glob.ts';\n\nconst MAX_INPUT_LENGTH = 4096;\n// biome-ignore lint/suspicious/noControlCharactersInRegex: the whole point is to catch a NUL byte or control character.\nconst CONTROL_OR_NUL = /[\\x00-\\x1f\\x7f]/;\nconst ENV_SYNTAX = /\\$\\{[^}]*\\}|\\$[A-Za-z_][A-Za-z0-9_]*|%[A-Za-z_][A-Za-z0-9_]*%/;\n// The home-directory shorthand is a whole SEGMENT — `~` or `~user` — never a tilde anywhere in a name: refusing\n// every `~` made `notes.txt~`, `a~b.ts` and `~$report.docx` (an Office lock file) unaddressable.\nconst HOME_SHORTHAND_SEGMENT = /^~([A-Za-z0-9_][A-Za-z0-9_-]*)?$/;\nconst WINDOWS_DRIVE = /^[A-Za-z]:[\\\\/]/;\nconst UNC_PREFIX = /^\\\\\\\\/;\nconst WRITE_LIKE = new Set<PathIntent>(['write', 'create']);\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction violation(code: PathViolation['code'], security: boolean, detail: string): Result<never, PathViolation> {\n return err({ code, security, detail });\n}\n\nfunction segmentsOf(absolutePosixPath: string): string[] {\n return absolutePosixPath.split('/').filter((part) => part.length > 0);\n}\n\n/** Containment by path SEGMENTS, never `startsWith`: `apps/api` must not contain `apps/api-gateway`. */\nfunction segmentsContain(longer: readonly string[], shorter: readonly string[]): boolean {\n if (longer.length < shorter.length) return false;\n for (let index = 0; index < shorter.length; index += 1) {\n if (longer[index] !== shorter[index]) return false;\n }\n return true;\n}\n\nfunction findRoot(absolutePosixPath: string, roots: readonly string[]): string | undefined {\n const target = segmentsOf(absolutePosixPath);\n return roots.find((root) => segmentsContain(target, segmentsOf(root)));\n}\n\nfunction isWithinAny(absolutePosixPath: string, candidates: readonly string[]): boolean {\n const target = segmentsOf(absolutePosixPath);\n return candidates.some((candidate) => segmentsContain(target, segmentsOf(candidate)));\n}\n\n/**\n * POSIX-relative form of `absolutePosixPath` to `root`, which always CONTAINS it: the caller picks `root` with\n * `findRoot` on the CANONICAL path. It can therefore never climb with `..` — and it must not, because the deny\n * globs and the protected-repository patterns are matched against this string, and a `..` segment matches no\n * double-star pattern (a relative form with `..` silently disabled both layers).\n */\nfunction relativeTo(root: string, absolutePosixPath: string): string {\n return segmentsOf(absolutePosixPath).slice(segmentsOf(root).length).join('/');\n}\n\ninterface Lstat {\n isSymbolicLink(): boolean;\n isFile(): boolean;\n isFIFO(): boolean;\n isSocket(): boolean;\n isBlockDevice(): boolean;\n isCharacterDevice(): boolean;\n dev: number;\n ino: number;\n nlink: number;\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && 'code' in error;\n}\n\n/** `null` for \"does not exist\" (ENOENT — or ENOTDIR, an ancestor turned out not to be a directory). */\nfunction lstatOrNull(absolutePath: string): Lstat | null {\n try {\n return lstatSync(absolutePath);\n } catch (error) {\n if (isErrnoException(error) && (error.code === 'ENOENT' || error.code === 'ENOTDIR')) return null;\n throw error;\n }\n}\n\nfunction isSpecialFile(stat: Lstat): boolean {\n return stat.isFIFO() || stat.isSocket() || stat.isBlockDevice() || stat.isCharacterDevice();\n}\n\n/**\n * The one point a blind create could alias an existing entry that `realpath` cannot fix for us, because the\n * requested name does not exist yet: a case-insensitive volume already holds a differently-cased sibling.\n */\nfunction caseInsensitiveSiblingExists(dir: string, requestedName: string): boolean {\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n return false;\n }\n const lower = requestedName.toLowerCase();\n return entries.some((entry) => entry !== requestedName && entry.toLowerCase() === lower);\n}\n\ninterface WalkOutcome {\n /** on-disk case, absolute POSIX, no trailing slash: the deepest existing position of the walk. */\n canonicalDir: string;\n /** the requested-case segments beyond `canonicalDir` that do not exist yet; empty once fully resolved. */\n tailSegments: string[];\n exists: boolean;\n viaSymlink: boolean;\n}\n\nexport function createPathResolver(options: PathResolverOptions): PathResolver {\n const roots = options.roots.map((root): string => root);\n const protectedRoots = options.protectedRoots.map((root): string => root);\n const protectedRepoPath = compilePatterns(PROTECTED_REPO_GLOBS);\n const { mode: symlinkMode, hardlinksOnWrite } = options.symlinks;\n\n /** DESIGN 2.6.3 steps 3-4: one component at a time, from `root` to the leaf. */\n function walk(root: string, target: string, intent: PathIntent): Result<WalkOutcome, PathViolation> {\n const remaining = segmentsOf(target).slice(segmentsOf(root).length);\n let current = root;\n let viaSymlink = false;\n\n for (let index = 0; index < remaining.length; index += 1) {\n const name = remaining[index];\n if (name === undefined) break; // unreachable: index ranges over remaining.length\n const candidate = `${current}/${name}`;\n const isFinal = index === remaining.length - 1;\n const stat = lstatOrNull(candidate);\n\n if (stat === null) {\n const canonicalDir = realpathSync.native(current);\n if (WRITE_LIKE.has(intent) && caseInsensitiveSiblingExists(canonicalDir, name)) {\n return violation(\n 'case-collision',\n true,\n `${candidate} collides, case-insensitively, with an existing entry of ${canonicalDir}`,\n );\n }\n return ok({ canonicalDir, tailSegments: remaining.slice(index), exists: false, viaSymlink });\n }\n\n if (stat.isSymbolicLink()) {\n if (isFinal && WRITE_LIKE.has(intent)) {\n return violation(\n 'symlink-final-write',\n true,\n `${candidate} is a symlink; a write never follows the final path component`,\n );\n }\n if (symlinkMode === 'deny-all') {\n return violation('symlink-denied', true, `${candidate} is a symlink; policy is deny-all`);\n }\n let linkTarget: string;\n try {\n linkTarget = realpathSync.native(candidate);\n } catch (error) {\n return violation('symlink-escape', true, `${candidate} could not be resolved: ${describeError(error)}`);\n }\n if (symlinkMode === 'deny-outgoing' && findRoot(linkTarget, roots) === undefined) {\n return violation('symlink-escape', true, `${candidate} -> ${linkTarget} leaves every root`);\n }\n current = linkTarget;\n viaSymlink = true;\n continue;\n }\n\n if (isSpecialFile(stat) && !isFinal) {\n return violation('special-file', true, `${candidate} is a FIFO, socket or device: cannot descend into it`);\n }\n current = candidate;\n }\n\n return ok({ canonicalDir: realpathSync.native(current), tailSegments: [], exists: true, viaSymlink });\n }\n\n function resolveOnce(input: string, base: CanonicalPath, intent: PathIntent): Result<ResolvedPath, PathViolation> {\n if (CONTROL_OR_NUL.test(input)) return violation('nul-byte', true, 'control character or NUL byte in path');\n if (Buffer.byteLength(input, 'utf8') > MAX_INPUT_LENGTH) {\n return violation('too-long', true, `path exceeds ${MAX_INPUT_LENGTH} bytes`);\n }\n if (input.split('/').some((segment) => HOME_SHORTHAND_SEGMENT.test(segment))) {\n return violation('outside-roots', true, 'home-directory shorthand (~) is never expanded');\n }\n if (ENV_SYNTAX.test(input))\n return violation('outside-roots', true, 'environment-variable syntax is never expanded');\n if (WINDOWS_DRIVE.test(input) || UNC_PREFIX.test(input)) {\n return violation('outside-roots', true, 'Windows drive/UNC path forms are not supported');\n }\n\n const target = resolvePath(base, input.normalize('NFC'));\n // The LEXICAL root only says where to start the walk; it decides nothing.\n const lexicalRoot = findRoot(target, roots);\n if (lexicalRoot === undefined) return violation('outside-roots', true, `${target} is outside every root`);\n\n const walked = walk(lexicalRoot, target, intent);\n if (!walked.ok) return walked;\n const { canonicalDir, tailSegments, exists, viaSymlink } = walked.value;\n const canonical = tailSegments.length === 0 ? canonicalDir : `${canonicalDir}/${tailSegments.join('/')}`;\n\n // Step 4, AFTER the walk: containment is decided on the canonical path, never on the lexical one. With more\n // than one root — the normal grant shape, a workspace plus read-only roots — a symlink (or a realpath'd\n // ancestor) can land in a root OTHER than the one the input pointed at, and `root` / `relative` must name\n // where the bytes really are: step 5 and every relative deny-glob below match on `relative`.\n const root = findRoot(canonical, roots);\n if (root === undefined) return violation('outside-roots', true, `${canonical} resolves outside every root`);\n\n // Step 5: built-in protected roots — never overridable by config or approval.\n if (isWithinAny(canonical, protectedRoots))\n return violation('protected-root', true, `${canonical} is a protected root`);\n const relative = relativeTo(root, canonical);\n if (protectedRepoPath(relative))\n return violation('protected-root', true, `${relative} is a protected repository path`);\n\n // Step 6: hardlink / special-file, on the resolved target.\n let identity: ResolvedPath['identity'];\n if (exists) {\n const stat = lstatSync(canonical);\n if (isSpecialFile(stat)) return violation('special-file', true, `${canonical} is a FIFO, socket or device`);\n if (WRITE_LIKE.has(intent) && stat.isFile() && stat.nlink > 1 && hardlinksOnWrite === 'deny') {\n return violation('hardlink-multiply-linked', true, `${canonical} has ${stat.nlink} hard links`);\n }\n identity = { dev: stat.dev, ino: stat.ino, nlink: stat.nlink };\n }\n\n return ok({\n canonical: canonical as CanonicalPath,\n relative,\n root: root as CanonicalPath,\n exists,\n viaSymlink,\n ...(identity ? { identity } : {}),\n });\n }\n\n return {\n resolve(input, base, intent) {\n try {\n return resolveOnce(input, base, intent);\n } catch (error) {\n // Fail closed (I2): a symlink loop `realpath` cannot follow, a permission error walking a component,\n // anything unforeseen — never an uncaught throw.\n const detail = `unexpected error resolving ${JSON.stringify(input)}: ${describeError(error)}`;\n return violation('outside-roots', true, detail);\n }\n },\n };\n}\n","// DESIGN 2.7 — the 9 V3.0 tools + the 3 seams, as DATA: name, model-facing description, input schema, effect,\n// terminal, and the path-argument annotations `pathArgsOf` reads. Every input schema is authored UNCLOSED (as every\n// TypeBox schema in this repo is) and closed once, uniformly, by `toStrictSchema` in `./index.ts` — the same\n// generator `@cohorte/protocol` uses for commands and events (DESIGN 0.1 C3), so \"additionalProperties: false\" is\n// never something an author can forget.\nimport type { JsonValue } from '@cohorte/base';\nimport { AgentOutput, ClosedEnum } from '@cohorte/protocol';\n// The ONE closed union of path intents (DESIGN 2.6.3): re-exported, never re-declared, so `toolIntrospection`'s\n// `PathArg[]` IS a `ToolIntrospection` result and no cast bridges two copies of the same union.\nimport type { PathIntent } from '@cohorte/security/contract';\nimport { type Static, type TSchema, Type } from 'typebox';\n\nexport type { PathIntent };\nexport interface PathArg {\n arg: string;\n value: string;\n intent: PathIntent;\n}\n\nconst ReadFileInput = Type.Object({\n path: Type.String(),\n offset: Type.Optional(Type.Integer({ minimum: 0 })),\n limit: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst ListFilesInput = Type.Object({\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n maxEntries: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst SearchInput = Type.Object({\n pattern: Type.String(),\n path: Type.Optional(Type.String()),\n glob: Type.Optional(Type.String()),\n caseInsensitive: Type.Optional(Type.Boolean()),\n maxMatches: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nconst WriteFileInput = Type.Object({ path: Type.String(), content: Type.String() });\nconst PatchFileInput = Type.Object({\n path: Type.String(),\n edits: Type.Array(Type.Object({ oldText: Type.String(), newText: Type.String() }), { minItems: 1 }),\n});\nconst RunCommandInput = Type.Object({\n argv: Type.Array(Type.String(), { minItems: 1 }),\n cwd: Type.Optional(Type.String()),\n timeoutMs: Type.Optional(Type.Integer({ minimum: 1 })),\n});\nexport const GIT_DIFF_BASES = ['run-base', 'integration', 'checkpoint'] as const;\nconst GitDiffInput = Type.Object({\n base: Type.Optional(ClosedEnum(GIT_DIFF_BASES)),\n paths: Type.Optional(Type.Array(Type.String())),\n stat: Type.Optional(Type.Boolean()),\n});\nconst ApprovalRequestInput = Type.Object({\n question: Type.String(),\n options: Type.Optional(Type.Array(Type.String())),\n});\nconst GitCommitInput = Type.Object({ message: Type.String() });\nconst NetworkRequestInput = Type.Object({ url: Type.String(), method: Type.Optional(Type.String()) });\nconst SecretReadInput = Type.Object({ id: Type.String() });\n\nexport type ReadFileInput = Static<typeof ReadFileInput>;\nexport type ListFilesInput = Static<typeof ListFilesInput>;\nexport type SearchInput = Static<typeof SearchInput>;\nexport type WriteFileInput = Static<typeof WriteFileInput>;\nexport type PatchFileInput = Static<typeof PatchFileInput>;\nexport type RunCommandInput = Static<typeof RunCommandInput>;\nexport type GitDiffInput = Static<typeof GitDiffInput>;\nexport type ApprovalRequestInput = Static<typeof ApprovalRequestInput>;\nexport type GitCommitInput = Static<typeof GitCommitInput>;\nexport type NetworkRequestInput = Static<typeof NetworkRequestInput>;\nexport type SecretReadInput = Static<typeof SecretReadInput>;\n\nexport interface CatalogueRow {\n readonly name: string;\n readonly description: string;\n readonly inputSchema: TSchema;\n readonly effect: 'read' | 'write' | 'execute' | 'network' | 'control';\n readonly terminal: boolean;\n readonly pathArgsOf: (input: JsonValue) => PathArg[];\n}\n\nconst noPaths = (): PathArg[] => [];\nconst stringField = (input: JsonValue, key: string): string | undefined => {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return undefined;\n const value = (input as Record<string, JsonValue>)[key];\n return typeof value === 'string' ? value : undefined;\n};\nconst arrayField = (input: JsonValue, key: string): JsonValue[] | undefined => {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return undefined;\n const value = (input as Record<string, JsonValue>)[key];\n return Array.isArray(value) ? value : undefined;\n};\n\n/** DESIGN 2.7, in table order. `submit_result.inputSchema` is `AgentOutput` itself — closed by the same\n * `toStrictSchema` every other row goes through in `./index.ts`, so the two are deep-equal by construction. */\nexport const CATALOGUE_ROWS: readonly CatalogueRow[] = [\n {\n name: 'read_file',\n description:\n 'Read a file as sealed text with line numbers. offset/limit page through it; binary files error; capped at 256 KiB per call.',\n inputSchema: ReadFileInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'read' }];\n },\n },\n {\n name: 'list_files',\n description:\n 'List files under a path (default the workspace root), filtered by glob. Deny sets are filtered out; outgoing symlinks are never followed.',\n inputSchema: ListFilesInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'list' }];\n },\n },\n {\n name: 'search',\n description:\n 'Search file contents for a pattern (a literal argv element, never a shell string). Every hit is filtered against the deny sets and the grant before it is returned.',\n inputSchema: SearchInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'list' }];\n },\n },\n {\n name: 'write_file',\n description: 'Write the complete content of a file, creating it if it does not exist. The whole file is replaced.',\n inputSchema: WriteFileInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'write' }];\n },\n },\n {\n name: 'patch_file',\n description:\n 'Apply exact-match text edits to a file: each oldText must occur exactly once in the current content, or the call fails without writing anything.',\n inputSchema: PatchFileInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: (input) => {\n const path = stringField(input, 'path');\n return path === undefined ? [] : [{ arg: 'path', value: path, intent: 'write' }];\n },\n },\n {\n name: 'run_command',\n description: 'Run one allow-listed command (argv only, never a shell line) and return its output.',\n inputSchema: RunCommandInput,\n effect: 'execute',\n terminal: false,\n pathArgsOf: (input) => {\n const cwd = stringField(input, 'cwd');\n return cwd === undefined ? [] : [{ arg: 'cwd', value: cwd, intent: 'exec-cwd' }];\n },\n },\n {\n name: 'git_diff',\n description:\n \"Show a diff of the worktree against 'run-base' (the run's pinned base, the default on a read-only review ref), 'integration' (the default in a slot) or 'checkpoint'.\",\n inputSchema: GitDiffInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: (input) => {\n const paths = arrayField(input, 'paths');\n if (!paths) return [];\n const out: PathArg[] = [];\n paths.forEach((value, index) => {\n if (typeof value === 'string') out.push({ arg: `paths[${index}]`, value, intent: 'read' });\n });\n return out;\n },\n },\n {\n name: 'approval_request',\n description:\n 'Ask a human a question before proceeding, optionally offering a fixed set of answers. Waits for a decision.',\n inputSchema: ApprovalRequestInput,\n effect: 'control',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'submit_result',\n description:\n 'Submit the final structured result for this task. Call submit_result alone, last: no other tool call may follow it in the same batch.',\n inputSchema: AgentOutput,\n effect: 'control',\n terminal: true,\n pathArgsOf: (input) => {\n const artifacts = arrayField(input, 'artifacts');\n if (!artifacts) return [];\n const out: PathArg[] = [];\n artifacts.forEach((artifact, index) => {\n const path = stringField(artifact, 'path');\n if (path !== undefined) out.push({ arg: `artifacts[${index}].path`, value: path, intent: 'read' });\n });\n return out;\n },\n },\n {\n name: 'git_commit',\n description: 'Reserved: granted to nobody in V3.0. Cohorte alone commits agent work.',\n inputSchema: GitCommitInput,\n effect: 'write',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'network_request',\n description: 'Reserved: granted to nobody in V3.0. Agents have no network access.',\n inputSchema: NetworkRequestInput,\n effect: 'network',\n terminal: false,\n pathArgsOf: noPaths,\n },\n {\n name: 'secret_read',\n description: 'Reserved: granted to nobody in V3.0.',\n inputSchema: SecretReadInput,\n effect: 'read',\n terminal: false,\n pathArgsOf: noPaths,\n },\n];\n\n/** Tools registered but granted to nobody in V3.0 (DESIGN 2.7): the default policy denies every call, on principle. */\nexport const SEAM_TOOL_NAMES = ['git_commit', 'network_request', 'secret_read'] as const;\n\nexport const TOOL_NAMES = CATALOGUE_ROWS.map((row) => row.name);\n","import type { JsonValue } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type { ToolExecContext, ToolExecuteResult, ToolImplementation, ToolPlan } from '../../catalogue/types.ts';\n\nexport const EXEC_TOOL_NAMES = ['run_command'] as const;\nconst metadata = CATALOGUE_ROWS.find((row) => row.name === 'run_command');\nif (!metadata) throw new Error('missing catalogue row: run_command');\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\n\nconst runCommand: ToolImplementation = {\n ...metadata,\n plan(input, n): ToolPlan {\n return {\n kind: 'tool.run_command',\n replayClass: n.command?.replay ?? 'at-most-once',\n verify: { tool: 'run_command', input, normalized: JSON.parse(JSON.stringify(n)) as JsonValue },\n };\n },\n async execute(input, n, ctx: ToolExecContext, signal): Promise<ToolExecuteResult<JsonValue>> {\n if (signal.aborted) fail('tool-transient/cancelled', 'command was cancelled');\n const command = n.command ?? fail('permission/command-not-allowed', 'run_command has no normalized command');\n const value = input as { argv: string[]; timeoutMs?: number };\n const result = await ctx.executor.run(\n {\n file: command.file,\n args: command.args,\n cwd: command.cwd,\n env: {},\n fs: { readWrite: [ctx.workspaceRoot], readOnly: [], denyRead: [] },\n network: 'none',\n timeoutMs: value.timeoutMs ?? command.timeoutMs,\n maxOutputBytes: 1024 * 1024,\n stdin: 'ignore',\n limits: {},\n require: 'best-effort',\n },\n signal,\n );\n const text = String(result.tail);\n return {\n output: {\n argv: value.argv,\n exitCode: result.exitCode,\n ...(result.signal === undefined ? {} : { signal: result.signal }),\n outcome: result.outcome,\n text,\n outputSha256: result.outputSha256,\n outputBytes: result.outputBytes,\n truncated: result.truncated,\n },\n modelText: text,\n filesTouched: [],\n };\n },\n verifyAfterCrash: async (_record: EffectRecord) => 'in-doubt',\n describeForNote: (record) => `run_command ${record.idempotencyKey}`,\n};\n\nexport const EXEC_TOOLS: Readonly<Record<(typeof EXEC_TOOL_NAMES)[number], ToolImplementation>> = Object.freeze({\n run_command: runCommand,\n});\n","import { createHash } from 'node:crypto';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport type { JsonValue } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type {\n NormalizedCall,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from '../../catalogue/types.ts';\n\nexport const READ_TOOL_NAMES = ['read_file', 'list_files', 'search', 'git_diff'] as const;\ntype ReadName = (typeof READ_TOOL_NAMES)[number];\nconst row = (name: ReadName) => {\n const entry = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (entry === undefined) throw new Error(`missing catalogue row: ${name}`);\n return entry;\n};\nconst sha256 = (bytes: Uint8Array): string => createHash('sha256').update(bytes).digest('hex');\nconst result = (output: JsonValue, modelText: string): ToolExecuteResult<JsonValue> => ({\n output,\n modelText,\n filesTouched: [],\n});\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\nconst requiredPath = (value: string | undefined, message: string): string =>\n value ?? fail('permission/path-outside-grant', message);\nconst make = (\n name: ReadName,\n execute: (\n input: JsonValue,\n n: NormalizedCall,\n ctx: ToolExecContext,\n signal: AbortSignal,\n ) => Promise<ToolExecuteResult<JsonValue>>,\n): ToolImplementation => {\n const metadata = row(name);\n return {\n ...metadata,\n plan: (input, n): ToolPlan => ({\n kind: 'tool.read',\n replayClass: 'idempotent',\n verify: { tool: name, input, normalized: JSON.parse(JSON.stringify(n)) as JsonValue },\n }),\n execute,\n verifyAfterCrash: async (_record: EffectRecord) => 'done',\n describeForNote: (record) => `${name} ${record.idempotencyKey}`,\n };\n};\n\nconst readFileTool = make('read_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'read was cancelled');\n const target = requiredPath(n.paths[0]?.resolved.canonical, 'read_file has no resolved path');\n const bytes = await readFile(target);\n if (bytes.byteLength > 256 * 1024) fail('tool-terminal/output-too-large', 'file exceeds the 256 KiB read limit');\n if (bytes.includes(0)) fail('tool-terminal/binary-file', 'binary files are not returned as text');\n const value = input as { path: string; offset?: number; limit?: number };\n const offset = value.offset ?? 0;\n const selected = bytes\n .toString('utf8')\n .split(/\\r?\\n/)\n .slice(offset, value.limit === undefined ? undefined : offset + value.limit);\n const text = selected.map((line, index) => `${offset + index + 1}: ${line}`).join('\\n');\n return result(\n { path: n.paths[0]?.resolved.relative ?? value.path, text, sha256: sha256(bytes), offset, lines: selected.length },\n text,\n );\n});\n\nconst walk = async (root: string, current: string, output: string[], max: number): Promise<void> => {\n if (output.length >= max) return;\n for (const entry of await readdir(current, { withFileTypes: true })) {\n if (entry.name === '.git' || entry.name === '.cohorte' || entry.name === '.pi' || entry.isSymbolicLink()) continue;\n const absolute = join(current, entry.name);\n if (entry.isDirectory()) await walk(root, absolute, output, max);\n else output.push(relative(root, absolute).split('\\\\').join('/'));\n if (output.length >= max) return;\n }\n};\nconst globMatch = (value: string, pattern?: string): boolean => {\n if (!pattern || pattern === '**') return true;\n const escaped = pattern\n .replace(/[.*+?^()|[\\]\\\\]/g, '\\\\$&')\n .replaceAll('\\\\*\\\\*', '.*')\n .replaceAll('\\\\*', '[^/]*')\n .replaceAll('\\\\?', '[^/]');\n return new RegExp(`^${escaped}$`).test(value);\n};\n\nconst listFilesTool = make('list_files', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'listing was cancelled');\n const root = requiredPath(n.paths[0]?.resolved.canonical, 'list_files has no resolved root');\n const value = input as { glob?: string; maxEntries?: number };\n const files: string[] = [];\n await walk(root, root, files, value.maxEntries ?? 1000);\n const filtered = files.filter((file) => globMatch(file, value.glob));\n return result({ files: filtered, truncated: files.length >= (value.maxEntries ?? 1000) }, filtered.join('\\n'));\n});\n\nconst searchTool = make('search', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'search was cancelled');\n const root = requiredPath(n.paths[0]?.resolved.canonical, 'search has no resolved root');\n const value = input as { pattern: string; caseInsensitive?: boolean; glob?: string; maxMatches?: number };\n const expression = new RegExp(value.pattern, value.caseInsensitive ? 'i' : '');\n const files: string[] = [];\n await walk(root, root, files, 10_000);\n const matches: { path: string; line: number; text: string }[] = [];\n for (const file of files.filter((candidate) => globMatch(candidate, value.glob))) {\n if (matches.length >= (value.maxMatches ?? 100)) break;\n const text = await readFile(join(root, file), 'utf8').catch(() => undefined);\n if (text === undefined) continue;\n text.split(/\\r?\\n/).forEach((line, index) => {\n if (matches.length < (value.maxMatches ?? 100) && expression.test(line))\n matches.push({ path: file, line: index + 1, text: line });\n });\n }\n return result(\n { matches, filteredPaths: 0 },\n matches.map((match) => `${match.path}:${match.line}:${match.text}`).join('\\n'),\n );\n});\n\nconst gitDiffTool = make('git_diff', async (input, _n, ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'diff was cancelled');\n const value = input as { base?: 'run-base' | 'integration' | 'checkpoint'; stat?: boolean };\n const output = await ctx.git.diffBySurface({\n repo: ctx.workspaceRoot,\n base: value.base ?? 'integration',\n head: 'HEAD',\n surfaces: { surfaceOf: () => 'shared' },\n });\n const text = output.map((item) => new TextDecoder().decode(item.patch.bytes)).join('\\\\n');\n return result(\n {\n base: value.base ?? 'integration',\n stat: value.stat ?? false,\n files: output.flatMap((item) => item.files),\n diff: text,\n },\n text,\n );\n});\n\nexport const READ_TOOLS: Readonly<Record<ReadName, ToolImplementation>> = Object.freeze({\n read_file: readFileTool,\n list_files: listFilesTool,\n search: searchTool,\n git_diff: gitDiffTool,\n});\n","// The Wave-0 seam of every catalogue tool. It lives in its own module — not in `./index.ts` — so that `./index.ts`\n// can assemble `TOOL_CATALOGUE` from `impl/**` (DESIGN 2.7) while `impl/**` keeps importing the stub: the edge runs\n// `index.ts -> impl/** -> stub.ts` in one direction only.\nimport type { JsonValue } from '@cohorte/base';\nimport { NotImplemented } from '@cohorte/base';\nimport { CATALOGUE_ROWS } from './schemas.ts';\nimport type { ToolExecuteResult, ToolImplementation, ToolPlan } from './types.ts';\n\nconst rowByName = new Map(CATALOGUE_ROWS.map((row) => [row.name, row]));\n\n/**\n * Every deliverable of THIS unit (U0.08) ends here: a `ToolImplementation` whose `plan`/`execute`/`verifyAfterCrash`\n * /`describeForNote` throw. The metadata (`name`, `inputSchema`, `description`, `effect`, `terminal`) is real —\n * `impl/read`, `impl/write`, `impl/exec` and `impl/state` (Wave 2: `U2.03`, `U2.04`) call this for every tool they\n * do not yet implement, and REPLACE the body, never the metadata, one tool at a time.\n */\nexport function stubImplementation(name: string): ToolImplementation {\n const row = rowByName.get(name);\n if (!row) throw new RangeError(`stubImplementation: unknown tool ${JSON.stringify(name)}`);\n const notImplemented = (member: string): never => {\n throw new NotImplemented(`tools/${name}.${member} (Wave 2 fills packages/tools/src/impl/**)`);\n };\n return {\n name: row.name,\n inputSchema: row.inputSchema,\n description: row.description,\n effect: row.effect,\n terminal: row.terminal,\n plan(): ToolPlan | null {\n return notImplemented('plan');\n },\n execute(): Promise<ToolExecuteResult<JsonValue>> {\n return notImplemented('execute');\n },\n verifyAfterCrash(): Promise<'done' | 'not-done' | 'in-doubt'> {\n return notImplemented('verifyAfterCrash');\n },\n describeForNote(): string {\n return notImplemented('describeForNote');\n },\n };\n}\n","import type { JsonValue } from '@cohorte/base';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport { stubImplementation } from '../../catalogue/stub.ts';\nimport type { ToolImplementation } from '../../catalogue/types.ts';\n\nexport const STATE_TOOL_NAMES = [\n 'approval_request',\n 'submit_result',\n 'git_commit',\n 'network_request',\n 'secret_read',\n] as const;\n\nconst metadata = (name: (typeof STATE_TOOL_NAMES)[number]) => {\n const row = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (row === undefined) throw new Error(`missing catalogue row: ${name}`);\n return row;\n};\n\nconst approvalRequest: ToolImplementation = {\n ...metadata('approval_request'),\n plan: () => null,\n execute: async (input, _normalized, ctx) => {\n const value = input as { question: string; options?: string[] };\n const decision = await ctx.requestApproval(value.question, value.options);\n return {\n output: decision as unknown as JsonValue,\n modelText: decision.answer ?? decision.decision,\n filesTouched: [],\n };\n },\n verifyAfterCrash: async () => 'done',\n describeForNote: () => 'approval request',\n};\n\nconst submitResult: ToolImplementation = {\n ...metadata('submit_result'),\n plan: () => null,\n execute: async (input, _normalized, ctx) => {\n const accepted = await ctx.acceptResult(input as never);\n if (!accepted.accepted) throw new Error(`validation/agent-output: ${accepted.reason ?? 'result was rejected'}`);\n return { output: { accepted: true }, modelText: 'result submitted', filesTouched: [] };\n },\n verifyAfterCrash: async () => 'done',\n describeForNote: () => 'submit result',\n};\n\nexport const STATE_TOOLS: Readonly<Record<(typeof STATE_TOOL_NAMES)[number], ToolImplementation>> = Object.freeze({\n approval_request: approvalRequest,\n submit_result: submitResult,\n git_commit: stubImplementation('git_commit'),\n network_request: stubImplementation('network_request'),\n secret_read: stubImplementation('secret_read'),\n});\n","import { createHash } from 'node:crypto';\nimport { readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { type JsonValue, type Sha256, sha256Hex } from '@cohorte/base';\nimport type { EffectRecord } from '@cohorte/persistence/contract';\nimport { CATALOGUE_ROWS } from '../../catalogue/schemas.ts';\nimport type {\n NormalizedCall,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from '../../catalogue/types.ts';\n\nexport const WRITE_TOOL_NAMES = ['write_file', 'patch_file'] as const;\ntype WriteName = (typeof WRITE_TOOL_NAMES)[number];\nconst row = (name: WriteName) => {\n const entry = CATALOGUE_ROWS.find((candidate) => candidate.name === name);\n if (entry === undefined) throw new Error(`missing catalogue row: ${name}`);\n return entry;\n};\nconst digest = (value: Uint8Array | string): Sha256 => sha256Hex(createHash('sha256').update(value).digest());\nconst fail = (code: string, message: string): never => {\n throw new Error(`${code}: ${message}`);\n};\nconst requiredPath = (n: NormalizedCall): string =>\n n.paths[0]?.resolved.canonical ?? fail('permission/path-outside-grant', 'write tool has no resolved path');\nconst result = (\n output: JsonValue,\n modelText: string,\n filesTouched: ToolExecuteResult<JsonValue>['filesTouched'],\n): ToolExecuteResult<JsonValue> => ({ output, modelText, filesTouched });\n\nconst make = (\n name: WriteName,\n execute: (\n input: JsonValue,\n n: NormalizedCall,\n ctx: ToolExecContext,\n signal: AbortSignal,\n ) => Promise<ToolExecuteResult<JsonValue>>,\n): ToolImplementation => {\n const metadata = row(name);\n return {\n ...metadata,\n plan: (input, _n): ToolPlan => ({\n kind: name === 'write_file' ? 'tool.write_file' : 'tool.patch_file',\n replayClass: 'verifiable',\n verify: { tool: name, input },\n }),\n execute,\n verifyAfterCrash: async (record: EffectRecord, ctx: ToolExecContext) => {\n const request = record.request as unknown as { path?: string; content?: string };\n if (!request.path) return 'in-doubt';\n try {\n const path = ctx.paths.resolve(request.path, ctx.workspaceRoot, 'read');\n if (!path.ok) return 'in-doubt';\n const bytes = await readFile(path.value.canonical);\n return request.content !== undefined && digest(bytes) === digest(request.content) ? 'done' : 'not-done';\n } catch {\n return 'not-done';\n }\n },\n describeForNote: (record) => `${name} ${record.idempotencyKey}`,\n };\n};\n\nconst atomicWrite = async (target: string, content: string): Promise<void> => {\n const temporary = join(dirname(target), `.cohorte-write-${process.pid}-${Date.now()}`);\n await writeFile(temporary, content, { encoding: 'utf8', flag: 'wx' });\n await rename(temporary, target);\n};\n\nconst writeFileTool = make('write_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'write was cancelled');\n const target = requiredPath(n);\n const value = input as { path: string; content: string };\n let before: Uint8Array | undefined;\n try {\n before = await readFile(target);\n } catch {\n /* create */\n }\n await atomicWrite(target, value.content);\n const after = Buffer.from(value.content);\n const path = n.paths[0]?.resolved.relative ?? value.path;\n return result({ path, bytes: after.byteLength, sha256: digest(after) }, `wrote ${after.byteLength} bytes`, [\n {\n path,\n op: before === undefined ? 'create' : 'modify',\n ...(before === undefined ? {} : { beforeSha256: digest(before) }),\n afterSha256: digest(after),\n bytes: after.byteLength,\n },\n ]);\n});\n\nconst patchFileTool = make('patch_file', async (input, n, _ctx, signal) => {\n if (signal.aborted) fail('tool-transient/cancelled', 'patch was cancelled');\n const target = requiredPath(n);\n const value = input as { path: string; edits: { oldText: string; newText: string }[] };\n const before = await readFile(target, 'utf8');\n let next = before;\n for (const edit of value.edits) {\n const count = next.split(edit.oldText).length - 1;\n if (count !== 1) fail('tool-terminal/patch-mismatch', `expected one occurrence, found ${count}`);\n next = next.replace(edit.oldText, edit.newText);\n }\n await atomicWrite(target, next);\n const after = Buffer.from(next);\n const path = n.paths[0]?.resolved.relative ?? value.path;\n return result(\n { path, bytes: after.byteLength, sha256: digest(after), edits: value.edits.length },\n `patched ${path}`,\n [\n {\n path,\n op: 'modify',\n beforeSha256: digest(Buffer.from(before)),\n afterSha256: digest(after),\n bytes: after.byteLength,\n },\n ],\n );\n});\n\nexport const WRITE_TOOLS: Readonly<Record<WriteName, ToolImplementation>> = Object.freeze({\n write_file: writeFileTool,\n patch_file: patchFileTool,\n});\n","// @cohorte/tools/catalogue — DESIGN 2.7, frozen in Wave 0: both the prompts and the fake scripts meet on these\n// shapes. `toToolGrant` is the ONLY place a `ToolGrant` (what the brain sees) is minted from the catalogue's own\n// data, and it is where the flat-schema rule is ASSERTED, not merely hoped for.\n\nimport type { JsonValue } from '@cohorte/base';\nimport { toStrictSchema } from '@cohorte/protocol';\nimport {\n TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS,\n type ToolGrant,\n ToolGrant as ToolGrantSchema,\n toolGrantProblems,\n} from '@cohorte/runtime-contract';\nimport type { ToolIntrospection } from '@cohorte/security/contract';\nimport { Compile } from 'typebox/compile';\nimport { EXEC_TOOLS } from '../impl/exec/index.ts';\nimport { READ_TOOLS } from '../impl/read/index.ts';\nimport { STATE_TOOLS } from '../impl/state/index.ts';\nimport { WRITE_TOOLS } from '../impl/write/index.ts';\nimport { CATALOGUE_ROWS } from './schemas.ts';\nimport type { ToolImplementation } from './types.ts';\n\nexport type {\n ApprovalRequestInput,\n CatalogueRow,\n GitCommitInput,\n GitDiffInput,\n ListFilesInput,\n NetworkRequestInput,\n PatchFileInput,\n PathArg,\n PathIntent,\n ReadFileInput,\n RunCommandInput,\n SearchInput,\n SecretReadInput,\n WriteFileInput,\n} from './schemas.ts';\nexport { CATALOGUE_ROWS, GIT_DIFF_BASES, SEAM_TOOL_NAMES, TOOL_NAMES } from './schemas.ts';\nexport { stubImplementation } from './stub.ts';\nexport type {\n EffectIntent,\n EffectKind,\n EffectRecord,\n NormalizedCall,\n ReplayClass,\n ToolExecContext,\n ToolExecuteResult,\n ToolImplementation,\n ToolPlan,\n} from './types.ts';\n\nconst rowByName = new Map(CATALOGUE_ROWS.map((row) => [row.name, row]));\n\n/** `ToolIntrospection` is on the per-tool-call path (PLAN PC-4: the gate validates a call's shape without importing\n * `tools`), so the strict schema of every row is built ONCE, here: `schemaOf` returns the same object identity on\n * every call and a validator cache keyed by schema identity in the gate (U2.01/U2.02) keeps working. */\nconst strictSchemaByName = new Map<string, JsonValue>(\n CATALOGUE_ROWS.map((row) => [row.name, toStrictSchema(row.inputSchema) as JsonValue]),\n);\n\n/** One TypeBox compilation for the whole process, not one per minted grant. */\nconst GRANT_CHECK = Compile(ToolGrantSchema);\n\nconst isFlatObjectSchema = (schema: JsonValue): boolean => {\n if (typeof schema !== 'object' || schema === null || Array.isArray(schema)) return false;\n const record = schema as Record<string, JsonValue>;\n if (record.type !== 'object') return false;\n return TOOL_INPUT_SCHEMA_FORBIDDEN_ROOT_KEYS.every((key) => !(key in record));\n};\n\n/**\n * Mints the `ToolGrant` (what the brain sees) of one catalogue tool: the closed, strict form of its schema\n * (`toStrictSchema`, the same generator `@cohorte/protocol` uses everywhere else — DESIGN 0.1 C3), asserted to be\n * ONE flat top-level object with no `$ref`/`$defs`/`oneOf`/`anyOf`/`allOf` at the root (DESIGN 2.7).\n */\nexport function toToolGrant(name: string): ToolGrant {\n const row = rowByName.get(name);\n if (!row) throw new RangeError(`toToolGrant: unknown tool ${JSON.stringify(name)}`);\n const inputSchema = strictSchemaByName.get(name);\n if (inputSchema === undefined || !isFlatObjectSchema(inputSchema)) {\n throw new TypeError(`toToolGrant: ${name}'s input schema is not one flat top-level object`);\n }\n const grant: ToolGrant = {\n tool: row.name,\n description: row.description,\n inputSchema,\n effect: row.effect,\n terminal: row.terminal,\n };\n const problems = GRANT_CHECK.Errors(grant);\n const first = problems[0];\n if (first) throw new TypeError(`toToolGrant: ${name} does not validate against ToolGrant: ${first.message}`);\n return grant;\n}\n\nconst namingProblems = toolGrantProblems(CATALOGUE_ROWS.map((row) => ({ tool: row.name })));\nif (namingProblems.length > 0) throw new TypeError(`tool catalogue: ${namingProblems.join('; ')}`);\n\n/** Catalogue-derived: never a second, hand-written copy of what a tool's input schema says (PLAN PC-4: `security`\n * validates a call's shape and path arguments without importing `tools`). */\nexport const toolIntrospection: ToolIntrospection = {\n schemaOf(tool) {\n return strictSchemaByName.get(tool);\n },\n pathArgsOf(tool, input) {\n const row = rowByName.get(tool);\n if (!row) return [];\n return row.pathArgsOf(input);\n },\n};\n\n/** The 9 V3.0 tools + the 3 seams, by name (DESIGN 2.7). Every value is `stubImplementation(name)` until Wave 2\n * replaces the bodies in `impl/**`; the metadata is already the catalogue's own. */\nexport const TOOL_CATALOGUE: Readonly<Record<string, ToolImplementation>> = Object.freeze({\n ...READ_TOOLS,\n ...WRITE_TOOLS,\n ...EXEC_TOOLS,\n ...STATE_TOOLS,\n});\n"],"mappings":"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"}