@iowarp/clio-coder 0.3.2 → 0.3.4

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 (259) hide show
  1. package/CHANGELOG.md +269 -458
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +3 -3
  4. package/dist/{acp-BIYHVZIM.js → acp-S5R4RR5B.js} +7 -6
  5. package/dist/{agents-YT6SSRIT.js → agents-P6DMMVZY.js} +24 -21
  6. package/dist/assets/codewiki.json +1 -1
  7. package/dist/{auth-5TWEIYDN.js → auth-2XCZLPKS.js} +12 -8
  8. package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
  9. package/dist/{chunk-WMSVI4G2.js → chunk-2LZI5CAG.js} +133 -13
  10. package/dist/{chunk-OAO4GE4M.js → chunk-2TZWSW76.js} +2 -2
  11. package/dist/{chunk-OOJYHWRB.js → chunk-34475P3I.js} +2 -2
  12. package/dist/{chunk-WVO7V2QY.js → chunk-35MKKU5R.js} +4 -4
  13. package/dist/{chunk-LBNRH5WM.js → chunk-3HZ5RWN2.js} +5 -5
  14. package/dist/{chunk-AGYYIBLL.js → chunk-3JLKSKD7.js} +2 -2
  15. package/dist/{chunk-MBS4V7ZP.js → chunk-4JUF2NNX.js} +7 -7
  16. package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
  17. package/dist/chunk-5M54SPOL.js +926 -0
  18. package/dist/{chunk-STBPMHSX.js → chunk-7RXG6QRZ.js} +51 -11
  19. package/dist/{chunk-77VKQEHF.js → chunk-A2GZF7DC.js} +5 -5
  20. package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
  21. package/dist/chunk-AOCYTWAV.js +449 -0
  22. package/dist/chunk-BEY543CS.js +258 -0
  23. package/dist/{chunk-6N5PTWMY.js → chunk-BP4OYD6A.js} +32 -13
  24. package/dist/chunk-BPGS2WCQ.js +612 -0
  25. package/dist/{chunk-J5HN4RYU.js → chunk-BRXQQJFP.js} +8 -8
  26. package/dist/chunk-CFGTUFWB.js +67 -0
  27. package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
  28. package/dist/{chunk-G2DE3C7R.js → chunk-EDRHSCIE.js} +4 -4
  29. package/dist/{chunk-4KLWL3UC.js → chunk-EFADSJET.js} +2 -2
  30. package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
  31. package/dist/chunk-FYYLNIL5.js +313 -0
  32. package/dist/{chunk-EPVUXGXG.js → chunk-HV5X7OR2.js} +14 -12
  33. package/dist/{chunk-TZTZS7QK.js → chunk-HXG4IURW.js} +5 -3
  34. package/dist/{chunk-IGLFWIYI.js → chunk-K6WL7QZT.js} +3 -3
  35. package/dist/chunk-K7VKOLQQ.js +15 -0
  36. package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
  37. package/dist/{chunk-V4RXGQ5Q.js → chunk-KRPY7NTG.js} +10 -7
  38. package/dist/chunk-LL4KHSZI.js +22 -0
  39. package/dist/{chunk-KJ5LWLOE.js → chunk-MEQ45TQ4.js} +15 -9
  40. package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
  41. package/dist/{chunk-AO4RKG4M.js → chunk-N4CZJQRK.js} +5 -5
  42. package/dist/{chunk-ARBGF5F7.js → chunk-NILBFAPG.js} +14 -8
  43. package/dist/chunk-OZNBF4L3.js +23 -0
  44. package/dist/{verify-G6V4D2G7.js → chunk-PCZJO5TI.js} +127 -42
  45. package/dist/chunk-QQK64KLB.js +1360 -0
  46. package/dist/{chunk-6EJV5X2W.js → chunk-QQL5RT5M.js} +979 -1619
  47. package/dist/{chunk-LZSJBIVT.js → chunk-QWU7ZBO7.js} +70 -720
  48. package/dist/{chunk-2EHAIA3X.js → chunk-RD5U66HV.js} +3 -3
  49. package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
  50. package/dist/{chunk-OQ33BKR3.js → chunk-TTNYS3EA.js} +3 -60
  51. package/dist/chunk-TW3WDMVS.js +677 -0
  52. package/dist/chunk-TZSKNMZG.js +434 -0
  53. package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
  54. package/dist/{chunk-7EYHLWU7.js → chunk-UZHIZC5S.js} +7 -7
  55. package/dist/{chunk-QTYWRVRA.js → chunk-VAWWTKDP.js} +8 -8
  56. package/dist/{chunk-X75S7HFS.js → chunk-VEZEGCGW.js} +214 -20
  57. package/dist/{chunk-OHHN2SO4.js → chunk-VMNQ6OZA.js} +98 -202
  58. package/dist/chunk-VSNATDE6.js +122 -0
  59. package/dist/chunk-W6GROXXM.js +69 -0
  60. package/dist/chunk-WPQLXFOZ.js +375 -0
  61. package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
  62. package/dist/{chunk-3ZXDFGR5.js → chunk-X6COSD2O.js} +5 -5
  63. package/dist/chunk-ZGVHUX3M.js +66 -0
  64. package/dist/{chunk-MAW544W2.js → chunk-ZWMF7253.js} +4 -4
  65. package/dist/{chunk-MQSRRFWA.js → chunk-ZYKPLLNQ.js} +563 -546
  66. package/dist/cli/index.js +27 -23
  67. package/dist/{clio-4LY5K2AC.js → clio-J5JIOIDS.js} +7 -6
  68. package/dist/{code-nav-7AX6FYE6.js → code-nav-AXCXSBHX.js} +5 -3
  69. package/dist/{config-GTLUW2PR.js → config-OEBMIN2U.js} +37 -27
  70. package/dist/{configure-R6A64DHX.js → configure-PUQOSIXQ.js} +16 -13
  71. package/dist/{context-5VKGUVJJ.js → context-EKDCKUUZ.js} +82 -7
  72. package/dist/{context-RW5HC47S.js → context-MGSE4Z2T.js} +33 -23
  73. package/dist/{context-JFZEJ7W5.js → context-URSXPBCK.js} +17 -9
  74. package/dist/{context-clear-6ZHBAZZT.js → context-clear-KDAJRNUK.js} +33 -23
  75. package/dist/context-working-set-SBKMPPI2.js +1552 -0
  76. package/dist/{dispatch-runner-VKBRCWQC.js → dispatch-runner-MSWN72NK.js} +43 -29
  77. package/dist/{doctor-KI767GSN.js → doctor-7BSE27PJ.js} +10 -10
  78. package/dist/{eval-XSSNATB4.js → eval-IZGDOO4H.js} +9 -8
  79. package/dist/{evidence-UA6AWDQQ.js → evidence-SR7WXB5B.js} +51 -23
  80. package/dist/{evolve-QNTFGV6Z.js → evolve-K7VE2CBX.js} +30 -20
  81. package/dist/{fleet-Q7UOMUSG.js → fleet-7XMJNQNF.js} +48 -38
  82. package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-AQNAH644.js} +3 -3
  83. package/dist/{init-WBB65ZHQ.js → init-JGNPAYXT.js} +41 -31
  84. package/dist/{memory-MD3O64RI.js → memory-4ALKDJ4Q.js} +32 -22
  85. package/dist/{models-BZU34YWD.js → models-ZMMLFJNN.js} +22 -19
  86. package/dist/{monitor-MEQA5C3I.js → monitor-2F3T5KHP.js} +55 -43
  87. package/dist/{orchestrator-CGFKEP27.js → orchestrator-ORHT43JB.js} +2507 -1896
  88. package/dist/{reset-L2FQEE3E.js → reset-NXGTYNUO.js} +4 -3
  89. package/dist/{run-IV4Q6RLN.js → run-RF4WJGMT.js} +51 -41
  90. package/dist/{share-S5BZQC5I.js → share-UT3W6E4M.js} +5 -4
  91. package/dist/{skills-LQEKRDTN.js → skills-PSACKC5Q.js} +2 -2
  92. package/dist/{skills-eval-3DC4HEWS.js → skills-eval-WJSI55RZ.js} +34 -24
  93. package/dist/{targets-C4SSGQOB.js → targets-PIIRAOYS.js} +23 -20
  94. package/dist/{terminal-lease-IT5JW2NR.js → terminal-lease-ULWXWNVY.js} +5 -4
  95. package/dist/{upgrade-7TT7SQ3G.js → upgrade-346TZ6AV.js} +18 -17
  96. package/dist/{usage-GV4PKT3M.js → usage-6KKXR32N.js} +34 -24
  97. package/dist/verifiers-4UUM6TEE.js +1214 -0
  98. package/dist/verify-X5HDROLA.js +25 -0
  99. package/dist/{wiki-generate-DQF6Z66B.js → wiki-generate-7STOCIFZ.js} +42 -31
  100. package/dist/worker/entry.js +33 -24
  101. package/docs/README.md +8 -7
  102. package/docs/acp.md +1 -1
  103. package/docs/alcf-provider.md +1 -1
  104. package/docs/architecture.md +2 -2
  105. package/docs/artifact-versions.md +1 -1
  106. package/docs/built-in-agents.md +1 -1
  107. package/docs/capacity-and-scheduling.md +1 -1
  108. package/docs/commands-and-modes.md +53 -21
  109. package/docs/config-knobs-audit.md +1 -2
  110. package/docs/configuration-and-targets.md +15 -1
  111. package/docs/context-engine.md +64 -12
  112. package/docs/context-working-set.md +194 -0
  113. package/docs/development-pipeline.md +1 -1
  114. package/docs/documentation-coverage.md +5 -5
  115. package/docs/documentation-guide.md +6 -5
  116. package/docs/environment-variables.md +2 -1
  117. package/docs/eval-runner.md +1 -1
  118. package/docs/evals-internal.md +14 -1
  119. package/docs/evidence-and-memory.md +74 -2
  120. package/docs/evolution.md +1 -1
  121. package/docs/exit-codes-and-output.md +1 -1
  122. package/docs/extensions-and-sharing.md +2 -2
  123. package/docs/fleet-dispatch.md +22 -7
  124. package/docs/glossary.md +21 -1
  125. package/docs/installation-and-lifecycle.md +6 -6
  126. package/docs/middleware-and-components.md +1 -1
  127. package/docs/model-catalog.md +7 -9
  128. package/docs/observability.md +4 -4
  129. package/docs/performance-methodology.md +2 -2
  130. package/docs/proactive-memory.md +1 -1
  131. package/docs/prompt-envelope-and-tools.md +4 -4
  132. package/docs/provider-adapter-cookbook.md +1 -1
  133. package/docs/release-cut-checklist.md +35 -35
  134. package/docs/safety-model.md +23 -4
  135. package/docs/scientific-validation.md +21 -3
  136. package/docs/session-lifecycle.md +3 -3
  137. package/docs/skills-marketplace.md +1 -1
  138. package/docs/tool-usage.md +79 -12
  139. package/docs/trace-store.md +1 -1
  140. package/docs/troubleshooting.md +1 -1
  141. package/docs/tui-design.md +2 -2
  142. package/docs/worker-dispatch-mechanics.md +11 -1
  143. package/package.json +8 -11
  144. package/skills/meta/clio-test/SKILL.md +20 -17
  145. package/skills/meta/clio-test/evals.md +3 -3
  146. package/skills/meta/clio-test/references/harness.md +35 -6
  147. package/skills/meta/clio-test/references/test-map.md +20 -10
  148. package/skills/registry.yaml +2 -2
  149. package/skills/skill-marketplace.json +1 -1
  150. package/src/cli/context-working-set.ts +513 -0
  151. package/src/cli/context.ts +8 -0
  152. package/src/cli/evidence.ts +20 -2
  153. package/src/cli/index.ts +4 -0
  154. package/src/cli/verifiers.ts +325 -0
  155. package/src/core/bash-exec.ts +39 -14
  156. package/src/core/bus-events.ts +19 -4
  157. package/src/core/config.ts +54 -0
  158. package/src/core/defaults.ts +50 -3
  159. package/src/core/git-commit-attribution.ts +46 -21
  160. package/src/core/verification-scripts.ts +6 -0
  161. package/src/domains/agents/builtins/verifier.md +3 -0
  162. package/src/domains/config/classify.ts +1 -0
  163. package/src/domains/config/keybindings.ts +3 -3
  164. package/src/domains/context/working-set/contract.ts +161 -0
  165. package/src/domains/context/working-set/defaults.ts +28 -0
  166. package/src/domains/context/working-set/engine.ts +203 -0
  167. package/src/domains/context/working-set/fold.ts +62 -0
  168. package/src/domains/context/working-set/horizon.ts +38 -0
  169. package/src/domains/context/working-set/marker.ts +103 -0
  170. package/src/domains/context/working-set/path-index.ts +436 -0
  171. package/src/domains/context/working-set/payload.ts +152 -0
  172. package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
  173. package/src/domains/context/working-set/policies/index.ts +21 -0
  174. package/src/domains/context/working-set/policies/structural.ts +160 -0
  175. package/src/domains/context/working-set/project.ts +132 -0
  176. package/src/domains/context/working-set/protect.ts +109 -0
  177. package/src/domains/context/working-set/recall.ts +177 -0
  178. package/src/domains/context/working-set/replay/controls.ts +112 -0
  179. package/src/domains/context/working-set/replay/load-clio.ts +199 -0
  180. package/src/domains/context/working-set/replay/metrics.ts +185 -0
  181. package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
  182. package/src/domains/context/working-set/replay/report.ts +139 -0
  183. package/src/domains/context/working-set/replay/runner.ts +325 -0
  184. package/src/domains/context/working-set/replay/synthetic.ts +422 -0
  185. package/src/domains/context/working-set/replay/trace.ts +21 -0
  186. package/src/domains/context/working-set/visible.ts +54 -0
  187. package/src/domains/evidence/build.ts +112 -45
  188. package/src/domains/evidence/eval.ts +24 -7
  189. package/src/domains/evidence/index.ts +53 -0
  190. package/src/domains/evidence/ordering.ts +12 -0
  191. package/src/domains/evidence/run-trust.ts +221 -0
  192. package/src/domains/evidence/store.ts +46 -6
  193. package/src/domains/evidence/trust-status.ts +854 -0
  194. package/src/domains/evidence/types.ts +26 -0
  195. package/src/domains/middleware/memory-intervention.ts +3 -0
  196. package/src/domains/middleware/stalled-turn.ts +165 -4
  197. package/src/domains/safety/autonomy.ts +1 -1
  198. package/src/domains/safety/default-path-policy.ts +8 -0
  199. package/src/domains/safety/finish-contract.ts +4 -3
  200. package/src/domains/safety/policy-engine.ts +48 -6
  201. package/src/domains/session/compaction/compact.ts +23 -1
  202. package/src/domains/session/compaction/cut-point.ts +2 -0
  203. package/src/domains/session/compaction/tokens.ts +16 -1
  204. package/src/domains/session/context-ledger.ts +2 -0
  205. package/src/domains/session/entries.ts +107 -1
  206. package/src/domains/session/manager.ts +9 -2
  207. package/src/domains/session/migrations/index.ts +22 -3
  208. package/src/engine/acp/server.ts +3 -0
  209. package/src/engine/agent.ts +18 -1
  210. package/src/engine/session.ts +9 -3
  211. package/src/entry/orchestrator.ts +16 -4
  212. package/src/interactive/chat-loop-messages.ts +18 -6
  213. package/src/interactive/chat-panel.ts +571 -244
  214. package/src/interactive/chat-renderer.ts +79 -39
  215. package/src/interactive/context-meter.ts +10 -0
  216. package/src/interactive/context-overlay.ts +81 -6
  217. package/src/interactive/context-recall-command.ts +110 -0
  218. package/src/interactive/editor-submit.ts +26 -1
  219. package/src/interactive/footer/widgets.ts +22 -20
  220. package/src/interactive/footer-panel.ts +6 -1
  221. package/src/interactive/interactive-application.ts +2 -0
  222. package/src/interactive/interactive-event-projection.ts +12 -0
  223. package/src/interactive/interactive-slash-runtime.ts +49 -8
  224. package/src/interactive/model-session-replay.ts +21 -0
  225. package/src/interactive/overlay-general-openers.ts +6 -0
  226. package/src/interactive/overlay-session-lifecycle.ts +8 -4
  227. package/src/interactive/overlays/ask-user.ts +146 -24
  228. package/src/interactive/renderers/tool-execution.ts +167 -56
  229. package/src/interactive/session-transcript.ts +2 -2
  230. package/src/interactive/slash-commands.ts +29 -2
  231. package/src/interactive/status/index.ts +12 -1
  232. package/src/interactive/status/reasoning.ts +87 -0
  233. package/src/interactive/status/summary.ts +13 -2
  234. package/src/interactive/transcript-detail.ts +120 -0
  235. package/src/interactive/turn-context.ts +238 -88
  236. package/src/interactive/turn-middleware.ts +6 -6
  237. package/src/tools/agent-tools.ts +11 -4
  238. package/src/tools/bash.ts +144 -82
  239. package/src/tools/builtin-tool-catalog.ts +18 -6
  240. package/src/tools/context/index.ts +105 -3
  241. package/src/tools/context/surface.ts +3 -2
  242. package/src/tools/core-bootstrap.ts +21 -0
  243. package/src/tools/dispatch-runner.ts +9 -7
  244. package/src/tools/monitor.ts +28 -20
  245. package/src/tools/presentation.ts +107 -0
  246. package/src/tools/registry.ts +65 -7
  247. package/src/tools/result-disposition.ts +550 -0
  248. package/src/tools/result-shaping.ts +262 -19
  249. package/src/tools/safe-exec.ts +2 -0
  250. package/src/tools/verify/authoring.ts +1119 -0
  251. package/src/tools/verify/catalog.ts +346 -0
  252. package/src/tools/verify/index.ts +13 -3
  253. package/src/tools/verify/scripts.ts +135 -37
  254. package/src/tools/verify/surface.ts +9 -5
  255. package/src/tools/worker-evidence.ts +35 -12
  256. package/dist/chunk-MNA4JGU4.js +0 -255
  257. package/dist/chunk-SRF2PJNW.js +0 -184
  258. package/dist/chunk-T6YILFSB.js +0 -80
  259. package/dist/chunk-VAKQQHWR.js +0 -434
