@iowarp/clio-coder 0.3.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 (226) hide show
  1. package/CHANGELOG.md +407 -0
  2. package/CODE_OF_CONDUCT.md +21 -0
  3. package/CONTRIBUTING.md +224 -0
  4. package/LICENSE +202 -0
  5. package/NOTICE +9 -0
  6. package/README.md +798 -0
  7. package/SECURITY.md +72 -0
  8. package/assets/clio-coder-logo-128.webp +0 -0
  9. package/damage-control-rules.yaml +419 -0
  10. package/dist/acp-UMLFVA3F.js +92 -0
  11. package/dist/agents-Q4MYPMUW.js +91 -0
  12. package/dist/auth-O6HYIJ6J.js +521 -0
  13. package/dist/chunk-262G75JS.js +35 -0
  14. package/dist/chunk-26BZQOAD.js +1281 -0
  15. package/dist/chunk-2J63S4SF.js +508 -0
  16. package/dist/chunk-3DANZDGR.js +717 -0
  17. package/dist/chunk-4UQA7NCT.js +29 -0
  18. package/dist/chunk-527KG6XR.js +497 -0
  19. package/dist/chunk-5LDRNKX2.js +1063 -0
  20. package/dist/chunk-5N2FG33Q.js +25 -0
  21. package/dist/chunk-67MTHP2E.js +135 -0
  22. package/dist/chunk-6CWDTGUC.js +20 -0
  23. package/dist/chunk-7BHLZB3A.js +2115 -0
  24. package/dist/chunk-7RBKDI66.js +348 -0
  25. package/dist/chunk-AMFR5YA3.js +541 -0
  26. package/dist/chunk-BBUH4VAA.js +1224 -0
  27. package/dist/chunk-BYEU76JP.js +899 -0
  28. package/dist/chunk-CLJ5HLUD.js +458 -0
  29. package/dist/chunk-D5YD55AR.js +116 -0
  30. package/dist/chunk-DXQNI4PC.js +61 -0
  31. package/dist/chunk-E3NYWENM.js +1004 -0
  32. package/dist/chunk-GNGDQYDU.js +34688 -0
  33. package/dist/chunk-GOTUR54M.js +9 -0
  34. package/dist/chunk-HBU5MTAM.js +41 -0
  35. package/dist/chunk-HMYNFFY4.js +28 -0
  36. package/dist/chunk-JPOWPFCU.js +1010 -0
  37. package/dist/chunk-JWHCJDCI.js +1215 -0
  38. package/dist/chunk-KBR4MZZR.js +41 -0
  39. package/dist/chunk-KKKPTZLM.js +93 -0
  40. package/dist/chunk-ME6DNWIU.js +66 -0
  41. package/dist/chunk-NI4DEJMC.js +88 -0
  42. package/dist/chunk-O4EJEDHO.js +659 -0
  43. package/dist/chunk-PIDUD6M2.js +31 -0
  44. package/dist/chunk-PS4PFJQP.js +29459 -0
  45. package/dist/chunk-QV47YRF4.js +48 -0
  46. package/dist/chunk-RQDWMVRB.js +279 -0
  47. package/dist/chunk-TFSSEXL6.js +136 -0
  48. package/dist/chunk-TKHQ4DGZ.js +8290 -0
  49. package/dist/chunk-TPOCL34A.js +2876 -0
  50. package/dist/chunk-UGYAX5YI.js +565 -0
  51. package/dist/chunk-UHTSULZS.js +461 -0
  52. package/dist/chunk-UU3R62TT.js +128 -0
  53. package/dist/chunk-UWIJNAOB.js +3906 -0
  54. package/dist/chunk-VOO7NYPP.js +914 -0
  55. package/dist/chunk-VPAWTYLY.js +117 -0
  56. package/dist/chunk-WD6AJM35.js +1216 -0
  57. package/dist/chunk-X3BR7HWV.js +115 -0
  58. package/dist/chunk-X3NE4WVW.js +120 -0
  59. package/dist/chunk-XNISANGE.js +1395 -0
  60. package/dist/chunk-XV4ZJ6ZM.js +3177 -0
  61. package/dist/cli/index.js +236 -0
  62. package/dist/clio-KIQ5SNDS.js +53 -0
  63. package/dist/components-JVHMUBEB.js +653 -0
  64. package/dist/config-ZFCDBMDC.js +372 -0
  65. package/dist/configure-G4E3A2PG.js +27 -0
  66. package/dist/context-CDXTP2MP.js +293 -0
  67. package/dist/context-E3KIFVXI.js +185 -0
  68. package/dist/context-clear-3F4PLXOS.js +102 -0
  69. package/dist/context-index-Q7YSYTR3.js +106 -0
  70. package/dist/docs-YIETIWZI.js +280 -0
  71. package/dist/doctor-M5HJJZOL.js +61 -0
  72. package/dist/domains/agents/builtins/architect.md +33 -0
  73. package/dist/domains/agents/builtins/coder.md +31 -0
  74. package/dist/domains/agents/builtins/context-bootstrap.md +38 -0
  75. package/dist/domains/agents/builtins/debugger.md +30 -0
  76. package/dist/domains/agents/builtins/documenter.md +31 -0
  77. package/dist/domains/agents/builtins/git-master.md +30 -0
  78. package/dist/domains/agents/builtins/provenance.md +30 -0
  79. package/dist/domains/agents/builtins/researcher.md +71 -0
  80. package/dist/domains/agents/builtins/scout.md +42 -0
  81. package/dist/domains/agents/builtins/tester.md +31 -0
  82. package/dist/domains/agents/builtins/verifier.md +30 -0
  83. package/dist/domains/agents/builtins/wiki-writer.md +41 -0
  84. package/dist/eval-B3KZZESM.js +2674 -0
  85. package/dist/evidence-V67CHM35.js +233 -0
  86. package/dist/evolve-YDZSUQYA.js +518 -0
  87. package/dist/extensions-SRG7XCAH.js +207 -0
  88. package/dist/fleet-CA2CRTVG.js +760 -0
  89. package/dist/fleet-preflight-CLIAX7YR.js +21 -0
  90. package/dist/init-2OZDJE2D.js +227 -0
  91. package/dist/memory-3PIQQAKX.js +207 -0
  92. package/dist/models-DY35XI7Y.js +237 -0
  93. package/dist/paths-5OMXW7Z4.js +57 -0
  94. package/dist/preload-KZVHET2B.js +11 -0
  95. package/dist/reset-PIFYNOS3.js +216 -0
  96. package/dist/run-3VSPP24F.js +735 -0
  97. package/dist/share-D36RQCXM.js +241 -0
  98. package/dist/skills-F2MRLELY.js +445 -0
  99. package/dist/skills-eval-E2ZTW4PL.js +932 -0
  100. package/dist/targets-DZMEZAH4.js +977 -0
  101. package/dist/trace-7NYCUI2J.js +250 -0
  102. package/dist/uninstall-AD3JWHBB.js +322 -0
  103. package/dist/upgrade-WYYBKGDY.js +301 -0
  104. package/dist/usage-ULIDAGFF.js +755 -0
  105. package/dist/version-ROZ6CZKH.js +16 -0
  106. package/dist/wiki-generate-PKFIX6OB.js +377 -0
  107. package/dist/worker/entry.js +1739 -0
  108. package/docs/README.md +93 -0
  109. package/docs/acp.md +120 -0
  110. package/docs/alcf-provider.md +72 -0
  111. package/docs/architecture.md +172 -0
  112. package/docs/artifact-versions.md +54 -0
  113. package/docs/built-in-agents.md +265 -0
  114. package/docs/capacity-and-scheduling.md +97 -0
  115. package/docs/commands-and-modes.md +554 -0
  116. package/docs/config-knobs-audit.md +115 -0
  117. package/docs/configuration-and-targets.md +812 -0
  118. package/docs/context-engine.md +236 -0
  119. package/docs/dispatch-architecture-rationale.md +126 -0
  120. package/docs/documentation-coverage.md +46 -0
  121. package/docs/documentation-guide.md +166 -0
  122. package/docs/environment-variables.md +105 -0
  123. package/docs/eval-runner.md +205 -0
  124. package/docs/evals-internal.md +298 -0
  125. package/docs/evidence-and-memory.md +243 -0
  126. package/docs/evolution.md +143 -0
  127. package/docs/exit-codes-and-output.md +74 -0
  128. package/docs/extensions-and-sharing.md +306 -0
  129. package/docs/fleet-demo-runbook.md +179 -0
  130. package/docs/fleet-dispatch.md +591 -0
  131. package/docs/glossary.md +75 -0
  132. package/docs/html/agents_blueprint.html +936 -0
  133. package/docs/html/alcf_blueprint.html +324 -0
  134. package/docs/html/architecture_blueprint.html +850 -0
  135. package/docs/html/commands_blueprint.html +794 -0
  136. package/docs/html/config_knobs_audit_blueprint.html +178 -0
  137. package/docs/html/configuration_blueprint.html +1080 -0
  138. package/docs/html/context_blueprint.html +603 -0
  139. package/docs/html/documentation_blueprint.html +832 -0
  140. package/docs/html/environment_blueprint.html +404 -0
  141. package/docs/html/eval_blueprint.html +743 -0
  142. package/docs/html/evals_internal_blueprint.html +190 -0
  143. package/docs/html/evolution_blueprint.html +674 -0
  144. package/docs/html/extensions_blueprint.html +2065 -0
  145. package/docs/html/fleet_dispatch_blueprint.html +286 -0
  146. package/docs/html/index.html +919 -0
  147. package/docs/html/lifecycle_blueprint.html +723 -0
  148. package/docs/html/memory_blueprint.html +699 -0
  149. package/docs/html/middleware_blueprint.html +664 -0
  150. package/docs/html/models_blueprint.html +2366 -0
  151. package/docs/html/observability_blueprint.html +683 -0
  152. package/docs/html/provider_adapter_blueprint.html +245 -0
  153. package/docs/html/safety_blueprint.html +1386 -0
  154. package/docs/html/shared.css +571 -0
  155. package/docs/html/shared.js +143 -0
  156. package/docs/html/skills_blueprint.html +671 -0
  157. package/docs/html/soak_blueprint.html +182 -0
  158. package/docs/html/tool_usage_blueprint.html +350 -0
  159. package/docs/html/tools_blueprint.html +2249 -0
  160. package/docs/html/trace_blueprint.html +235 -0
  161. package/docs/html/tui_design_blueprint.html +314 -0
  162. package/docs/html/validation_blueprint.html +961 -0
  163. package/docs/html/worker_dispatch_blueprint.html +231 -0
  164. package/docs/installation-and-lifecycle.md +308 -0
  165. package/docs/middleware-and-components.md +148 -0
  166. package/docs/model-catalog.md +189 -0
  167. package/docs/observability.md +233 -0
  168. package/docs/proactive-memory.md +452 -0
  169. package/docs/prompt-envelope-and-tools.md +142 -0
  170. package/docs/provider-adapter-cookbook.md +148 -0
  171. package/docs/release-cut-checklist.md +138 -0
  172. package/docs/safety-model.md +357 -0
  173. package/docs/scientific-validation.md +105 -0
  174. package/docs/session-lifecycle.md +156 -0
  175. package/docs/skills-marketplace.md +46 -0
  176. package/docs/tool-usage.md +527 -0
  177. package/docs/trace-store.md +132 -0
  178. package/docs/troubleshooting.md +33 -0
  179. package/docs/tui-design.md +239 -0
  180. package/docs/worker-dispatch-mechanics.md +242 -0
  181. package/package.json +132 -0
  182. package/skills/README.md +408 -0
  183. package/skills/git/commit-crafting/SKILL.md +79 -0
  184. package/skills/git/commit-crafting/evals.md +92 -0
  185. package/skills/git/create-pr/SKILL.md +116 -0
  186. package/skills/git/create-pr/evals.md +114 -0
  187. package/skills/git/investigate-issue/SKILL.md +139 -0
  188. package/skills/git/investigate-issue/evals.md +94 -0
  189. package/skills/git/resolve-merge-conflicts/SKILL.md +96 -0
  190. package/skills/git/resolve-merge-conflicts/evals.md +58 -0
  191. package/skills/git/review-changes/SKILL.md +103 -0
  192. package/skills/git/review-changes/evals.md +85 -0
  193. package/skills/git/worktree-create/SKILL.md +92 -0
  194. package/skills/git/worktree-create/evals.md +97 -0
  195. package/skills/git/worktree-create/references/worktree-setup.md +66 -0
  196. package/skills/git/worktree-merge/SKILL.md +95 -0
  197. package/skills/git/worktree-merge/evals.md +114 -0
  198. package/skills/skill-marketplace.json +261 -0
  199. package/skills/workflow/cut-it/SKILL.md +86 -0
  200. package/skills/workflow/cut-it/evals.md +42 -0
  201. package/src/domains/agents/builtins/architect.md +33 -0
  202. package/src/domains/agents/builtins/coder.md +31 -0
  203. package/src/domains/agents/builtins/context-bootstrap.md +38 -0
  204. package/src/domains/agents/builtins/debugger.md +30 -0
  205. package/src/domains/agents/builtins/documenter.md +31 -0
  206. package/src/domains/agents/builtins/git-master.md +30 -0
  207. package/src/domains/agents/builtins/provenance.md +30 -0
  208. package/src/domains/agents/builtins/researcher.md +71 -0
  209. package/src/domains/agents/builtins/scout.md +42 -0
  210. package/src/domains/agents/builtins/tester.md +31 -0
  211. package/src/domains/agents/builtins/verifier.md +30 -0
  212. package/src/domains/agents/builtins/wiki-writer.md +41 -0
  213. package/src/domains/agents/fleets/build-review.md +34 -0
  214. package/src/domains/agents/fleets/build-test.md +35 -0
  215. package/src/domains/agents/fleets/sdlc.md +86 -0
  216. package/src/domains/prompts/fragments/identity/clio-worker.md +11 -0
  217. package/src/domains/prompts/fragments/identity/clio.md +26 -0
  218. package/src/domains/prompts/fragments/operating/contract.md +64 -0
  219. package/src/domains/prompts/fragments/safety/auto-edit.md +14 -0
  220. package/src/domains/prompts/fragments/safety/full-auto.md +14 -0
  221. package/src/domains/prompts/fragments/safety/read-only.md +13 -0
  222. package/src/domains/prompts/fragments/safety/suggest.md +13 -0
  223. package/src/domains/prompts/fragments/wiki/page.md +75 -0
  224. package/src/domains/prompts/fragments/wiki/plan.md +48 -0
  225. package/src/domains/providers/models/cloud-models/alcf.yaml +40 -0
  226. package/src/domains/providers/models/local-models/clio-local-coding-targets.yaml +993 -0
