@aragon-agent/cli 0.6.44 → 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 (236) 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/session/validate-session.js +32 -1
  170. package/dist/team/runtime.d.ts +8 -0
  171. package/dist/team/runtime.js +9 -0
  172. package/dist/team/subagent.d.ts +23 -0
  173. package/dist/team/subagent.js +14 -3
  174. package/dist/team/types.d.ts +6 -0
  175. package/dist/tools/index.d.ts +30 -7
  176. package/dist/tools/index.js +14 -0
  177. package/dist/tools/plan-tools.d.ts +14 -2
  178. package/dist/tools/plan-tools.js +5 -2
  179. package/dist/ui/App.js +145 -25
  180. package/dist/ui/BottomStatusRow.js +1 -1
  181. package/dist/ui/Composer.d.ts +7 -1
  182. package/dist/ui/Composer.js +9 -6
  183. package/dist/ui/GovernancePanel.d.ts +50 -0
  184. package/dist/ui/GovernancePanel.js +77 -0
  185. package/dist/ui/GovernanceRun.d.ts +18 -0
  186. package/dist/ui/GovernanceRun.js +11 -0
  187. package/dist/ui/StatusBar.d.ts +15 -2
  188. package/dist/ui/StatusBar.js +10 -4
  189. package/dist/ui/Transcript.js +3 -0
  190. package/dist/ui/entries/GovernanceCard.d.ts +30 -0
  191. package/dist/ui/entries/GovernanceCard.js +32 -0
  192. package/dist/ui/governance-copy.d.ts +69 -0
  193. package/dist/ui/governance-copy.js +104 -0
  194. package/dist/ui/governance-status.d.ts +145 -0
  195. package/dist/ui/governance-status.js +326 -0
  196. package/dist/ui/interaction-copy.d.ts +4 -0
  197. package/dist/ui/interaction-copy.js +5 -0
  198. package/dist/ui/interaction-hints.d.ts +17 -0
  199. package/dist/ui/interaction-hints.js +14 -2
  200. package/dist/ui/layout/governance-board.d.ts +121 -0
  201. package/dist/ui/layout/governance-board.js +382 -0
  202. package/dist/ui/layout/governance-card.d.ts +53 -0
  203. package/dist/ui/layout/governance-card.js +134 -0
  204. package/dist/ui/layout/governance-chip.d.ts +38 -0
  205. package/dist/ui/layout/governance-chip.js +64 -0
  206. package/dist/ui/layout/governance-panel.d.ts +85 -0
  207. package/dist/ui/layout/governance-panel.js +358 -0
  208. package/dist/ui/layout/governance-roster.d.ts +65 -0
  209. package/dist/ui/layout/governance-roster.js +275 -0
  210. package/dist/ui/layout/status-detail-layout.js +3 -3
  211. package/dist/ui/layout/status-layout.d.ts +5 -2
  212. package/dist/ui/layout/status-layout.js +10 -6
  213. package/dist/ui/layout/virtual-window.js +11 -0
  214. package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
  215. package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
  216. package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
  217. package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
  218. package/dist/ui/overlays/HelpOverlay.js +4 -3
  219. package/dist/ui/overlays/QuestionOverlay.d.ts +9 -1
  220. package/dist/ui/overlays/QuestionOverlay.js +4 -2
  221. package/dist/ui/overlays/SettingsScreen.d.ts +7 -0
  222. package/dist/ui/overlays/SettingsScreen.js +21 -1
  223. package/dist/ui/overlays/governance-settings.d.ts +79 -0
  224. package/dist/ui/overlays/governance-settings.js +140 -0
  225. package/dist/ui/overlays/model-profile-state.d.ts +6 -1
  226. package/dist/ui/overlays/model-profile-state.js +10 -0
  227. package/dist/ui/palettes.d.ts +17 -0
  228. package/dist/ui/palettes.js +9 -0
  229. package/dist/ui/scrollback/live-preview.js +2 -0
  230. package/dist/ui/scrollback/settled-boundary.js +3 -0
  231. package/dist/ui/shortcuts.js +2 -2
  232. package/dist/ui/theme.d.ts +7 -0
  233. package/dist/ui/theme.js +1 -0
  234. package/dist/ui/transcript-text.js +9 -0
  235. package/dist/ui/use-wheel-routing.js +3 -1
  236. package/package.json +2 -2
