@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,396 @@
1
+ /**
2
+ * `ledger_apply` / `ledger_rule` / `ledger_settle` - the engine side (governance-mode 5.4,
3
+ * 5.6, 5.7, 7.3).
4
+ *
5
+ * ASCII ONLY (`governance/` is glyph-scanned).
6
+ *
7
+ * THE INSPECTOR HAS NO SECOND ACCOUNTING PATH (I-G7). Everything it books goes through the
8
+ * same `core.ledgerOp` as the engine's own events, with the same catalogue deltas and the
9
+ * same caps; the only difference is `by: "inspector:insp"` and the evidence it must attach.
10
+ * It cannot name its own amount, cannot target itself (I-G5) and cannot book a mechanical
11
+ * code - those are refused here even if the tool layer let them through.
12
+ */
13
+ import { getLogger } from '../../logging/logger.js';
14
+ import { GOV_LIMITS } from '../limits.js';
15
+ import { ruleClaim } from '../rules/claims.js';
16
+ import { eventDef, isEventCode, isInspectorBookable } from '../rules/events-table.js';
17
+ import { teamHealthStatus } from '../rules/elimination.js';
18
+ import { settlePhaseR1R2 } from '../rules/settlement.js';
19
+ import { normalizeLedgerApply, normalizeLedgerRule, normalizeLedgerSettle, } from '../tools/inspector-tools.js';
20
+ import { formatNotAccepted } from '../tools/normalize-util.js';
21
+ import { applyEvents } from './aftermath.js';
22
+ import { artifactIdFor, persistArtifact } from './artifact-persist.js';
23
+ import { PHASE_WP_SEGMENT } from '../store/artifacts.js';
24
+ import { announceEscalation, applyIntegrationFailure, applyIntegrationPass, staticVerificationProblem, } from './integration.js';
25
+ import { livePhaseWps } from './phase-members.js';
26
+ import { renderInspectorMarkdown } from './submission-render.js';
27
+ import { latestReview, submissionsOf } from './submission-queries.js';
28
+ import { nextEscalationId, openEscalation } from './state-machine.js';
29
+ const NOT_ACCEPTED = 'NOT ACCEPTED:';
30
+ const INSPECTOR_ACTOR = 'insp';
31
+ const INSPECTOR_BY = `inspector:${INSPECTOR_ACTOR}`;
32
+ function guarded(tool, fn) {
33
+ try {
34
+ return fn();
35
+ }
36
+ catch (error) {
37
+ const message = error instanceof Error ? error.message : String(error);
38
+ getLogger().warn('agent', 'governance.inspector_internal_error', { tool, message });
39
+ return (`${NOT_ACCEPTED} internal error while recording ${tool} (${message}). Nothing was ` +
40
+ `recorded.`);
41
+ }
42
+ }
43
+ /** The inspector tools only make sense inside a running settle / integrate stage. */
44
+ function inspectorStage(core, tool) {
45
+ const run = core.run;
46
+ if (run === null)
47
+ return `${NOT_ACCEPTED} no governance run is active.`;
48
+ const stage = run.stage;
49
+ if (stage === null ||
50
+ stage.status !== 'running' ||
51
+ (stage.kind !== 'settle' && stage.kind !== 'integrate')) {
52
+ const now = stage ? `${stage.kind} (${stage.status})` : 'none';
53
+ return (`${NOT_ACCEPTED} ${tool} is only available in a running settle or integrate stage ` +
54
+ `(current: ${now}).`);
55
+ }
56
+ const phase = run.phases[stage.phase];
57
+ if (phase === undefined)
58
+ return `${NOT_ACCEPTED} the stage refers to an unknown phase.`;
59
+ return { run, kind: stage.kind, phase };
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // ledger_apply
63
+ // ---------------------------------------------------------------------------
64
+ function applyPreconditions(core, input) {
65
+ if (!isEventCode(input.code))
66
+ return `${NOT_ACCEPTED} unknown event code "${String(input.code)}".`;
67
+ if (!isInspectorBookable(input.code)) {
68
+ return (`${NOT_ACCEPTED} this event is handled by the engine (${input.code}: ` +
69
+ `${eventDef(input.code).title}).`);
70
+ }
71
+ if (input.agentId.toLowerCase() === INSPECTOR_ACTOR) {
72
+ return `${NOT_ACCEPTED} the inspector is not scored and cannot be the subject of an event.`;
73
+ }
74
+ const agent = core.ledger.agents[input.agentId];
75
+ if (agent === undefined) {
76
+ return (`${NOT_ACCEPTED} unknown agent "${input.agentId}". Roster: ` +
77
+ `${Object.keys(core.ledger.agents).join(', ')}.`);
78
+ }
79
+ if (agent.status !== 'active') {
80
+ return (`${NOT_ACCEPTED} ${agent.id} is already ` +
81
+ `eliminated${agent.replacedBy ? ` (replaced by ${agent.replacedBy})` : ''}; book against ` +
82
+ `the successor.`);
83
+ }
84
+ const def = eventDef(input.code);
85
+ if (def.role !== 'ALL' && def.role !== agent.role) {
86
+ return (`${NOT_ACCEPTED} ${input.code} applies to ${def.role} agents; ${agent.id} is ` +
87
+ `${agent.role}.`);
88
+ }
89
+ if (input.evidence.trim().length < GOV_LIMITS.evidenceMinChars) {
90
+ return (`${NOT_ACCEPTED} evidence must be concrete (at least ${GOV_LIMITS.evidenceMinChars} ` +
91
+ `characters: files, lines, quotes). No evidence, no event.`);
92
+ }
93
+ return null;
94
+ }
95
+ /** The same judgment about the same agent and work package is booked once per phase. */
96
+ function alreadyJudged(core, input, phase) {
97
+ const agent = core.ledger.agents[input.agentId];
98
+ if (agent === undefined)
99
+ return false;
100
+ return agent.history.some((e) => e.code === input.code &&
101
+ e.phase === phase &&
102
+ e.wpId === input.wpId &&
103
+ e.by === INSPECTOR_BY &&
104
+ (input.incidentId === undefined || e.incidentId === input.incidentId));
105
+ }
106
+ export function handleInspectorApply(core, input) {
107
+ return guarded('ledger_apply', () => {
108
+ const normalized = normalizeLedgerApply(input);
109
+ if (!normalized.ok)
110
+ return formatNotAccepted('ledger_apply', normalized.errors);
111
+ const value = normalized.value;
112
+ const stage = inspectorStage(core, 'ledger_apply');
113
+ if (typeof stage === 'string')
114
+ return stage;
115
+ const problem = applyPreconditions(core, value);
116
+ if (problem !== null)
117
+ return problem;
118
+ const wp = value.wpId === undefined ? undefined : stage.run.workPackages[value.wpId];
119
+ if (value.wpId !== undefined && wp === undefined) {
120
+ return `${NOT_ACCEPTED} unknown work package "${value.wpId}".`;
121
+ }
122
+ const phase = wp ? wp.phase : stage.phase.index;
123
+ if (alreadyJudged(core, value, phase)) {
124
+ return (`${NOT_ACCEPTED} ${value.code} was already booked for ` +
125
+ `${value.agentId}${value.wpId ? ` on ${value.wpId}` : ''} in this phase.`);
126
+ }
127
+ const event = {
128
+ code: value.code,
129
+ agentId: value.agentId,
130
+ at: core.now(),
131
+ phase,
132
+ by: INSPECTOR_BY,
133
+ reason: value.reason,
134
+ evidence: value.evidence,
135
+ ...(value.wpId !== undefined ? { wpId: value.wpId } : {}),
136
+ ...(value.incidentId !== undefined ? { incidentId: value.incidentId } : {}),
137
+ };
138
+ const booked = applyEvents(core, [event], { actor: INSPECTOR_ACTOR, phase });
139
+ core.checkpoint();
140
+ const mine = booked.find((b) => b.agentId === value.agentId && b.entry.code === value.code);
141
+ if (mine === undefined) {
142
+ return (`${NOT_ACCEPTED} the ledger refused ${value.code} for ${value.agentId} (agent not ` +
143
+ `scorable right now).`);
144
+ }
145
+ const cap = mine.entry.capped
146
+ ? ` CAPPED: requested ${mine.entry.capped.requested}, applied ` +
147
+ `${mine.entry.capped.applied}; state this in your settle summary.`
148
+ : '';
149
+ const sign = mine.entry.delta > 0 ? '+' : '';
150
+ return (`OK: booked ${value.code} ` +
151
+ `${sign}${mine.entry.delta}${mine.entry.settlement === 'provisional' ? 'P' : ''} for ` +
152
+ `${value.agentId}.${cap}`);
153
+ });
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // ledger_rule
157
+ // ---------------------------------------------------------------------------
158
+ export function handleInspectorRule(core, input) {
159
+ return guarded('ledger_rule', () => {
160
+ const normalized = normalizeLedgerRule(input);
161
+ if (!normalized.ok)
162
+ return formatNotAccepted('ledger_rule', normalized.errors);
163
+ const value = normalized.value;
164
+ const stage = inspectorStage(core, 'ledger_rule');
165
+ if (typeof stage === 'string')
166
+ return stage;
167
+ const claim = stage.run.claims.find((c) => c.id === value.claimId);
168
+ if (claim === undefined) {
169
+ const open = stage.run.claims.filter((c) => c.status === 'open').map((c) => c.id);
170
+ return (`${NOT_ACCEPTED} unknown claim "${value.claimId}". Open claims: ` +
171
+ `${open.join(', ') || '(none)'}.`);
172
+ }
173
+ if (claim.status !== 'open')
174
+ return `${NOT_ACCEPTED} claim ${claim.id} is already ${claim.status}.`;
175
+ const ruled = ruleClaim({
176
+ state: core.ledger,
177
+ claim,
178
+ decision: value.decision,
179
+ ruling: value.ruling,
180
+ at: core.now(),
181
+ inspectorId: INSPECTOR_ACTOR,
182
+ });
183
+ Object.assign(claim, ruled.claim);
184
+ core.log('ruling', INSPECTOR_ACTOR, { claimId: claim.id, decision: value.decision });
185
+ applyEvents(core, ruled.events, { actor: INSPECTOR_ACTOR, phase: claim.phase });
186
+ core.checkpoint();
187
+ const remaining = stage.run.claims.filter((c) => c.status === 'open').length;
188
+ const booked = ruled.events.map((e) => `${e.code} ${e.agentId}`).join(', ');
189
+ return [
190
+ `OK: claim ${claim.id} ` +
191
+ `${value.decision}${booked ? ` (booked: ${booked})` : ' (no event booked)'}.`,
192
+ ...ruled.notes,
193
+ `${remaining} open claim(s) remain.`,
194
+ ].join('\n');
195
+ });
196
+ }
197
+ // ---------------------------------------------------------------------------
198
+ // ledger_settle
199
+ // ---------------------------------------------------------------------------
200
+ function rejectionRecords(core, wps) {
201
+ const out = [];
202
+ for (const wp of wps) {
203
+ const reviews = submissionsOf(core, wp.id, 'review');
204
+ reviews.forEach((review, index) => {
205
+ if (review.verdict !== 'NEEDS_REWORK')
206
+ return;
207
+ const ids = new Set(review.findings.map((f) => f.id));
208
+ const withdrawn = reviews
209
+ .slice(index + 1)
210
+ .some((later) => later.appealResponses.some((a) => a.decision === 'withdraw' && ids.has(a.findingId)));
211
+ out.push({
212
+ id: review.id,
213
+ wpId: wp.id,
214
+ reviewer: review.identity,
215
+ hasBlockerOrMajor: review.findings.some((f) => f.severity === 'blocker' || f.severity === 'major'),
216
+ withdrawn,
217
+ });
218
+ });
219
+ }
220
+ return out;
221
+ }
222
+ function payPhaseBonuses(core, run, phase) {
223
+ const wps = livePhaseWps(run, phase);
224
+ const reviewedWps = wps.flatMap((wp) => {
225
+ const review = latestReview(core, wp.id);
226
+ const passed = review !== undefined && review.verdict !== 'NEEDS_REWORK';
227
+ return passed ? [{ wpId: wp.id, reviewer: review.identity }] : [];
228
+ });
229
+ const result = settlePhaseR1R2({
230
+ state: core.ledger,
231
+ phase: phase.index,
232
+ at: core.now(),
233
+ reviewedWps,
234
+ testedOkWpIds: wps.filter((w) => w.status === 'tested_ok').map((w) => w.id),
235
+ claims: run.claims,
236
+ rejections: rejectionRecords(core, wps),
237
+ });
238
+ applyEvents(core, result.events, { phase: phase.index });
239
+ return result.notes;
240
+ }
241
+ function openInspectorEscalations(core, run, phase, input) {
242
+ const opened = [];
243
+ for (const item of input.escalations) {
244
+ const escalation = {
245
+ id: nextEscalationId(run),
246
+ level: 'L3',
247
+ kind: item.kind,
248
+ phase: phase.index,
249
+ topic: item.topic,
250
+ positions: item.positions,
251
+ status: 'open',
252
+ ...(item.wpId !== undefined ? { wpId: item.wpId } : {}),
253
+ };
254
+ openEscalation(run, escalation);
255
+ announceEscalation(core, escalation);
256
+ core.stageWarnings.push(`ESCALATION ${escalation.id}: ${item.topic}`);
257
+ opened.push(escalation);
258
+ }
259
+ return opened;
260
+ }
261
+ function buildReport(core, input, phase) {
262
+ const target = {
263
+ phase: phase.index,
264
+ wpId: PHASE_WP_SEGMENT,
265
+ stage: input.kind,
266
+ identity: INSPECTOR_ACTOR,
267
+ };
268
+ const report = {
269
+ kind: 'inspector',
270
+ id: artifactIdFor(core, target),
271
+ phase: phase.index,
272
+ stage: input.kind,
273
+ at: core.now(),
274
+ summary: input.summary,
275
+ contractChecks: input.contractChecks,
276
+ escalations: input.escalations,
277
+ ...(input.integration ? { integration: input.integration } : {}),
278
+ ...(input.rca ? { rca: input.rca } : {}),
279
+ };
280
+ persistArtifact(core, target, report.id, report, renderInspectorMarkdown(report));
281
+ return report;
282
+ }
283
+ /** `reports/phase-N.md`: settlement and integration reports of the phase, in order. */
284
+ function writePhaseReport(core, phase) {
285
+ const reports = [...core.submissionCache.values()]
286
+ .filter((r) => r.kind === 'inspector' && r.phase === phase.index)
287
+ .sort((a, b) => a.at - b.at);
288
+ core.writeFile(`reports/phase-${phase.index + 1}.md`, reports.map(renderInspectorMarkdown).join('\n---\n\n'));
289
+ }
290
+ function validateSettleInput(core, stage, input) {
291
+ if (input.kind !== stage.kind) {
292
+ return (`${NOT_ACCEPTED} this is the ${stage.kind} stage; ledger_settle kind must be ` +
293
+ `"${stage.kind}".`);
294
+ }
295
+ if (input.phase - 1 !== stage.phase.index) {
296
+ return (`${NOT_ACCEPTED} phase must be ${stage.phase.index + 1} (the running phase), not ` +
297
+ `${input.phase}.`);
298
+ }
299
+ if (core.stageSubmitted.has(INSPECTOR_ACTOR)) {
300
+ return `${NOT_ACCEPTED} already settled: ledger_settle is called exactly once per stage.`;
301
+ }
302
+ return null;
303
+ }
304
+ function settleStage(core, stage, input) {
305
+ const { run, phase } = stage;
306
+ const open = run.claims.filter((c) => c.phase === phase.index && c.status === 'open');
307
+ if (open.length > 0) {
308
+ return (`${NOT_ACCEPTED} ${open.length} claim(s) are not ruled: ` +
309
+ `${open.map((c) => c.id).join(', ')}. ` +
310
+ 'Rule each with ledger_rule (upheld or rejected), then call ledger_settle.');
311
+ }
312
+ const notes = payPhaseBonuses(core, run, phase);
313
+ const mismatches = input.contractChecks.filter((c) => c.status === 'mismatch');
314
+ const opened = openInspectorEscalations(core, run, phase, input);
315
+ phase.settled = true;
316
+ const report = buildReport(core, input, phase);
317
+ writePhaseReport(core, phase);
318
+ core.stageSubmitted.add(INSPECTOR_ACTOR);
319
+ const headline = `phase ${phase.index + 1} settled`;
320
+ core.inspectorOutcome = { kind: 'settle', phase: phase.index, passed: true, headline };
321
+ core.log('submission', INSPECTOR_ACTOR, {
322
+ kind: 'inspector',
323
+ stage: 'settle',
324
+ reportId: report.id,
325
+ });
326
+ core.stageResults.push(`settle: ${input.summary.slice(0, 160)}`);
327
+ core.checkpoint();
328
+ const health = teamHealthStatus(core.ledger);
329
+ return [
330
+ `OK: settle recorded for phase ${phase.index + 1}.`,
331
+ ...notes,
332
+ mismatches.length > 0
333
+ ? `${mismatches.length} contract mismatch(es) recorded ` +
334
+ `(${mismatches.map((m) => m.contractId).join(', ')}); book D14/D15 with ledger_apply ` +
335
+ `if you have not.`
336
+ : 'All checked contracts are consistent.',
337
+ opened.length > 0 ? `${opened.length} escalation(s) opened for the user.` : '',
338
+ health.advisory ?? '',
339
+ ]
340
+ .filter((l) => l !== '')
341
+ .join('\n');
342
+ }
343
+ function integrateStage(core, stage, input) {
344
+ const { run, phase } = stage;
345
+ const integration = input.integration;
346
+ if (integration === undefined) {
347
+ return (`${NOT_ACCEPTED} integrate needs integration: {result: pass | fail | not_run, ` + `commands}.`);
348
+ }
349
+ if (integration.result === 'fail' && input.rca === undefined) {
350
+ return (`${NOT_ACCEPTED} integration failed: include rca {failingChecks, boundary, ` +
351
+ `attributions, systemic}.`);
352
+ }
353
+ if (integration.result === 'not_run') {
354
+ const problem = staticVerificationProblem(run, phase, input);
355
+ if (problem !== null)
356
+ return problem;
357
+ }
358
+ const report = buildReport(core, input, phase);
359
+ core.stageSubmitted.add(INSPECTOR_ACTOR);
360
+ core.log('submission', INSPECTOR_ACTOR, {
361
+ kind: 'inspector',
362
+ stage: 'integrate',
363
+ reportId: report.id,
364
+ });
365
+ const verdict = integration.result === 'fail'
366
+ ? applyIntegrationFailure(core, phase, input.rca)
367
+ : applyIntegrationPass(core, phase, { accepted: true });
368
+ openInspectorEscalations(core, run, phase, input);
369
+ writePhaseReport(core, phase);
370
+ core.inspectorOutcome = {
371
+ kind: 'integrate',
372
+ phase: phase.index,
373
+ passed: verdict.passed,
374
+ headline: verdict.headline,
375
+ };
376
+ core.stageResults.push(`integrate: ${verdict.headline}`);
377
+ core.checkpoint();
378
+ const prefix = verdict.passed ? 'OK: integration passed.' : 'OK: integration failure recorded.';
379
+ return [prefix, ...verdict.lines].join('\n');
380
+ }
381
+ export function handleInspectorSettle(core, input) {
382
+ return guarded('ledger_settle', () => {
383
+ const normalized = normalizeLedgerSettle(input);
384
+ if (!normalized.ok)
385
+ return formatNotAccepted('ledger_settle', normalized.errors);
386
+ const stage = inspectorStage(core, 'ledger_settle');
387
+ if (typeof stage === 'string')
388
+ return stage;
389
+ const problem = validateSettleInput(core, stage, normalized.value);
390
+ if (problem !== null)
391
+ return problem;
392
+ return stage.kind === 'settle'
393
+ ? settleStage(core, stage, normalized.value)
394
+ : integrateStage(core, stage, normalized.value);
395
+ });
396
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The integrate stage's verdict (governance-mode 5.7): pass releases escrow and pays the
3
+ * collective; fail attributes the failure, claws escrow back from the primary and opens a
4
+ * fix cycle - or, when the fix budget is spent, an escalation to the user.
5
+ *
6
+ * ASCII ONLY (`governance/` is glyph-scanned).
7
+ *
8
+ * `integrationAttempts` is incremented HERE (every integrate) and `fixCycles` by the stage
9
+ * runner (every fix); the legality table and `isIntegrationExhausted` read both, so each
10
+ * counter must have exactly one writer.
11
+ */
12
+ import type { Escalation, PhaseState, RcaInput, RunState } from '../types.js';
13
+ import type { LedgerSettleInput } from '../tools/inspector-tools.js';
14
+ import type { EngineCore } from './engine-core.js';
15
+ export interface IntegrationVerdict {
16
+ /** Did the phase become integrated? */
17
+ passed: boolean;
18
+ headline: string;
19
+ /** Text lines for the inspector's `OK:` answer. */
20
+ lines: string[];
21
+ }
22
+ /** Contracts whose producer or a consumer belongs to the phase (and are still live). */
23
+ export declare function contractsOfPhase(run: RunState, phase: PhaseState): string[];
24
+ /**
25
+ * `not_run` is legal only when there is nothing to run: no registered commands, and every
26
+ * live contract of the phase statically checked `ok`. Returns a refusal text or null.
27
+ */
28
+ export declare function staticVerificationProblem(run: RunState, phase: PhaseState, input: LedgerSettleInput): string | null;
29
+ /** Pass: escrow -> confirmed, D12, C1 (first attempt only), tail check, WPs integrated. */
30
+ export declare function applyIntegrationPass(core: EngineCore, phase: PhaseState, options: {
31
+ accepted: boolean;
32
+ }): IntegrationVerdict;
33
+ export declare function announceEscalation(core: EngineCore, escalation: Escalation): void;
34
+ /** Fail: attribute, claw back, count the attempt, escalate when the fix budget is gone. */
35
+ export declare function applyIntegrationFailure(core: EngineCore, phase: PhaseState, rca: RcaInput): IntegrationVerdict;
@@ -0,0 +1,220 @@
1
+ /**
2
+ * The integrate stage's verdict (governance-mode 5.7): pass releases escrow and pays the
3
+ * collective; fail attributes the failure, claws escrow back from the primary and opens a
4
+ * fix cycle - or, when the fix budget is spent, an escalation to the user.
5
+ *
6
+ * ASCII ONLY (`governance/` is glyph-scanned).
7
+ *
8
+ * `integrationAttempts` is incremented HERE (every integrate) and `fixCycles` by the stage
9
+ * runner (every fix); the legality table and `isIntegrationExhausted` read both, so each
10
+ * counter must have exactly one writer.
11
+ */
12
+ import { expandRca } from '../rules/rca.js';
13
+ import { applyEvents, afterLedgerChange, emitLedger, runTailCheck } from './aftermath.js';
14
+ import { escalationCard, phaseCard } from './cards.js';
15
+ import { alreadyBooked, livePhaseWps, phaseMembers, wasPrimaryInPhase } from './phase-members.js';
16
+ import { isIntegrationExhausted, nextEscalationId, openEscalation, recordRework, } from './state-machine.js';
17
+ const NOT_ACCEPTED = 'NOT ACCEPTED:';
18
+ /** Contracts whose producer or a consumer belongs to the phase (and are still live). */
19
+ export function contractsOfPhase(run, phase) {
20
+ const inPhase = new Set(livePhaseWps(run, phase).map((w) => w.id));
21
+ return run.contracts
22
+ .filter((c) => c.voided !== true && (inPhase.has(c.producer) || c.consumers.some((id) => inPhase.has(id))))
23
+ .map((c) => c.id);
24
+ }
25
+ /**
26
+ * `not_run` is legal only when there is nothing to run: no registered commands, and every
27
+ * live contract of the phase statically checked `ok`. Returns a refusal text or null.
28
+ */
29
+ export function staticVerificationProblem(run, phase, input) {
30
+ if (run.integrationCommands.length > 0) {
31
+ return (`${NOT_ACCEPTED} integration commands are registered ` +
32
+ `(${run.integrationCommands.join(' | ')}); ` +
33
+ 'run them and report result pass or fail, not not_run.');
34
+ }
35
+ const required = contractsOfPhase(run, phase);
36
+ const checks = new Map(input.contractChecks.map((c) => [c.contractId, c.status]));
37
+ const missing = required.filter((id) => !checks.has(id));
38
+ if (missing.length > 0) {
39
+ return (`${NOT_ACCEPTED} static verification must check every contract; missing: ` +
40
+ `${missing.join(', ')}.`);
41
+ }
42
+ const bad = required.filter((id) => checks.get(id) !== 'ok');
43
+ if (bad.length > 0) {
44
+ return (`${NOT_ACCEPTED} contract(s) ${bad.join(', ')} did not check ok. Report integration result ` +
45
+ 'fail with an rca, or verify them and report ok.');
46
+ }
47
+ return null;
48
+ }
49
+ function cleanDeveloperEvents(core, phase) {
50
+ const run = core.requireRun();
51
+ const at = core.now();
52
+ const events = [];
53
+ for (const wp of livePhaseWps(run, phase)) {
54
+ const dev = wp.assignee;
55
+ if (dev === null || core.ledger.agents[dev]?.status !== 'active')
56
+ continue;
57
+ if (wasPrimaryInPhase(core, dev, phase.index))
58
+ continue;
59
+ const incidentId = `d12:${wp.id}`;
60
+ if (alreadyBooked(core, dev, 'D12', incidentId))
61
+ continue;
62
+ events.push({
63
+ code: 'D12',
64
+ agentId: dev,
65
+ at,
66
+ phase: phase.index,
67
+ by: 'engine',
68
+ reason: `integration passed with ${wp.id} clean`,
69
+ wpId: wp.id,
70
+ incidentId,
71
+ });
72
+ }
73
+ return events;
74
+ }
75
+ /** Pass: escrow -> confirmed, D12, C1 (first attempt only), tail check, WPs integrated. */
76
+ export function applyIntegrationPass(core, phase, options) {
77
+ const run = core.requireRun();
78
+ const firstAttempt = phase.integrationAttempts === 0;
79
+ phase.integrationAttempts += 1;
80
+ phase.lastIntegrationFailed = false;
81
+ const members = phaseMembers(core, phase);
82
+ const at = core.now();
83
+ const escrow = core.ledgerOp({ op: 'confirm_escrow', phase: phase.index, at });
84
+ core.noteBooked(escrow.booked);
85
+ applyEvents(core, cleanDeveloperEvents(core, phase), { phase: phase.index });
86
+ if (firstAttempt) {
87
+ const op = {
88
+ op: 'collective',
89
+ spec: {
90
+ code: 'C1',
91
+ at,
92
+ phase: phase.index,
93
+ by: 'engine',
94
+ reason: 'integration passed first time',
95
+ participants: members,
96
+ incidentId: `c1:p${phase.index}`,
97
+ },
98
+ };
99
+ core.noteBooked(core.ledgerOp(op).booked);
100
+ }
101
+ phase.integrated = true;
102
+ phase.integrationAccepted = options.accepted;
103
+ for (const wp of livePhaseWps(run, phase)) {
104
+ if (wp.status === 'tested_ok')
105
+ wp.status = 'integrated';
106
+ }
107
+ core.log('escrow', 'engine', { phase: phase.index, released: escrow.booked.length });
108
+ core.emit((snapshot) => ({ type: 'escrow', snapshot, phase: phase.index, released: true }));
109
+ runTailCheck(core, phase.index);
110
+ afterLedgerChange(core, { phase: phase.index });
111
+ emitLedger(core);
112
+ core.exportScoreboard();
113
+ const headline = `integration passed (attempt ${phase.integrationAttempts})`;
114
+ const card = phaseCard(core, phase.index, headline, 'ok');
115
+ core.emit((snapshot) => ({ type: 'stage_ended', snapshot, card }));
116
+ return {
117
+ passed: true,
118
+ headline,
119
+ lines: [
120
+ `Phase ${phase.index + 1} integrated; escrow ` +
121
+ `released${firstAttempt ? '; collective C1 awarded' : ''}.`,
122
+ ],
123
+ };
124
+ }
125
+ /** WPs implicated by an RCA: the ones owned by attributed agents, else every live WP. */
126
+ function implicatedWps(run, phase, rca) {
127
+ const ids = new Set(rca.attributions.map((a) => a.agentId));
128
+ const live = livePhaseWps(run, phase);
129
+ const owned = live.filter((wp) => wp.assignee !== null && ids.has(wp.assignee));
130
+ return owned.length > 0 ? owned : live;
131
+ }
132
+ function sendBackToDev(core, phase, rca) {
133
+ const run = core.requireRun();
134
+ const lines = [];
135
+ for (const wp of implicatedWps(run, phase, rca)) {
136
+ const outcome = recordRework(run, wp.id);
137
+ lines.push(`${wp.id}: ${outcome.outcome} (${outcome.reworkCount}/${outcome.limit})`);
138
+ if (outcome.escalation !== null) {
139
+ openEscalation(run, outcome.escalation);
140
+ core.stageWarnings.push(`ESCALATION ${outcome.escalation.id}: ${wp.id} reached the rework limit.`);
141
+ announceEscalation(core, outcome.escalation);
142
+ }
143
+ }
144
+ phase.settled = false;
145
+ return lines;
146
+ }
147
+ export function announceEscalation(core, escalation) {
148
+ core.log('escalation', 'engine', { escalation });
149
+ core.emit((snapshot) => ({
150
+ type: 'escalation',
151
+ snapshot,
152
+ escalation,
153
+ card: escalationCard(core, escalation),
154
+ }));
155
+ }
156
+ /** Fix budget spent and still failing: hand the decision to the user (L3). */
157
+ function escalateIfExhausted(core, phase) {
158
+ const run = core.requireRun();
159
+ if (!isIntegrationExhausted(run, phase))
160
+ return [];
161
+ const escalation = {
162
+ id: nextEscalationId(run),
163
+ level: 'L3',
164
+ kind: 'integration_exhausted',
165
+ phase: phase.index,
166
+ topic: `Phase ${phase.index + 1} integration still fails after ${phase.fixCycles} fix ` +
167
+ `cycle(s).`,
168
+ positions: [],
169
+ status: 'open',
170
+ };
171
+ openEscalation(run, escalation);
172
+ core.stageWarnings.push(`ESCALATION ${escalation.id}: integration fix cycles are exhausted; ask the user.`);
173
+ announceEscalation(core, escalation);
174
+ return [`Fix cycles exhausted: escalated to the user (${escalation.id}).`];
175
+ }
176
+ /** Fail: attribute, claw back, count the attempt, escalate when the fix budget is gone. */
177
+ export function applyIntegrationFailure(core, phase, rca) {
178
+ phase.integrationAttempts += 1;
179
+ const lines = [];
180
+ const incidentId = `integ-p${phase.index + 1}-a${phase.integrationAttempts}`;
181
+ const expansion = expandRca(rca, {
182
+ state: core.ledger,
183
+ phase: phase.index,
184
+ at: core.now(),
185
+ incidentId,
186
+ fixCycles: phase.fixCycles,
187
+ by: 'inspector:insp',
188
+ participants: phaseMembers(core, phase),
189
+ });
190
+ lines.push(...expansion.breakdown);
191
+ if (expansion.individualDefect) {
192
+ phase.lastIntegrationFailed = false;
193
+ lines.push('Not an integration failure: affected work goes back to its developer.');
194
+ lines.push(...sendBackToDev(core, phase, rca));
195
+ return finishFailure(core, phase, lines, 'individual defect, sent back to development');
196
+ }
197
+ phase.lastIntegrationFailed = true;
198
+ const op = { op: 'incident', events: expansion.events, clawbacks: expansion.clawbacks };
199
+ const { booked } = core.ledgerOp(op, 'insp');
200
+ core.noteBooked(booked);
201
+ for (const b of booked) {
202
+ if (b.entry.capped !== undefined) {
203
+ const { requested, applied } = b.entry.capped;
204
+ const text = `CAPPED ${String(b.entry.code)} on ${b.agentId}: requested ${requested}, ` +
205
+ `applied ${applied} (single-incident limit).`;
206
+ core.stageWarnings.push(text);
207
+ lines.push(text);
208
+ }
209
+ }
210
+ afterLedgerChange(core, { phase: phase.index });
211
+ emitLedger(core);
212
+ lines.push(...escalateIfExhausted(core, phase));
213
+ return finishFailure(core, phase, lines, `integration failed (attempt ${phase.integrationAttempts})`);
214
+ }
215
+ function finishFailure(core, phase, lines, headline) {
216
+ core.exportScoreboard();
217
+ const card = phaseCard(core, phase.index, headline, 'error');
218
+ core.emit((snapshot) => ({ type: 'stage_ended', snapshot, card }));
219
+ return { passed: false, headline, lines };
220
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Run lifecycle: start, resume, close, abandon, resolve, status (governance-mode 7.2, 8.4).
3
+ *
4
+ * ASCII ONLY (`governance/` is glyph-scanned).
5
+ *
6
+ * Every function here answers with plain text that begins `OK:` / `NOT ACCEPTED:` /
7
+ * `ESCALATION:` and ends with `NEXT:` (D-16, 14.5). A refusal is a normal tool RESULT, never
8
+ * an error: an error result invites an identical retry, a result that says what to do
9
+ * instead does not.
10
+ */
11
+ import type { Escalation } from '../types.js';
12
+ import type { EngineCore } from './engine-core.js';
13
+ export declare const BUDGET_TOPIC_PREFIX = "Team token budget";
14
+ /** `gov_run start`. Creates nothing unless every check passes (7.2). */
15
+ export declare function startRun(core: EngineCore, raw: unknown, signal?: AbortSignal): Promise<string>;
16
+ /** Retention prune, once per engine instance, never blocking and never throwing. */
17
+ export declare function pruneOnce(core: EngineCore): void;
18
+ /** `gov_run resume`. Only WPs that lack a submission for their stage will be re-run. */
19
+ export declare function resumeRun(core: EngineCore, runId?: string): Promise<string>;
20
+ /** `gov_run status`: the board as text. Rebuildable by a compacted orchestrator (R-11). */
21
+ export declare function statusText(core: EngineCore): string;
22
+ /** `gov_run close`: only when every phase is integrated (or the run was abandoned). */
23
+ export declare function closeRun(core: EngineCore, summary?: string): Promise<string>;
24
+ /** `gov_run abandon`: keeps every artifact, ends the run, frees the directory for a new one. */
25
+ export declare function abandonRun(core: EngineCore, reason: string): Promise<string>;
26
+ /** Open a budget escalation (called by the stage runner when the cap is hit). */
27
+ export declare function openBudgetEscalation(core: EngineCore): Escalation;
28
+ /** `gov_run resolve`: the user's L3 ruling, optionally with a disposition (7.2). */
29
+ export declare function resolveEscalation(core: EngineCore, raw: unknown): Promise<string>;