@@ -0,0 +1,265 @@
1
+ # Clio Coder Agent Fleet
2
+
3
+ Clio Coder dispatches focused fleet agents from Markdown recipes. Recipes are data files, not hidden code plugins: YAML frontmatter declares identity, mode, tools, optional target/model hints, and thinking level; the Markdown body is the agent instruction text.
4
+
5
+ > [!TIP]
6
+ > **Interactive Spec Available:** An interactive dashboard for the agent registry and dispatch admission check gates is located at [docs/html/agents_blueprint.html](html/agents_blueprint.html) (Version: 0.3.0).
7
+
8
+ The source of truth is `src/domains/agents/**`. Clio's agent dispatch engine and execution boundaries are built upon the [@earendil-works/pi-agent-core](https://www.npmjs.com/package/@earendil-works/pi-agent-core) library.
9
+
10
+ ---
11
+
12
+ ## Agent Architecture Semantics
13
+
14
+ Clio's agent architecture distinguishes between authoring configurations and runtime policies:
15
+
16
+ * **Recipe**: An authored Markdown file containing frontmatter configuration and an instruction body.
17
+ * **AgentSpec**: The normalized runtime and catalog policy object derived from a recipe.
18
+ * **audience**: Determines visibility and routing (`base` | `shadow` | `custom` | `internal`).
19
+ * **source**: Origin of the recipe (`builtin` | `user` | `project`).
20
+
21
+ ### Discovery, Overrides, and Precedence
22
+ At startup, Clio loads recipes from three roots:
23
+
24
+ | Source | Root | Notes |
25
+ | --- | --- | --- |
26
+ | **Built-in** | `src/domains/agents/builtins/*.md` in the installed package | Shipped defaults. |
27
+ | **User** | `<configDir>/agents/*.md` | Per-user recipes. `<configDir>` follows Clio's XDG/platform config directory. |
28
+ | **Project** | `.clio-coder/agents/*.md` under the current repo | Repository-local overrides and additions (custom/domain agents). |
29
+
30
+ Recipe IDs are derived from filenames (e.g., `architect.md` -> `architect`). Recipes must live directly under their respective directories.
31
+
32
+ * **Customization**: User-level agents can override/customize shipped base agents.
33
+ * **Shadow Protection**: User or project agents can **never** override shadow or internal agents.
34
+ * **Built-in Protection**: Project agents cannot override any shipped built-ins; they are strictly treated as custom/domain agents.
35
+ * **Reserved IDs**: The IDs `worker` and `delegate` are strictly reserved for custom/internal contexts and cannot be registered as custom agent IDs.
36
+ * **Local Ignored Custom Examples**: Local examples (e.g., `benchmark-runner`, `clio-dev`, `implementer`, `scientific-validator`) may exist under `.clio-coder/agents` for documentation or test purposes, but are ignored if they collide with reserved/built-in rules.
37
+ * **Fleet Contracts**: Shipped builtin fleet contracts (`build-test`, `build-review`, `sdlc`) live under `src/domains/agents/fleets/*.md`. Project-level fleet contracts placed at `.clio-coder/fleets/<name>.md` shadow builtin fleets of the same name. Deterministic code steps reference commands declared in `.clio-coder/fleets/commands.yaml`. Contract v4 requires per-step write boundaries (`writes`).
38
+
39
+ ---
40
+
41
+ ## Built-in catalog
42
+
43
+ Current built-ins under `src/domains/agents/builtins/`:
44
+
45
+ ### Shipped Base Agents
46
+ User-facing agents visible in `clio-coder agents` and `/agents`.
47
+
48
+ | Agent ID | Primary tools | Purpose | Capability | Latency |
49
+ | --- | --- | --- | --- | --- |
50
+ | `architect` | read, grep, find, ls, code_nav, git, artifact, context | Designs changes across boundaries, contracts, migrations, and validation gates. | `artifact-write` | `deep` |
51
+ | `coder` | read, write, edit, grep, find, ls, web_fetch, git, verify, code_nav | Implements bounded code changes and behavior-preserving refactors. | `workspace-edit` | `balanced` |
52
+ | `debugger` | read, grep, find, ls, git, verify, code_nav | Diagnoses failing code, tests, or receipts without making edits. | `verification` | `balanced` |
53
+ | `documenter` | read, write, edit, grep, find, ls, git, verify, code_nav, context | Updates developer-facing docs, examples, and operational runbooks. | `workspace-edit` | `balanced` |
54
+ | `git-master` | read, write, edit, context, git, bash, grep, find, ls, code_nav | Executes bounded git operations: history, commits, worktrees, and PR prep. | `workspace-edit` | `balanced` |
55
+ | `tester` | read, write, edit, grep, find, ls, git, verify, code_nav | Adds focused deterministic tests for regressions and missing coverage. | `workspace-edit` | `balanced` |
56
+ | `verifier` | read, grep, find, ls, git, verify, code_nav | Independently runs and reports test, lint, build, review, and release gates. | `verification` | `fast` |
57
+ | `wiki-writer` | read, write, edit, grep, find, ls, code_nav, context | Plans one repository wiki, or researches and writes one wiki page. | `workspace-edit` | `balanced` |
58
+
59
+ ### Shipped Shadow and Internal Agents
60
+ Internal orchestration helpers and internal process agents. They are hidden from default displays (but visible via `clio-coder agents --all` and in a separate section of the prompt catalog).
61
+
62
+ | Agent ID | Primary tools | Purpose | Capability | Latency |
63
+ | --- | --- | --- | --- | --- |
64
+ | `scout` | read, grep, find, ls, context, code_nav, git | Broad repository reconnaissance, codebase orientation, structure and entry-point mapping, and multi-file symbol hunting. | `read-only` | `fast` |
65
+ | `researcher` | read, web_fetch, context | Shadow docs and external-source researcher for coding decisions. | `read-only` | `deep` |
66
+ | `provenance` | read, grep, find, ls, git | Shadow evidence, receipt, diff, and telemetry reader for handoffs. | `read-only` | `balanced` |
67
+ | `context-bootstrap` | read, grep, find, ls, context, code_nav | Internal agent behind `clio-coder context init` that parses repository and returns CLIO-CODER.md payload. | `read-only` | `balanced` |
68
+
69
+ `scout` is bound by a live-grounding contract: its whole final response is one `scout-report` object whose every finding carries the `claim` it observed and the `path:line` that grounds it, a lead it could not confirm live is simply left out, and wiki or index content is orientation only, never citable as evidence. It has an 18-call exploration phase followed by a tool-free synthesis phase; wide parallel batches cannot consume the synthesis backstop as separate violations. Dispatch labels its answer `reconnaissance output (advisory leads, not validation evidence):`.
70
+
71
+ Grounding is checked against the run's own reads, not just against the file. The worker records the exact line span every successful read returned, and a cited line must fall inside one. A line that exists in the file but was never read fails, which is what stops an approximated or inferred line number from passing as observation. `grep` and `code_nav` hits are leads: read the file before citing what they point at.
72
+
73
+ Every contract-bearing agent gets bounded in-worker repair. When the terminal result misses its contract, the worker replays the validator's own reason, the exact accepted shape, and the `path:line` locations this run actually read, then asks for the result again. Two repair rounds is the whole allowance; after that the run fails with `result_contract_exhausted`. This is what keeps a small local model that gathered the right evidence from being failed for a shape mistake nobody told it about.
74
+
75
+ ---
76
+
77
+ ## Frontmatter schema
78
+
79
+ `src/domains/agents/registry.ts` parses frontmatter fields from recipe markdown:
80
+
81
+ ```yaml
82
+ ---
83
+ name: Coder # string; defaults to recipe id when absent
84
+ description: Bounded code changes # string; defaults to empty string
85
+ tools: [read, edit, verify] # string array; filtered by target capabilities and dispatch admission
86
+ model: null # string only when set; null is ignored
87
+ target: null # string only when set; target hint
88
+ thinkingLevel: off # off | minimal | low | medium | high | xhigh
89
+ category: implement # explore | plan | research | implement | quality | science | evolution | operations | internal
90
+ capabilityClass: workspace-edit # read-only | artifact-write | workspace-edit | verification | orchestration | internal
91
+ latencyClass: balanced # fast | balanced | deep
92
+ tags: [implementation, repair] # short lowercase routing hints for catalog display
93
+ skills: [] # knowledge attachments; requiring the context tool, never expands tool authority
94
+ output: null # optional expected artifact name (e.g. PLAN.md)
95
+ budget: # optional strict worker-loop phase policy
96
+ toolCalls: 50 # admitted calls before final response handling
97
+ readReserve: 5 # final admitted slots reserved for canonical read
98
+ synthesis: true # true: text-only final round; false: stop immediately
99
+ ---
100
+ ```
101
+
102
+ A custom source recipe may omit `budget`; admission then materializes a concrete WorkerSpec v3 budget from the operator's current `guardrails.workerToolCallCap`. Built-in recipes declare the field and fail startup if their strict frontmatter is malformed. When a source recipe includes `budget`, it must be a non-null YAML object containing exactly `toolCalls`, `readReserve`, and `synthesis`: the numeric fields must be safe integers, `toolCalls > 0`, and `0 <= readReserve < toolCalls`; `synthesis` must be a boolean. Unknown, missing, quoted-numeric, floating-point, null, and relationally invalid values reject the recipe with its source path and property. Scout declares `18/4/true`; Coder declares `50/5/true`. The model-visible catalog shows declared policy or `operator-default`, never a mutable effective cap.
103
+
104
+ The operator cap is independent and cannot be widened by a recipe. Dispatch clamps `toolCalls` to that cap and clamps `readReserve` to zero when canonical `read` is absent after tool admission. Reserve slots admit only `read`, not every read-class tool. Blocked non-read attempts do not consume admitted reserve slots, but they still count toward the operator attempt ceiling.
105
+
106
+ ### Skills
107
+ Skills are knowledge attachments declared under `skills: [...]` in the YAML frontmatter.
108
+ * They are injected compactly into the prompt/catalog.
109
+ * They require the `context` tool to be accessible; a recipe that declares skills without exposing `context` fails spec validation.
110
+ * They **never** expand the agent's tool authority; they act purely as static knowledge context.
111
+
112
+ ---
113
+
114
+ ## Dispatching agents
115
+
116
+ * **Visibility**: Normal `clio-coder agents` lists user-visible (base/custom) agents. The `/agents` slash command shows both Clio fleet agents and ACP delegation agents. The command `clio-coder agents --all` includes shadow/internal specs reserved for Clio orchestration.
117
+ * **Invocation limits**: User-origin `/run` and `clio-coder run --agent` **cannot** invoke shadow/internal agents.
118
+ * **Orchestrator dispatch**: Internal main-agent dispatch can invoke shadow agents through the `dispatch` tool. The operating contract and Scout's catalog description steer the model to dispatch Scout for broad repository reconnaissance, while narrow file or symbol inspection remains local to the main agent. If a turn reaches 9 or more manual read-only exploration calls without completing Scout dispatch, a threshold nudge advises delegation on the continuation.
119
+ * **TUI rendering and control**: Shadow dispatch rows are marked with an `sh:` prefix. The Fleet Runs island and board show the bounded task, run ID, live tools, tokens, priced cost, retry state, and terminal outcome. Select an HTTP/SDK run to steer it or cancel any active worker/retry timer.
120
+ * **ACP Delegation**: The `/delegate` command is reserved for ACP delegation only, which is separate from Clio fleet subagents.
121
+
122
+ ### Measured agent automation
123
+
124
+ An assignment may request `agent: auto`, but agent choice is advisory by default and is independent of target/model/runtime/node route activation. The coordinator first removes recipes that fail audience, capability-class, execution-role, tool-surface, result-contract, target, or policy constraints. Those are hard constraints and never become score weights. The remaining recipes are ranked deterministically with measured evidence and bounded cold-start priors.
125
+
126
+ Active agent selection requires an exact `{agentId, executionRole}` entry in `routing.agentAutomation.activeAgentRoles` and a passing readiness report for that same agent and role. Empty activation settings are the default. If no eligible agent is ready, active automation fails closed instead of falling back to the fixed requested recipe.
127
+
128
+ Scout is the bounded escalation path for broad reconnaissance, not an authority shortcut. Its strict `scout-report` may return grounded findings or a split recommendation with typed subtasks. The coordinator validates the transition, assigns fresh authority and an absolute deadline to each child, and records the decision. A recovery attempt uses the dedicated recovery role and may not silently inherit broader builder authority.
129
+
130
+ ### ACP Delegation Agents as First-Class Workers
131
+
132
+ ACP delegation agents (registered under `delegation.agents` in `settings.yaml`) are integrated as first-class workers:
133
+ - **Automatic Routing:** When a task is dispatched to an agent ID matching a configured ACP delegation agent, the dispatch engine automatically routes the execution to that delegation agent.
134
+ - **Dynamic Spec Discovery:** The agent registry automatically synthesizes complete AgentSpecs for configured ACP delegation agents. They are visible via `clio-coder agents` and in slash command menus.
135
+
136
+ ### Restricted Shadow Agent Delegation
137
+
138
+ To ensure security and proper boundary isolation, shadow and internal agents are restricted from being delegated:
139
+ - **shadow/internal Restriction:** The dispatch engine rejects any attempt to run a shadow or internal agent on an external ACP delegation worker, throwing a validation error.
140
+
141
+ ### Subscription Worker Runtimes
142
+
143
+ In addition to standard HTTP targets and [Agent Client Protocol (ACP)](https://agentclientprotocol.com) delegation agents, Clio dispatches subagents to sanctioned subscription worker runtimes:
144
+ - **`claude-sdk` (Claude Agent SDK):** Serves as a main worker runtime for driving fleet agents. It integrates with [@anthropic-ai/claude-agent-sdk](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) alongside Clio's native subagent workers (like a local [llama.cpp](https://github.com/ggerganov/llama.cpp), [Ollama](https://ollama.com), [LM Studio](https://lmstudio.ai), [vLLM](https://github.com/vllm-project/vllm), or [SGLang](https://github.com/sgl-project/sglang) fleet) to execute tasks under a Claude subscription. Every tool call is mediated by Clio (`canUseTool` plus a `PreToolUse` hook): the safety net and autonomy matrix apply, and the run's admitted tool surface, which is narrowed by any `tool_profile`, is enforced authoritatively. Consequently, an out-of-profile tool (for example `bash` under `minimal-local`) is denied even though the underlying preset offers it. The narrowed surface is also translated into the SDK's `disallowedTools` option as defense in depth. Because it routes tool calls through Clio safety, it behaves as a native worker.
145
+ - **`claude-code` (Claude Subprocess):** Runs `claude -p` as a subprocess worker, mapping autonomy levels to the CLI's permission modes. It is a black box: tool calls run inside the `claude` process and are not routed through Clio's per-tool mediation, so Clio cannot enforce a per-tool profile on it. Dispatching a narrowing `tool_profile` (`minimal-local` or `science-local`) to this runtime is refused; use `full-agent` (or a native / `claude-sdk` worker) instead.
146
+ - **`antigravity-code` (Antigravity CLI):** Runs an Antigravity CLI subprocess as a subscription worker target for fleet dispatch. Like `claude-code`, it is a black box with no per-tool mediation and no per-tool allowlist, so a narrowing `tool_profile` is refused rather than silently ignored.
147
+
148
+ Agent budgets follow the same mediation boundary. Native workers and `claude-sdk` enforce canonical call counting, the canonical-`read` reserve, and the synthesis transition. `claude-code` and `antigravity-code` reject recipes that explicitly declare `budget`, because silently ignoring numeric bounds would be unsafe; a custom source recipe without the field receives the concrete operator-default budget at admission. Claude vendor aliases never appear in recipes or prompt authority and cannot reintroduce a canonical tool removed by admission.
149
+
150
+ Interactive TUI:
151
+
152
+ ```text
153
+ /run coder implement the new command
154
+ /run --target local-lmstudio --model your-model-id coder fix the failing unit test
155
+ /run --agent-profile cheap --tool-profile minimal-local verifier run the regression tests
156
+ ```
157
+
158
+ Headless CLI:
159
+
160
+ ```bash
161
+ clio-coder run --agent coder "Refactor the parser."
162
+ ```
163
+
164
+ Dispatch admission enforces three gates:
165
+
166
+ 1. The recipe's requested tools must be supported by target capabilities.
167
+ 2. The requested action classes must be allowed by the agent's scope.
168
+ 3. The worker scope must be a subset of the orchestrator's active scope.
169
+
170
+ ### Ad-hoc specialists
171
+
172
+ The dispatch tool can compose an ephemeral specialist for one task object with
173
+ `persona` and `tool_profile`. `persona` replaces the recipe body inside the
174
+ same stable worker shell used for recipe runs; it does not replace Clio's task
175
+ contract or safety scaffolding. `tool_profile` narrows tools through the same
176
+ validated profiles as recipe dispatch (`minimal-local`, `science-local`, or
177
+ `full-agent`).
178
+
179
+ Personas are capped at 8000 characters and are rejected for shadow agents and
180
+ ACP delegation agents. A composed run legitimately gets its own
181
+ `staticCompositionHash`, and its receipt and run ledger carry
182
+ `personaOverride.promptHash` so the override is explicit and queryable.
183
+ Recipe-based runs omit `personaOverride`.
184
+
185
+ ### Worker context injection
186
+
187
+ Every dispatched worker receives per-run context through dynamic prompt
188
+ messages (user-role messages sent before the task), never through the stable
189
+ system prompt, so the static prompt composition hash stays byte-identical run
190
+ over run:
191
+
192
+ - **Project context** (capability classes `workspace-edit`, `verification`,
193
+ and `artifact-write` only): the project name, conventions, and hard
194
+ invariants parsed from `CLIO-CODER.md`, capped at 1500 characters with conventions
195
+ truncated first. Read-only, shadow, and orchestration recipes get none, and
196
+ no message is sent when `CLIO-CODER.md` is absent or malformed.
197
+ - **Safety posture** (every run, including ACP delegation): one line naming
198
+ the run's effective autonomy level with the same directive text the session
199
+ prompt's safety section uses.
200
+ - **Memory** (when the request carries an approved memory section): unchanged,
201
+ delivered after the two messages above.
202
+ - **Pipeline input** (`pipeline`-mode steps after the first): the previous
203
+ step's final assistant output, threaded as data inside a fixed
204
+ `<<<PIPELINE-INPUT ... PIPELINE-INPUT>>>` delimiter and labeled as input,
205
+ not instructions. It is ordered last, after memory and adjacent to the task,
206
+ and capped at 12000 characters; the receiving run's receipt records
207
+ `pipeline` provenance (source run, step position, input bytes, whether the
208
+ cap truncated it). Step 1 and every non-pipeline run get none. The `pipeline`
209
+ and `personaOverride` field shapes and their stability labels are documented
210
+ in the [receipt provenance schema](./observability.md#receipt-fields-for-dispatch-provenance).
211
+
212
+ ---
213
+
214
+ ## Fleet Management and Fault Tolerance
215
+
216
+ Clio manages running subagent tasks, tracks token costs, and handles task failures. It operates under specific safety, concurrency, and retry limits:
217
+
218
+ ### 1. In-Memory Retry Queue
219
+ Subagent runs that terminate with retryable outcomes are placed in an in-memory retry queue. The queue does not survive process restarts. The retryable outcomes are:
220
+ - `failed`: The subagent process exited non-zero or returned an error receipt.
221
+ - `timed_out`: The run or delegation turn exceeded its timeout limit.
222
+ - `stalled`: The run exceeded the event-inactivity window without progress or stopped responding to heartbeats.
223
+ - `spawn_failed`: The runtime failed to spawn the subprocess or establish connection.
224
+
225
+ ### 2. Backoff and Cooldown
226
+ Scheduled retries use an exponential backoff state to calculate subsequent retry delays. Furthermore, targets that fail are subject to a cooldown period. The retry engine ensures that a retried task waits for the maximum of the exponential backoff delay or the remaining target cooldown duration. Retries are brand-new runs that must re-pass all admission checks. If target policies or budgets deny a retry, the task chain terminates as denied.
227
+
228
+ ### 3. Concurrency Limits
229
+ The setting `budget.concurrency` restricts the number of concurrent subagent tasks. Setting it to `auto` determines the concurrency limit dynamically based on system capabilities.
230
+
231
+ ### 4. Heartbeats and Reconciler
232
+ For native subprocess workers, Clio uses a heartbeat mechanism. The reconciler monitors the active heartbeat timestamp. If a worker stops responding and updates no heartbeats, the reconciler terminates the stalled subprocess automatically.
233
+
234
+ ### 5. Worker Permission Postures
235
+ A dispatched worker has no operator by default, so a tool call that requires interactive permission must resolve within bounded time. The `workers.onPermission` setting picks the posture:
236
+
237
+ - `deny` (default): the parked call becomes a structured tool denial and the run continues.
238
+ - `fail`: the run finalizes immediately with outcome `failed`/`permission_required`.
239
+ - `escalate`: the parked call is handed up to the interactive operator. The worker emits a `clio_permission_escalated` event over its stdout; the dispatch domain republishes it on the bus as a permission request tagged with the run id; the operator resolves it in the TUI permission overlay; and the decision travels back down the worker's stdin as a `permission_decision` line (the same pipe steers use). No model can approve a worker permission; resolution is human-only.
240
+
241
+ Escalate is only meaningful with an interactive operator attached. Headless sessions have no subscriber, so the escalation resolves by the timeout fallback. The bounds are `workers.escalation` (`{ timeoutMs, fallback }`, defaults 120000 ms and `deny`): a parked ask that no operator answers within `timeoutMs` applies the fallback deny/fail, so an escalate-posture run can never hang forever. The heartbeat timer runs independently of the parked call, so an escalated worker keeps reporting alive while it waits. Each escalation and its resolution (operator or timeout) is tallied on the receipt's `safety.decisions` escalation counters, documented with their stability labels in the [receipt provenance schema](./observability.md#receipt-fields-for-dispatch-provenance); a timed-out or denied escalation also raises an `escalation` finding in the evidence bundle. ACP delegations are out of scope: they resolve permissions through their own mediator and have no worker stdin channel.
242
+
243
+ ---
244
+
245
+
246
+ ## Adding a project agent
247
+
248
+ Create `.clio-coder/agents/my-agent.md`:
249
+
250
+ ```md
251
+ ---
252
+ name: My Agent
253
+ description: Focused local review helper.
254
+ tools: [read, grep, find, ls, git, artifact]
255
+ ---
256
+
257
+ You are My Agent. Inspect only the requested area. Never edit files. End by writing a concise review artifact (`artifact` kind="review") with risks, evidence, and follow-up tests.
258
+ ```
259
+
260
+ Then run:
261
+
262
+ ```bash
263
+ clio-coder agents
264
+ clio-coder run --agent my-agent "Review the parser change."
265
+ ```
@@ -0,0 +1,97 @@
1
+ # Capacity Leases & Fleet Scheduling
2
+
3
+ This document specifies the multi-process capacity leasing protocols, node scheduling models, cross-process transaction locks, and failure recovery mechanics implemented in Clio Coder `v0.3.0`.
4
+
5
+ Source implementations: `src/domains/scheduling/` and `src/domains/dispatch/capacity-lease.ts`.
6
+
7
+ ---
8
+
9
+ ## 1. Capacity Model & Admission Invariants
10
+
11
+ Fleet dispatch manages compute resources across local and remote execution nodes as a unified capacity pool. Dispatched workers must acquire a durable capacity lease before they are spawned.
12
+
13
+ ```mermaid
14
+ graph TD
15
+ req[Dispatch Request] --> lock[Acquire Cross-Process Lock: dispatch-admission.json.lock]
16
+ lock --> reap[Reap Expired Leases & Dead PIDs]
17
+ reap --> check[Check Capacity Limits: global & per-node]
18
+ check -->|Within Limits| grant[Grant Capacity Lease & Write State]
19
+ check -->|Limits Exceeded| queue[Queue / Reject Request]
20
+ grant --> unlock[Release Lock]
21
+ unlock --> spawn[Spawn Worker Process]
22
+ ```
23
+
24
+ ### State Storage & Format
25
+
26
+ All capacity state is stored in a single durable JSON file:
27
+
28
+ - **Path**: `<stateDir>/dispatch-admission.json` (`src/domains/dispatch/capacity-lease.ts:capacityStatePath()`)
29
+ - **Version**: `version: 2` (`CapacityStateFile`)
30
+ - **Transaction Lock**: `<stateDir>/dispatch-admission.json.lock` (`withStateFileLockSync`)
31
+
32
+ ```typescript
33
+ export interface CapacityStateFile {
34
+ version: 2;
35
+ draining: CapacityDrain | null;
36
+ leases: CapacityLease[];
37
+ reservations: unknown[];
38
+ }
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 2. Capacity Lease Schema & TTLs
44
+
45
+ Each in-flight worker holds one `CapacityLease` (`src/domains/dispatch/capacity-lease.ts:18-29`):
46
+
47
+ ```typescript
48
+ export interface CapacityLease {
49
+ leaseId: string; // Unique lease identifier
50
+ assignmentId: string; // Owning dispatch assignment ID
51
+ nodeId: string; // Execution node identifier ("local" or remote ID)
52
+ ownerPid: number; // Process ID of the orchestrator/worker owner
53
+ processBirthToken: string; // OS-level token preventing PID reuse collisions
54
+ acquiredAt: string; // ISO-8601 acquisition timestamp
55
+ expiresAt: string; // ISO-8601 expiration timestamp
56
+ heartbeatAt: string; // ISO-8601 last heartbeat timestamp
57
+ reservationOwnerId: string | null;
58
+ reservationMemberId: string | null;
59
+ }
60
+ ```
61
+
62
+ ### Constants & Operational Bounds
63
+
64
+ | Constant | Value | Description | Source Reference |
65
+ | :--- | :--- | :--- | :--- |
66
+ | `MAX_CAPACITY_LEASES` | `1000` | Hard cap on simultaneous active capacity leases across all nodes. | `src/domains/dispatch/capacity-lease.ts:8` |
67
+ | `DEFAULT_CAPACITY_LEASE_TTL_MS` | `30000` ms (30s) | Inactivity expiration window for leases without a refreshed heartbeat. | `src/domains/dispatch/capacity-lease.ts:9` |
68
+ | `DEFAULT_CAPACITY_DRAIN_TTL_MS` | `3600000` ms (1h) | Automatic expiration window for operator drain mode. | `src/domains/dispatch/capacity-lease.ts:16` |
69
+ | `NODE_DEATH_FAILURE_THRESHOLD` | `2` consecutive failures | Channel failure count before a remote node is classified offline. | `src/domains/scheduling/cluster.ts:64` |
70
+
71
+ ---
72
+
73
+ ## 3. Heartbeats & Dead-Process Recovery
74
+
75
+ To prevent leaked leases when workers or orchestrators crash:
76
+
77
+ 1. **Heartbeat Protocol**: Active workers emit heartbeats over their control channel every 1,000 ms (`src/worker/heartbeat.ts`). The orchestrator updates `heartbeatAt` and extends `expiresAt` by `DEFAULT_CAPACITY_LEASE_TTL_MS`.
78
+ 2. **PID Liveness & Birth Tokens**: The lease reconciler inspects `ownerPid` and validates `processBirthToken` against operating system process tables. If the PID has terminated or been recycled by the OS, the lease is immediately reclaimed.
79
+ 3. **Lazy Reaping**: Every admission attempt purges expired leases and dead process records inside the cross-process transaction lock before calculating available capacity.
80
+
81
+ ---
82
+
83
+ ## 4. Cluster Drain & Emergency Control
84
+
85
+ The fleet can be drained for maintenance without terminating running jobs:
86
+
87
+ - **Drain Command**: `clio-coder fleet drain` sets `draining` in `dispatch-admission.json`.
88
+ - **Drain Invariant**: When draining is active, existing runs continue to completion, but all new dispatch admissions are refused with a drain notice.
89
+ - **Auto-Expiry**: To prevent an unmanaged lockup if a draining operator disconnects, the drain state automatically expires after `DEFAULT_CAPACITY_DRAIN_TTL_MS` (1 hour).
90
+ - **Resume Command**: `clio-coder fleet resume` clears the drain state immediately.
91
+
92
+ ---
93
+
94
+ ## 5. Fail-Closed Invariants
95
+
96
+ 1. **Corrupted State File**: If `dispatch-admission.json` contains invalid JSON or schema violations, the admission engine fails closed, refusing new work until repaired.
97
+ 2. **Lock Timeouts**: If the cross-process lock cannot be acquired within the timeout window, dispatch fails closed rather than executing uncoordinated parallel operations.