cohorte 2.10.1 → 3.0.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +7 -0
  2. package/assets/manifest.json +193 -0
  3. package/assets/migrations/config/README.md +12 -0
  4. package/assets/migrations/state/0001_init.sql +154 -0
  5. package/assets/prompts/README.md +11 -0
  6. package/assets/prompts/agents/fixer.md +7 -0
  7. package/assets/prompts/agents/implementer.md +12 -0
  8. package/assets/prompts/agents/reviewer.md +8 -0
  9. package/assets/prompts/agents/security-reviewer.md +7 -0
  10. package/assets/prompts/phases/build.md +5 -0
  11. package/assets/prompts/phases/review.md +5 -0
  12. package/assets/prompts/phases/test.md +5 -0
  13. package/assets/prompts/system.md +11 -0
  14. package/assets/schemas/agent-output.schema.json +225 -0
  15. package/assets/schemas/auth-status.schema.json +87 -0
  16. package/assets/schemas/command-result.schema.json +192 -0
  17. package/assets/schemas/commands.schema.json +952 -0
  18. package/assets/schemas/config.schema.json +2259 -0
  19. package/assets/schemas/doctor-report.schema.json +104 -0
  20. package/assets/schemas/events.schema.json +8514 -0
  21. package/assets/schemas/fake-script.schema.json +549 -0
  22. package/assets/schemas/inspect.schema.json +3133 -0
  23. package/assets/schemas/manifest.schema.json +79 -0
  24. package/assets/schemas/ownership.schema.json +52 -0
  25. package/assets/schemas/policy-verdict.schema.json +282 -0
  26. package/assets/schemas/project-model.schema.json +783 -0
  27. package/assets/schemas/project-status.schema.json +217 -0
  28. package/assets/schemas/reconcile-plan.schema.json +155 -0
  29. package/assets/schemas/run-diff.schema.json +177 -0
  30. package/assets/schemas/run-snapshot-manifest.schema.json +2104 -0
  31. package/assets/schemas/run-state.schema.json +1755 -0
  32. package/assets/schemas/runtime-capabilities.schema.json +1545 -0
  33. package/assets/schemas/sandbox-capabilities.schema.json +116 -0
  34. package/assets/schemas/skill.schema.json +87 -0
  35. package/assets/schemas/spec.schema.json +202 -0
  36. package/assets/schemas/tool-catalogue.schema.json +655 -0
  37. package/assets/schemas/trust-record.schema.json +38 -0
  38. package/assets/skills/README.md +9 -0
  39. package/assets/skills/inspect-surface.md +4 -0
  40. package/dist/agent-host.mjs +50 -0
  41. package/dist/agent-host.mjs.map +1 -0
  42. package/dist/bundle-manifest.json +102 -0
  43. package/dist/chunks/__host-DgGPyco9.mjs +18 -0
  44. package/dist/chunks/__host-DgGPyco9.mjs.map +1 -0
  45. package/dist/chunks/approve-Cv135UqI.mjs +19 -0
  46. package/dist/chunks/approve-Cv135UqI.mjs.map +1 -0
  47. package/dist/chunks/auth-BT5oVp76.mjs +132 -0
  48. package/dist/chunks/auth-BT5oVp76.mjs.map +1 -0
  49. package/dist/chunks/auth-D8rCVY33.mjs +84 -0
  50. package/dist/chunks/auth-D8rCVY33.mjs.map +1 -0
  51. package/dist/chunks/brainstorm-CU10T1tm.mjs +7 -0
  52. package/dist/chunks/brainstorm-CU10T1tm.mjs.map +1 -0
  53. package/dist/chunks/cancel-KV_cpsqS.mjs +15 -0
  54. package/dist/chunks/cancel-KV_cpsqS.mjs.map +1 -0
  55. package/dist/chunks/canonical-C8UxeEmB.mjs +57 -0
  56. package/dist/chunks/canonical-C8UxeEmB.mjs.map +1 -0
  57. package/dist/chunks/catalogue-BvwSrM_j.mjs +1549 -0
  58. package/dist/chunks/catalogue-BvwSrM_j.mjs.map +1 -0
  59. package/dist/chunks/compose-Cr0hP0qm.mjs +7303 -0
  60. package/dist/chunks/compose-Cr0hP0qm.mjs.map +1 -0
  61. package/dist/chunks/config-DefHA2Lw.mjs +96 -0
  62. package/dist/chunks/config-DefHA2Lw.mjs.map +1 -0
  63. package/dist/chunks/contract-B0ra2-bm.mjs +295 -0
  64. package/dist/chunks/contract-B0ra2-bm.mjs.map +1 -0
  65. package/dist/chunks/contract-vYbwYr0Y.mjs +123 -0
  66. package/dist/chunks/contract-vYbwYr0Y.mjs.map +1 -0
  67. package/dist/chunks/deny-ClTxSvHJ.mjs +15 -0
  68. package/dist/chunks/deny-ClTxSvHJ.mjs.map +1 -0
  69. package/dist/chunks/diff-Qw0II0sj.mjs +101 -0
  70. package/dist/chunks/diff-Qw0II0sj.mjs.map +1 -0
  71. package/dist/chunks/discover-30Ciya_0.mjs +20 -0
  72. package/dist/chunks/discover-30Ciya_0.mjs.map +1 -0
  73. package/dist/chunks/doctor-DfCrKpfT.mjs +222 -0
  74. package/dist/chunks/doctor-DfCrKpfT.mjs.map +1 -0
  75. package/dist/chunks/fix-D4Tj8RVA.mjs +18 -0
  76. package/dist/chunks/fix-D4Tj8RVA.mjs.map +1 -0
  77. package/dist/chunks/gc-BBXlBF5w.mjs +161 -0
  78. package/dist/chunks/gc-BBXlBF5w.mjs.map +1 -0
  79. package/dist/chunks/init-Okz4mlhW.mjs +30 -0
  80. package/dist/chunks/init-Okz4mlhW.mjs.map +1 -0
  81. package/dist/chunks/inspect-Buby4cQD.mjs +22 -0
  82. package/dist/chunks/inspect-Buby4cQD.mjs.map +1 -0
  83. package/dist/chunks/logs-Giq5sUau.mjs +25 -0
  84. package/dist/chunks/logs-Giq5sUau.mjs.map +1 -0
  85. package/dist/chunks/migrate-DRoFUg53.mjs +19 -0
  86. package/dist/chunks/migrate-DRoFUg53.mjs.map +1 -0
  87. package/dist/chunks/models-Btp6X2YZ.mjs +24 -0
  88. package/dist/chunks/models-Btp6X2YZ.mjs.map +1 -0
  89. package/dist/chunks/pause-BASBfKLO.mjs +16 -0
  90. package/dist/chunks/pause-BASBfKLO.mjs.map +1 -0
  91. package/dist/chunks/policy-DUIgzF3W.mjs +139 -0
  92. package/dist/chunks/policy-DUIgzF3W.mjs.map +1 -0
  93. package/dist/chunks/providers-Dx78imKj.mjs +19 -0
  94. package/dist/chunks/providers-Dx78imKj.mjs.map +1 -0
  95. package/dist/chunks/reconcile-BfD785gd.mjs +26 -0
  96. package/dist/chunks/reconcile-BfD785gd.mjs.map +1 -0
  97. package/dist/chunks/render-DyZr5Lgi.mjs +53 -0
  98. package/dist/chunks/render-DyZr5Lgi.mjs.map +1 -0
  99. package/dist/chunks/resume-GJQRb2Eb.mjs +15 -0
  100. package/dist/chunks/resume-GJQRb2Eb.mjs.map +1 -0
  101. package/dist/chunks/retry-CLrUem1H.mjs +15 -0
  102. package/dist/chunks/retry-CLrUem1H.mjs.map +1 -0
  103. package/dist/chunks/review-BDdjb6kB.mjs +17 -0
  104. package/dist/chunks/review-BDdjb6kB.mjs.map +1 -0
  105. package/dist/chunks/run-CgTWYlcd.mjs +82 -0
  106. package/dist/chunks/run-CgTWYlcd.mjs.map +1 -0
  107. package/dist/chunks/run-tool-C3rAv4XF.mjs +26 -0
  108. package/dist/chunks/run-tool-C3rAv4XF.mjs.map +1 -0
  109. package/dist/chunks/schema-C9QbUW4H.mjs +578 -0
  110. package/dist/chunks/schema-C9QbUW4H.mjs.map +1 -0
  111. package/dist/chunks/send-BdnJ85Nz.mjs +19 -0
  112. package/dist/chunks/send-BdnJ85Nz.mjs.map +1 -0
  113. package/dist/chunks/ship-DTuLGoaJ.mjs +19 -0
  114. package/dist/chunks/ship-DTuLGoaJ.mjs.map +1 -0
  115. package/dist/chunks/shutdown-BM92Iyv2.mjs +15 -0
  116. package/dist/chunks/shutdown-BM92Iyv2.mjs.map +1 -0
  117. package/dist/chunks/skip-DZG5kpcH.mjs +18 -0
  118. package/dist/chunks/skip-DZG5kpcH.mjs.map +1 -0
  119. package/dist/chunks/spec-Bq0P3jVh.mjs +20 -0
  120. package/dist/chunks/spec-Bq0P3jVh.mjs.map +1 -0
  121. package/dist/chunks/src-CId6kMsY.mjs +1689 -0
  122. package/dist/chunks/src-CId6kMsY.mjs.map +1 -0
  123. package/dist/chunks/src-CfAOde7C.mjs +5403 -0
  124. package/dist/chunks/src-CfAOde7C.mjs.map +1 -0
  125. package/dist/chunks/src-Cu3TxNob.mjs +783 -0
  126. package/dist/chunks/src-Cu3TxNob.mjs.map +1 -0
  127. package/dist/chunks/src-DcU4IXMe.mjs +117 -0
  128. package/dist/chunks/src-DcU4IXMe.mjs.map +1 -0
  129. package/dist/chunks/src-JxawBQBn.mjs +446 -0
  130. package/dist/chunks/src-JxawBQBn.mjs.map +1 -0
  131. package/dist/chunks/src-s7YRvk0t.mjs +2116 -0
  132. package/dist/chunks/src-s7YRvk0t.mjs.map +1 -0
  133. package/dist/chunks/status-SMjiOMYy.mjs +29 -0
  134. package/dist/chunks/status-SMjiOMYy.mjs.map +1 -0
  135. package/dist/chunks/tail-BuhT-2PH.mjs +25 -0
  136. package/dist/chunks/tail-BuhT-2PH.mjs.map +1 -0
  137. package/dist/chunks/update-BXIppsbi.mjs +16 -0
  138. package/dist/chunks/update-BXIppsbi.mjs.map +1 -0
  139. package/dist/cli.mjs +175 -0
  140. package/dist/cli.mjs.map +1 -0
  141. package/package.json +17 -32
  142. package/CHANGELOG.md +0 -1461
  143. package/bin/cli.js +0 -817
  144. package/bin/report.js +0 -141
  145. package/core/adapter/render.js +0 -415
  146. package/core/agents/implementer.template.md +0 -142
  147. package/core/agents/profile-reader.md +0 -50
  148. package/core/agents/release.md +0 -58
  149. package/core/agents/review.md +0 -179
  150. package/core/commands/cohorte-align-ds.md +0 -33
  151. package/core/commands/cohorte-audit.md +0 -58
  152. package/core/commands/cohorte-brainstorm.md +0 -70
  153. package/core/commands/cohorte-build.md +0 -219
  154. package/core/commands/cohorte-doctor.md +0 -194
  155. package/core/commands/cohorte-fix.md +0 -80
  156. package/core/commands/cohorte-fleet.md +0 -103
  157. package/core/commands/cohorte-init-pipeline.md +0 -31
  158. package/core/commands/cohorte-intake.md +0 -92
  159. package/core/commands/cohorte-patch.md +0 -118
  160. package/core/commands/cohorte-refactor.md +0 -59
  161. package/core/commands/cohorte-retro.md +0 -85
  162. package/core/commands/cohorte-review.md +0 -270
  163. package/core/commands/cohorte-ship.md +0 -122
  164. package/core/commands/cohorte-spec.md +0 -101
  165. package/core/commands/cohorte-update-pipeline.md +0 -165
  166. package/core/hooks/gate.py +0 -588
  167. package/core/runtimes/claude.json +0 -74
  168. package/core/runtimes/codex.json +0 -85
  169. package/core/runtimes/cursor.json +0 -76
  170. package/core/runtimes/gemini.json +0 -76
  171. package/core/runtimes/opencode.json +0 -73
  172. package/core/templates/agent-handoff.md +0 -34
  173. package/core/templates/brainstorm-return.md +0 -36
  174. package/core/templates/decisions.template.md +0 -42
  175. package/core/templates/design-brief.md +0 -44
  176. package/core/templates/patch.template.md +0 -86
  177. package/core/templates/pr-body.md +0 -25
  178. package/core/templates/review-feedback.md +0 -38
  179. package/core/templates/spec.template.md +0 -87
  180. package/core/templates/steps/init-pipeline/01-detect-stack.md +0 -44
  181. package/core/templates/steps/init-pipeline/02-interview-gaps.md +0 -55
  182. package/core/templates/steps/init-pipeline/03-draft-profile.md +0 -10
  183. package/core/templates/steps/init-pipeline/04-write-render.md +0 -145
  184. package/core/templates/steps/init-pipeline/05-report.md +0 -12
  185. package/core/workflows/audit.js +0 -240
  186. package/core/workflows/loop.js +0 -641
  187. package/core/workflows/refactor.js +0 -276
  188. package/core/workflows/review.js +0 -456
  189. package/install.ps1 +0 -103
  190. package/install.sh +0 -114
  191. package/lib/doctor.js +0 -534
  192. package/lib/runtime.js +0 -139
  193. package/lib/versions.js +0 -149
  194. package/lib/yaml.js +0 -129
  195. package/profile/PIPELINE.template.md +0 -259
  196. package/profile/SCHEMA.md +0 -735
  197. package/profile/cohorte.config.template.yaml +0 -43
  198. package/scripts/assert-gate-hook.mjs +0 -75
  199. package/scripts/kanban-move.sh +0 -313
  200. package/scripts/metrics/collect.mjs +0 -531
  201. package/scripts/metrics/prices.json +0 -42
  202. package/scripts/new-feature.sh.template +0 -98
  203. package/scripts/preflight.sh +0 -124
  204. package/scripts/remove-feature.sh.template +0 -56
  205. package/scripts/test-adapter.mjs +0 -437
  206. package/scripts/test-gate.mjs +0 -443
  207. package/scripts/test-kanban.mjs +0 -304
  208. package/scripts/test-lib.mjs +0 -356
  209. package/scripts/test-metrics.mjs +0 -156
  210. package/scripts/test-workflows.mjs +0 -758
  211. package/scripts/validate-core.mjs +0 -325
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-C9QbUW4H.mjs","names":["closed","closed","closed","closed","names","closed"],"sources":["../../../../packages/config/src/schema/policy.ts","../../../../packages/config/src/schema/config.ts","../../../../packages/config/src/schema/manifest.ts","../../../../packages/config/src/schema/ownership.ts","../../../../packages/config/src/schema/skill.ts","../../../../packages/config/src/schema/spec.ts","../../../../packages/config/src/schema/trust.ts"],"sourcesContent":["// Policy DATA shapes (DESIGN 2.6.3, 2.6.4): declared here, evaluated by @cohorte/security. `config` never imports `security`.\nimport { type Static, type TUnsafe, Type } from 'typebox';\n\nconst closed = { additionalProperties: false } as const;\nconst tokens = () => Type.Array(Type.String({ minLength: 1 }));\n\nexport const COMMAND_RULE_ORIGINS = ['builtin', 'project-config', 'project-checks'] as const;\n\n/** DESIGN 2.6.4, verbatim. */\nexport interface CommandRule {\n id: string;\n program: string;\n /** exact tokens, e.g. ['run','test'] */\n subcommand?: readonly string[];\n /** anything not allowed is denied */\n flags?: { allow: readonly string[]; deny?: readonly string[] };\n positionals?:\n | { kind: 'none' }\n | { kind: 'paths-in-worktree'; max: number }\n | { kind: 'enum'; values: readonly string[]; max: number }\n | { kind: 'exact'; values: readonly string[] };\n decision: 'allow' | 'ask' | 'deny';\n when?: { branch?: 'any' | 'unprotected-only'; roles?: readonly string[]; phases?: readonly string[] };\n /** drives recovery (DESIGN 4.1) */\n replay: 'idempotent' | 'at-most-once';\n /** true => denied under L0; under L1 it fails closed in the sandbox */\n network: boolean;\n origin: (typeof COMMAND_RULE_ORIGINS)[number];\n}\n\nconst max = () => Type.Integer({ minimum: 0 });\n\nconst CommandRuleSchema = Type.Object(\n {\n id: Type.String({ minLength: 1 }),\n // A bare program name: a path separator can never name a program (DESIGN 2.6.4 step 1).\n program: Type.String({ pattern: '^[^/\\\\\\\\\\\\s]+$' }),\n subcommand: Type.Optional(tokens()),\n flags: Type.Optional(Type.Object({ allow: tokens(), deny: Type.Optional(tokens()) }, closed)),\n positionals: Type.Optional(\n Type.Union([\n Type.Object({ kind: Type.Literal('none') }, closed),\n Type.Object({ kind: Type.Literal('paths-in-worktree'), max: max() }, closed),\n Type.Object({ kind: Type.Literal('enum'), values: tokens(), max: max() }, closed),\n Type.Object({ kind: Type.Literal('exact'), values: Type.Array(Type.String()) }, closed),\n ]),\n ),\n decision: Type.Union([Type.Literal('allow'), Type.Literal('ask'), Type.Literal('deny')]),\n when: Type.Optional(\n Type.Object(\n {\n branch: Type.Optional(Type.Union([Type.Literal('any'), Type.Literal('unprotected-only')])),\n roles: Type.Optional(tokens()),\n phases: Type.Optional(tokens()),\n },\n closed,\n ),\n ),\n replay: Type.Union([Type.Literal('idempotent'), Type.Literal('at-most-once')]),\n network: Type.Boolean(),\n origin: Type.Union([Type.Literal('builtin'), Type.Literal('project-config'), Type.Literal('project-checks')]),\n },\n closed,\n);\n\n/** [S]. The explicit annotation keeps Biome's type inference out of the union (docs/v3/requests/U0.02.md R1). */\nexport const CommandRule: TUnsafe<CommandRule> = Type.Unsafe<CommandRule>(CommandRuleSchema);\n\n/** [S] DESIGN 2.6.3. Default: deny-outgoing + deny. */\nexport const SymlinkPolicy = Type.Object(\n {\n mode: Type.Union([Type.Literal('deny-outgoing'), Type.Literal('deny-all'), Type.Literal('allow')]),\n hardlinksOnWrite: Type.Union([Type.Literal('deny'), Type.Literal('allow')]),\n },\n closed,\n);\nexport type SymlinkPolicy = Static<typeof SymlinkPolicy>;\n\n/**\n * [S] What stage 4 evaluates for `network_request`. V3.0 has exactly one value: the tool is registered and always\n * denied (DESIGN 2.6.2, §9 \"proxy-based host allowlisting\" is out). The shape exists so a later version can add\n * an allowlist without moving the type.\n */\nexport const NetworkPolicyConfig = Type.Object({ default: Type.Literal('deny') }, closed);\nexport type NetworkPolicyConfig = Static<typeof NetworkPolicyConfig>;\n\nexport const DEFAULT_SYMLINK_POLICY: SymlinkPolicy = Object.freeze({ mode: 'deny-outgoing', hardlinksOnWrite: 'deny' });\nexport const DEFAULT_NETWORK_POLICY: NetworkPolicyConfig = Object.freeze({ default: 'deny' });\n","// `.cohorte/config.yaml` (DESIGN 2.10). NO open question of spec 32 is frozen as a literal type: `runtime.id`,\n// provider names and role keys are open strings; what 3.0 accepts among them is a LOADER rule, not a schema rule.\nimport { AuthMode, BudgetCounters, ID_PATTERN, ModelCapability, ModelRef, ThinkingLevel } from '@cohorte/base';\nimport { ActivePipelineState, type CohorteRole, EscalationPolicy } from '@cohorte/protocol';\nimport { type TUnsafe, Type } from 'typebox';\nimport { CommandRule, DEFAULT_SYMLINK_POLICY, SymlinkPolicy } from './policy.ts';\n\nconst closed = { additionalProperties: false } as const;\n\n/** The ONLY env channel of a provisioning effect (DESIGN 5.7): a closed allowlist of NAMES. */\nexport const PROVISION_ENV_NAMES = [\n 'npm_config_store_dir',\n 'npm_config_cache',\n 'YARN_CACHE_FOLDER',\n 'COREPACK_HOME',\n] as const;\nexport type ProvisionEnvName = (typeof PROVISION_ENV_NAMES)[number];\n\nexport interface TierTarget {\n ref: ModelRef;\n thinking: ThinkingLevel;\n}\nexport interface ApprovalsConfig {\n unattended: 'deny' | 'wait';\n expiryMinutes?: number;\n /** 10 */\n parkAfterMinutes: number;\n ship: 'human' | 'auto';\n notify: boolean;\n /** approve may spawn a host */\n autoResume: boolean;\n}\n\n/** DESIGN 2.10, verbatim. [S] schemas/config.schema.json */\nexport interface CohorteConfig {\n schemaVersion: 1;\n project: { id: string; defaultBranch: string; protectedBranches: string[] };\n runtime: { id: string /* 'pi' | 'fake' */; pi?: { loadFrom: 'package' | 'bundle' } };\n authentication: {\n mode: AuthMode;\n allowApiKeys: boolean;\n /** D2: all three true; accounted METERED (DESIGN 3.7) */\n anthropicSubscriptionViaPi?: {\n enabled: boolean;\n acknowledgePerTokenBilling: boolean;\n acknowledgeProviderTermsRisk: boolean;\n };\n };\n routing: {\n allowedProviders: string[];\n defaults: Partial<Record<CohorteRole, ModelCapability>>;\n tiers: Partial<Record<ModelCapability, TierTarget>>;\n escalation: EscalationPolicy;\n fallback: { enabled: boolean };\n };\n budgets: {\n run: BudgetCounters;\n phase: BudgetCounters;\n agent: BudgetCounters;\n provider: Record<string, BudgetCounters>;\n tool: Record<string, BudgetCounters>;\n /** 3 */\n concurrency: number;\n /** 5 */\n maxIncarnations: number;\n };\n loop: {\n maxFixRounds: number;\n noProgressWindow: number;\n maxDeniedCallsPerAgent: number;\n leftovers: Record<'major' | 'minor' | 'info', 'fix' | 'park' | 'ask'>;\n };\n /** argv arrays */\n checks: { typecheck?: string[]; lint?: string[]; test?: string[]; timeoutMs: number };\n provision: {\n argv?: string[];\n network: boolean;\n cacheDirs: string[];\n lockfiles: string[];\n env: Partial<Record<ProvisionEnvName, string>>;\n // default: every node_modules directory; read-only for agent commands and checks\n dependencyDirs: string[];\n /** writable, excluded from the dependency manifest, wiped before every check sequence */\n writableCaches: string[];\n };\n policy: {\n commands: { allow: CommandRule[]; ask: CommandRule[]; deny: CommandRule[] };\n dangerousCommands: CommandRule[];\n symlinks: SymlinkPolicy;\n approvals: ApprovalsConfig;\n /** default ask: an in-doubt effect needs a human ack before the agent continues (DESIGN 4.4) */\n inDoubt: 'ask' | 'continue';\n skip: ActivePipelineState[];\n steer: { enabled: boolean };\n admin: { runTool: boolean };\n quota: { autoResume: boolean };\n };\n host: { idleExitMinutes: number; pauseKeepAliveMinutes: number; pollMs: number };\n /** forward HTTP(S)_PROXY to the brain; default false */\n network: { proxyEnv: boolean };\n /** `require` absent = the computed default of DESIGN 2.6.6 */\n sandbox: { require?: 'native' | 'best-effort'; brain: 'os-if-available' | 'os' | 'process' };\n git: {\n worktreeRoot?: string;\n branchPrefix: string;\n commitIdentity: 'user' | 'cohorte';\n keepWorktrees: 'on-failure' | 'always' | 'never';\n };\n retention: {\n transcriptsDays: number;\n eventsDays: number | 'forever';\n artifactsDays: number;\n compressAfterDays: number;\n };\n /** default false; `true` is rejected by the LOADER in 3.0 (configuration/telemetry-remote-unavailable, ADR-0013) */\n telemetry: { remote: boolean };\n}\n\nconst oneOf = <const V extends readonly string[]>(values: V): TUnsafe<V[number]> =>\n Type.Unsafe<V[number]>({ type: 'string', enum: [...values] });\nconst count = (minimum = 0) => Type.Integer({ minimum });\nconst argv = () => Type.Array(Type.String(), { minItems: 1 });\nconst strings = () => Type.Array(Type.String({ minLength: 1 }));\nconst rules = () => Type.Array(CommandRule);\n// Explicit return types: a `Static<TRecord>` that Biome has to infer overflows its stack (docs/v3/requests/U0.03.md R1).\nconst budgetMap = (): TUnsafe<Record<string, BudgetCounters>> =>\n Type.Unsafe<Record<string, BudgetCounters>>(Type.Record(Type.String(), BudgetCounters));\nconst roleDefaults = (): TUnsafe<Partial<Record<CohorteRole, ModelCapability>>> =>\n Type.Unsafe<Partial<Record<CohorteRole, ModelCapability>>>(Type.Record(Type.String(), ModelCapability));\nconst tier = () => Type.Optional(Type.Object({ ref: ModelRef, thinking: ThinkingLevel }, closed));\nconst envValue = () => Type.Optional(Type.String({ minLength: 1 }));\nconst leftover = () => oneOf(['fix', 'park', 'ask']);\n\nconst CohorteConfigSchema = Type.Object(\n {\n schemaVersion: Type.Literal(1),\n project: Type.Object(\n {\n id: Type.String({ pattern: ID_PATTERN }),\n defaultBranch: Type.String({ minLength: 1 }),\n protectedBranches: strings(),\n },\n closed,\n ),\n runtime: Type.Object(\n {\n id: Type.String({ minLength: 1 }),\n pi: Type.Optional(Type.Object({ loadFrom: oneOf(['package', 'bundle']) }, closed)),\n },\n closed,\n ),\n authentication: Type.Object(\n {\n mode: AuthMode,\n allowApiKeys: Type.Boolean(),\n anthropicSubscriptionViaPi: Type.Optional(\n Type.Object(\n {\n enabled: Type.Boolean(),\n acknowledgePerTokenBilling: Type.Boolean(),\n acknowledgeProviderTermsRisk: Type.Boolean(),\n },\n closed,\n ),\n ),\n },\n closed,\n ),\n routing: Type.Object(\n {\n allowedProviders: strings(),\n defaults: roleDefaults(),\n tiers: Type.Object({ fast: tier(), coding: tier(), reasoning: tier(), vision: tier(), cheap: tier() }, closed),\n escalation: EscalationPolicy,\n fallback: Type.Object({ enabled: Type.Boolean() }, closed),\n },\n closed,\n ),\n budgets: Type.Object(\n {\n run: BudgetCounters,\n phase: BudgetCounters,\n agent: BudgetCounters,\n provider: budgetMap(),\n tool: budgetMap(),\n concurrency: count(1),\n maxIncarnations: count(1),\n },\n closed,\n ),\n loop: Type.Object(\n {\n maxFixRounds: count(),\n noProgressWindow: count(1),\n maxDeniedCallsPerAgent: count(),\n leftovers: Type.Object({ major: leftover(), minor: leftover(), info: leftover() }, closed),\n },\n closed,\n ),\n checks: Type.Object(\n {\n typecheck: Type.Optional(argv()),\n lint: Type.Optional(argv()),\n test: Type.Optional(argv()),\n timeoutMs: count(1),\n },\n closed,\n ),\n provision: Type.Object(\n {\n argv: Type.Optional(argv()),\n network: Type.Boolean(),\n cacheDirs: strings(),\n lockfiles: strings(),\n env: Type.Object(\n {\n npm_config_store_dir: envValue(),\n npm_config_cache: envValue(),\n YARN_CACHE_FOLDER: envValue(),\n COREPACK_HOME: envValue(),\n },\n closed,\n ),\n dependencyDirs: strings(),\n writableCaches: strings(),\n },\n closed,\n ),\n policy: Type.Object(\n {\n commands: Type.Object({ allow: rules(), ask: rules(), deny: rules() }, closed),\n dangerousCommands: rules(),\n symlinks: SymlinkPolicy,\n approvals: Type.Object(\n {\n unattended: oneOf(['deny', 'wait']),\n expiryMinutes: Type.Optional(count(1)),\n parkAfterMinutes: count(),\n ship: oneOf(['human', 'auto']),\n notify: Type.Boolean(),\n autoResume: Type.Boolean(),\n },\n closed,\n ),\n inDoubt: oneOf(['ask', 'continue']),\n skip: Type.Array(ActivePipelineState),\n steer: Type.Object({ enabled: Type.Boolean() }, closed),\n admin: Type.Object({ runTool: Type.Boolean() }, closed),\n quota: Type.Object({ autoResume: Type.Boolean() }, closed),\n },\n closed,\n ),\n host: Type.Object({ idleExitMinutes: count(), pauseKeepAliveMinutes: count(), pollMs: count(1) }, closed),\n network: Type.Object({ proxyEnv: Type.Boolean() }, closed),\n sandbox: Type.Object(\n {\n require: Type.Optional(oneOf(['native', 'best-effort'])),\n brain: oneOf(['os-if-available', 'os', 'process']),\n },\n closed,\n ),\n git: Type.Object(\n {\n worktreeRoot: Type.Optional(Type.String({ minLength: 1 })),\n branchPrefix: Type.String({ minLength: 1 }),\n commitIdentity: oneOf(['user', 'cohorte']),\n keepWorktrees: oneOf(['on-failure', 'always', 'never']),\n },\n closed,\n ),\n retention: Type.Object(\n {\n transcriptsDays: count(),\n eventsDays: Type.Union([count(), Type.Literal('forever')]),\n artifactsDays: count(),\n compressAfterDays: count(),\n },\n closed,\n ),\n telemetry: Type.Object({ remote: Type.Boolean() }, closed),\n },\n closed,\n);\n\n/** [S]. Annotated on purpose: Biome must not infer this type (docs/v3/requests/U0.02.md R1, U0.05.md R1). */\nexport const CohorteConfig: TUnsafe<CohorteConfig> = Type.Unsafe<CohorteConfig>(CohorteConfigSchema);\n\nfunction deepFreeze<T>(value: T): T {\n if (typeof value === 'object' && value !== null && !Object.isFrozen(value)) {\n Object.freeze(value);\n for (const member of Object.values(value)) deepFreeze(member);\n }\n return value;\n}\n\nconst MINUTE = 60_000;\n\n/**\n * The lowest layer of the load order (DESIGN 2.10): shipped defaults < user file < project file < CLI flags.\n * `project.id` is a placeholder that `cohorte init` always replaces. DESIGN gives the numbers it cares about\n * (concurrency 3, maxIncarnations 5, loop 5/3/5, host 30/30/250, parkAfterMinutes 10); the budget and retention\n * figures are provisional defaults of this file.\n */\nexport const DEFAULT_CONFIG: CohorteConfig = deepFreeze<CohorteConfig>({\n schemaVersion: 1,\n project: { id: 'project', defaultBranch: 'main', protectedBranches: ['main', 'master'] },\n runtime: { id: 'pi', pi: { loadFrom: 'package' } },\n authentication: { mode: 'subscription', allowApiKeys: false },\n routing: {\n allowedProviders: ['openai-codex'],\n defaults: { implementer: 'coding', fixer: 'coding', reviewer: 'reasoning', 'security-reviewer': 'reasoning' },\n tiers: {\n coding: { ref: { provider: 'openai-codex', model: 'gpt-5.5', capability: 'coding' }, thinking: 'medium' },\n reasoning: { ref: { provider: 'openai-codex', model: 'gpt-5.5', capability: 'reasoning' }, thinking: 'high' },\n fast: { ref: { provider: 'openai-codex', model: 'gpt-5.4-mini', capability: 'fast' }, thinking: 'low' },\n cheap: { ref: { provider: 'openai-codex', model: 'gpt-5.4-mini', capability: 'cheap' }, thinking: 'low' },\n },\n escalation: { sameFailureCount: 2, ladder: [{ kind: 'human' }], maxPerRun: 2 },\n fallback: { enabled: false },\n },\n budgets: {\n run: { modelRequests: 2000, toolCalls: 10_000, wallClockMs: 360 * MINUTE },\n phase: { wallClockMs: 120 * MINUTE },\n agent: { modelRequests: 200, toolCalls: 400, wallClockMs: 45 * MINUTE, contextTokens: 200_000 },\n provider: {},\n tool: {},\n concurrency: 3,\n maxIncarnations: 5,\n },\n loop: {\n maxFixRounds: 5,\n noProgressWindow: 3,\n maxDeniedCallsPerAgent: 5,\n leftovers: { major: 'fix', minor: 'park', info: 'park' },\n },\n checks: { timeoutMs: 10 * MINUTE },\n provision: {\n network: false,\n cacheDirs: [],\n lockfiles: ['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock'],\n env: {},\n dependencyDirs: ['**/node_modules'],\n writableCaches: ['node_modules/.cache', 'node_modules/.vite', 'node_modules/.vitest', 'node_modules/.vite-temp'],\n },\n policy: {\n commands: { allow: [], ask: [], deny: [] },\n dangerousCommands: [],\n symlinks: { ...DEFAULT_SYMLINK_POLICY },\n approvals: { unattended: 'deny', parkAfterMinutes: 10, ship: 'human', notify: false, autoResume: false },\n inDoubt: 'ask',\n skip: [],\n steer: { enabled: false },\n admin: { runTool: false },\n quota: { autoResume: false },\n },\n host: { idleExitMinutes: 30, pauseKeepAliveMinutes: 30, pollMs: 250 },\n network: { proxyEnv: false },\n sandbox: { brain: 'os-if-available' },\n git: { branchPrefix: 'cohorte/', commitIdentity: 'user', keepWorktrees: 'on-failure' },\n retention: { transcriptsDays: 30, eventsDays: 'forever', artifactsDays: 90, compressAfterDays: 7 },\n telemetry: { remote: false },\n});\n","// `.cohorte/manifest.yaml` (DESIGN 2.10): the detection marker and the previous-hash guard of spec 14.\nimport { Sha256 } from '@cohorte/base';\nimport { type Static, Type } from 'typebox';\n\nconst closed = { additionalProperties: false } as const;\n\nexport const GeneratedFile = Type.Object(\n {\n /** `.cohorte`-relative POSIX path */\n path: Type.String({ minLength: 1 }),\n templateId: Type.String({ minLength: 1 }),\n templateSha256: Sha256,\n /** a generated file is replaced only if its CURRENT hash equals this one */\n renderedSha256: Sha256,\n },\n closed,\n);\nexport type GeneratedFile = Static<typeof GeneratedFile>;\n\n/** [S] */\nexport const Manifest = Type.Object(\n {\n schemaVersion: Type.Literal(1),\n cohorteVersion: Type.String({ minLength: 1 }),\n createdWith: Type.String({ minLength: 1 }),\n protocol: Type.Object({ min: Type.String({ minLength: 1 }), max: Type.String({ minLength: 1 }) }, closed),\n stateSchemaVersion: Type.Integer({ minimum: 0 }),\n generated: Type.Array(GeneratedFile),\n },\n closed,\n);\nexport type Manifest = Static<typeof Manifest>;\n","// `.cohorte/ownership.yaml` (DESIGN 2.10): surfaces, their paths, owners and reviewers.\nimport { ID_PATTERN } from '@cohorte/base';\nimport { type TUnsafe, Type } from 'typebox';\n\nconst closed = { additionalProperties: false } as const;\n\n/** The one surface whose paths may overlap any other surface's (DESIGN 2.10, 5.6). */\nexport const SHARED_SURFACE_ID = 'shared';\n\nexport interface Surface {\n /** worktree-relative POSIX globs */\n paths: string[];\n /** role ids allowed to WRITE the surface */\n owners: string[];\n reviewers: string[];\n /** a write to one of these paths is an `ask` (DESIGN 5.6) */\n approval?: 'human';\n}\nexport interface Ownership {\n surfaces: Record<string, Surface>;\n}\n\nconst names = () => Type.Array(Type.String({ minLength: 1 }));\nconst SurfaceSchema = Type.Object(\n {\n paths: Type.Array(Type.String({ minLength: 1 }), { minItems: 1 }),\n owners: names(),\n reviewers: names(),\n approval: Type.Optional(Type.Literal('human')),\n },\n closed,\n);\nconst OwnershipSchema = Type.Object(\n { surfaces: Type.Record(Type.String({ pattern: ID_PATTERN }), SurfaceSchema) },\n closed,\n);\n\n/** [S]. Annotated: a `Static<TRecord>` inferred by Biome overflows its stack (docs/v3/requests/U0.03.md R1). */\nexport const Ownership: TUnsafe<Ownership> = Type.Unsafe<Ownership>(OwnershipSchema);\n\nconst GLOB_META = /[*?[\\]{}()!]/;\n\n/** The literal prefix of a glob, by path SEGMENT: the segments before the first one holding a glob metacharacter (DESIGN 5.6). */\nexport function literalPrefixOf(pattern: string): string[] {\n const prefix: string[] = [];\n for (const segment of pattern.split('/')) {\n if (segment === '' || segment === '.') continue;\n if (GLOB_META.test(segment)) break;\n prefix.push(segment);\n }\n return prefix;\n}\n\nconst isSegmentAncestorOrEqual = (a: readonly string[], b: readonly string[]): boolean =>\n a.length <= b.length && a.every((segment, index) => segment === b[index]);\n\n/** Two patterns overlap when one literal prefix is a segment-ancestor of (or equal to) the other; no literal prefix overlaps everything. */\nexport function patternsOverlap(a: string, b: string): boolean {\n const left = literalPrefixOf(a);\n const right = literalPrefixOf(b);\n return isSegmentAncestorOrEqual(left, right) || isSegmentAncestorOrEqual(right, left);\n}\n\nexport interface OwnershipProblem {\n /** JSON pointer into the ownership document */\n path: string;\n message: string;\n}\n\n/**\n * The rule a JSON Schema cannot say: every surface path is DISJOINT from the paths of every other surface, unless\n * one of the two surfaces is `shared`. Conservative on purpose (prefix overlap, not glob intersection): a false\n * \"overlap\" costs an edit of ownership.yaml, a missed one lets two agents write the same file.\n */\nexport function ownershipProblems(ownership: Ownership): OwnershipProblem[] {\n const problems: OwnershipProblem[] = [];\n const entries = Object.entries(ownership.surfaces).filter(([id]) => id !== SHARED_SURFACE_ID);\n entries.forEach(([id, surface], at) => {\n for (const [otherId, other] of entries.slice(at + 1)) {\n surface.paths.forEach((path, index) => {\n const clash = other.paths.find((candidate) => patternsOverlap(path, candidate));\n if (clash !== undefined) {\n problems.push({\n path: `/surfaces/${id}/paths/${index}`,\n message: `\"${path}\" of surface \"${id}\" overlaps \"${clash}\" of surface \"${otherId}\": make them disjoint or move the path to the \"${SHARED_SURFACE_ID}\" surface`,\n });\n }\n });\n }\n });\n return problems;\n}\n","// `.cohorte/skills/<id>/skill.yaml` (DESIGN 2.10, ADR-0011). Spec 8 with ONE change: `checks[].command`, a shell\n// string, becomes `argv` (D-25, I3). Checks are declarative in V3.0: never run, and they create no CommandRule.\nimport { ID_PATTERN } from '@cohorte/base';\nimport { type Static, Type } from 'typebox';\n\nconst closed = { additionalProperties: false } as const;\nconst names = () => Type.Optional(Type.Array(Type.String({ minLength: 1 })));\n\n/** [S] schemas/skill.schema.json */\nexport const SkillManifest = Type.Object(\n {\n id: Type.String({ pattern: ID_PATTERN }),\n version: Type.String({ minLength: 1 }),\n /** matched against the Project Model, deterministically */\n appliesWhen: Type.Object(\n { languages: names(), frameworks: names(), packageManagers: names(), roles: names() },\n closed,\n ),\n /** relative path of the Markdown, inside the skill directory */\n prompt: Type.String({ minLength: 1 }),\n checks: Type.Optional(\n Type.Array(\n Type.Object(\n { name: Type.Optional(Type.String({ minLength: 1 })), argv: Type.Array(Type.String(), { minItems: 1 }) },\n closed,\n ),\n ),\n ),\n /** reserved (ADR-0011): no signature is verified in V3.0 */\n signature: Type.Optional(Type.String()),\n /** reserved (ADR-0011) */\n source: Type.Optional(Type.String()),\n },\n closed,\n);\nexport type SkillManifest = Static<typeof SkillManifest>;\n","// `.cohorte/specs/<id>.yaml` (DESIGN 2.10): a feature or a patch, draft or frozen; immutable once frozen.\nimport { canonicalJson, ID_PATTERN, type JsonValue, Sha256, sha256Hex } from '@cohorte/base';\nimport { type TUnsafe, Type } from 'typebox';\n\nconst closed = { additionalProperties: false } as const;\n\ninterface SpecBody {\n id: string;\n kind: 'feature' | 'patch';\n title: string;\n acceptance: string[];\n surfaces: Record<string, { tasks: string[] }>;\n /** worktree-relative path of the contract file */\n contract?: string;\n openQuestions: string[];\n patch?: { repro: string; regressionTest: string; causeConfirmed: boolean };\n}\nexport interface DraftSpec extends SpecBody {\n status: 'draft';\n}\nexport interface FrozenSpec extends SpecBody {\n status: 'frozen';\n /** sha256 of the canonical JSON of the spec WITHOUT `status` and `sha256`: see {@link specContentSha256} */\n sha256: Sha256;\n}\nexport type Spec = DraftSpec | FrozenSpec;\n\nconst texts = () => Type.Array(Type.String({ minLength: 1 }));\nconst body = {\n id: Type.String({ pattern: ID_PATTERN }),\n kind: Type.Union([Type.Literal('feature'), Type.Literal('patch')]),\n title: Type.String({ minLength: 1 }),\n acceptance: texts(),\n surfaces: Type.Record(Type.String({ pattern: ID_PATTERN }), Type.Object({ tasks: texts() }, closed)),\n contract: Type.Optional(Type.String({ minLength: 1 })),\n openQuestions: texts(),\n patch: Type.Optional(\n Type.Object({ repro: Type.String(), regressionTest: Type.String(), causeConfirmed: Type.Boolean() }, closed),\n ),\n};\nconst SpecSchema = Type.Union([\n Type.Object({ ...body, status: Type.Literal('draft') }, closed),\n Type.Object({ ...body, status: Type.Literal('frozen'), sha256: Sha256 }, closed),\n]);\n\n/** [S]. A frozen spec WITHOUT a sha256, and a draft WITH one, are both invalid. */\nexport const Spec: TUnsafe<Spec> = Type.Unsafe<Spec>(SpecSchema);\n\n/** What freezing signs: everything a human wrote, nothing the freeze itself adds. */\nexport function specContentSha256(spec: Spec): Sha256 {\n const content: Record<string, JsonValue> = {};\n for (const [key, value] of Object.entries(spec)) {\n if (key !== 'status' && key !== 'sha256' && value !== undefined) content[key] = value as JsonValue;\n }\n return sha256Hex(canonicalJson(content));\n}\n\nexport interface SpecProblem {\n path: string;\n message: string;\n}\n\n/** A frozen spec rejects edits: its content must still hash to the sha256 it was frozen with. A draft has nothing to prove. */\nexport function frozenSpecProblems(spec: Spec): SpecProblem[] {\n if (spec.status !== 'frozen') return [];\n const actual = specContentSha256(spec);\n if (actual === spec.sha256) return [];\n return [\n {\n path: '/sha256',\n message: `spec \"${spec.id}\" is frozen and was edited: content hashes to ${actual}, frozen as ${spec.sha256}. Revert the edit, or write a new spec`,\n },\n ];\n}\n","// What the repository may decide, and what only the local user may decide (DESIGN 2.10.1, ADR-0026): the key-trust\n// classification as frozen DATA, the trust record, and the TrustStore PORT that `security` implements and the\n// loader consumes (`config` may not import `security`).\nimport { IsoInstant, type JsonValue, Sha256 } from '@cohorte/base';\nimport { type TUnsafe, Type } from 'typebox';\n\nexport const TRUST_CLASSES = ['tighten-only', 'loosen', 'neutral'] as const;\nexport type TrustClass = (typeof TRUST_CLASSES)[number];\n\nexport interface ConfigKeyTrustRule {\n /**\n * JSON pointer into `CohorteConfig`. A rule covers the key it names AND its whole subtree. Rules are prefix-disjoint:\n * no pointer is an ancestor of another one, so a key has exactly one class.\n */\n pointer: string;\n class: TrustClass;\n /**\n * Only on a `loosen` rule whose class depends on the VALUE (DESIGN 2.10.1: `sandbox.require: best-effort`,\n * `policy.symlinks` towards `allow`, ...): the values that loosen. Every other value of the key is `tighten-only`.\n */\n loosenOnly?: readonly JsonValue[];\n}\n\nconst tighten = (pointer: string): ConfigKeyTrustRule => Object.freeze({ pointer, class: 'tighten-only' });\nconst neutral = (pointer: string): ConfigKeyTrustRule => Object.freeze({ pointer, class: 'neutral' });\nconst loosen = (pointer: string, ...loosenOnly: JsonValue[]): ConfigKeyTrustRule =>\n Object.freeze(\n loosenOnly.length === 0\n ? { pointer, class: 'loosen' }\n : { pointer, class: 'loosen', loosenOnly: Object.freeze(loosenOnly) },\n );\n\n/** DESIGN 2.10.1, as data. TOTAL over `CohorteConfig` (a unit test enumerates the schema). */\nexport const CONFIG_KEY_TRUST: readonly ConfigKeyTrustRule[] = Object.freeze([\n neutral('/schemaVersion'),\n neutral('/project'),\n neutral('/runtime/id'),\n loosen('/runtime/pi'),\n neutral('/authentication/mode'),\n loosen('/authentication/allowApiKeys'),\n loosen('/authentication/anthropicSubscriptionViaPi'),\n loosen('/routing/allowedProviders'),\n neutral('/routing/defaults'),\n neutral('/routing/tiers'),\n neutral('/routing/escalation'),\n loosen('/routing/fallback'),\n tighten('/budgets'),\n tighten('/loop'),\n loosen('/checks'),\n loosen('/provision/argv'),\n loosen('/provision/network'),\n loosen('/provision/cacheDirs'),\n neutral('/provision/lockfiles'),\n loosen('/provision/env'),\n loosen('/provision/dependencyDirs'),\n loosen('/provision/writableCaches'),\n loosen('/policy/commands/allow'),\n tighten('/policy/commands/ask'),\n tighten('/policy/commands/deny'),\n loosen('/policy/dangerousCommands'),\n loosen('/policy/symlinks/mode', 'allow'),\n loosen('/policy/symlinks/hardlinksOnWrite', 'allow'),\n loosen('/policy/approvals/unattended', 'wait'),\n tighten('/policy/approvals/expiryMinutes'),\n tighten('/policy/approvals/parkAfterMinutes'),\n loosen('/policy/approvals/ship', 'auto'),\n neutral('/policy/approvals/notify'),\n loosen('/policy/approvals/autoResume'),\n loosen('/policy/inDoubt', 'continue'),\n loosen('/policy/skip'),\n loosen('/policy/steer'),\n loosen('/policy/admin'),\n neutral('/policy/quota'),\n neutral('/host'),\n loosen('/network/proxyEnv'),\n loosen('/sandbox/require', 'best-effort'),\n loosen('/sandbox/brain', 'process'),\n loosen('/git/worktreeRoot'),\n neutral('/git/branchPrefix'),\n neutral('/git/commitIdentity'),\n neutral('/git/keepWorktrees'),\n tighten('/retention'),\n neutral('/telemetry'),\n]);\n\nconst covers = (rule: ConfigKeyTrustRule, pointer: string): boolean =>\n pointer === rule.pointer || pointer.startsWith(`${rule.pointer}/`);\n\n/** Every rule that covers `pointer`. The data is total and prefix-disjoint, so this has exactly one member for a real key. */\nexport function trustRulesFor(pointer: string): ConfigKeyTrustRule[] {\n return CONFIG_KEY_TRUST.filter((rule) => covers(rule, pointer));\n}\n\n/**\n * The class of one key of the PROJECT file. `value` decides for the keys classed by value; without it such a key is\n * reported `loosen` (fail closed). An unknown key is `loosen` too: nothing unclassified is ever honoured silently.\n */\nexport function trustClassOf(pointer: string, value?: JsonValue): TrustClass {\n const [rule, ...others] = trustRulesFor(pointer);\n if (rule === undefined || others.length > 0) return 'loosen';\n if (rule.class !== 'loosen' || rule.loosenOnly === undefined || value === undefined) return rule.class;\n if (pointer !== rule.pointer) return 'loosen';\n return rule.loosenOnly.some((candidate) => candidate === value) ? 'loosen' : 'tighten-only';\n}\n\n/** One file per project: `~/.cohorte/trust/<projectKeyId>.json`, `0600` in a `0700` directory, a protected root. */\nexport interface TrustRecord {\n /** sha256(canonicalJson(the project file's values for every loosen-class key + ownership.yaml)) */\n policySha256: Sha256;\n /** JSON pointers of the loosening keys the user saw and accepted */\n loosenedKeys: string[];\n grantedAt: IsoInstant;\n /** a label for the audit trail (the OS user name); the MAC proves \"a key holder\", never which one (ADR-0022) */\n grantedBy: string;\n /** HMAC-SHA256 with the project key over the canonical JSON of the record minus `mac` */\n mac: string;\n}\n\n/**\n * [S]. The type is written by hand and the const annotated: a `Promise<Static<...>>` that Biome has to resolve for\n * nursery/noFloatingPromises overflows its stack, and a crashed Biome exits 0 (docs/v3/requests/U0.02.md R1).\n */\nexport const TrustRecord: TUnsafe<TrustRecord> = Type.Unsafe<TrustRecord>(\n Type.Object(\n {\n policySha256: Sha256,\n loosenedKeys: Type.Array(Type.String()),\n grantedAt: IsoInstant,\n grantedBy: Type.String({ minLength: 1 }),\n mac: Type.String({ minLength: 1 }),\n },\n { additionalProperties: false },\n ),\n);\n\nexport interface TrustGrant {\n policySha256: Sha256;\n loosenedKeys: string[];\n grantedBy: string;\n}\n\n/**\n * PORT (file implementation: `@cohorte/security/auth`, `createTrustStore`). A record with a bad MAC or wrong file\n * modes is ABSENT: `lookup` fails closed.\n */\nexport interface TrustStore {\n /** The record, only if it is authentic AND was granted for exactly this policy hash. */\n lookup(projectKeyId: string, policySha256: Sha256): Promise<TrustRecord | undefined>;\n grant(projectKeyId: string, grant: TrustGrant): Promise<TrustRecord>;\n /** false = there was nothing to revoke */\n revoke(projectKeyId: string): Promise<boolean>;\n}\n"],"mappings":";;;;;AAGA,MAAMA,WAAS,EAAE,sBAAsB,MAAM;AAC7C,MAAM,eAAe,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AA0B7D,MAAM,YAAY,KAAK,QAAQ,EAAE,SAAS,EAAE,CAAC;AAE7C,MAAM,oBAAoB,KAAK,OAC7B;CACE,IAAI,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CAEhC,SAAS,KAAK,OAAO,EAAE,SAAS,iBAAiB,CAAC;CAClD,YAAY,KAAK,SAAS,OAAO,CAAC;CAClC,OAAO,KAAK,SAAS,KAAK,OAAO;EAAE,OAAO,OAAO;EAAG,MAAM,KAAK,SAAS,OAAO,CAAC;CAAE,GAAGA,QAAM,CAAC;CAC5F,aAAa,KAAK,SAChB,KAAK,MAAM;EACT,KAAK,OAAO,EAAE,MAAM,KAAK,QAAQ,MAAM,EAAE,GAAGA,QAAM;EAClD,KAAK,OAAO;GAAE,MAAM,KAAK,QAAQ,mBAAmB;GAAG,KAAK,IAAI;EAAE,GAAGA,QAAM;EAC3E,KAAK,OAAO;GAAE,MAAM,KAAK,QAAQ,MAAM;GAAG,QAAQ,OAAO;GAAG,KAAK,IAAI;EAAE,GAAGA,QAAM;EAChF,KAAK,OAAO;GAAE,MAAM,KAAK,QAAQ,OAAO;GAAG,QAAQ,KAAK,MAAM,KAAK,OAAO,CAAC;EAAE,GAAGA,QAAM;CACxF,CAAC,CACH;CACA,UAAU,KAAK,MAAM;EAAC,KAAK,QAAQ,OAAO;EAAG,KAAK,QAAQ,KAAK;EAAG,KAAK,QAAQ,MAAM;CAAC,CAAC;CACvF,MAAM,KAAK,SACT,KAAK,OACH;EACE,QAAQ,KAAK,SAAS,KAAK,MAAM,CAAC,KAAK,QAAQ,KAAK,GAAG,KAAK,QAAQ,kBAAkB,CAAC,CAAC,CAAC;EACzF,OAAO,KAAK,SAAS,OAAO,CAAC;EAC7B,QAAQ,KAAK,SAAS,OAAO,CAAC;CAChC,GACAA,QACF,CACF;CACA,QAAQ,KAAK,MAAM,CAAC,KAAK,QAAQ,YAAY,GAAG,KAAK,QAAQ,cAAc,CAAC,CAAC;CAC7E,SAAS,KAAK,QAAQ;CACtB,QAAQ,KAAK,MAAM;EAAC,KAAK,QAAQ,SAAS;EAAG,KAAK,QAAQ,gBAAgB;EAAG,KAAK,QAAQ,gBAAgB;CAAC,CAAC;AAC9G,GACAA,QACF;;AAGA,MAAa,cAAoC,KAAK,OAAoB,iBAAiB;;AAG3F,MAAa,gBAAgB,KAAK,OAChC;CACE,MAAM,KAAK,MAAM;EAAC,KAAK,QAAQ,eAAe;EAAG,KAAK,QAAQ,UAAU;EAAG,KAAK,QAAQ,OAAO;CAAC,CAAC;CACjG,kBAAkB,KAAK,MAAM,CAAC,KAAK,QAAQ,MAAM,GAAG,KAAK,QAAQ,OAAO,CAAC,CAAC;AAC5E,GACAA,QACF;AAQmC,KAAK,OAAO,EAAE,SAAS,KAAK,QAAQ,MAAM,EAAE,GAAGA,QAAM;AAGxF,MAAa,yBAAwC,OAAO,OAAO;CAAE,MAAM;CAAiB,kBAAkB;AAAO,CAAC;AACtH,MAAa,yBAA8C,OAAO,OAAO,EAAE,SAAS,OAAO,CAAC;;;AChF5F,MAAMC,WAAS,EAAE,sBAAsB,MAAM;AA+G7C,MAAM,SAA4C,WAChD,KAAK,OAAkB;CAAE,MAAM;CAAU,MAAM,CAAC,GAAG,MAAM;AAAE,CAAC;AAC9D,MAAM,SAAS,UAAU,MAAM,KAAK,QAAQ,EAAE,QAAQ,CAAC;AACvD,MAAM,aAAa,KAAK,MAAM,KAAK,OAAO,GAAG,EAAE,UAAU,EAAE,CAAC;AAC5D,MAAM,gBAAgB,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AAC9D,MAAM,cAAc,KAAK,MAAM,WAAW;AAE1C,MAAM,kBACJ,KAAK,OAAuC,KAAK,OAAO,KAAK,OAAO,GAAG,cAAc,CAAC;AACxF,MAAM,qBACJ,KAAK,OAAsD,KAAK,OAAO,KAAK,OAAO,GAAG,eAAe,CAAC;AACxG,MAAM,aAAa,KAAK,SAAS,KAAK,OAAO;CAAE,KAAK;CAAU,UAAU;AAAc,GAAGA,QAAM,CAAC;AAChG,MAAM,iBAAiB,KAAK,SAAS,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AAClE,MAAM,iBAAiB,MAAM;CAAC;CAAO;CAAQ;AAAK,CAAC;AAEnD,MAAM,sBAAsB,KAAK,OAC/B;CACE,eAAe,KAAK,QAAQ,CAAC;CAC7B,SAAS,KAAK,OACZ;EACE,IAAI,KAAK,OAAO,EAAE,SAAS,WAAW,CAAC;EACvC,eAAe,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;EAC3C,mBAAmB,QAAQ;CAC7B,GACAA,QACF;CACA,SAAS,KAAK,OACZ;EACE,IAAI,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;EAChC,IAAI,KAAK,SAAS,KAAK,OAAO,EAAE,UAAU,MAAM,CAAC,WAAW,QAAQ,CAAC,EAAE,GAAGA,QAAM,CAAC;CACnF,GACAA,QACF;CACA,gBAAgB,KAAK,OACnB;EACE,MAAM;EACN,cAAc,KAAK,QAAQ;EAC3B,4BAA4B,KAAK,SAC/B,KAAK,OACH;GACE,SAAS,KAAK,QAAQ;GACtB,4BAA4B,KAAK,QAAQ;GACzC,8BAA8B,KAAK,QAAQ;EAC7C,GACAA,QACF,CACF;CACF,GACAA,QACF;CACA,SAAS,KAAK,OACZ;EACE,kBAAkB,QAAQ;EAC1B,UAAU,aAAa;EACvB,OAAO,KAAK,OAAO;GAAE,MAAM,KAAK;GAAG,QAAQ,KAAK;GAAG,WAAW,KAAK;GAAG,QAAQ,KAAK;GAAG,OAAO,KAAK;EAAE,GAAGA,QAAM;EAC7G,YAAY;EACZ,UAAU,KAAK,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,GAAGA,QAAM;CAC3D,GACAA,QACF;CACA,SAAS,KAAK,OACZ;EACE,KAAK;EACL,OAAO;EACP,OAAO;EACP,UAAU,UAAU;EACpB,MAAM,UAAU;EAChB,aAAa,MAAM,CAAC;EACpB,iBAAiB,MAAM,CAAC;CAC1B,GACAA,QACF;CACA,MAAM,KAAK,OACT;EACE,cAAc,MAAM;EACpB,kBAAkB,MAAM,CAAC;EACzB,wBAAwB,MAAM;EAC9B,WAAW,KAAK,OAAO;GAAE,OAAO,SAAS;GAAG,OAAO,SAAS;GAAG,MAAM,SAAS;EAAE,GAAGA,QAAM;CAC3F,GACAA,QACF;CACA,QAAQ,KAAK,OACX;EACE,WAAW,KAAK,SAAS,KAAK,CAAC;EAC/B,MAAM,KAAK,SAAS,KAAK,CAAC;EAC1B,MAAM,KAAK,SAAS,KAAK,CAAC;EAC1B,WAAW,MAAM,CAAC;CACpB,GACAA,QACF;CACA,WAAW,KAAK,OACd;EACE,MAAM,KAAK,SAAS,KAAK,CAAC;EAC1B,SAAS,KAAK,QAAQ;EACtB,WAAW,QAAQ;EACnB,WAAW,QAAQ;EACnB,KAAK,KAAK,OACR;GACE,sBAAsB,SAAS;GAC/B,kBAAkB,SAAS;GAC3B,mBAAmB,SAAS;GAC5B,eAAe,SAAS;EAC1B,GACAA,QACF;EACA,gBAAgB,QAAQ;EACxB,gBAAgB,QAAQ;CAC1B,GACAA,QACF;CACA,QAAQ,KAAK,OACX;EACE,UAAU,KAAK,OAAO;GAAE,OAAO,MAAM;GAAG,KAAK,MAAM;GAAG,MAAM,MAAM;EAAE,GAAGA,QAAM;EAC7E,mBAAmB,MAAM;EACzB,UAAU;EACV,WAAW,KAAK,OACd;GACE,YAAY,MAAM,CAAC,QAAQ,MAAM,CAAC;GAClC,eAAe,KAAK,SAAS,MAAM,CAAC,CAAC;GACrC,kBAAkB,MAAM;GACxB,MAAM,MAAM,CAAC,SAAS,MAAM,CAAC;GAC7B,QAAQ,KAAK,QAAQ;GACrB,YAAY,KAAK,QAAQ;EAC3B,GACAA,QACF;EACA,SAAS,MAAM,CAAC,OAAO,UAAU,CAAC;EAClC,MAAM,KAAK,MAAM,mBAAmB;EACpC,OAAO,KAAK,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,GAAGA,QAAM;EACtD,OAAO,KAAK,OAAO,EAAE,SAAS,KAAK,QAAQ,EAAE,GAAGA,QAAM;EACtD,OAAO,KAAK,OAAO,EAAE,YAAY,KAAK,QAAQ,EAAE,GAAGA,QAAM;CAC3D,GACAA,QACF;CACA,MAAM,KAAK,OAAO;EAAE,iBAAiB,MAAM;EAAG,uBAAuB,MAAM;EAAG,QAAQ,MAAM,CAAC;CAAE,GAAGA,QAAM;CACxG,SAAS,KAAK,OAAO,EAAE,UAAU,KAAK,QAAQ,EAAE,GAAGA,QAAM;CACzD,SAAS,KAAK,OACZ;EACE,SAAS,KAAK,SAAS,MAAM,CAAC,UAAU,aAAa,CAAC,CAAC;EACvD,OAAO,MAAM;GAAC;GAAmB;GAAM;EAAS,CAAC;CACnD,GACAA,QACF;CACA,KAAK,KAAK,OACR;EACE,cAAc,KAAK,SAAS,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;EACzD,cAAc,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;EAC1C,gBAAgB,MAAM,CAAC,QAAQ,SAAS,CAAC;EACzC,eAAe,MAAM;GAAC;GAAc;GAAU;EAAO,CAAC;CACxD,GACAA,QACF;CACA,WAAW,KAAK,OACd;EACE,iBAAiB,MAAM;EACvB,YAAY,KAAK,MAAM,CAAC,MAAM,GAAG,KAAK,QAAQ,SAAS,CAAC,CAAC;EACzD,eAAe,MAAM;EACrB,mBAAmB,MAAM;CAC3B,GACAA,QACF;CACA,WAAW,KAAK,OAAO,EAAE,QAAQ,KAAK,QAAQ,EAAE,GAAGA,QAAM;AAC3D,GACAA,QACF;;AAGA,MAAa,gBAAwC,KAAK,OAAsB,mBAAmB;AAEnG,SAAS,WAAc,OAAa;CAClC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,OAAO,SAAS,KAAK,GAAG;EAC1E,OAAO,OAAO,KAAK;EACnB,KAAK,MAAM,UAAU,OAAO,OAAO,KAAK,GAAG,WAAW,MAAM;CAC9D;CACA,OAAO;AACT;AAEA,MAAM,SAAS;;;;;;;AAQf,MAAa,iBAAgC,WAA0B;CACrE,eAAe;CACf,SAAS;EAAE,IAAI;EAAW,eAAe;EAAQ,mBAAmB,CAAC,QAAQ,QAAQ;CAAE;CACvF,SAAS;EAAE,IAAI;EAAM,IAAI,EAAE,UAAU,UAAU;CAAE;CACjD,gBAAgB;EAAE,MAAM;EAAgB,cAAc;CAAM;CAC5D,SAAS;EACP,kBAAkB,CAAC,cAAc;EACjC,UAAU;GAAE,aAAa;GAAU,OAAO;GAAU,UAAU;GAAa,qBAAqB;EAAY;EAC5G,OAAO;GACL,QAAQ;IAAE,KAAK;KAAE,UAAU;KAAgB,OAAO;KAAW,YAAY;IAAS;IAAG,UAAU;GAAS;GACxG,WAAW;IAAE,KAAK;KAAE,UAAU;KAAgB,OAAO;KAAW,YAAY;IAAY;IAAG,UAAU;GAAO;GAC5G,MAAM;IAAE,KAAK;KAAE,UAAU;KAAgB,OAAO;KAAgB,YAAY;IAAO;IAAG,UAAU;GAAM;GACtG,OAAO;IAAE,KAAK;KAAE,UAAU;KAAgB,OAAO;KAAgB,YAAY;IAAQ;IAAG,UAAU;GAAM;EAC1G;EACA,YAAY;GAAE,kBAAkB;GAAG,QAAQ,CAAC,EAAE,MAAM,QAAQ,CAAC;GAAG,WAAW;EAAE;EAC7E,UAAU,EAAE,SAAS,MAAM;CAC7B;CACA,SAAS;EACP,KAAK;GAAE,eAAe;GAAM,WAAW;GAAQ,aAAa,MAAM;EAAO;EACzE,OAAO,EAAE,aAAa,MAAM,OAAO;EACnC,OAAO;GAAE,eAAe;GAAK,WAAW;GAAK,aAAa,KAAK;GAAQ,eAAe;EAAQ;EAC9F,UAAU,CAAC;EACX,MAAM,CAAC;EACP,aAAa;EACb,iBAAiB;CACnB;CACA,MAAM;EACJ,cAAc;EACd,kBAAkB;EAClB,wBAAwB;EACxB,WAAW;GAAE,OAAO;GAAO,OAAO;GAAQ,MAAM;EAAO;CACzD;CACA,QAAQ,EAAE,WAAW,KAAK,OAAO;CACjC,WAAW;EACT,SAAS;EACT,WAAW,CAAC;EACZ,WAAW;GAAC;GAAkB;GAAqB;EAAW;EAC9D,KAAK,CAAC;EACN,gBAAgB,CAAC,iBAAiB;EAClC,gBAAgB;GAAC;GAAuB;GAAsB;GAAwB;EAAyB;CACjH;CACA,QAAQ;EACN,UAAU;GAAE,OAAO,CAAC;GAAG,KAAK,CAAC;GAAG,MAAM,CAAC;EAAE;EACzC,mBAAmB,CAAC;EACpB,UAAU,EAAE,GAAG,uBAAuB;EACtC,WAAW;GAAE,YAAY;GAAQ,kBAAkB;GAAI,MAAM;GAAS,QAAQ;GAAO,YAAY;EAAM;EACvG,SAAS;EACT,MAAM,CAAC;EACP,OAAO,EAAE,SAAS,MAAM;EACxB,OAAO,EAAE,SAAS,MAAM;EACxB,OAAO,EAAE,YAAY,MAAM;CAC7B;CACA,MAAM;EAAE,iBAAiB;EAAI,uBAAuB;EAAI,QAAQ;CAAI;CACpE,SAAS,EAAE,UAAU,MAAM;CAC3B,SAAS,EAAE,OAAO,kBAAkB;CACpC,KAAK;EAAE,cAAc;EAAY,gBAAgB;EAAQ,eAAe;CAAa;CACrF,WAAW;EAAE,iBAAiB;EAAI,YAAY;EAAW,eAAe;EAAI,mBAAmB;CAAE;CACjG,WAAW,EAAE,QAAQ,MAAM;AAC7B,CAAC;;;ACrWD,MAAMC,WAAS,EAAE,sBAAsB,MAAM;AAE7C,MAAa,gBAAgB,KAAK,OAChC;;CAEE,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CAClC,YAAY,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CACxC,gBAAgB;;CAEhB,gBAAgB;AAClB,GACAA,QACF;AAIwB,KAAK,OAC3B;CACE,eAAe,KAAK,QAAQ,CAAC;CAC7B,gBAAgB,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CAC5C,aAAa,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CACzC,UAAU,KAAK,OAAO;EAAE,KAAK,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;EAAG,KAAK,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CAAE,GAAGA,QAAM;CACxG,oBAAoB,KAAK,QAAQ,EAAE,SAAS,EAAE,CAAC;CAC/C,WAAW,KAAK,MAAM,aAAa;AACrC,GACAA,QACF;;;AC1BA,MAAMC,WAAS,EAAE,sBAAsB,MAAM;AAkB7C,MAAMC,gBAAc,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AAC5D,MAAM,gBAAgB,KAAK,OACzB;CACE,OAAO,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC;CAChE,QAAQA,QAAM;CACd,WAAWA,QAAM;CACjB,UAAU,KAAK,SAAS,KAAK,QAAQ,OAAO,CAAC;AAC/C,GACAD,QACF;AACA,MAAM,kBAAkB,KAAK,OAC3B,EAAE,UAAU,KAAK,OAAO,KAAK,OAAO,EAAE,SAAS,WAAW,CAAC,GAAG,aAAa,EAAE,GAC7EA,QACF;;AAGA,MAAa,YAAgC,KAAK,OAAkB,eAAe;AAEnF,MAAM,YAAY;;AAGlB,SAAgB,gBAAgB,SAA2B;CACzD,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,WAAW,QAAQ,MAAM,GAAG,GAAG;EACxC,IAAI,YAAY,MAAM,YAAY,KAAK;EACvC,IAAI,UAAU,KAAK,OAAO,GAAG;EAC7B,OAAO,KAAK,OAAO;CACrB;CACA,OAAO;AACT;;;AC9CA,MAAME,WAAS,EAAE,sBAAsB,MAAM;AAC7C,MAAM,cAAc,KAAK,SAAS,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AAG9C,KAAK,OAChC;CACE,IAAI,KAAK,OAAO,EAAE,SAAS,WAAW,CAAC;CACvC,SAAS,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;;CAErC,aAAa,KAAK,OAChB;EAAE,WAAW,MAAM;EAAG,YAAY,MAAM;EAAG,iBAAiB,MAAM;EAAG,OAAO,MAAM;CAAE,GACpFA,QACF;;CAEA,QAAQ,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CACpC,QAAQ,KAAK,SACX,KAAK,MACH,KAAK,OACH;EAAE,MAAM,KAAK,SAAS,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;EAAG,MAAM,KAAK,MAAM,KAAK,OAAO,GAAG,EAAE,UAAU,EAAE,CAAC;CAAE,GACvGA,QACF,CACF,CACF;;CAEA,WAAW,KAAK,SAAS,KAAK,OAAO,CAAC;;CAEtC,QAAQ,KAAK,SAAS,KAAK,OAAO,CAAC;AACrC,GACAA,QACF;;;AC9BA,MAAM,SAAS,EAAE,sBAAsB,MAAM;AAuB7C,MAAM,cAAc,KAAK,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AAC5D,MAAM,OAAO;CACX,IAAI,KAAK,OAAO,EAAE,SAAS,WAAW,CAAC;CACvC,MAAM,KAAK,MAAM,CAAC,KAAK,QAAQ,SAAS,GAAG,KAAK,QAAQ,OAAO,CAAC,CAAC;CACjE,OAAO,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CACnC,YAAY,MAAM;CAClB,UAAU,KAAK,OAAO,KAAK,OAAO,EAAE,SAAS,WAAW,CAAC,GAAG,KAAK,OAAO,EAAE,OAAO,MAAM,EAAE,GAAG,MAAM,CAAC;CACnG,UAAU,KAAK,SAAS,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;CACrD,eAAe,MAAM;CACrB,OAAO,KAAK,SACV,KAAK,OAAO;EAAE,OAAO,KAAK,OAAO;EAAG,gBAAgB,KAAK,OAAO;EAAG,gBAAgB,KAAK,QAAQ;CAAE,GAAG,MAAM,CAC7G;AACF;AACA,MAAM,aAAa,KAAK,MAAM,CAC5B,KAAK,OAAO;CAAE,GAAG;CAAM,QAAQ,KAAK,QAAQ,OAAO;AAAE,GAAG,MAAM,GAC9D,KAAK,OAAO;CAAE,GAAG;CAAM,QAAQ,KAAK,QAAQ,QAAQ;CAAG,QAAQ;AAAO,GAAG,MAAM,CACjF,CAAC;;AAGD,MAAa,OAAsB,KAAK,OAAa,UAAU;;AAG/D,SAAgB,kBAAkB,MAAoB;CACpD,MAAM,UAAqC,CAAC;CAC5C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,GAC5C,IAAI,QAAQ,YAAY,QAAQ,YAAY,UAAU,KAAA,GAAW,QAAQ,OAAO;CAElF,OAAO,UAAU,cAAc,OAAO,CAAC;AACzC;;AAQA,SAAgB,mBAAmB,MAA2B;CAC5D,IAAI,KAAK,WAAW,UAAU,OAAO,CAAC;CACtC,MAAM,SAAS,kBAAkB,IAAI;CACrC,IAAI,WAAW,KAAK,QAAQ,OAAO,CAAC;CACpC,OAAO,CACL;EACE,MAAM;EACN,SAAS,SAAS,KAAK,GAAG,gDAAgD,OAAO,cAAc,KAAK,OAAO;CAC7G,CACF;AACF;;;AClDA,MAAM,WAAW,YAAwC,OAAO,OAAO;CAAE;CAAS,OAAO;AAAe,CAAC;AACzG,MAAM,WAAW,YAAwC,OAAO,OAAO;CAAE;CAAS,OAAO;AAAU,CAAC;AACpG,MAAM,UAAU,SAAiB,GAAG,eAClC,OAAO,OACL,WAAW,WAAW,IAClB;CAAE;CAAS,OAAO;AAAS,IAC3B;CAAE;CAAS,OAAO;CAAU,YAAY,OAAO,OAAO,UAAU;AAAE,CACxE;AAG6D,OAAO,OAAO;CAC3E,QAAQ,gBAAgB;CACxB,QAAQ,UAAU;CAClB,QAAQ,aAAa;CACrB,OAAO,aAAa;CACpB,QAAQ,sBAAsB;CAC9B,OAAO,8BAA8B;CACrC,OAAO,4CAA4C;CACnD,OAAO,2BAA2B;CAClC,QAAQ,mBAAmB;CAC3B,QAAQ,gBAAgB;CACxB,QAAQ,qBAAqB;CAC7B,OAAO,mBAAmB;CAC1B,QAAQ,UAAU;CAClB,QAAQ,OAAO;CACf,OAAO,SAAS;CAChB,OAAO,iBAAiB;CACxB,OAAO,oBAAoB;CAC3B,OAAO,sBAAsB;CAC7B,QAAQ,sBAAsB;CAC9B,OAAO,gBAAgB;CACvB,OAAO,2BAA2B;CAClC,OAAO,2BAA2B;CAClC,OAAO,wBAAwB;CAC/B,QAAQ,sBAAsB;CAC9B,QAAQ,uBAAuB;CAC/B,OAAO,2BAA2B;CAClC,OAAO,yBAAyB,OAAO;CACvC,OAAO,qCAAqC,OAAO;CACnD,OAAO,gCAAgC,MAAM;CAC7C,QAAQ,iCAAiC;CACzC,QAAQ,oCAAoC;CAC5C,OAAO,0BAA0B,MAAM;CACvC,QAAQ,0BAA0B;CAClC,OAAO,8BAA8B;CACrC,OAAO,mBAAmB,UAAU;CACpC,OAAO,cAAc;CACrB,OAAO,eAAe;CACtB,OAAO,eAAe;CACtB,QAAQ,eAAe;CACvB,QAAQ,OAAO;CACf,OAAO,mBAAmB;CAC1B,OAAO,oBAAoB,aAAa;CACxC,OAAO,kBAAkB,SAAS;CAClC,OAAO,mBAAmB;CAC1B,QAAQ,mBAAmB;CAC3B,QAAQ,qBAAqB;CAC7B,QAAQ,oBAAoB;CAC5B,QAAQ,YAAY;CACpB,QAAQ,YAAY;AACtB,CAAC;AAuCgD,KAAK,OACpD,KAAK,OACH;CACE,cAAc;CACd,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;CACtC,WAAW;CACX,WAAW,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;CACvC,KAAK,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC;AACnC,GACA,EAAE,sBAAsB,MAAM,CAChC,CACF"}
@@ -0,0 +1,19 @@
1
+ //#region src/commands/send/index.ts
2
+ const send = {
3
+ verb: "send",
4
+ async run(ctx, args) {
5
+ const [runId, agentId, ...textParts] = args.positionals;
6
+ if (!runId || !agentId || textParts.length === 0) return 2;
7
+ const result = await ctx.controller.send("agent.send", {
8
+ agentId,
9
+ text: textParts.join(" "),
10
+ delivery: "steer"
11
+ }, { runId });
12
+ ctx.stdio.stdout.write(`${JSON.stringify(result)}\n`);
13
+ return result.status === "rejected" ? 3 : result.status === "pending" ? 4 : 0;
14
+ }
15
+ };
16
+ //#endregion
17
+ export { send as default };
18
+
19
+ //# sourceMappingURL=send-BdnJ85Nz.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-BdnJ85Nz.mjs","names":[],"sources":["../../../../apps/cli/src/commands/send/index.ts"],"sourcesContent":["import type { CommandModule } from '../../contract/index.ts';\n\nconst send: CommandModule = {\n verb: 'send',\n async run(ctx, args) {\n const [runId, agentId, ...textParts] = args.positionals;\n if (!runId || !agentId || textParts.length === 0) return 2;\n const result = await ctx.controller.send(\n 'agent.send',\n { agentId: agentId as never, text: textParts.join(' '), delivery: 'steer' },\n { runId },\n );\n ctx.stdio.stdout.write(`${JSON.stringify(result)}\\n`);\n return result.status === 'rejected' ? 3 : result.status === 'pending' ? 4 : 0;\n },\n};\n\nexport default send;\n"],"mappings":";AAEA,MAAM,OAAsB;CAC1B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,CAAC,OAAO,SAAS,GAAG,aAAa,KAAK;EAC5C,IAAI,CAAC,SAAS,CAAC,WAAW,UAAU,WAAW,GAAG,OAAO;EACzD,MAAM,SAAS,MAAM,IAAI,WAAW,KAClC,cACA;GAAW;GAAkB,MAAM,UAAU,KAAK,GAAG;GAAG,UAAU;EAAQ,GAC1E,EAAE,MAAM,CACV;EACA,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;EACpD,OAAO,OAAO,WAAW,aAAa,IAAI,OAAO,WAAW,YAAY,IAAI;CAC9E;AACF"}
@@ -0,0 +1,19 @@
1
+ //#region src/commands/ship/index.ts
2
+ const ship = {
3
+ verb: "ship",
4
+ async run(ctx, args) {
5
+ const [runId, approvalId] = args.positionals;
6
+ if (!runId || !approvalId) return 2;
7
+ const result = await ctx.controller.send("approve", {
8
+ approvalId,
9
+ scope: "run",
10
+ answer: "ship"
11
+ }, { runId });
12
+ ctx.stdio.stdout.write(`${JSON.stringify(result)}\n`);
13
+ return result.status === "rejected" ? 3 : result.status === "pending" ? 4 : 0;
14
+ }
15
+ };
16
+ //#endregion
17
+ export { ship as default };
18
+
19
+ //# sourceMappingURL=ship-DTuLGoaJ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ship-DTuLGoaJ.mjs","names":[],"sources":["../../../../apps/cli/src/commands/ship/index.ts"],"sourcesContent":["// apps/cli/src/commands/ship/index.ts — DESIGN §9 verb `ship` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/ship/**`.\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst ship: CommandModule = {\n verb: 'ship',\n async run(ctx, args) {\n const [runId, approvalId] = args.positionals;\n if (!runId || !approvalId) return 2;\n const result = await ctx.controller.send(\n 'approve',\n { approvalId: approvalId as never, scope: 'run', answer: 'ship' },\n { runId },\n );\n ctx.stdio.stdout.write(`${JSON.stringify(result)}\\n`);\n return result.status === 'rejected' ? 3 : result.status === 'pending' ? 4 : 0;\n },\n};\n\nexport default ship;\n"],"mappings":";AAMA,MAAM,OAAsB;CAC1B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,CAAC,OAAO,cAAc,KAAK;EACjC,IAAI,CAAC,SAAS,CAAC,YAAY,OAAO;EAClC,MAAM,SAAS,MAAM,IAAI,WAAW,KAClC,WACA;GAAc;GAAqB,OAAO;GAAO,QAAQ;EAAO,GAChE,EAAE,MAAM,CACV;EACA,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;EACpD,OAAO,OAAO,WAAW,aAAa,IAAI,OAAO,WAAW,YAAY,IAAI;CAC9E;AACF"}
@@ -0,0 +1,15 @@
1
+ //#region src/commands/shutdown/index.ts
2
+ const shutdown = {
3
+ verb: "shutdown",
4
+ async run(ctx, args) {
5
+ const runId = args.positionals[0];
6
+ if (!runId) return 2;
7
+ const result = await ctx.controller.send("shutdown", { graceMs: 5e3 }, { runId });
8
+ ctx.stdio.stdout.write(`${JSON.stringify(result)}\n`);
9
+ return result.status === "rejected" ? 3 : result.status === "pending" ? 4 : 0;
10
+ }
11
+ };
12
+ //#endregion
13
+ export { shutdown as default };
14
+
15
+ //# sourceMappingURL=shutdown-BM92Iyv2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shutdown-BM92Iyv2.mjs","names":[],"sources":["../../../../apps/cli/src/commands/shutdown/index.ts"],"sourcesContent":["// apps/cli/src/commands/shutdown/index.ts — DESIGN §9 verb `shutdown` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/shutdown/**`.\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst shutdown: CommandModule = {\n verb: 'shutdown',\n async run(ctx, args) {\n const runId = args.positionals[0];\n if (!runId) return 2;\n const result = await ctx.controller.send('shutdown', { graceMs: 5000 }, { runId });\n ctx.stdio.stdout.write(`${JSON.stringify(result)}\\n`);\n return result.status === 'rejected' ? 3 : result.status === 'pending' ? 4 : 0;\n },\n};\n\nexport default shutdown;\n"],"mappings":";AAMA,MAAM,WAA0B;CAC9B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,QAAQ,KAAK,YAAY;EAC/B,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,SAAS,MAAM,IAAI,WAAW,KAAK,YAAY,EAAE,SAAS,IAAK,GAAG,EAAE,MAAM,CAAC;EACjF,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;EACpD,OAAO,OAAO,WAAW,aAAa,IAAI,OAAO,WAAW,YAAY,IAAI;CAC9E;AACF"}
@@ -0,0 +1,18 @@
1
+ //#region src/commands/skip/index.ts
2
+ const skip = {
3
+ verb: "skip",
4
+ async run(ctx, args) {
5
+ const [runId, phase, ...rest] = args.positionals;
6
+ if (!runId || !phase) return 2;
7
+ const result = await ctx.controller.send("skip", {
8
+ phase,
9
+ justification: rest.join(" ") || "requested by operator"
10
+ }, { runId });
11
+ ctx.stdio.stdout.write(`${JSON.stringify(result)}\n`);
12
+ return result.status === "rejected" ? 3 : result.status === "pending" ? 4 : 0;
13
+ }
14
+ };
15
+ //#endregion
16
+ export { skip as default };
17
+
18
+ //# sourceMappingURL=skip-DZG5kpcH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skip-DZG5kpcH.mjs","names":[],"sources":["../../../../apps/cli/src/commands/skip/index.ts"],"sourcesContent":["// apps/cli/src/commands/skip/index.ts — DESIGN §9 verb `skip` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/skip/**`.\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst skip: CommandModule = {\n verb: 'skip',\n async run(ctx, args) {\n const [runId, phase, ...rest] = args.positionals;\n if (!runId || !phase) return 2;\n const result = await ctx.controller.send(\n 'skip',\n { phase: phase as never, justification: rest.join(' ') || 'requested by operator' },\n { runId },\n );\n ctx.stdio.stdout.write(`${JSON.stringify(result)}\\n`);\n return result.status === 'rejected' ? 3 : result.status === 'pending' ? 4 : 0;\n },\n};\n\nexport default skip;\n"],"mappings":";AAMA,MAAM,OAAsB;CAC1B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,CAAC,OAAO,OAAO,GAAG,QAAQ,KAAK;EACrC,IAAI,CAAC,SAAS,CAAC,OAAO,OAAO;EAC7B,MAAM,SAAS,MAAM,IAAI,WAAW,KAClC,QACA;GAAS;GAAgB,eAAe,KAAK,KAAK,GAAG,KAAK;EAAwB,GAClF,EAAE,MAAM,CACV;EACA,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,MAAM,EAAE,GAAG;EACpD,OAAO,OAAO,WAAW,aAAa,IAAI,OAAO,WAAW,YAAY,IAAI;CAC9E;AACF"}
@@ -0,0 +1,20 @@
1
+ import { r as loadSpec, t as freezeSpec } from "./src-DcU4IXMe.mjs";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { stringify } from "yaml";
4
+ //#region src/commands/spec/index.ts
5
+ const spec = {
6
+ verb: "spec",
7
+ async run(ctx, args) {
8
+ const file = args.positionals.find((value) => !value.startsWith("--"));
9
+ if (!file) return 2;
10
+ const frozen = args.subVerb === "freeze";
11
+ const value = frozen ? await freezeSpec(file) : await loadSpec(file);
12
+ if (frozen) await writeFile(file, stringify(value));
13
+ ctx.stdio.stdout.write(`${JSON.stringify(value)}\n`);
14
+ return 0;
15
+ }
16
+ };
17
+ //#endregion
18
+ export { spec as default };
19
+
20
+ //# sourceMappingURL=spec-Bq0P3jVh.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-Bq0P3jVh.mjs","names":[],"sources":["../../../../apps/cli/src/commands/spec/index.ts"],"sourcesContent":["// apps/cli/src/commands/spec/index.ts — DESIGN §9 verb `spec` (PLAN §3 rule 3 \"later units fill\n// stub files that lie inside their owned paths; they never edit ... the registry\"). Wave-0 stub: exits with the\n// documented not-available error (spec 24 `configuration/phase-not-available`); filled by the Wave-4/5\n// unit that owns `apps/cli/src/commands/spec/**`.\nimport { writeFile } from 'node:fs/promises';\nimport { freezeSpec, loadSpec } from '@cohorte/config';\nimport { stringify } from 'yaml';\nimport type { CommandModule } from '../../contract/index.ts';\n\nconst spec: CommandModule = {\n verb: 'spec',\n async run(ctx, args) {\n const file = args.positionals.find((value) => !value.startsWith('--'));\n if (!file) return 2;\n const frozen = args.subVerb === 'freeze';\n const value = frozen ? await freezeSpec(file) : await loadSpec(file);\n if (frozen) await writeFile(file, stringify(value));\n ctx.stdio.stdout.write(`${JSON.stringify(value)}\\n`);\n return 0;\n },\n};\n\nexport default spec;\n"],"mappings":";;;;AASA,MAAM,OAAsB;CAC1B,MAAM;CACN,MAAM,IAAI,KAAK,MAAM;EACnB,MAAM,OAAO,KAAK,YAAY,MAAM,UAAU,CAAC,MAAM,WAAW,IAAI,CAAC;EACrE,IAAI,CAAC,MAAM,OAAO;EAClB,MAAM,SAAS,KAAK,YAAY;EAChC,MAAM,QAAQ,SAAS,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,IAAI;EACnE,IAAI,QAAQ,MAAM,UAAU,MAAM,UAAU,KAAK,CAAC;EAClD,IAAI,MAAM,OAAO,MAAM,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;EACnD,OAAO;CACT;AACF"}