@aragon-agent/cli 0.6.43 → 0.6.45

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 (251) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +69 -2
  3. package/dist/agent/controller.d.ts +69 -0
  4. package/dist/agent/controller.js +224 -11
  5. package/dist/agent/governance-view.d.ts +40 -0
  6. package/dist/agent/governance-view.js +40 -0
  7. package/dist/agent/governance-wiring.d.ts +162 -0
  8. package/dist/agent/governance-wiring.js +470 -0
  9. package/dist/agent/plan-prompt.d.ts +7 -0
  10. package/dist/agent/plan-prompt.js +2 -1
  11. package/dist/agent/reducer.d.ts +33 -1
  12. package/dist/agent/reducer.js +45 -9
  13. package/dist/agent/system-prompt.d.ts +19 -0
  14. package/dist/agent/system-prompt.js +9 -1
  15. package/dist/cli.js +45 -1
  16. package/dist/commands/builtins.js +10 -4
  17. package/dist/commands/governance-command.d.ts +35 -0
  18. package/dist/commands/governance-command.js +292 -0
  19. package/dist/commands/governance-runs-table.d.ts +40 -0
  20. package/dist/commands/governance-runs-table.js +130 -0
  21. package/dist/commands/registry.d.ts +12 -0
  22. package/dist/config/app-paths.d.ts +10 -0
  23. package/dist/config/app-paths.js +12 -0
  24. package/dist/config/cli-commands.d.ts +18 -0
  25. package/dist/config/cli-commands.js +47 -1
  26. package/dist/config/env.d.ts +2 -1
  27. package/dist/config/env.js +10 -1
  28. package/dist/config/governance-config.d.ts +125 -0
  29. package/dist/config/governance-config.js +164 -0
  30. package/dist/config/governance-launch.d.ts +71 -0
  31. package/dist/config/governance-launch.js +58 -0
  32. package/dist/config/load.d.ts +15 -0
  33. package/dist/config/load.js +26 -1
  34. package/dist/config/model-profile-store.d.ts +4 -2
  35. package/dist/config/schema.d.ts +22 -0
  36. package/dist/config/schema.js +6 -0
  37. package/dist/config/store.js +14 -1
  38. package/dist/config/ui-state.d.ts +11 -0
  39. package/dist/config/ui-state.js +11 -0
  40. package/dist/diagnostics/doctor.js +20 -0
  41. package/dist/governance/card-normalize.d.ts +24 -0
  42. package/dist/governance/card-normalize.js +76 -0
  43. package/dist/governance/copy.d.ts +109 -0
  44. package/dist/governance/copy.js +223 -0
  45. package/dist/governance/engine/aftermath.d.ts +49 -0
  46. package/dist/governance/engine/aftermath.js +134 -0
  47. package/dist/governance/engine/artifact-persist.d.ts +35 -0
  48. package/dist/governance/engine/artifact-persist.js +86 -0
  49. package/dist/governance/engine/budget.d.ts +52 -0
  50. package/dist/governance/engine/budget.js +112 -0
  51. package/dist/governance/engine/cards.d.ts +18 -0
  52. package/dist/governance/engine/cards.js +186 -0
  53. package/dist/governance/engine/digest.d.ts +32 -0
  54. package/dist/governance/engine/digest.js +63 -0
  55. package/dist/governance/engine/engine-core.d.ts +219 -0
  56. package/dist/governance/engine/engine-core.js +562 -0
  57. package/dist/governance/engine/engine.d.ts +68 -0
  58. package/dist/governance/engine/engine.js +314 -0
  59. package/dist/governance/engine/estimate.d.ts +38 -0
  60. package/dist/governance/engine/estimate.js +46 -0
  61. package/dist/governance/engine/inspector.d.ts +16 -0
  62. package/dist/governance/engine/inspector.js +396 -0
  63. package/dist/governance/engine/integration.d.ts +35 -0
  64. package/dist/governance/engine/integration.js +220 -0
  65. package/dist/governance/engine/lifecycle.d.ts +29 -0
  66. package/dist/governance/engine/lifecycle.js +656 -0
  67. package/dist/governance/engine/pause.d.ts +56 -0
  68. package/dist/governance/engine/pause.js +107 -0
  69. package/dist/governance/engine/phase-members.d.ts +15 -0
  70. package/dist/governance/engine/phase-members.js +34 -0
  71. package/dist/governance/engine/phase-planner.d.ts +53 -0
  72. package/dist/governance/engine/phase-planner.js +282 -0
  73. package/dist/governance/engine/rebuild.d.ts +27 -0
  74. package/dist/governance/engine/rebuild.js +57 -0
  75. package/dist/governance/engine/report.d.ts +66 -0
  76. package/dist/governance/engine/report.js +220 -0
  77. package/dist/governance/engine/run-digest.d.ts +20 -0
  78. package/dist/governance/engine/run-digest.js +42 -0
  79. package/dist/governance/engine/spec-builder.d.ts +117 -0
  80. package/dist/governance/engine/spec-builder.js +321 -0
  81. package/dist/governance/engine/stage-runner.d.ts +22 -0
  82. package/dist/governance/engine/stage-runner.js +664 -0
  83. package/dist/governance/engine/start-input.d.ts +19 -0
  84. package/dist/governance/engine/start-input.js +111 -0
  85. package/dist/governance/engine/state-machine.d.ts +101 -0
  86. package/dist/governance/engine/state-machine.js +586 -0
  87. package/dist/governance/engine/submission-queries.d.ts +42 -0
  88. package/dist/governance/engine/submission-queries.js +97 -0
  89. package/dist/governance/engine/submission-render.d.ts +12 -0
  90. package/dist/governance/engine/submission-render.js +92 -0
  91. package/dist/governance/engine/submissions.d.ts +27 -0
  92. package/dist/governance/engine/submissions.js +455 -0
  93. package/dist/governance/engine/visibility.d.ts +104 -0
  94. package/dist/governance/engine/visibility.js +223 -0
  95. package/dist/governance/governed-dispatch.d.ts +19 -0
  96. package/dist/governance/governed-dispatch.js +17 -0
  97. package/dist/governance/limits.d.ts +107 -0
  98. package/dist/governance/limits.js +131 -0
  99. package/dist/governance/posture-transition.d.ts +38 -0
  100. package/dist/governance/posture-transition.js +44 -0
  101. package/dist/governance/posture.d.ts +35 -0
  102. package/dist/governance/posture.js +59 -0
  103. package/dist/governance/profiles.d.ts +48 -0
  104. package/dist/governance/profiles.js +140 -0
  105. package/dist/governance/prompts/orchestrator-block.d.ts +40 -0
  106. package/dist/governance/prompts/orchestrator-block.js +128 -0
  107. package/dist/governance/prompts/plan-addendum.d.ts +22 -0
  108. package/dist/governance/prompts/plan-addendum.js +60 -0
  109. package/dist/governance/prompts/refusals.d.ts +48 -0
  110. package/dist/governance/prompts/refusals.js +82 -0
  111. package/dist/governance/prompts/role-blocks.d.ts +40 -0
  112. package/dist/governance/prompts/role-blocks.js +255 -0
  113. package/dist/governance/report-reader.d.ts +31 -0
  114. package/dist/governance/report-reader.js +57 -0
  115. package/dist/governance/roles.d.ts +83 -0
  116. package/dist/governance/roles.js +142 -0
  117. package/dist/governance/rules/claims.d.ts +83 -0
  118. package/dist/governance/rules/claims.js +250 -0
  119. package/dist/governance/rules/elimination.d.ts +66 -0
  120. package/dist/governance/rules/elimination.js +105 -0
  121. package/dist/governance/rules/events-table.d.ts +46 -0
  122. package/dist/governance/rules/events-table.js +94 -0
  123. package/dist/governance/rules/failure-analysis.d.ts +28 -0
  124. package/dist/governance/rules/failure-analysis.js +93 -0
  125. package/dist/governance/rules/ledger-replay.d.ts +53 -0
  126. package/dist/governance/rules/ledger-replay.js +53 -0
  127. package/dist/governance/rules/ledger-state.d.ts +85 -0
  128. package/dist/governance/rules/ledger-state.js +175 -0
  129. package/dist/governance/rules/ledger.d.ts +228 -0
  130. package/dist/governance/rules/ledger.js +560 -0
  131. package/dist/governance/rules/rca.d.ts +68 -0
  132. package/dist/governance/rules/rca.js +220 -0
  133. package/dist/governance/rules/settlement.d.ts +129 -0
  134. package/dist/governance/rules/settlement.js +363 -0
  135. package/dist/governance/rules/suspicion.d.ts +66 -0
  136. package/dist/governance/rules/suspicion.js +169 -0
  137. package/dist/governance/store/artifacts.d.ts +81 -0
  138. package/dist/governance/store/artifacts.js +173 -0
  139. package/dist/governance/store/atomic.d.ts +79 -0
  140. package/dist/governance/store/atomic.js +119 -0
  141. package/dist/governance/store/events-log.d.ts +35 -0
  142. package/dist/governance/store/events-log.js +86 -0
  143. package/dist/governance/store/run-lock.d.ts +51 -0
  144. package/dist/governance/store/run-lock.js +122 -0
  145. package/dist/governance/store/run-store.d.ts +229 -0
  146. package/dist/governance/store/run-store.js +644 -0
  147. package/dist/governance/store/scoreboard-export.d.ts +53 -0
  148. package/dist/governance/store/scoreboard-export.js +65 -0
  149. package/dist/governance/tools/child-tools.d.ts +31 -0
  150. package/dist/governance/tools/child-tools.js +65 -0
  151. package/dist/governance/tools/guard.d.ts +71 -0
  152. package/dist/governance/tools/guard.js +194 -0
  153. package/dist/governance/tools/inspector-tools.d.ts +63 -0
  154. package/dist/governance/tools/inspector-tools.js +424 -0
  155. package/dist/governance/tools/lead-tools.d.ts +42 -0
  156. package/dist/governance/tools/lead-tools.js +226 -0
  157. package/dist/governance/tools/normalize-util.d.ts +101 -0
  158. package/dist/governance/tools/normalize-util.js +230 -0
  159. package/dist/governance/tools/scan-incomplete.d.ts +79 -0
  160. package/dist/governance/tools/scan-incomplete.js +486 -0
  161. package/dist/governance/tools/shared-tools.d.ts +44 -0
  162. package/dist/governance/tools/shared-tools.js +125 -0
  163. package/dist/governance/tools/submit-normalizers.d.ts +28 -0
  164. package/dist/governance/tools/submit-normalizers.js +474 -0
  165. package/dist/governance/tools/submit-tools.d.ts +26 -0
  166. package/dist/governance/tools/submit-tools.js +171 -0
  167. package/dist/governance/types.d.ts +661 -0
  168. package/dist/governance/types.js +27 -0
  169. package/dist/proc/kill-tree.d.ts +19 -1
  170. package/dist/proc/kill-tree.js +32 -5
  171. package/dist/proc/limits.d.ts +19 -0
  172. package/dist/proc/limits.js +19 -0
  173. package/dist/proc/supervisor.js +8 -1
  174. package/dist/session/validate-session.js +32 -1
  175. package/dist/team/runtime.d.ts +8 -0
  176. package/dist/team/runtime.js +9 -0
  177. package/dist/team/subagent.d.ts +23 -0
  178. package/dist/team/subagent.js +14 -3
  179. package/dist/team/types.d.ts +6 -0
  180. package/dist/tools/bounded-spawn.d.ts +56 -0
  181. package/dist/tools/bounded-spawn.js +76 -0
  182. package/dist/tools/index.d.ts +30 -7
  183. package/dist/tools/index.js +14 -0
  184. package/dist/tools/plan-tools.d.ts +14 -2
  185. package/dist/tools/plan-tools.js +5 -2
  186. package/dist/tools/search-tools.js +52 -44
  187. package/dist/ui/App.js +145 -25
  188. package/dist/ui/BottomStatusRow.js +1 -1
  189. package/dist/ui/Composer.d.ts +7 -1
  190. package/dist/ui/Composer.js +9 -6
  191. package/dist/ui/GovernancePanel.d.ts +50 -0
  192. package/dist/ui/GovernancePanel.js +77 -0
  193. package/dist/ui/GovernanceRun.d.ts +18 -0
  194. package/dist/ui/GovernanceRun.js +11 -0
  195. package/dist/ui/ScrollbackShell.d.ts +35 -7
  196. package/dist/ui/ScrollbackShell.js +1 -1
  197. package/dist/ui/StatusBar.d.ts +15 -2
  198. package/dist/ui/StatusBar.js +10 -4
  199. package/dist/ui/Transcript.js +3 -0
  200. package/dist/ui/entries/GovernanceCard.d.ts +30 -0
  201. package/dist/ui/entries/GovernanceCard.js +32 -0
  202. package/dist/ui/governance-copy.d.ts +69 -0
  203. package/dist/ui/governance-copy.js +104 -0
  204. package/dist/ui/governance-status.d.ts +145 -0
  205. package/dist/ui/governance-status.js +326 -0
  206. package/dist/ui/interaction-copy.d.ts +4 -0
  207. package/dist/ui/interaction-copy.js +5 -0
  208. package/dist/ui/interaction-hints.d.ts +17 -0
  209. package/dist/ui/interaction-hints.js +14 -2
  210. package/dist/ui/layout/governance-board.d.ts +121 -0
  211. package/dist/ui/layout/governance-board.js +382 -0
  212. package/dist/ui/layout/governance-card.d.ts +53 -0
  213. package/dist/ui/layout/governance-card.js +134 -0
  214. package/dist/ui/layout/governance-chip.d.ts +38 -0
  215. package/dist/ui/layout/governance-chip.js +64 -0
  216. package/dist/ui/layout/governance-panel.d.ts +85 -0
  217. package/dist/ui/layout/governance-panel.js +358 -0
  218. package/dist/ui/layout/governance-roster.d.ts +65 -0
  219. package/dist/ui/layout/governance-roster.js +275 -0
  220. package/dist/ui/layout/status-detail-layout.js +3 -3
  221. package/dist/ui/layout/status-layout.d.ts +5 -2
  222. package/dist/ui/layout/status-layout.js +10 -6
  223. package/dist/ui/layout/virtual-window.js +11 -0
  224. package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
  225. package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
  226. package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
  227. package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
  228. package/dist/ui/overlays/HelpOverlay.js +4 -3
  229. package/dist/ui/overlays/QuestionOverlay.d.ts +9 -1
  230. package/dist/ui/overlays/QuestionOverlay.js +4 -2
  231. package/dist/ui/overlays/SettingsScreen.d.ts +7 -0
  232. package/dist/ui/overlays/SettingsScreen.js +21 -1
  233. package/dist/ui/overlays/governance-settings.d.ts +79 -0
  234. package/dist/ui/overlays/governance-settings.js +140 -0
  235. package/dist/ui/overlays/model-profile-state.d.ts +6 -1
  236. package/dist/ui/overlays/model-profile-state.js +10 -0
  237. package/dist/ui/palettes.d.ts +17 -0
  238. package/dist/ui/palettes.js +9 -0
  239. package/dist/ui/scrollback/LiveTail.d.ts +3 -1
  240. package/dist/ui/scrollback/budget.d.ts +12 -6
  241. package/dist/ui/scrollback/budget.js +11 -4
  242. package/dist/ui/scrollback/live-preview.js +2 -0
  243. package/dist/ui/scrollback/settled-boundary.js +3 -0
  244. package/dist/ui/scrollback/tail-anchor.d.ts +5 -2
  245. package/dist/ui/scrollback/tail-anchor.js +3 -1
  246. package/dist/ui/shortcuts.js +2 -2
  247. package/dist/ui/theme.d.ts +7 -0
  248. package/dist/ui/theme.js +1 -0
  249. package/dist/ui/transcript-text.js +9 -0
  250. package/dist/ui/use-wheel-routing.js +3 -1
  251. package/package.json +2 -2
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Sub-agent spec construction (governance-mode 8.3).
3
+ *
4
+ * ASCII ONLY (`governance/` is glyph-scanned).
5
+ *
6
+ * THE ENGINE BUILDS EVERY BRIEF; THE ORCHESTRATOR NEVER DOES (6.2 rule 5). That is what
7
+ * makes the information boundary real: a role sees exactly the sections this module is
8
+ * handed, and the CALLER (the engine) is the one who decides what each role may be
9
+ * handed, from `visibility.ts`. This module is deliberately a pure assembler with no
10
+ * access to the store, so it cannot leak a section it was not given.
11
+ *
12
+ * It also re-applies the three length clamps `normalizeSubagentSpecs` applies to the
13
+ * orchestrator's own specs (D-24 / RV-4): the engine bypasses that function, so the
14
+ * `label` / `description` / `prompt` bounds have to hold here or nowhere.
15
+ */
16
+ import { TEAM_AGGREGATE_LABEL, TEAM_LIMITS } from '../../team/limits.js';
17
+ import { GOV_LIMITS } from '../limits.js';
18
+ /** Marker appended to any clipped section. Stable: tests and models rely on it. */
19
+ export const TRUNCATION_MARK = '[truncated]';
20
+ const ROLE_WORD = {
21
+ DEV: 'DEV',
22
+ REV: 'REV',
23
+ TEST: 'TEST',
24
+ INSP: 'INSP',
25
+ };
26
+ function clampText(text, max) {
27
+ const trimmed = text.trim();
28
+ return trimmed.length > max ? `${trimmed.slice(0, Math.max(0, max - 1))}~` : trimmed;
29
+ }
30
+ function bullet(items) {
31
+ return items.map((i) => `- ${i}`).join('\n');
32
+ }
33
+ function describeWp(wp) {
34
+ const lines = [
35
+ `WP ${wp.id}: ${wp.title}`,
36
+ ` goal: ${wp.goal}`,
37
+ ` owned files: ${wp.files.length > 0 ? wp.files.join(', ') : '(none declared)'}`,
38
+ ` acceptance:`,
39
+ ...wp.acceptance.map((a) => ` - ${a}`),
40
+ ];
41
+ if (wp.dependsOn.length > 0)
42
+ lines.push(` depends on: ${wp.dependsOn.join(', ')}`);
43
+ return lines.join('\n');
44
+ }
45
+ function describeContracts(contracts, wpIds) {
46
+ const relevant = contracts.filter((c) => !c.voided &&
47
+ (wpIds === null || wpIds.has(c.producer) || c.consumers.some((id) => wpIds.has(id))));
48
+ if (relevant.length === 0)
49
+ return '';
50
+ return relevant
51
+ .map((c) => `${c.id} ${c.name}: producer ${c.producer}; consumers ${c.consumers.join(', ')}\n` +
52
+ ` ${c.definition}`)
53
+ .join('\n');
54
+ }
55
+ /** The one-line "what to do and which tool to call" instruction. Priority 1. */
56
+ function taskInstruction(brief) {
57
+ const wpList = brief.wps.map((w) => w.id).join(', ');
58
+ const n = brief.wps.length;
59
+ const once = (tool) => n > 1
60
+ ? `Call ${tool} exactly once for EACH of these ${n} work packages (${wpList}), ` +
61
+ `in this order, passing the wpId each time.`
62
+ : `Call ${tool} exactly once when you are finished.`;
63
+ switch (brief.stage) {
64
+ case 'dev':
65
+ return (`Implement work package ${wpList} completely. Touch only the files it owns. ` +
66
+ `Verify every contract you produce or consume. ${once('gov_submit_work')}`);
67
+ case 'fix':
68
+ return (`Integration failed. Fix work package ${wpList} so the interfaces align with the ` +
69
+ `contracts. The goal is interface alignment, not turning the test green. State ` +
70
+ `which contracts you re-verified. ${once('gov_submit_work')}`);
71
+ case 'review':
72
+ return (`Review work package ${wpList} independently of the developer. ${once('gov_submit_review')} Do not merge or skip any package.`);
73
+ case 'test':
74
+ return (`Test work package ${wpList}: run the existing suites, write missing tests ` +
75
+ `(including cross-module boundary tests) and trace every acceptance criterion to ` +
76
+ `evidence. ${once('gov_submit_test')}`);
77
+ case 'settle':
78
+ return (`Run the settle stage of phase ${brief.phase}: rule on every open claim with ` +
79
+ `ledger_rule, audit the flags below, award or withhold discretionary events with ` +
80
+ `ledger_apply (evidence required), and check each contract statically on both ` +
81
+ `sides. Finish with exactly one ledger_settle call (kind "settle").`);
82
+ case 'integrate':
83
+ return (`Run the integrate stage of phase ${brief.phase}: use only the registered ` +
84
+ `integration commands, record the result, and on failure include a structured ` +
85
+ `RCA. Finish with exactly one ledger_settle call (kind "integrate").`);
86
+ }
87
+ }
88
+ function reworkSection(brief) {
89
+ if (brief.requiredChanges === undefined)
90
+ return null;
91
+ const parts = [];
92
+ for (const wp of brief.wps) {
93
+ const items = brief.requiredChanges[wp.id];
94
+ if (items === undefined || items.length === 0)
95
+ continue;
96
+ parts.push(`WP ${wp.id} (rework ${wp.reworkCount}):\n` +
97
+ items.map((c, i) => ` ${i + 1}. ${c.file}: ${c.issue} -> ${c.change}`).join('\n'));
98
+ }
99
+ if (parts.length === 0)
100
+ return null;
101
+ return {
102
+ priority: 4,
103
+ title: 'REQUIRED CHANGES (address each one, or use your single appeal)',
104
+ body: parts.join('\n'),
105
+ };
106
+ }
107
+ function submissionSection(brief) {
108
+ if (brief.workSubmissions !== undefined) {
109
+ const parts = [];
110
+ for (const wp of brief.wps) {
111
+ const sub = brief.workSubmissions[wp.id];
112
+ if (sub === undefined)
113
+ continue;
114
+ const contracts = sub.interfaceContracts
115
+ .map((c) => `${c.interface}/${c.role}/${c.verified}`)
116
+ .join('; ');
117
+ parts.push(`WP ${wp.id} by ${sub.identity}: ${clampText(sub.summary, 600)}\n` +
118
+ ` files changed: ${sub.filesChanged.join(', ') || '(none)'}\n` +
119
+ ` contract claims: ${contracts || '(none)'}`);
120
+ }
121
+ return parts.length === 0
122
+ ? null
123
+ : { priority: 5, title: 'SUBMITTED WORK UNDER REVIEW', body: parts.join('\n') };
124
+ }
125
+ if (brief.changeLists !== undefined) {
126
+ const parts = brief.wps.map((wp) => `WP ${wp.id}: ${(brief.changeLists?.[wp.id] ?? []).join(', ') || '(none)'}`);
127
+ return { priority: 5, title: 'FILES CHANGED BY THE DEVELOPER', body: parts.join('\n') };
128
+ }
129
+ return null;
130
+ }
131
+ function verdictSection(brief) {
132
+ if (brief.reviewVerdicts === undefined)
133
+ return null;
134
+ const parts = brief.wps
135
+ .filter((wp) => brief.reviewVerdicts?.[wp.id] !== undefined)
136
+ .map((wp) => `WP ${wp.id}: review verdict ${brief.reviewVerdicts?.[wp.id]}`);
137
+ if (parts.length === 0)
138
+ return null;
139
+ return {
140
+ priority: 6,
141
+ title: 'REVIEW CONCLUSIONS (conclusion only; comments are withheld on purpose)',
142
+ body: parts.join('\n'),
143
+ };
144
+ }
145
+ function appealSection(brief) {
146
+ if (brief.appeals === undefined)
147
+ return null;
148
+ const parts = brief.wps
149
+ .filter((wp) => brief.appeals?.[wp.id] !== undefined)
150
+ .map((wp) => {
151
+ const a = brief.appeals[wp.id];
152
+ return (`WP ${wp.id}: the developer appeals findings [${a.findingIds.join(', ')}]: ` +
153
+ `${clampText(a.argument, 500)}\n You MUST answer each with appealResponses ` +
154
+ `(uphold or withdraw).`);
155
+ });
156
+ if (parts.length === 0)
157
+ return null;
158
+ return { priority: 7, title: 'APPEAL', body: parts.join('\n') };
159
+ }
160
+ function inspectorSection(brief) {
161
+ const m = brief.inspector;
162
+ if (m === undefined)
163
+ return null;
164
+ const lines = [];
165
+ lines.push(`Registered integration commands: ${brief.run.integrationCommands.length > 0 ? brief.run.integrationCommands.join(' | ') : '(none - static verification only)'}`);
166
+ if (m.integrationAttempt !== undefined)
167
+ lines.push(`Integration attempt: ${m.integrationAttempt}`);
168
+ if (m.healthWarning === true) {
169
+ lines.push('Team health is low: check interface conflicts specifically.');
170
+ }
171
+ lines.push('Events already booked by the engine (do not re-book):');
172
+ lines.push(m.autoEvents.length > 0 ? bullet(m.autoEvents) : '- (none)');
173
+ lines.push('Open claims:');
174
+ lines.push(m.openClaims.length > 0
175
+ ? bullet(m.openClaims.map((c) => `${c.id} [${c.kind}] ${c.raisedBy} vs ${c.against} on ${c.wpId}: ${c.text}`))
176
+ : '- (none)');
177
+ lines.push('Mechanical flags:');
178
+ lines.push(m.flags.length > 0 ? bullet(m.flags) : '- (none)');
179
+ for (const [wpId, text] of Object.entries(m.reviewDigest))
180
+ lines.push(`Review ${wpId}: ${text}`);
181
+ for (const [wpId, text] of Object.entries(m.testDigest))
182
+ lines.push(`Test ${wpId}: ${text}`);
183
+ if (m.viewEvents !== undefined && m.viewEvents.length > 0) {
184
+ lines.push('View requests this phase:');
185
+ lines.push(bullet(m.viewEvents));
186
+ }
187
+ return { priority: 10, title: 'INSPECTOR BRIEF', body: lines.join('\n') };
188
+ }
189
+ function notesSection(brief) {
190
+ if (brief.notes === undefined)
191
+ return null;
192
+ if (brief.stage !== 'dev' && brief.stage !== 'fix')
193
+ return null;
194
+ const parts = brief.wps
195
+ .filter((wp) => (brief.notes?.[wp.id] ?? '').trim().length > 0)
196
+ .map((wp) => `WP ${wp.id}: ${clampText(brief.notes[wp.id], GOV_LIMITS.noteChars)}`);
197
+ if (parts.length === 0)
198
+ return null;
199
+ return { priority: 9, title: 'ORCHESTRATOR NOTE', body: parts.join('\n') };
200
+ }
201
+ function buildSections(brief) {
202
+ const wpIds = new Set(brief.wps.map((w) => w.id));
203
+ const isInspector = brief.role === 'INSP';
204
+ const sections = [
205
+ { priority: 1, title: 'TASK', body: taskInstruction(brief) },
206
+ brief.missingOnly !== undefined && brief.missingOnly.length > 0
207
+ ? {
208
+ priority: 1,
209
+ title: 'REMINDER',
210
+ body: `Your earlier attempt ended without a submission for: ` +
211
+ `${brief.missingOnly.join(', ')}. Submit those now; they are the only ones listed.`,
212
+ }
213
+ : null,
214
+ brief.wps.length > 0
215
+ ? { priority: 2, title: 'WORK PACKAGES', body: brief.wps.map(describeWp).join('\n\n') }
216
+ : null,
217
+ describeContracts(brief.run.contracts, isInspector ? null : wpIds) === ''
218
+ ? null
219
+ : {
220
+ priority: 3,
221
+ title: 'CONTRACTS (exact interfaces shared between work packages)',
222
+ body: describeContracts(brief.run.contracts, isInspector ? null : wpIds),
223
+ },
224
+ reworkSection(brief),
225
+ brief.rcaText !== undefined && brief.rcaText.length > 0
226
+ ? { priority: 4, title: 'ROOT CAUSE ANALYSIS', body: brief.rcaText }
227
+ : null,
228
+ submissionSection(brief),
229
+ verdictSection(brief),
230
+ appealSection(brief),
231
+ {
232
+ priority: 8,
233
+ title: 'SPECIFICATION EXCERPT (priority: spec > charter and contracts > best practice)',
234
+ body: clampText(brief.run.spec, GOV_LIMITS.specExcerptChars),
235
+ },
236
+ notesSection(brief),
237
+ inspectorSection(brief),
238
+ ];
239
+ return sections.filter((s) => s !== null);
240
+ }
241
+ /**
242
+ * Join sections by priority under `budget` characters, clipping from the LOW-priority end
243
+ * and marking every clipped section. The task instruction is never clipped: a brief
244
+ * without its instruction is a brief that cannot be followed.
245
+ */
246
+ export function assemblePrompt(sections, budget) {
247
+ const ordered = [...sections].sort((a, b) => a.priority - b.priority);
248
+ const render = (s, body) => `## ${s.title}\n${body}`;
249
+ const rendered = ordered.map((s) => render(s, s.body));
250
+ const total = rendered.reduce((n, r) => n + r.length + 2, 0);
251
+ if (total <= budget)
252
+ return rendered.join('\n\n');
253
+ const out = [];
254
+ let remaining = budget;
255
+ for (const s of ordered) {
256
+ const full = render(s, s.body);
257
+ const cost = full.length + 2;
258
+ if (cost <= remaining || s.priority === 1) {
259
+ out.push(full);
260
+ remaining -= cost;
261
+ continue;
262
+ }
263
+ const header = `## ${s.title}\n`;
264
+ const room = remaining - header.length - TRUNCATION_MARK.length - 3;
265
+ if (room < 60)
266
+ continue;
267
+ out.push(`${header}${s.body.slice(0, room)} ${TRUNCATION_MARK}`);
268
+ remaining = 0;
269
+ }
270
+ return out.join('\n\n');
271
+ }
272
+ function describe(brief) {
273
+ const ids = brief.wps.map((w) => w.id).join(',');
274
+ const head = brief.role === 'INSP' ? `INSP ${brief.stage}` : `${ROLE_WORD[brief.role]} ${ids}`;
275
+ const tail = brief.stage === 'dev'
276
+ ? 'implement'
277
+ : brief.stage === 'fix'
278
+ ? 'align interfaces'
279
+ : brief.stage === 'review'
280
+ ? 'review'
281
+ : brief.stage === 'test'
282
+ ? 'verify'
283
+ : brief.stage;
284
+ return clampText(`${head}: ${tail}`, TEAM_LIMITS.descriptionChars);
285
+ }
286
+ /**
287
+ * Build one `SubagentSpec`. The label IS the roster identity, which already satisfies
288
+ * `[a-z0-9-]{1,12}`; the guard below catches a future identity scheme that does not,
289
+ * rather than letting `TeamRuntime` discover it as a dropped child.
290
+ */
291
+ export function buildSubagentSpec(brief) {
292
+ const label = brief.identity.toLowerCase().slice(0, TEAM_LIMITS.labelChars);
293
+ if (!/^[a-z0-9-]{1,12}$/.test(label) || label === TEAM_AGGREGATE_LABEL) {
294
+ throw new Error(`governance: identity "${brief.identity}" is not a legal subagent label`);
295
+ }
296
+ const ext = {
297
+ role: brief.role,
298
+ identity: brief.identity,
299
+ runId: brief.run.runId,
300
+ phase: brief.phase,
301
+ stage: brief.stage,
302
+ wpIds: brief.wps.map((w) => w.id),
303
+ tokens: brief.tokens,
304
+ generation: brief.generation,
305
+ profile: brief.run.profile,
306
+ ...(brief.predecessor ? { predecessorAnalysis: brief.predecessor } : {}),
307
+ ...(brief.role === 'INSP' ? { integrationCommands: [...brief.run.integrationCommands] } : {}),
308
+ };
309
+ const prompt = assemblePrompt(buildSections(brief), TEAM_LIMITS.promptChars);
310
+ return {
311
+ label,
312
+ description: describe(brief),
313
+ prompt,
314
+ readOnly: false,
315
+ governance: ext,
316
+ };
317
+ }
318
+ /** Convenience for tests and the engine: render derived required changes from a review. */
319
+ export function requiredChangesOf(review) {
320
+ return review.requiredChanges;
321
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `gov_dispatch`: run one stage of the current phase (governance-mode 7.2, 8.2-8.4).
3
+ *
4
+ * ASCII ONLY (`governance/` is glyph-scanned).
5
+ *
6
+ * THE DIVISION OF LABOUR. This module owns everything BEFORE and AFTER the children run:
7
+ * legality, budget, assignment, briefs, the stage record, the single automatic redispatch of
8
+ * whatever came back without a submission, the pause on abort, and the digest. It owns NONE
9
+ * of the judgement: when a child calls `gov_submit_*` / `ledger_*` the adjudication half
10
+ * (`submissions.ts`, `inspector.ts`) books the ledger and routes the work package
11
+ * synchronously inside that tool call. That is why a stage that is aborted half way keeps
12
+ * every submission already made, and why "resume re-runs only what is missing" needs no
13
+ * bookkeeping here: a routed WP is simply no longer eligible for the stage.
14
+ *
15
+ * A MISSING SUBMISSION IS NOT A MISDEED (8.4). Infrastructure failures, a model that
16
+ * wandered off and a context that ran out all look the same from here, so the first answer
17
+ * is one reminder-bearing redispatch of only the missing WPs, and the second is `blocked`
18
+ * with `blockedAt` set to this stage - never a deduction.
19
+ */
20
+ import type { EngineCore } from './engine-core.js';
21
+ /** `gov_dispatch`. Always returns text; an interrupted stage is `PAUSED:`, not an error. */
22
+ export declare function runStage(core: EngineCore, raw: unknown, signal?: AbortSignal): Promise<string>;