@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
@@ -12,5 +12,12 @@ export declare const PLAN_MODE_BLOCK_VERSION = "v3-2026-10-26";
12
12
  export interface PlanModeBlockOptions {
13
13
  /** False under `-p` / piped stdin: no overlay can be rendered, so no tools. */
14
14
  interactive: boolean;
15
+ /**
16
+ * PLAN+GOVERN's interview addendum (governance-mode 6.3). Appended INSIDE the block,
17
+ * just before the closing tag, and only for an interactive block: a governed team needs
18
+ * a human to interview. Absent leaves the block byte-identical, so
19
+ * `PLAN_MODE_BLOCK_VERSION` does not move.
20
+ */
21
+ governAddendum?: string;
15
22
  }
16
23
  export declare function buildPlanModeBlock(options: PlanModeBlockOptions): string;
@@ -42,7 +42,7 @@ const HEADLESS_PARAGRAPH = [
42
42
  ' write the finished plan as your final message in markdown.',
43
43
  ].join('\n');
44
44
  export function buildPlanModeBlock(options) {
45
- const { interactive } = options;
45
+ const { interactive, governAddendum } = options;
46
46
  // NO ROUND COUNT APPEARS HERE, and none may be reintroduced: the number used
47
47
  // to be substituted from `planModeMaxAskRounds`, which meant the prompt itself
48
48
  // told the model it would run out. "3-5 questions" was also wrong against a
@@ -95,6 +95,7 @@ export function buildPlanModeBlock(options) {
95
95
  '- Never invent a path. Cite files you have read.',
96
96
  ...verdictRule,
97
97
  interactive ? SUPERSEDE_PARAGRAPH : HEADLESS_PARAGRAPH,
98
+ ...(interactive && governAddendum ? ['', governAddendum] : []),
98
99
  '</plan_mode>',
99
100
  ].join('\n');
100
101
  }
@@ -21,9 +21,11 @@ import type { JobKind, ServiceSnapshot, ServiceStatus } from '../proc/types.js';
21
21
  import type { RetryPhase } from './retry-view.js';
22
22
  import type { FilePatch } from '../tools/patch.js';
23
23
  import type { TaskSummaryView } from '../fast/task-summary-types.js';
24
+ import type { GovernanceCardData, GovernanceSnapshot } from '../governance/types.js';
25
+ import type { Posture } from '../governance/posture.js';
24
26
  export type NoticeLevel = 'info' | 'warn' | 'error';
25
27
  export type ToastLevel = NoticeLevel | 'success';
26
- export type Overlay = null | 'settings' | 'model' | 'help' | 'queue' | 'confirm' | 'question' | 'plan' | 'kit' | 'prompts' | 'prompt-pick' | 'agents'
28
+ export type Overlay = null | 'settings' | 'model' | 'help' | 'queue' | 'confirm' | 'question' | 'plan' | 'kit' | 'prompts' | 'prompt-pick' | 'agents' | 'governance'
27
29
  /**
28
30
  * tui-shortcut-drawer-and-task-summary §4.5: the keyboard drawer (`Ctrl+G` /
29
31
  * `/keys`). A single field, so the drawer and `/help` cannot both hold the
@@ -140,6 +142,11 @@ export type Entry = {
140
142
  kind: 'notice';
141
143
  level: NoticeLevel;
142
144
  text: string;
145
+ } | {
146
+ id: string;
147
+ kind: 'governance';
148
+ at: number;
149
+ card: GovernanceCardData;
143
150
  } | {
144
151
  id: string;
145
152
  kind: 'team';
@@ -372,6 +379,20 @@ export interface ViewState {
372
379
  agentMode: AgentMode;
373
380
  /** Set only by a DEFERRED `plan -> build`; drives the `PLAN -> BUILD` readout. */
374
381
  pendingAgentMode: AgentMode | null;