@@ -1,18 +1,24 @@
1
1
  import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
2
  import {
3
3
  AGENT_AUTOMATION_AUTHORITIES,
4
+ classify
5
+ } from "./chunk-AOCYTWAV.js";
6
+ import {
4
7
  artifactDefaultPath,
5
- classify,
6
8
  detectValidationCommand,
7
9
  extractCommandDeleteTargets,
8
10
  extractCommandWriteTargets,
9
11
  inlineShellScript,
10
12
  tokenizeShellLike,
11
13
  toolMutationPaths
12
- } from "./chunk-5UUP6MWO.js";
14
+ } from "./chunk-MV3K5QF2.js";
15
+ import {
16
+ loadProjectVerifierCatalog
17
+ } from "./chunk-FYYLNIL5.js";
13
18
  import {
19
+ isProjectVerifierCheckId,
14
20
  isVerificationScriptName
15
- } from "./chunk-7MNJORFF.js";
21
+ } from "./chunk-UL3WSD3F.js";
16
22
  import {
17
23
  canonicalizeExistingPath
18
24
  } from "./chunk-ECH6PKUQ.js";
@@ -974,8 +980,9 @@ function typedValidationSummary(toolName, payload) {
974
980
  const path5 = typeof args?.path === "string" && args.path.trim().length > 0 ? args.path.trim() : "artifact";
975
981
  return `verify frontend ${path5}`;
976
982
  }