@@ -0,0 +1,424 @@
1
+ /**
2
+ * The Inspector's ledger tools: `ledger_apply`, `ledger_rule`, `ledger_settle`
3
+ * (governance-mode 5.4, 5.6, 5.7, 7.3).
4
+ *
5
+ * ASCII ONLY (`governance/` is glyph-scanned).
6
+ *
7
+ * THE INSPECTOR BOOKS JUDGEMENT, NOT MECHANICS (D-4). The rule engine books every
8
+ * mechanical event by itself; `ledger_apply` accepts ONLY the codes whose bookers include
9
+ * `S` (`isInspectorBookable`), and answers any other code with "this event is handled by
10
+ * the engine". That is what removes a whole class of failure: an LLM inspector that forgets
11
+ * to book, books twice, or invents an amount. Amounts never come from the model - the
12
+ * catalogue row supplies the delta.
13
+ *
14
+ * EVIDENCE OR NO EVENT. A judgement event needs concrete evidence (files, lines, quotes) of
15
+ * at least `GOV_LIMITS.evidenceMinChars`; the check also rejects filler such as one repeated
16
+ * character, which would satisfy a bare length test.
17
+ *
18
+ * THE INSPECTOR IS NOT SCORED (I-G5). A target of `insp` is refused here, before the
19
+ * engine, and the engine refuses it again (defence in depth for a rule the whole fairness
20
+ * argument rests on).
21
+ *
22
+ * THE TARGET'S ROLE MUST MATCH THE EVENT'S. `D6` is a developer event; booking it against
23
+ * `rev1` is a typo or a hallucination, and a ledger that accepts it is wrong silently.
24
+ */
25
+ import { textResult } from '@aragon-agent/core';
26
+ import { GOV_LIMITS } from '../limits.js';
27
+ import { INSPECTOR_ID, parseIdentityId } from '../roles.js';
28
+ import { eventDef, inspectorBookableCodes, isEventCode, isInspectorBookable, } from '../rules/events-table.js';
29
+ import { Issues, SUBMIT_LIMITS as L, formatNotAccepted, isRecord, readBool, readInteger, withNotes, } from './normalize-util.js';
30
+ const ID_PATTERN = /^[A-Za-z0-9._:-]+$/;
31
+ const SETTLE_KINDS = ['settle', 'integrate'];
32
+ const MIN_DISTINCT_EVIDENCE_CHARS = 6;
33
+ const RCA_ATTRIBUTIONS_MAX = 20;
34
+ const CONTRACT_CHECK_STATUSES = ['ok', 'mismatch', 'unverifiable'];
35
+ const INTEGRATION_RESULTS = ['pass', 'fail', 'not_run'];
36
+ const ATTRIBUTION_LEVELS = ['primary', 'contributing', 'oversight'];
37
+ const CONTRACT_KINDS = ['producer', 'consumer_unverified', 'none'];
38
+ const MISS_KINDS = ['review_integration', 'test_defect', 'test_boundary'];
39
+ const ESCALATION_KINDS = [
40
+ 'wp_rework_cap',
41
+ 'integration_exhausted',
42
+ 'dispute',
43
+ ];
44
+ function argsOf(raw, issues, expected) {
45
+ if (isRecord(raw))
46
+ return raw;
47
+ issues.fail(`the arguments must be an object with ${expected}.`);
48
+ return {};
49
+ }
50
+ /** A short identifier (claim id, incident id, contract id); never clipped. */
51
+ function readId(raw, label, issues, required) {
52
+ const id = issues.str(raw, label, 200, required);
53
+ if (id !== '' && (id.length > L.idChars || !ID_PATTERN.test(id))) {
54
+ issues.fail(`${label} "${id.slice(0, 40)}" is not a valid id (letters, digits, . _ : -).`);
55
+ }
56
+ return id;
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // ledger_apply
60
+ // ---------------------------------------------------------------------------
61
+ function judgmentCodesHint() {
62
+ return `Judgment codes you may book: ${inspectorBookableCodes().join(', ')}.`;
63
+ }
64
+ /** The event code, or `undefined` after recording why it cannot be booked here. */
65
+ function readApplyCode(raw, issues) {
66
+ const text = issues.str(raw, 'code', 8, true).toUpperCase();
67
+ if (text === '')
68
+ return undefined;
69
+ if (!isEventCode(text)) {
70
+ issues.fail(`unknown event code "${text}". ${judgmentCodesHint()}`);
71
+ return undefined;
72
+ }
73
+ if (!isInspectorBookable(text)) {
74
+ issues.fail(`this event is handled by the engine (${text}: ${eventDef(text).title}). ` +
75
+ judgmentCodesHint());
76
+ return undefined;
77
+ }
78
+ return text;
79
+ }
80
+ /** The booked agent. The inspector is refused; the role must match the event's role. */
81
+ function readApplyTarget(raw, code, issues) {
82
+ const id = issues.str(raw, 'agentId', 40, true).toLowerCase();
83
+ if (id === '')
84
+ return id;
85
+ if (id === INSPECTOR_ID) {
86
+ issues.fail('the inspector is not scored: ledger events cannot target insp.');
87
+ return id;
88
+ }
89
+ const parsed = parseIdentityId(id);
90
+ if (!parsed) {
91
+ issues.fail(`agentId "${id}" is not a roster id (for example dev1, rev2, tst1, dev2-r1).`);
92
+ return id;
93
+ }
94
+ const role = code ? eventDef(code).role : 'ALL';
95
+ if (role !== 'ALL' && role !== parsed.role) {
96
+ issues.fail(`${code} applies to ${role} agents; ${id} is a ${parsed.role} agent.`);
97
+ }
98
+ return id;
99
+ }
100
+ /** Evidence must be concrete: long enough, and not one character repeated. */
101
+ function readEvidence(raw, issues) {
102
+ const evidence = issues.str(raw, 'evidence', GOV_LIMITS.evidenceMaxChars);
103
+ const distinct = new Set(evidence.toLowerCase().replace(/\s/g, '')).size;
104
+ if (evidence.length < GOV_LIMITS.evidenceMinChars || distinct < MIN_DISTINCT_EVIDENCE_CHARS) {
105
+ issues.fail('evidence must be concrete (files, lines, quotes) and at least ' +
106
+ `${GOV_LIMITS.evidenceMinChars} characters; no evidence, no event.`);
107
+ }
108
+ return evidence;
109
+ }
110
+ /** Validate a `ledger_apply` argument object. Pure; the engine may reuse it. */
111
+ export function normalizeLedgerApply(raw) {
112
+ const issues = new Issues();
113
+ const args = argsOf(raw, issues, 'code, agentId, reason and evidence');
114
+ const code = readApplyCode(args.code, issues);
115
+ const agentId = readApplyTarget(args.agentId, code, issues);
116
+ const reason = issues.str(args.reason, 'reason', GOV_LIMITS.reasonChars, true);
117
+ const evidence = readEvidence(args.evidence, issues);
118
+ const wpId = issues.wpId(args.wpId, 'wpId', false);
119
+ const incidentId = readId(args.incidentId, 'incidentId', issues, false);
120
+ if (code === undefined) {
121
+ return { ok: false, errors: issues.errors.length > 0 ? issues.errors : ['code is required.'] };
122
+ }
123
+ return issues.result({
124
+ code,
125
+ agentId,
126
+ reason,
127
+ evidence,
128
+ ...(wpId !== '' ? { wpId } : {}),
129
+ ...(incidentId !== '' ? { incidentId } : {}),
130
+ });
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // ledger_rule
134
+ // ---------------------------------------------------------------------------
135
+ /** Validate a `ledger_rule` argument object. Pure. */
136
+ export function normalizeLedgerRule(raw) {
137
+ const issues = new Issues();
138
+ const args = argsOf(raw, issues, 'claimId, decision and ruling');
139
+ const claimId = readId(args.claimId, 'claimId', issues, true);
140
+ const decision = issues.oneOf(args.decision, 'decision', ['upheld', 'rejected'], {
141
+ aliases: { uphold: 'upheld', reject: 'rejected', denied: 'rejected' },
142
+ required: true,
143
+ });
144
+ const ruling = issues.str(args.ruling, 'ruling', GOV_LIMITS.rulingChars, true);
145
+ return issues.result({ claimId, decision: decision ?? 'rejected', ruling });
146
+ }
147
+ // ---------------------------------------------------------------------------
148
+ // ledger_settle
149
+ // ---------------------------------------------------------------------------
150
+ function readContractChecks(raw, issues) {
151
+ const out = [];
152
+ issues.items(raw, 'contractChecks', L.contractsMax).forEach((item, i) => {
153
+ const at = `contractChecks[${i}]`;
154
+ if (!isRecord(item)) {
155
+ issues.fail(`${at} must be {contractId, status: ok | mismatch | unverifiable, note}.`);
156
+ return;
157
+ }
158
+ const status = issues.oneOf(item.status, `${at}.status`, CONTRACT_CHECK_STATUSES, {
159
+ aliases: { pass: 'ok', fail: 'mismatch', mismatched: 'mismatch', unknown: 'unverifiable' },
160
+ required: true,
161
+ });
162
+ out.push({
163
+ contractId: readId(item.contractId, `${at}.contractId`, issues, true),
164
+ status: status ?? 'unverifiable',
165
+ note: issues.str(item.note, `${at}.note`, L.rationaleChars),
166
+ });
167
+ });
168
+ return out;
169
+ }
170
+ function readIntegration(raw, issues) {
171
+ if (raw === undefined || raw === null)
172
+ return undefined;
173
+ if (!isRecord(raw)) {
174
+ issues.fail('integration must be {result: pass | fail | not_run, commands: [..]}.');
175
+ return undefined;
176
+ }
177
+ const result = issues.oneOf(raw.result, 'integration.result', INTEGRATION_RESULTS, {
178
+ aliases: { passed: 'pass', failed: 'fail', skipped: 'not_run', notrun: 'not_run' },
179
+ required: true,
180
+ });
181
+ const commands = [];
182
+ issues.items(raw.commands, 'integration.commands', L.commandsMax).forEach((item, i) => {
183
+ const at = `integration.commands[${i}]`;
184
+ if (!isRecord(item)) {
185
+ issues.fail(`${at} must be {cmd, exit, summary}.`);
186
+ return;
187
+ }
188
+ const exit = readInteger(item.exit);
189
+ if (exit === undefined)
190
+ issues.fail(`${at}.exit must be the integer exit code.`);
191
+ commands.push({
192
+ cmd: issues.str(item.cmd, `${at}.cmd`, L.commandChars, true),
193
+ exit: exit ?? -1,
194
+ summary: issues.str(item.summary, `${at}.summary`, L.resultChars),
195
+ });
196
+ });
197
+ return { result: result ?? 'not_run', commands };
198
+ }
199
+ function readAttributions(raw, issues) {
200
+ const out = [];
201
+ issues.items(raw, 'rca.attributions', RCA_ATTRIBUTIONS_MAX).forEach((item, i) => {
202
+ const at = `rca.attributions[${i}]`;
203
+ if (!isRecord(item)) {
204
+ issues.fail(`${at} must be {agentId, level, contract, miss?, note}.`);
205
+ return;
206
+ }
207
+ const agentId = readApplyTarget(item.agentId, undefined, issues);
208
+ const level = issues.oneOf(item.level, `${at}.level`, ATTRIBUTION_LEVELS, { required: true });
209
+ const contract = issues.oneOf(item.contract, `${at}.contract`, CONTRACT_KINDS);
210
+ const miss = issues.oneOf(item.miss, `${at}.miss`, MISS_KINDS);
211
+ if (miss !== undefined && level !== 'oversight') {
212
+ issues.note(`${at}.miss was dropped: it applies to oversight attributions only.`);
213
+ }
214
+ out.push({
215
+ agentId,
216
+ level: level ?? 'contributing',
217
+ contract: contract ?? 'none',
218
+ ...(miss !== undefined && level === 'oversight' ? { miss } : {}),
219
+ note: issues.str(item.note, `${at}.note`, L.rationaleChars),
220
+ });
221
+ });
222
+ return out;
223
+ }
224
+ function readRca(raw, issues) {
225
+ if (raw === undefined || raw === null)
226
+ return undefined;
227
+ if (!isRecord(raw)) {
228
+ issues.fail('rca must be {failingChecks, boundary, attributions, systemic}.');
229
+ return undefined;
230
+ }
231
+ const failingChecks = [];
232
+ issues.items(raw.failingChecks, 'rca.failingChecks', L.commandsMax).forEach((item, i) => {
233
+ const at = `rca.failingChecks[${i}]`;
234
+ if (!isRecord(item)) {
235
+ issues.fail(`${at} must be {name, files: [..]}.`);
236
+ return;
237
+ }
238
+ failingChecks.push({
239
+ name: issues.str(item.name, `${at}.name`, L.shortChars, true),
240
+ files: issues.list(item.files, `${at}.files`, L.filesMax, L.pathChars),
241
+ });
242
+ });
243
+ const boundary = readBool(raw.boundary);
244
+ if (boundary === undefined)
245
+ issues.fail('rca.boundary is required: true or false.');
246
+ const attributions = readAttributions(raw.attributions, issues);
247
+ const systemic = readBool(raw.systemic) ?? false;
248
+ if (boundary === true && !systemic && attributions.length === 0) {
249
+ issues.fail('a boundary failure needs at least one attribution, or systemic:true.');
250
+ }
251
+ return { failingChecks, boundary: boundary ?? false, attributions, systemic };
252
+ }
253
+ function readEscalations(raw, issues) {
254
+ const out = [];
255
+ issues.items(raw, 'escalations', L.claimsMax).forEach((item, i) => {
256
+ const at = `escalations[${i}]`;
257
+ if (!isRecord(item)) {
258
+ issues.fail(`${at} must be {kind, wpId?, topic, positions: [{by, text}]}.`);
259
+ return;
260
+ }
261
+ const kind = issues.oneOf(item.kind, `${at}.kind`, ESCALATION_KINDS, {
262
+ aliases: { disagreement: 'dispute' },
263
+ });
264
+ const positions = [];
265
+ issues.items(item.positions, `${at}.positions`, 4).forEach((p, j) => {
266
+ if (!isRecord(p)) {
267
+ issues.fail(`${at}.positions[${j}] must be {by, text}.`);
268
+ return;
269
+ }
270
+ positions.push({
271
+ by: issues.str(p.by, `${at}.positions[${j}].by`, L.idChars, true),
272
+ text: issues.str(p.text, `${at}.positions[${j}].text`, L.argumentChars, true),
273
+ });
274
+ });
275
+ if (positions.length === 0)
276
+ issues.fail(`${at}.positions needs at least one position.`);
277
+ const wpId = issues.wpId(item.wpId, `${at}.wpId`, false);
278
+ out.push({
279
+ kind: kind ?? 'dispute',
280
+ topic: issues.str(item.topic, `${at}.topic`, L.shortChars * 2, true),
281
+ positions,
282
+ ...(wpId !== '' ? { wpId } : {}),
283
+ });
284
+ });
285
+ return out;
286
+ }
287
+ /** Cross-field rules: integrate needs a result; a failed one needs a root-cause analysis. */
288
+ function crossCheckSettle(value, issues) {
289
+ if (value.kind !== 'integrate')
290
+ return;
291
+ if (!value.integration) {
292
+ issues.fail('integrate needs integration: {result: pass | fail | not_run, commands}.');
293
+ }
294
+ else if (value.integration.result === 'fail' && !value.rca) {
295
+ issues.fail('integration failed: include rca {failingChecks, boundary, attributions, systemic}. ' +
296
+ 'Attribute only what you can show in code.');
297
+ }
298
+ }
299
+ /** Validate a `ledger_settle` argument object. Pure. */
300
+ export function normalizeLedgerSettle(raw) {
301
+ const issues = new Issues();
302
+ const args = argsOf(raw, issues, 'kind, phase and summary');
303
+ const kind = issues.oneOf(args.kind, 'kind', SETTLE_KINDS, { required: true });
304
+ const phase = readInteger(args.phase);
305
+ if (phase === undefined || phase < 1)
306
+ issues.fail('phase must be the 1-based phase number.');
307
+ const integration = readIntegration(args.integration, issues);
308
+ const rca = readRca(args.rca, issues);
309
+ const value = {
310
+ kind: kind ?? 'settle',
311
+ phase: phase ?? 0,
312
+ summary: issues.str(args.summary, 'summary', L.summaryChars, true),
313
+ contractChecks: readContractChecks(args.contractChecks, issues),
314
+ escalations: readEscalations(args.escalations, issues),
315
+ ...(integration ? { integration } : {}),
316
+ ...(rca && integration?.result !== 'pass' ? { rca } : {}),
317
+ };
318
+ if (rca && integration?.result === 'pass') {
319
+ issues.note('rca was ignored: the integration passed.');
320
+ }
321
+ if (kind !== undefined)
322
+ crossCheckSettle(value, issues);
323
+ return issues.result(value);
324
+ }
325
+ const TEXT = { type: 'string' };
326
+ const APPLY_DESCRIPTION = 'Book ONE judgment event against a developer, reviewer or tester. code must be a ' +
327
+ 'judgment code (the mechanical ones are booked by the engine; booking them is refused). ' +
328
+ `agentId is the roster id; evidence must be concrete (files, lines, quotes), at least ` +
329
+ `${GOV_LIMITS.evidenceMinChars} characters. The amount comes from the event catalogue, ` +
330
+ 'never from you. The inspector cannot be a target. No evidence, no event.';
331
+ const RULE_DESCRIPTION = 'Rule on ONE open claim: decision upheld or rejected, with a ruling. Ruling priority: ' +
332
+ 'spec text, then charter and contracts, then general engineering practice. The engine ' +
333
+ 'books the resulting events. A ruling is final unless escalated to the user.';
334
+ const SETTLE_DESCRIPTION = 'Close your stage with exactly ONE call. kind: settle or integrate; phase: the 1-based ' +
335
+ 'phase number; summary; contractChecks as {contractId, status: ok | mismatch | ' +
336
+ 'unverifiable, note}. For integrate give integration {result: pass | fail | not_run, ' +
337
+ 'commands: [{cmd, exit, summary}]}; on failure also give rca {failingChecks: [{name, ' +
338
+ 'files}], boundary, attributions: [{agentId, level: primary | contributing | oversight, ' +
339
+ 'contract: producer | consumer_unverified | none, miss?, note}], systemic}. escalations ' +
340
+ 'lists disputes for the user as {kind, wpId?, topic, positions: [{by, text}]}.';
341
+ function inspect(tool, normalized, forward) {
342
+ if (!normalized.ok)
343
+ return textResult(formatNotAccepted(tool, normalized.errors));
344
+ return textResult(withNotes(forward(normalized.value), normalized.notes));
345
+ }
346
+ /** `NOT ACCEPTED: <first problem>` on one line, the rest below: the form 7.3 specifies. */
347
+ function inlineNotAccepted(errors) {
348
+ const [first = 'invalid arguments.', ...rest] = errors;
349
+ return [
350
+ `NOT ACCEPTED: ${first}`,
351
+ ...rest.slice(0, 7).map((e) => `- ${e}`),
352
+ 'No event was booked and nothing was deducted.',
353
+ ].join('\n');
354
+ }
355
+ /** `ledger_apply`: INSP only. */
356
+ export function makeLedgerApplyTool(engine) {
357
+ return {
358
+ name: 'ledger_apply',
359
+ label: 'Book judgment event',
360
+ description: APPLY_DESCRIPTION,
361
+ parameters: {
362
+ type: 'object',
363
+ properties: {
364
+ code: { type: 'string', description: 'Event code, for example D6.' },
365
+ agentId: { type: 'string', description: 'Roster id of the agent, for example dev1.' },
366
+ wpId: { type: 'string', description: 'The work package concerned, if any.' },
367
+ reason: { type: 'string', description: 'One sentence.' },
368
+ evidence: { type: 'string', description: 'Files, lines, quotes.' },
369
+ incidentId: { type: 'string', description: 'Groups events of one incident (cap).' },
370
+ },
371
+ required: ['code', 'agentId', 'reason', 'evidence'],
372
+ },
373
+ async execute(_id, params) {
374
+ const normalized = normalizeLedgerApply(params);
375
+ if (!normalized.ok)
376
+ return textResult(inlineNotAccepted(normalized.errors));
377
+ return textResult(withNotes(engine.inspectorApply(normalized.value), normalized.notes));
378
+ },
379
+ };
380
+ }
381
+ /** `ledger_rule`: INSP only. */
382
+ export function makeLedgerRuleTool(engine) {
383
+ return {
384
+ name: 'ledger_rule',
385
+ label: 'Rule on claim',
386
+ description: RULE_DESCRIPTION,
387
+ parameters: {
388
+ type: 'object',
389
+ properties: {
390
+ claimId: { type: 'string' },
391
+ decision: { type: 'string', description: 'upheld | rejected' },
392
+ ruling: TEXT,
393
+ },
394
+ required: ['claimId', 'decision', 'ruling'],
395
+ },
396
+ async execute(_id, params) {
397
+ return inspect('ledger_rule', normalizeLedgerRule(params), (v) => engine.inspectorRule(v));
398
+ },
399
+ };
400
+ }
401
+ /** `ledger_settle`: INSP only. The stage ends with this call. */
402
+ export function makeLedgerSettleTool(engine) {
403
+ return {
404
+ name: 'ledger_settle',
405
+ label: 'Settle stage',
406
+ description: SETTLE_DESCRIPTION,
407
+ parameters: {
408
+ type: 'object',
409
+ properties: {
410
+ kind: { type: 'string', description: 'settle | integrate' },
411
+ phase: { type: 'number' },
412
+ summary: TEXT,
413
+ contractChecks: { type: 'array', items: { type: 'object' } },
414
+ integration: { type: 'object' },
415
+ rca: { type: 'object' },
416
+ escalations: { type: 'array', items: { type: 'object' } },
417
+ },
418
+ required: ['kind', 'phase', 'summary'],
419
+ },
420
+ async execute(_id, params) {
421
+ return inspect('ledger_settle', normalizeLedgerSettle(params), (v) => engine.inspectorSettle(v));
422
+ },
423
+ };
424
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The Orchestrator's two tools, `gov_run` and `gov_dispatch` (governance-mode 7.2).
3
+ *
4
+ * ASCII ONLY (`governance/` is glyph-scanned).
5
+ *
6
+ * THE SCHEMAS DECLARE SHAPE, NOT POLICY (the `plan-tools.ts` P0-4 lesson). `type`,
7
+ * `required` and `default` stay; every bound lives in the `description`, which is what the
8
+ * model reads, and is enforced by the engine's own validation. Putting `maxItems` or an
9
+ * `enum` in the schema would make behaviour depend on whether `ajv`, an OPTIONAL dependency
10
+ * of core, happened to install: with it a bad call is rejected by the executor as a tool
11
+ * ERROR (inviting an identical retry), without it the same call reaches the engine. One
12
+ * design, two behaviours.
13
+ *
14
+ * RESULTS ARE ALWAYS `textResult` (7.1 rule 2), aborts and partial failures included - an
15
+ * error result invites the most expensive possible reaction, a retry of the whole stage.
16
+ * The engine owns validation and the `NOT ACCEPTED:` / `NEXT:` vocabulary; these tools only
17
+ * route.
18
+ */
19
+ import { type AgentTool } from '@aragon-agent/core';
20
+ import type { GovernanceEngineApi } from '../types.js';
21
+ /** The `gov_run` actions, in the order the description lists them. */
22
+ export declare const GOV_RUN_ACTIONS: readonly ["start", "status", "resume", "close", "abandon", "resolve"];
23
+ export type GovRunAction = (typeof GOV_RUN_ACTIONS)[number];
24
+ /** Text returned when the tool call's signal was already aborted at entry. */
25
+ export declare const DISPATCH_ABORTED_AT_ENTRY: string;
26
+ /**
27
+ * `gov_run`: start, inspect, resume, close, abandon and resolve a governed run.
28
+ *
29
+ * An unknown `action` is a non-error `NOT ACCEPTED` that lists the valid ones: the model
30
+ * guessed a verb, and a list repairs that in one turn.
31
+ */
32
+ export declare function makeGovRunTool(engine: GovernanceEngineApi): AgentTool;
33
+ /**
34
+ * `gov_dispatch`: run one stage.
35
+ *
36
+ * ABORT HANDLING (D-21). The executor timer is disabled for this tool (`gov_dispatch: 0`),
37
+ * which is safe ONLY because the tool honours `ctx.signal`: (1) a signal that is already
38
+ * aborted returns the paused text at once, without touching the engine; (2) the signal is
39
+ * handed to the engine so the stage can stop; (3) if the engine rejects after an abort, that
40
+ * is a pause, not a tool failure. Any other rejection is a real defect and propagates.
41
+ */
42
+ export declare function makeGovDispatchTool(engine: GovernanceEngineApi): AgentTool;