382
+ /**
383
+ * The user-visible posture and its deferred twin (governance-mode 4.3). Written in the
384
+ * SAME dispatch as `agentMode` / `pendingAgentMode` and only from what the controller
385
+ * adopted, so the badge and the gate cannot diverge. `agentMode` keeps gating.
386
+ */
387
+ posture: Posture;
388
+ pendingPosture: Posture | null;
389
+ /**
390
+ * The live governed-run snapshot, or `null` when there is no run.
391
+ *
392
+ * NEVER PERSISTED, like `team`: `/save` writes `entries` (the settlement cards are the
393
+ * history) and a resumed session has no live run to show.
394
+ */
395
+ governance: GovernanceSnapshot | null;
375
396
  /**
376
397
  * The live team roster, or `null` when no dispatch is running.
377
398
  *
@@ -622,6 +643,17 @@ export type ViewAction = {
622
643
  type: 'setAgentMode';
623
644
  mode: AgentMode;
624
645
  pending: AgentMode | null;
646
+ posture?: Posture;
647
+ pendingPosture?: Posture | null;
648
+ } | {
649
+ type: 'govSnapshot';
650
+ snapshot: GovernanceSnapshot;
651
+ } | {
652
+ type: 'govEnd';
653
+ } | {
654
+ type: 'governanceCard';
655
+ card: GovernanceCardData;
656
+ at?: number;
625
657
  } | {
626
658
  type: 'teamStart';
627
659
  dispatchId: string;
@@ -15,6 +15,8 @@ import { reconcileSteeringReceipt } from './queued-messages.js';
15
15
  import { emptyContextUsage } from '../compaction/meter.js';
16
16
  import { addUsage, computeCost } from './usage.js';
17
17
  import { ENTRY_LIMITS, appendBounded, entryRetain, trimEntries } from './entry-limits.js';
18
+ import { isGovernedDispatch } from '../governance/governed-dispatch.js';
19
+ import { adoptPosture, foldGovernanceSnapshot } from './governance-view.js';
18
20
  /** Default auto-dismiss window for a toast. */
19
21
  export const DEFAULT_TOAST_TTL_MS = 2500;