977
- if (!isVerificationScriptName(check)) return null;
978
- return `npm run ${check}`;
983
+ if (isVerificationScriptName(check)) return `npm run ${check}`;
984
+ if (isProjectVerifierCheckId(check)) return `verify ${check}`;
985
+ return null;
979
986
  }
980
987
  return null;
981
988
  }
@@ -1156,7 +1163,7 @@ function autonomyAskRejection(level, tool, actionClass, exposure = DEFAULT_AUTON
1156
1163
  // and models otherwise stall retrying denied bash for checks or
1157
1164
  // directory listings.
1158
1165
  ...actionClass === "execute" ? [
1159
- 'A declared package.json check runs without approval through the verify tool: verify(check="<script>").',
1166
+ 'A declared package or project-catalog check runs without approval through the verify tool: verify(check="<id>").',
1160
1167
  "Read-only inspection runs without approval through the ls, read, grep, and find tools."
1161
1168
  ] : []
1162
1169
  ]
@@ -1326,6 +1333,14 @@ var DEFAULT_DAMAGE_CONTROL_PATH_POLICY = {
1326
1333
  "*.dump"
1327
1334
  ],
1328
1335
  readOnlyPaths: [
1336
+ // Clio's own operator-authority files in the project. `safety.yaml` is the
1337
+ // policy that gates the model's tools, and `verifiers.yaml` is an argv
1338
+ // catalog that verify() executes; a model that can author either one can
1339
+ // widen its own permissions in two tool calls. Both are authored by the
1340
+ // operator through the CLI (`clio-coder verifiers author` lands nothing
1341
+ // before `--yes`), so model-side writes and deletes are refused.
1342
+ ".clio-coder/safety.yaml",
1343
+ ".clio-coder/verifiers.yaml",
1329
1344
  "/etc/",
1330
1345
  "/usr/",
1331
1346
  "/bin/",
@@ -1914,7 +1929,9 @@ function createSafetyPolicyEngine(options = {}) {
1914
1929
  const rawClassification = classify(call);
1915
1930
  const command = commandArg(call.args);
1916
1931
  const callCwd = cwdArg(call.args, cwd);
1917
- const scan = damageControlScan(call);
1932
+ const catalogCheck = resolveVerifyCatalogCheck(call, cwd);
1933
+ const catalogCommand = catalogCheck === null ? null : catalogCheck.command.join(" ");
1934
+ const scan = catalogCommand ?? damageControlScan(call);
1918
1935
  const hit = scan ? matchSourcedRule(scan, sourcedRules) : null;
1919
1936
  const classification = effectiveClassification(rawClassification, hit?.match);
1920
1937
  const base = baseDecision(call, classification, callCwd, posture, command);
@@ -1971,8 +1988,9 @@ function createSafetyPolicyEngine(options = {}) {
1971
1988
  if (projectPolicy.path !== null) blockInput.projectPolicyPath = projectPolicy.path;
1972
1989
  return blockDecision(base, blockInput);
1973
1990
  }
1974
- if (call.tool === ToolNames.Bash && command !== null) {
1975
- const secretRead = evaluateBashZeroAccessRead(zeroAccessPolicy, command, callCwd);
1991
+ const scannedCommand = call.tool === ToolNames.Bash ? command : catalogCommand;
1992
+ if (scannedCommand !== null) {
1993
+ const secretRead = evaluateBashZeroAccessRead(zeroAccessPolicy, scannedCommand, callCwd);
1976
1994
  if (secretRead !== null) {
1977
1995
  const blockInput = {
1978
1996
  ruleId: "secret_path_bash",
@@ -2027,7 +2045,15 @@ function createSafetyPolicyEngine(options = {}) {
2027
2045
  };
2028
2046
  if (hit?.match.ruleId !== void 0) allowInput.ruleId = hit.match.ruleId;
2029
2047
  if (hit?.match !== void 0) allowInput.match = hit.match;
2030
- if (classification.actionClass === "execute") allowInput.execRecognition = "recognized";
2048
+ if (classification.actionClass === "execute") {
2049
+ allowInput.execRecognition = catalogCheck === null ? "recognized" : "unrecognized";
2050
+ if (catalogCheck !== null) {
2051
+ allowInput.reasons = [
2052
+ ...allowInput.reasons,
2053
+ `project verifier '${catalogCheck.id}' runs declared argv: ${catalogCommand ?? ""}`
2054
+ ];
2055
+ }
2056
+ }
2031
2057
  return allowDecision(base, allowInput);
2032
2058
  },
2033
2059
  metadata() {
@@ -2396,6 +2422,20 @@ function damageControlScan(call) {
2396
2422
  const pathArg2 = call.args?.path;
2397
2423
  return typeof pathArg2 === "string" ? pathArg2 : "";
2398
2424
  }
2425
+ function resolveVerifyCatalogCheck(call, workspaceRoot) {
2426
+ if (call.tool !== ToolNames.Verify) return null;
2427
+ const check = call.args?.check;
2428
+ if (typeof check !== "string") return null;
2429
+ const id = check.trim();
2430
+ if (id.length === 0 || id === "frontend") return null;
2431
+ try {
2432
+ const catalog = loadProjectVerifierCatalog(workspaceRoot);
2433
+ if (!catalog.ok || catalog.source === null) return null;
2434
+ return catalog.source.checks.find((candidate) => candidate.id === id) ?? null;
2435
+ } catch {
2436
+ return null;
2437
+ }
2438
+ }
2399
2439
  function serializeArgs(args) {
2400
2440
  if (!args) return "";
2401
2441
  const parts = [];
@@ -2453,4 +2493,4 @@ export {
2453
2493
  WRITE_ROOT_REFUSED_TOOLS,
2454
2494
  createSafetyPolicyEngine
2455
2495
  };
2456
- //# sourceMappingURL=chunk-STBPMHSX.js.map
2496
+ //# sourceMappingURL=chunk-7RXG6QRZ.js.map
@@ -7,10 +7,10 @@ import {
7
7
  fingerprintNativeRuntime,
8
8
  interopProposals,
9
9
  renderProposalEntry
10
- } from "./chunk-2EHAIA3X.js";
10
+ } from "./chunk-RD5U66HV.js";
11
11
  import {
12
12
  initializeClioHome
13
- } from "./chunk-BMEMKKIT.js";
13
+ } from "./chunk-KOHPCX4K.js";
14
14
  import {
15
15
  createDelayedManualCodeInput,
16
16
  promptOAuthSelection
@@ -44,13 +44,13 @@ import {
44
44
  probeCapabilitiesForModel,
45
45
  registerBuiltinRuntimes,
46
46
  supportGroupLabel
47
- } from "./chunk-LZSJBIVT.js";
47
+ } from "./chunk-QWU7ZBO7.js";
48
48
  import {
49
49
  readSettings,
50
50
  removeTargetFromSettings,
51
51
  settingsPath,
52
52
  updateSettings
53
- } from "./chunk-A3CYT5EX.js";
53
+ } from "./chunk-AD2SYQYC.js";
54
54
  import {
55
55
  openAuthStorage,
56
56
  registerClioOAuthProviders,
@@ -1489,4 +1489,4 @@ export {
1489
1489
  runTargetRename,
1490
1490
  runConfigureCommand
1491
1491
  };
1492
- //# sourceMappingURL=chunk-77VKQEHF.js.map
1492
+ //# sourceMappingURL=chunk-A2GZF7DC.js.map
@@ -5,7 +5,7 @@ import {
5
5
  ACTIVE_ROUTING_ROLES,
6
6
  DEFAULT_SETTINGS,
7
7
  THINKING_LEVELS
8
- } from "./chunk-ZDOOVTXZ.js";
8
+ } from "./chunk-4OC57DA6.js";
9
9
  import {
10
10
  MAX_TIMER_DELAY_MS
11
11
  } from "./chunk-FQ4SKYE4.js";
@@ -783,6 +783,7 @@ var TOP_LEVEL_KEYS = [
783
783
  "delegation",
784
784
  "keybindings",
785
785
  "compaction",
786
+ "context",
786
787
  "retry",
787
788
  "guardrails"
788
789
  ];
@@ -1182,6 +1183,58 @@ function validateSettings(raw) {
1182
1183
  }
1183
1184
  }
1184
1185
  }
1186
+ if ("context" in raw) {
1187
+ if (!isPlainObject(raw.context)) {
1188
+ issues.add("context", `expected a map, got ${describe(raw.context)}`);
1189
+ } else {
1190
+ issues.unknownKeys("context", raw.context, ["workingSet"]);
1191
+ if ("workingSet" in raw.context) {
1192
+ if (!isPlainObject(raw.context.workingSet)) {
1193
+ issues.add("context.workingSet", `expected a map, got ${describe(raw.context.workingSet)}`);
1194
+ } else {
1195
+ const workingSet = raw.context.workingSet;
1196
+ issues.unknownKeys("context.workingSet", workingSet, [
1197
+ "enabled",
1198
+ "policy",
1199
+ "target",
1200
+ "protectLastTurns",
1201
+ "minEvictableTokens"
1202
+ ]);
1203
+ if ("enabled" in workingSet) {
1204
+ const v = expectBoolean(issues, "context.workingSet.enabled", workingSet.enabled);
1205
+ if (v !== void 0) settings.context.workingSet.enabled = v;
1206
+ }
1207
+ if ("policy" in workingSet) {
1208
+ const v = expectEnum(issues, "context.workingSet.policy", workingSet.policy, [
1209
+ "age-horizon",
1210
+ "structural-v1"
1211
+ ]);
1212
+ if (v !== void 0) settings.context.workingSet.policy = v;
1213
+ }
1214
+ if ("target" in workingSet) {
1215
+ const v = expectNumber(issues, "context.workingSet.target", workingSet.target);
1216
+ if (v !== void 0 && (v <= 0 || v >= 1)) {
1217
+ issues.add("context.workingSet.target", `expected a number > 0 and < 1, got ${v}`);
1218
+ } else if (v !== void 0) {
1219
+ settings.context.workingSet.target = v;
1220
+ }
1221
+ }
1222
+ if ("protectLastTurns" in workingSet) {
1223
+ const v = expectInteger(issues, "context.workingSet.protectLastTurns", workingSet.protectLastTurns, {
1224
+ min: 1
1225
+ });
1226
+ if (v !== void 0) settings.context.workingSet.protectLastTurns = v;
1227
+ }
1228
+ if ("minEvictableTokens" in workingSet) {
1229
+ const v = expectInteger(issues, "context.workingSet.minEvictableTokens", workingSet.minEvictableTokens, {
1230
+ min: 0
1231
+ });
1232
+ if (v !== void 0) settings.context.workingSet.minEvictableTokens = v;
1233
+ }
1234
+ }
1235
+ }
1236
+ }
1237
+ }
1185
1238
  if ("retry" in raw) {
1186
1239
  if (!isPlainObject(raw.retry)) {
1187
1240
  issues.add("retry", `expected a map, got ${describe(raw.retry)}`);
@@ -1390,4 +1443,4 @@ export {
1390
1443
  removeFleetProfileFromSettings,
1391
1444
  bindAgentProfileInSettings
1392
1445
  };
1393
- //# sourceMappingURL=chunk-A3CYT5EX.js.map
1446
+ //# sourceMappingURL=chunk-AD2SYQYC.js.map
@@ -0,0 +1,449 @@
1
+ import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
2
+ import {
3
+ artifactDefaultPath,
4
+ extractCommandCdTargets,
5
+ extractCommandWriteTargets
6
+ } from "./chunk-MV3K5QF2.js";
7
+ import {
8
+ canonicalizeExistingPath
9
+ } from "./chunk-ECH6PKUQ.js";
10
+ import {
11
+ ToolNames,
12
+ isBuiltinToolName
13
+ } from "./chunk-CGKSTWHD.js";
14
+ import {
15
+ init_esm_shims
16
+ } from "./chunk-3R73A4XB.js";
17
+
18
+ // src/domains/agents/spec.ts
19
+ init_esm_shims();
20
+ import { createHash } from "node:crypto";
21
+
22
+ // src/domains/safety/action-classifier.ts
23
+ init_esm_shims();
24
+ import path from "node:path";
25
+ var GIT_DESTRUCTIVE_PATTERNS = [
26
+ { name: "git-push-force-long", re: /\bgit\s+push\s+--force\b/i },
27
+ { name: "git-push-force-short", re: /\bgit\s+push\s+-f\b/i },
28
+ { name: "git-reset-hard", re: /\bgit\s+reset\s+--hard\b/i },
29
+ { name: "git-clean-fd", re: /\bgit\s+clean\s+-fd?\b/i },
30
+ { name: "git-checkout-dot", re: /\bgit\s+checkout\s+--\s+\./i },
31
+ { name: "git-branch-D", re: /\bgit\s+branch\s+-D\b/i },
32
+ { name: "git-restore-source", re: /\bgit\s+restore\s+--source\b/i }
33
+ ];
34
+ var SYSTEM_MODIFY_PATTERNS = [
35
+ { name: "sudo-or-doas", re: /\b(sudo|doas)\b/i },
36
+ // allow rm -rf /tmp/... and /var/tmp/... but flag everything else rooted at /
37
+ { name: "rm-rf-root", re: /\brm\s+-rf?\s+\/(?!(tmp|var\/tmp)(?:\/|\s|$))/i },
38
+ { name: "apt-install", re: /\bapt(-get)?\s+(install|remove|purge)/i },
39
+ { name: "brew-install", re: /\bbrew\s+(install|uninstall|reinstall)/i },
40
+ { name: "npm-install-global", re: /\bnpm\s+install\s+-g\b/i },
41
+ { name: "pip-install", re: /\bpip\s+install\b/i },
42
+ { name: "systemctl", re: /\bsystemctl\s+/i },
43
+ { name: "chmod-root", re: /\bchmod\s+[0-7]{3,4}\s+\//i },
44
+ { name: "chown", re: /\bchown\s+/i }
45
+ ];
46
+ var SYSTEM_WRITE_ROOT_PREFIXES = ["/etc", "/usr", "/var", "/bin", "/sbin", "/run"];
47
+ var SYSTEM_WRITE_EXEMPT_PREFIXES = ["/var/tmp", "/var/folders"];
48
+ function isUnderPrefix(abs, prefix) {
49
+ return abs === prefix || abs.startsWith(`${prefix}/`);
50
+ }
51
+ function baseClassify(tool) {
52
+ switch (tool) {
53
+ case ToolNames.Read:
54
+ case ToolNames.Grep:
55
+ case ToolNames.Find:
56
+ case ToolNames.Ls:
57
+ case ToolNames.WebFetch:
58
+ case ToolNames.Git:
59
+ case ToolNames.CodeNav:
60
+ case ToolNames.Context:
61
+ case ToolNames.Monitor:
62
+ case ToolNames.AskUser:
63
+ case ToolNames.CredentialPresent:
64
+ // tasks pick mutates only Clio-owned session-ledger and project-local
65
+ // .clio-coder runtime state, never source-workspace files. By intentional
66
+ // policy it stays read class and ungated; the tool itself still requires
67
+ // a durable operator task id before it can mutate either store.
68
+ case ToolNames.Tasks:
69
+ // ledger posts a typed contribution to a coordination board and reads a
70
+ // local mirror. Neither touches the workspace, so it is never gated
71
+ // behind a confirmation.
72
+ case ToolNames.Ledger:
73
+ return "read";
74
+ case ToolNames.Write:
75
+ case ToolNames.Edit:
76
+ case ToolNames.Artifact:
77
+ return "write";
78
+ case ToolNames.Bash:
79
+ case ToolNames.Verify:
80
+ return "execute";
81
+ case ToolNames.Dispatch:
82
+ case ToolNames.Steer:
83
+ return "dispatch";
84
+ default:
85
+ return null;
86
+ }
87
+ }
88
+ function scanStringOf(args) {
89
+ if (!args) return "";
90
+ const parts = [];
91
+ for (const value of Object.values(args)) {
92
+ if (value == null) continue;
93
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
94
+ parts.push(String(value));
95
+ } else {
96
+ try {
97
+ parts.push(JSON.stringify(value));
98
+ } catch {
99
+ }
100
+ }
101
+ }
102
+ return parts.join(" ");
103
+ }
104
+ function matchFirst(patterns, haystack) {
105
+ for (const p of patterns) {
106
+ if (p.re.test(haystack)) return p;
107
+ }
108
+ return null;
109
+ }
110
+ function resolveCandidate(p, baseCwd) {
111
+ if (p.startsWith("~")) return p;
112
+ const base = canonicalizeExistingPath(path.resolve(baseCwd ?? process.cwd()));
113
+ const resolved = path.isAbsolute(p) ? path.resolve(p) : path.resolve(base, p);
114
+ return canonicalizeExistingPath(resolved);
115
+ }
116
+ function isInsideCwd(abs) {
117
+ const cwd = canonicalizeExistingPath(path.resolve(process.cwd()));
118
+ const candidate = canonicalizeExistingPath(abs);
119
+ const rel = path.relative(cwd, candidate);
120
+ return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
121
+ }
122
+ function writePathClass(pathArg, baseCwd) {
123
+ if (pathArg.startsWith("~")) {
124
+ return { cls: "system_modify", reason: `write-path-home-escape: ${pathArg}` };
125
+ }
126
+ const abs = resolveCandidate(pathArg, baseCwd);
127
+ const exempt = SYSTEM_WRITE_EXEMPT_PREFIXES.some((prefix) => isUnderPrefix(abs, prefix));
128
+ if (!exempt) {
129
+ for (const prefix of SYSTEM_WRITE_ROOT_PREFIXES) {
130
+ if (isUnderPrefix(abs, prefix)) {
131
+ return { cls: "system_modify", reason: `write-path-system-root: ${prefix}` };
132
+ }
133
+ }
134
+ }
135
+ if (!isInsideCwd(abs)) {
136
+ return { cls: "system_modify", reason: `write-path-outside-cwd: ${abs}` };
137
+ }
138
+ return { cls: "write" };
139
+ }
140
+ function extractWritePath(tool, args) {
141
+ const candidate = args?.path ?? args?.file_path ?? args?.filePath;
142
+ if (typeof candidate === "string" && candidate.length > 0) return candidate;
143
+ return tool === ToolNames.Artifact ? artifactDefaultPath(args?.kind) : null;
144
+ }
145
+ function classify(call) {
146
+ const base = baseClassify(call.tool);
147
+ if (base === null) {
148
+ return { actionClass: "unknown", reasons: [`unknown tool: ${call.tool}`] };
149
+ }
150
+ const reasons = [];
151
+ if (call.tool === ToolNames.Bash) {
152
+ const scan = scanStringOf(call.args);
153
+ const gitHit = matchFirst(GIT_DESTRUCTIVE_PATTERNS, scan);
154
+ if (gitHit) {
155
+ return { actionClass: "git_destructive", reasons: [`pattern:${gitHit.name}`] };
156
+ }
157
+ const sysHit = matchFirst(SYSTEM_MODIFY_PATTERNS, scan);
158
+ if (sysHit) {
159
+ return { actionClass: "system_modify", reasons: [`pattern:${sysHit.name}`] };
160
+ }
161
+ const command = typeof call.args?.command === "string" ? call.args.command : null;
162
+ const argCwd = typeof call.args?.cwd === "string" && call.args.cwd.length > 0 ? call.args.cwd : void 0;
163
+ if (command !== null) {
164
+ const targetReasons = [];
165
+ for (const target of extractCommandWriteTargets(command)) {
166
+ const decision = writePathClass(target, argCwd);
167
+ if (decision.cls === "system_modify") {
168
+ targetReasons.push(decision.reason ?? `bash-write-target: ${target}`);
169
+ }
170
+ }
171
+ for (const target of extractCommandCdTargets(command)) {
172
+ if (target.startsWith("~")) {
173
+ targetReasons.push(`bash-cd-home-escape: ${target}`);
174
+ continue;
175
+ }
176
+ const abs = resolveCandidate(target, argCwd);
177
+ if (!isInsideCwd(abs)) {
178
+ targetReasons.push(`bash-cd-outside-workspace: ${abs}`);
179
+ }
180
+ }
181
+ if (targetReasons.length > 0) {
182
+ return { actionClass: "system_modify", reasons: targetReasons };
183
+ }
184
+ }
185
+ return { actionClass: "execute", reasons };
186
+ }
187
+ if (base === "write") {
188
+ const pathArg = extractWritePath(call.tool, call.args);
189
+ if (pathArg) {
190
+ const decision = writePathClass(pathArg);
191
+ if (decision.cls === "system_modify") {
192
+ return { actionClass: "system_modify", reasons: decision.reason ? [decision.reason] : [] };
193
+ }
194
+ }
195
+ return { actionClass: "write", reasons };
196
+ }
197
+ return { actionClass: base, reasons };
198
+ }
199
+
200
+ // src/domains/agents/spec.ts
201
+ var AGENT_AUTOMATION_AUTHORITIES = ["read-only", "verification", "artifact-write", "workspace-edit"];
202
+ var AGENT_PRODUCTS = ["orientation"];
203
+ var AGENT_CATEGORIES = [
204
+ "explore",
205
+ "plan",
206
+ "research",
207
+ "implement",
208
+ "quality",
209
+ "science",
210
+ "evolution",
211
+ "operations",
212
+ "internal"
213
+ ];
214
+ var AGENT_CAPABILITY_CLASSES = [
215
+ "read-only",
216
+ "artifact-write",
217
+ "workspace-edit",
218
+ "verification",
219
+ "orchestration",
220
+ "internal"
221
+ ];
222
+ var AGENT_LATENCY_CLASSES = ["fast", "balanced", "deep"];
223
+ var AGENT_AUDIENCES = ["base", "shadow", "custom", "internal"];
224
+ var AGENT_PROJECT_CONTEXT_TIERS = ["none", "bounded"];
225
+ function includes(values, value) {
226
+ return typeof value === "string" && values.includes(value);
227
+ }
228
+ function isAgentCategory(value) {
229
+ return includes(AGENT_CATEGORIES, value);
230
+ }
231
+ function isAgentCapabilityClass(value) {
232
+ return includes(AGENT_CAPABILITY_CLASSES, value);
233
+ }
234
+ function isAgentLatencyClass(value) {
235
+ return includes(AGENT_LATENCY_CLASSES, value);
236
+ }
237
+ function isAgentAudience(value) {
238
+ return includes(AGENT_AUDIENCES, value);
239
+ }
240
+ function isAgentProjectContextTier(value) {
241
+ return includes(AGENT_PROJECT_CONTEXT_TIERS, value);
242
+ }
243
+ function isAgentProduct(value) {
244
+ return includes(AGENT_PRODUCTS, value);
245
+ }
246
+ function actionClassesForTools(tools) {
247
+ const actions = /* @__PURE__ */ new Set();
248
+ for (const tool of tools) actions.add(classify({ tool }).actionClass);
249
+ return actions;
250
+ }
251
+ function normalizeTools(recipe) {
252
+ const seen = /* @__PURE__ */ new Set();
253
+ const tools = [];
254
+ for (const tool of recipe.tools) {
255
+ if (typeof tool !== "string" || tool.trim().length === 0) {
256
+ throw new Error(`agent recipe '${recipe.id}' declares an invalid tool name`);
257
+ }
258
+ if (seen.has(tool)) continue;
259
+ seen.add(tool);
260
+ tools.push(isBuiltinToolName(tool) ? tool : tool);
261
+ }
262
+ return tools;
263
+ }
264
+ function asToolName(tool) {
265
+ return isBuiltinToolName(tool) ? tool : tool;
266
+ }
267
+ function normalizeToolRequirements(recipe, tools) {
268
+ if (!recipe.toolRequirements) {
269
+ throw new Error(`agent recipe '${recipe.id}' must declare tools.required and tools.optional`);
270
+ }
271
+ const declared = new Set(tools);
272
+ const required = recipe.toolRequirements.required.map((requirement, index) => {
273
+ if (typeof requirement === "string") return asToolName(requirement);
274
+ if (!Array.isArray(requirement.anyOf) || requirement.anyOf.length === 0) {
275
+ throw new Error(`agent recipe '${recipe.id}' tools.required[${index}].anyOf must be non-empty`);
276
+ }
277
+ return { anyOf: requirement.anyOf.map(asToolName) };
278
+ });
279
+ const optional = recipe.toolRequirements.optional.map(asToolName);
280
+ const mentioned = required.flatMap(
281
+ (requirement) => typeof requirement === "string" ? [requirement] : requirement.anyOf
282
+ );
283
+ for (const tool of [...mentioned, ...optional]) {
284
+ if (!declared.has(tool)) throw new Error(`agent recipe '${recipe.id}' requirement '${tool}' is not declared`);
285
+ }
286
+ if ((/* @__PURE__ */ new Set([...mentioned, ...optional])).size !== mentioned.length + optional.length) {
287
+ throw new Error(`agent recipe '${recipe.id}' contains duplicate tool requirements`);
288
+ }
289
+ if ((/* @__PURE__ */ new Set([...mentioned, ...optional])).size !== tools.length) {
290
+ throw new Error(`agent recipe '${recipe.id}' has declared tools without required/optional semantics`);
291
+ }
292
+ return { required, optional };
293
+ }
294
+ function resolveAgentToolCompatibility(spec, effectiveTools, options) {
295
+ const available = new Set(effectiveTools);
296
+ const missingRequired = [];
297
+ for (const requirement of spec.toolRequirements.required) {
298
+ if (typeof requirement === "string") {
299
+ if (!available.has(requirement)) missingRequired.push(requirement);
300
+ continue;
301
+ }
302
+ if (!requirement.anyOf.some((tool) => available.has(tool))) {
303
+ missingRequired.push(`anyOf(${requirement.anyOf.join("|")})`);
304
+ }
305
+ }
306
+ if (available.has(ToolNames.Dispatch) && !options.mediatesDispatch) {
307
+ missingRequired.push("dispatch(runtime mediation unavailable)");
308
+ }
309
+ return {
310
+ compatible: missingRequired.length === 0,
311
+ missingRequired,
312
+ lostOptional: spec.toolRequirements.optional.filter((tool) => !available.has(tool))
313
+ };
314
+ }
315
+ function normalizeAgentSpec(recipe) {
316
+ const tools = normalizeTools(recipe);
317
+ const toolRequirements = normalizeToolRequirements(recipe, tools);
318
+ return {
319
+ version: recipe.version,
320
+ id: recipe.id,
321
+ name: recipe.name,
322
+ description: recipe.description,
323
+ source: recipe.source,
324
+ filepath: recipe.filepath,
325
+ tools,
326
+ toolRequirements,
327
+ category: recipe.category,
328
+ capabilityClass: recipe.capabilityClass,
329
+ latencyClass: recipe.latencyClass,
330
+ projectContextTier: recipe.projectContextTier,
331
+ audience: recipe.audience,
332
+ tags: recipe.tags,
333
+ skills: recipe.skills,
334
+ resultContract: recipe.resultContract,
335
+ ...recipe.product !== void 0 ? { product: recipe.product } : {},
336
+ budget: recipe.budget,
337
+ body: recipe.body
338
+ };
339
+ }
340
+ function agentSpecFingerprint(spec) {
341
+ const requirement = (entry) => typeof entry === "string" ? entry : `anyOf(${[...entry.anyOf].sort().join("|")})`;
342
+ const payload = JSON.stringify({
343
+ id: spec.id,
344
+ tools: [...spec.tools].sort(),
345
+ required: spec.toolRequirements.required.map(requirement).sort(),
346
+ optional: [...spec.toolRequirements.optional].sort(),
347
+ capabilityClass: spec.capabilityClass,
348
+ latencyClass: spec.latencyClass,
349
+ projectContextTier: spec.projectContextTier,
350
+ audience: spec.audience,
351
+ skills: [...spec.skills].sort(),
352
+ resultContract: spec.resultContract,
353
+ budget: spec.budget,
354
+ body: createHash("sha256").update(spec.body, "utf8").digest("hex")
355
+ });
356
+ return createHash("sha256").update(payload, "utf8").digest("hex");
357
+ }
358
+ function isUserVisibleAgent(spec) {
359
+ return spec.audience === "base" || spec.audience === "custom";
360
+ }
361
+ function isShadowAgent(spec) {
362
+ return spec.audience === "shadow" || spec.audience === "internal";
363
+ }
364
+ function agentSpecPolicyErrors(spec) {
365
+ const errors = [];
366
+ const actions = actionClassesForTools(spec.tools);
367
+ const requiredGroups = spec.toolRequirements.required.map(
368
+ (requirement) => typeof requirement === "string" ? [requirement] : requirement.anyOf
369
+ );
370
+ const requiresTool = (tool) => requiredGroups.some((group) => group.length > 0 && group.every((candidate) => candidate === tool));
371
+ const requiresMutation = requiredGroups.some(
372
+ (group) => group.length > 0 && group.every((tool) => tool === ToolNames.Write || tool === ToolNames.Edit)
373
+ );
374
+ if (spec.capabilityClass === "workspace-edit" && (!requiresTool(ToolNames.Read) || !requiresMutation)) {
375
+ errors.push(`workspace-edit agent '${spec.id}' must require read and write|edit`);
376
+ }
377
+ if (spec.capabilityClass === "verification" && !requiresTool(ToolNames.Verify)) {
378
+ errors.push(`verification agent '${spec.id}' must require verify`);
379
+ }
380
+ if (spec.capabilityClass === "artifact-write" && !requiresTool(ToolNames.Artifact)) {
381
+ errors.push(`artifact-write agent '${spec.id}' must require artifact`);
382
+ }
383
+ if (spec.skills.length > 0 && !requiresTool(ToolNames.Context)) {
384
+ errors.push(`agent '${spec.id}' must require context for bound skills`);
385
+ }
386
+ if (spec.capabilityClass === "orchestration" && spec.tools.includes(ToolNames.Dispatch) && !requiresTool(ToolNames.Dispatch)) {
387
+ errors.push(`orchestration agent '${spec.id}' must require dispatch when it is declared`);
388
+ }
389
+ const toolList = spec.tools.join(", ");
390
+ if (spec.capabilityClass === "read-only") {
391
+ for (const action of actions) {
392
+ if (action !== "read") errors.push(`read-only agent '${spec.id}' requests ${action} tools (${toolList})`);
393
+ }
394
+ }
395
+ if (spec.capabilityClass === "artifact-write") {
396
+ for (const tool of spec.tools) {
397
+ const action = classify({ tool }).actionClass;
398
+ if (action === "execute" || action === "dispatch" || action === "system_modify" || action === "git_destructive") {
399
+ errors.push(`artifact-write agent '${spec.id}' requests ${action} tool '${tool}'`);
400
+ }
401
+ if (action === "write" && tool !== ToolNames.Artifact) {
402
+ errors.push(`artifact-write agent '${spec.id}' can only write terminal artifacts; got '${tool}'`);
403
+ }
404
+ }
405
+ }
406
+ if (spec.capabilityClass === "verification") {
407
+ for (const tool of spec.tools) {
408
+ const action = classify({ tool }).actionClass;
409
+ if (action === "write" || action === "dispatch" || action === "system_modify" || action === "git_destructive") {
410
+ errors.push(`verification agent '${spec.id}' must not request ${action} tool '${tool}'`);
411
+ }
412
+ if (tool === ToolNames.Bash)
413
+ errors.push(`verification agent '${spec.id}' must use typed validation tools, not bash`);
414
+ }
415
+ }
416
+ if (spec.capabilityClass !== "orchestration" && spec.tools.includes(ToolNames.Dispatch)) {
417
+ errors.push(`agent '${spec.id}' exposes dispatch without orchestration capability`);
418
+ }
419
+ if (spec.tools.includes(ToolNames.AskUser)) {
420
+ errors.push(`agent '${spec.id}' exposes ask_user, which is only available to the orchestrator`);
421
+ }
422
+ if (spec.skills.length > 0 && !spec.tools.includes(ToolNames.Context)) {
423
+ errors.push(`agent '${spec.id}' declares skills but does not expose context`);
424
+ }
425
+ return errors;
426
+ }
427
+ function assertAgentSpecPolicy(spec) {
428
+ const errors = agentSpecPolicyErrors(spec);
429
+ if (errors.length > 0) throw new Error(`agent policy violation:
430
+ ${errors.map((error) => `- ${error}`).join("\n")}`);
431
+ }
432
+
433
+ export {
434
+ classify,
435
+ AGENT_AUTOMATION_AUTHORITIES,
436
+ isAgentCategory,
437
+ isAgentCapabilityClass,
438
+ isAgentLatencyClass,
439
+ isAgentAudience,
440
+ isAgentProjectContextTier,
441
+ isAgentProduct,
442
+ resolveAgentToolCompatibility,
443
+ normalizeAgentSpec,
444
+ agentSpecFingerprint,
445
+ isUserVisibleAgent,
446
+ isShadowAgent,
447
+ assertAgentSpecPolicy
448
+ };
449
+ //# sourceMappingURL=chunk-AOCYTWAV.js.map