20
22
  /**
@@ -62,6 +64,9 @@ export function initialViewState(seed = {}) {
62
64
  // `controller.getAgentMode()` so `--plan` renders on the first frame.
63
65
  agentMode: 'build',
64
66
  pendingAgentMode: null,
67
+ posture: 'build',
68
+ pendingPosture: null,
69
+ governance: null,
65
70
  team: null,
66
71
  todos: null,
67
72
  retry: null,
@@ -904,6 +909,9 @@ export function viewReducer(state, action) {
904
909
  // those three.
905
910
  status: 'idle',
906
911
  team: null,
912
+ // The live run snapshot goes with the conversation it was shown in (the run itself
913
+ // survives on disk and announces itself again on its next event).
914
+ governance: null,
907
915
  fastEntryId: undefined,
908
916
  turnProduced: false,
909
917
  errorNoticed: false,
@@ -931,7 +939,24 @@ export function viewReducer(state, action) {
931
939
  // `controller.setAgentMode()` reported it ADOPTED, so this reducer has no
932
940
  // deferral logic of its own to get out of step with (§3.1 / R-P7).
933
941
  case 'setAgentMode':
934
- return { ...state, agentMode: action.mode, pendingAgentMode: action.pending };
942
+ return {
943
+ ...state,
944
+ agentMode: action.mode,
945
+ pendingAgentMode: action.pending,
946
+ ...adoptPosture(state.posture, action),
947
+ };
948
+ // --- Governance (governance-mode 14.4) -------------------------------------
949
+ case 'govSnapshot': {
950
+ const governance = foldGovernanceSnapshot(state.governance, action.snapshot);
951
+ return governance === state.governance ? state : { ...state, governance };
952
+ }
953
+ case 'govEnd':
954
+ return state.governance === null ? state : { ...state, governance: null };
955
+ case 'governanceCard': {
956
+ const { id, seq } = nextId(state);
957
+ const entry = { id, kind: 'governance', at: action.at ?? Date.now(), card: action.card };
958
+ return { ...state, seq, ...appendEntry(state, state.entries, entry) };
959
+ }
935
960
  case 'toggleThinking':
936
961
  return { ...state, thinkingVisible: !state.thinkingVisible };
937
962
  case 'pushToast': {
@@ -976,19 +1001,26 @@ export function viewReducer(state, action) {
976
1001
  aborted: false,
977
1002
  active: true,
978
1003
  };
1004
+ const team = {
1005
+ dispatchId: action.dispatchId,
1006
+ active: true,
1007
+ runs,
1008
+ requested: action.requested,
1009
+ startedAt: Date.now(),
1010
+ messageCount: 0,
1011
+ };
1012
+ // A GOVERNED DISPATCH LEAVES NO TRANSCRIPT CARD (RV-3): a run is 10-20 dispatches,
1013
+ // and a `TeamCard` for each would bury the conversation. The live snapshot is still
1014
+ // written - the legion panel and `/agents` read it - and with no `teamEntryId`,
1015
+ // `teamUpdate` / `teamEnd` already pass `entries` through untouched.
1016
+ if (isGovernedDispatch(action.specs))
1017
+ return { ...state, team };
979
1018
  return {
980
1019
  ...state,
981
1020
  seq,
982
1021
  ...appendEntry(state, state.entries, entry),
983
1022
  teamEntryId: id,
984
- team: {
985
- dispatchId: action.dispatchId,
986
- active: true,
987
- runs,
988
- requested: action.requested,
989
- startedAt: Date.now(),
990
- messageCount: 0,
991
- },
1023
+ team,
992
1024
  };
993
1025
  }
994
1026
  case 'teamUpdate': {
@@ -1476,6 +1508,10 @@ export function viewReducer(state, action) {
1476
1508
  // restored entries BEFORE this branch runs.
1477
1509
  taskSummary: null,
1478
1510
  taskSummaryPending: false,
1511
+ // Same rule for a live governed run: `/resume` adopts another conversation, and
1512
+ // a snapshot of the old one's run must not be drawn over it. Settlement cards
1513
+ // arrive with the restored `entries`.
1514
+ governance: null,
1479
1515
  };
1480
1516
  }
1481
1517
  // --- Background services (§3.10 / D-11) -----------------------------
@@ -159,6 +159,25 @@ export interface SystemPromptParams {
159
159
  * own appended instructions still come last and still win.
160
160
  */
161
161
  structuredResultBlock?: string;
162
+ /**
163
+ * The rendered `<governance_mode>` block (the Orchestrator's rules), or `''`
164
+ * (governance-mode 6.1). Spliced AFTER the plan block and BEFORE `teamBlock`, and
165
+ * conditional like every block above: governance off produces the pre-feature prompt
166
+ * BYTE FOR BYTE. The caller omits `teamBlock` / `forcedTeamBlock` in GOVERN with gate
167
+ * mode `build`, because `task` is refused there and advertising it would describe a
168
+ * refused capability.
169
+ */
170
+ governBlock?: string;
171
+ /**
172
+ * The rendered `<governance_role>` block of a governed CHILD, or `''`. Spliced after
173
+ * `subagentBlock`. Never set together with `governBlock`.
174
+ */
175
+ governanceRoleBlock?: string;
176
+ /**
177
+ * PLAN+GOVERN's interview addendum (governance-mode 6.3), placed inside `<plan_mode>`.
178
+ * Only read when `agentMode` is `'plan'`; absent leaves the plan block unchanged.
179
+ */
180
+ governAddendum?: string;
162
181
  }
163
182
  /** Describe the active shell so the model does not emit incompatible syntax. */
164
183
  export declare function describeShell(): {
@@ -33,7 +33,10 @@ export function buildSystemPrompt(params) {
33
33
  const skillsBlock = params.skillsBlock ?? '';
34
34
  const hasSkills = skillsBlock.length > 0;
35
35
  const planBlock = params.agentMode === 'plan'
36
- ? buildPlanModeBlock({ interactive: params.planInteractive !== false })
36
+ ? buildPlanModeBlock({
37
+ interactive: params.planInteractive !== false,
38
+ ...(params.governAddendum ? { governAddendum: params.governAddendum } : {}),
39
+ })
37
40
  : '';
38
41
  // `''` when the caller has no candidates or the feature is off — which is what
39
42
  // keeps this block's absence byte-identical to the pre-feature prompt (I-T1).
@@ -41,6 +44,8 @@ export function buildSystemPrompt(params) {
41
44
  const teamBlock = params.teamBlock ?? '';
42
45
  const forcedTeamBlock = params.forcedTeamBlock ?? '';
43
46
  const subagentBlock = params.subagentBlock ?? '';
47
+ const governBlock = params.governBlock ?? '';
48
+ const governanceRoleBlock = params.governanceRoleBlock ?? '';
44
49
  const todoBlock = params.todoBlock ?? '';
45
50
  const fastBlock = params.fastBlock ?? '';
46
51
  const backgroundBlock = params.backgroundBlock ?? '';
@@ -66,12 +71,15 @@ export function buildSystemPrompt(params) {
66
71
  // (whose step 1 defers to it). Conditional like every other optional block.
67
72
  ...(skillTriageBlock ? ['', skillTriageBlock] : []),
68
73
  ...(planBlock ? ['', planBlock] : []),
74
+ // AFTER the plan block it extends and BEFORE `<team_mode>` (governance-mode 6.1).
75
+ ...(governBlock ? ['', governBlock] : []),
69
76
  ...(teamBlock ? ['', teamBlock] : []),
70
77
  // IMMEDIATELY AFTER `<team_mode>`: "can" then "must". BEFORE the subagent
71
78
  // block, because a child reading an order to dispatch would be ordered to use
72
79
  // a tool it does not have (§3.6).
73
80
  ...(forcedTeamBlock ? ['', forcedTeamBlock] : []),
74
81
  ...(subagentBlock ? ['', subagentBlock] : []),
82
+ ...(governanceRoleBlock ? ['', governanceRoleBlock] : []),
75
83
  ...(todoBlock ? ['', todoBlock] : []),
76
84
  ...(fastBlock ? ['', fastBlock] : []),
77
85
  ...(backgroundBlock ? ['', backgroundBlock] : []),
package/dist/cli.js CHANGED
@@ -25,7 +25,8 @@ import { formatMigrationNotice, migrateLegacyState } from './config/migrate-lega
25
25
  import { formatHomeMigrationNotice, migrateToHome } from './config/migrate-home.js';
26
26
  import { migrateStateOutOfConfig } from './config/migrate-state-out-of-config.js';
27
27
  import { runHistoryCommand } from './config/history-commands.js';
28
- import { COMPACTION_CONFIG_SET_KEYS, FAST_CONFIG_SET_KEYS, LOG_CONFIG_SET_KEYS, RETRY_CONFIG_SET_KEYS, TEAM_CONFIG_SET_KEYS, JOBS_CONFIG_SET_KEYS, TASK_SUMMARY_CONFIG_SET_KEYS, UPDATE_CONFIG_SET_KEYS, applyCompactionConfigSet, applyFastConfigSet, applyLogConfigSet, applyRetryConfigSet, applyTeamConfigSet, applyJobsConfigSet, applyTaskSummaryConfigSet, applyUpdateConfigSet, runConfigEdit, runConfigGet, runConfigHome, runConfigList, warnIfRedactionDisabled, } from './config/cli-commands.js';
28
+ import { checkGovernanceCommandLine } from './config/governance-launch.js';
29
+ import { COMPACTION_CONFIG_SET_KEYS, FAST_CONFIG_SET_KEYS, LOG_CONFIG_SET_KEYS, RETRY_CONFIG_SET_KEYS, TEAM_CONFIG_SET_KEYS, GOVERNANCE_CONFIG_SET_KEYS, JOBS_CONFIG_SET_KEYS, TASK_SUMMARY_CONFIG_SET_KEYS, UPDATE_CONFIG_SET_KEYS, applyCompactionConfigSet, applyFastConfigSet, applyLogConfigSet, applyRetryConfigSet, applyTeamConfigSet, applyGovernanceConfigSet, applyJobsConfigSet, applyTaskSummaryConfigSet, applyUpdateConfigSet, runConfigEdit, runConfigGet, runConfigHome, runConfigList, warnIfRedactionDisabled, } from './config/cli-commands.js';
29
30
  import { attachAgentEvents, attachTeamEvents, installLogging, setScreenRestore, setSignalTerminator, } from './logging/install.js';
30
31
  import { getLogger } from './logging/logger.js';
31
32
  import { runLogsCommand } from './logging/cli-commands.js';
@@ -230,6 +231,12 @@ function toFlags(opts) {
230
231
  // reports nothing, does nothing, and leaves compaction armed.
231
232
  compaction: opts.compaction,
232
233
  compactionThreshold: opts.compactionThreshold,
234
+ // Site three of three for the governance flags. `--no-governance` is declared alone, so
235
+ // commander defaults `opts.governance` to `true` when it is absent; only an explicit
236
+ // `false` is forwarded, which keeps silence from reading as an override.
237
+ govern: opts.govern,
238
+ planGovern: opts.planGovern,
239
+ governance: opts.governance === false ? false : undefined,
233
240
  // Site three of three for `--resume` / `--save` -- ELEVEN features, one trap
234
241
  // (`mouse` P1-2, `team` P1-4, `todo` C-9, render L4, retry, fast, update,
235
242
  // compaction, now session identity). A flag needs the `.option()`
@@ -1599,6 +1606,11 @@ const CONFIG_SET_KEYS = new Set([
1599
1606
  // membership set accepts a write that never happens - the two halves the static
1600
1607
  // guard in `config.test.ts` exists to pair up.
1601
1608
  ...TASK_SUMMARY_CONFIG_SET_KEYS,
1609
+ // `governance.*` keys are handled by `applyGovernanceConfigSet`, same reasoning again
1610
+ // (governance-mode 11.1): without this line they fall through to `Unknown config key`,
1611
+ // and without the matching case in `runConfigSet` the membership set accepts a write
1612
+ // that never happens.
1613
+ ...GOVERNANCE_CONFIG_SET_KEYS,
1602
1614
  ]);
1603
1615
  /**
1604
1616
  * `aragon config set maxTokens <n|auto|default>`.
@@ -1771,6 +1783,15 @@ function runConfigSetValue(key, value) {
1771
1783
  process.stdout.write(`Set ${key} = ${String(merged.taskSummary[field])}\n`);
1772
1784
  return;
1773
1785
  }
1786
+ const governancePatch = applyGovernanceConfigSet(key, value);
1787
+ if (governancePatch) {
1788
+ // Echoed from the STORED value, like every section above: `config set
1789
+ // governance.maxRework 9` prints 5, which is what the read path will report.
1790
+ const merged = updatePersistedConfig(governancePatch);
1791
+ const field = key.slice('governance.'.length);
1792
+ process.stdout.write(`Set ${key} = ${String(merged.governance[field])}\n`);
1793
+ return;
1794
+ }
1774
1795
  const patch = {};
1775
1796
  switch (key) {
1776
1797
  case 'provider':
@@ -2188,6 +2209,13 @@ function buildProgram() {
2188
2209
  .option('--compaction', 'Compact the conversation when the context window fills (the default)')
2189
2210
  .option('--no-compaction', 'Never compact; a full context window ends the run as before')
2190
2211
  .option('--compaction-threshold <n>', 'Occupancy that triggers compaction for this run: 0.9 or 90% (0.5-0.95)')
2212
+ // Governance mode (governance-mode 11.2). `--govern` and `--plan-govern` only pick the
2213
+ // starting posture, so neither is a persisted pair. `--no-governance` is deliberately
2214
+ // negative-only: it can only ever switch the feature off, and `toFlags` forwards it only
2215
+ // when explicitly given. The rules between them live in `validateGovernanceLaunch`.
2216
+ .option('--govern', 'Start in GOVERN posture (a governed team of dev / review / test roles)')
2217
+ .option('--plan-govern', 'Start in PLAN+GOVERN posture (clarify and plan first, then govern)')
2218
+ .option('--no-governance', 'Disable governance mode for this launch (not persisted)')
2191
2219
  .option('--no-skills', 'Disable the skill system entirely (no catalog, no skill tools)')
2192
2220
  .option('--skill <name>', 'Force-load a skill at Level 2 for this run (repeatable)', (value, previous = []) => [...previous, value])
2193
2221
  .option('--skills-yes', 'Approve skill installs for this run (CI / headless)')
@@ -2251,6 +2279,22 @@ function buildProgram() {
2251
2279
  }
2252
2280
  void runInteractive(flags, { initialPrompt: prompt });
2253
2281
  });
2282
+ // The governance flag rules (governance-mode 11.2), checked for EVERY command because the
2283
+ // flags are root-level options and `exec` reads them through `toFlags(program.opts())`.
2284
+ // A `preAction` hook runs before the root action as well as before each subcommand, so one
2285
+ // place covers `aragon -p`, piped input and `aragon exec`.
2286
+ program.hook('preAction', (root, action) => {
2287
+ const check = checkGovernanceCommandLine(root.opts(), {
2288
+ commandName: action.name(),
2289
+ isRootAction: action === root,
2290
+ stdinIsTty: !!process.stdin.isTTY,
2291
+ stdoutIsTty: !!process.stdout.isTTY,
2292
+ });
2293
+ if (check.ok)
2294
+ return;
2295
+ process.stderr.write(`${check.message}\n`);
2296
+ process.exit(2);
2297
+ });
2254
2298
  // aragon config [set <key> <value> | path]
2255
2299
  const configCmd = program
2256
2300
  .command('config')
@@ -15,7 +15,9 @@ import { mergePendingEntries } from '../agent/queued-messages.js';
15
15
  import { TODO_FOLLOW_LIMITS } from '../todo/limits.js';
16
16
  import { buildContinuationMessage } from '../todo/follow-through.js';
17
17
  import { planIsResolved } from '../todo/acceptance.js';
18
- import { MODE_LABEL, nextMode } from '../agent/agent-mode.js';
18
+ import { nextMode } from '../agent/agent-mode.js';
19
+ import { POSTURE_LABEL } from '../governance/posture.js';
20
+ import { registerGovernanceCommand } from './governance-command.js';
19
21
  import { loadSession, resolveSessionPath, saveSession } from '../session/persist.js';
20
22
  import { applyRestoredSession } from '../session/startup-session.js';
21
23
  import { runSessionCommand } from './session-command.js';
@@ -353,12 +355,13 @@ const COMMANDS = [
353
355
  run: (ctx) => {
354
356
  const arg = ctx.args.trim().toLowerCase();
355
357
  if (arg === 'status') {
356
- const s = ctx.controller.getPlanStatus();
357
- const pending = s.pending ? ` (pending ${MODE_LABEL[s.pending]} after this run)` : '';
358
+ // The full posture (GOVERN / PLAN+GOVERN included), not just the gate mode.
359
+ const s = ctx.controller.getPostureState();
360
+ const pending = s.pending ? ` (pending ${POSTURE_LABEL[s.pending]} after this run)` : '';
358
361
  // NO ROUND COUNT. The old line ended with `Ask rounds used: 3/4.`, which
359
362
  // told the user their agent was rationing questions - a limit that no
360
363
  // longer exists. Nothing replaced it: "0 of unlimited" is noise.
361
- ctx.notify('info', `Mode: ${MODE_LABEL[s.effective]}${pending}.`);
364
+ ctx.notify('info', `Mode: ${POSTURE_LABEL[s.effective]}${pending}.`);
362
365
  return;
363
366
  }
364
367
  if (arg.length > 0 && arg !== 'on' && arg !== 'off') {
@@ -1346,6 +1349,9 @@ export function registerBuiltinCommands(registry) {
1346
1349
  // now live in the settings screen, and this command is the ACT: arm forced mode
1347
1350
  // and start work. Unconditional, for the reason `/subagent` above records.
1348
1351
  registerTeamCommand(registry);
1352
+ // `/gov` (governance-mode 11.3). Unconditional, like `/team` and for the same reason: the
1353
+ // session where governance cannot run is exactly where a user asks the command why.
1354
+ registerGovernanceCommand(registry);
1349
1355
  // The keyboard drawer (`Ctrl+G` / `/keys`) and the task label (`/task`). Two
1350
1356
  // registrations, no new mechanism: `/keys` sets the panel's pre-filter and opens
1351
1357
  // the same overlay `Ctrl+G` opens, and `/task` reports what the header cell says.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * `/gov`: enter, leave and inspect governance mode (governance-mode 11.3).
3
+ *
4
+ * ASCII ONLY: `src/commands/**` is inside `glyphs.test.ts::inScope`.
5
+ *
6
+ * THE GUARD ORDER IS A CONTRACT, and it is the order `/team` uses (and for the same
7
+ * reasons), not an alphabetical one:
8
+ *
9
+ * status / help / runs / report / board
10
+ * - questions, answerable in ANY session, including the
11
+ * ones where governance cannot run (that is where users
12
+ * ask why). `report` only READS files already on disk.
13
+ * off - leaving is always possible, even mid-stage.
14
+ * available? - `on` / `plan` / `resume` / `pause` name the exact reason.
15
+ * not busy - half a team dispatch under one posture and half under
16
+ * another leaves a result nothing can explain.
17
+ * act - switch posture / submit the resume turn / abort.
18
+ *
19
+ * `pause` sits BETWEEN `available?` and `not busy` and never takes the busy refusal: a stage
20
+ * running is exactly when someone wants to pause, and the request is cooperative (nothing is
21
+ * stopped), unlike `abort`.
22
+ *
23
+ * EVERY POSTURE CHANGE BELOW IS FOLLOWED BY A NOTICE OR TOAST IN THE SAME BRANCH: a
24
+ * posture change produces no `AgentEvent`, so without one the badge would wait for an
25
+ * unrelated state change to repaint (the lesson of team-command-forced-dispatch P1-6).
26
+ */
27
+ import type { CommandContext, CommandRegistry } from './registry.js';
28
+ /** The fixed English turn that makes the orchestrator call `gov_run resume` (11.3). */
29
+ export declare function resumeTurnText(runId: string): string;
30
+ /** `500`, `500k`, `2m`, `off`/`0`. NaN when unparseable. */
31
+ export declare function parseBudgetTokens(raw: string): number;
32
+ /** The command body; `registerGovernanceCommand` is the only registration site. */
33
+ export declare function runGovernanceCommand(ctx: CommandContext): Promise<void>;
34
+ /** Registered from `builtins.ts` with one line, next to every other subsystem. */
35
+ export declare function registerGovernanceCommand(registry: CommandRegistry): void;