@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.
- package/CHANGELOG.md +44 -0
- package/README.md +69 -2
- package/dist/agent/controller.d.ts +69 -0
- package/dist/agent/controller.js +224 -11
- package/dist/agent/governance-view.d.ts +40 -0
- package/dist/agent/governance-view.js +40 -0
- package/dist/agent/governance-wiring.d.ts +162 -0
- package/dist/agent/governance-wiring.js +470 -0
- package/dist/agent/plan-prompt.d.ts +7 -0
- package/dist/agent/plan-prompt.js +2 -1
- package/dist/agent/reducer.d.ts +33 -1
- package/dist/agent/reducer.js +45 -9
- package/dist/agent/system-prompt.d.ts +19 -0
- package/dist/agent/system-prompt.js +9 -1
- package/dist/cli.js +45 -1
- package/dist/commands/builtins.js +10 -4
- package/dist/commands/governance-command.d.ts +35 -0
- package/dist/commands/governance-command.js +292 -0
- package/dist/commands/governance-runs-table.d.ts +40 -0
- package/dist/commands/governance-runs-table.js +130 -0
- package/dist/commands/registry.d.ts +12 -0
- package/dist/config/app-paths.d.ts +10 -0
- package/dist/config/app-paths.js +12 -0
- package/dist/config/cli-commands.d.ts +18 -0
- package/dist/config/cli-commands.js +47 -1
- package/dist/config/env.d.ts +2 -1
- package/dist/config/env.js +10 -1
- package/dist/config/governance-config.d.ts +125 -0
- package/dist/config/governance-config.js +164 -0
- package/dist/config/governance-launch.d.ts +71 -0
- package/dist/config/governance-launch.js +58 -0
- package/dist/config/load.d.ts +15 -0
- package/dist/config/load.js +26 -1
- package/dist/config/model-profile-store.d.ts +4 -2
- package/dist/config/schema.d.ts +22 -0
- package/dist/config/schema.js +6 -0
- package/dist/config/store.js +14 -1
- package/dist/config/ui-state.d.ts +11 -0
- package/dist/config/ui-state.js +11 -0
- package/dist/diagnostics/doctor.js +20 -0
- package/dist/governance/card-normalize.d.ts +24 -0
- package/dist/governance/card-normalize.js +76 -0
- package/dist/governance/copy.d.ts +109 -0
- package/dist/governance/copy.js +223 -0
- package/dist/governance/engine/aftermath.d.ts +49 -0
- package/dist/governance/engine/aftermath.js +134 -0
- package/dist/governance/engine/artifact-persist.d.ts +35 -0
- package/dist/governance/engine/artifact-persist.js +86 -0
- package/dist/governance/engine/budget.d.ts +52 -0
- package/dist/governance/engine/budget.js +112 -0
- package/dist/governance/engine/cards.d.ts +18 -0
- package/dist/governance/engine/cards.js +186 -0
- package/dist/governance/engine/digest.d.ts +32 -0
- package/dist/governance/engine/digest.js +63 -0
- package/dist/governance/engine/engine-core.d.ts +219 -0
- package/dist/governance/engine/engine-core.js +562 -0
- package/dist/governance/engine/engine.d.ts +68 -0
- package/dist/governance/engine/engine.js +314 -0
- package/dist/governance/engine/estimate.d.ts +38 -0
- package/dist/governance/engine/estimate.js +46 -0
- package/dist/governance/engine/inspector.d.ts +16 -0
- package/dist/governance/engine/inspector.js +396 -0
- package/dist/governance/engine/integration.d.ts +35 -0
- package/dist/governance/engine/integration.js +220 -0
- package/dist/governance/engine/lifecycle.d.ts +29 -0
- package/dist/governance/engine/lifecycle.js +656 -0
- package/dist/governance/engine/pause.d.ts +56 -0
- package/dist/governance/engine/pause.js +107 -0
- package/dist/governance/engine/phase-members.d.ts +15 -0
- package/dist/governance/engine/phase-members.js +34 -0
- package/dist/governance/engine/phase-planner.d.ts +53 -0
- package/dist/governance/engine/phase-planner.js +282 -0
- package/dist/governance/engine/rebuild.d.ts +27 -0
- package/dist/governance/engine/rebuild.js +57 -0
- package/dist/governance/engine/report.d.ts +66 -0
- package/dist/governance/engine/report.js +220 -0
- package/dist/governance/engine/run-digest.d.ts +20 -0
- package/dist/governance/engine/run-digest.js +42 -0
- package/dist/governance/engine/spec-builder.d.ts +117 -0
- package/dist/governance/engine/spec-builder.js +321 -0
- package/dist/governance/engine/stage-runner.d.ts +22 -0
- package/dist/governance/engine/stage-runner.js +664 -0
- package/dist/governance/engine/start-input.d.ts +19 -0
- package/dist/governance/engine/start-input.js +111 -0
- package/dist/governance/engine/state-machine.d.ts +101 -0
- package/dist/governance/engine/state-machine.js +586 -0
- package/dist/governance/engine/submission-queries.d.ts +42 -0
- package/dist/governance/engine/submission-queries.js +97 -0
- package/dist/governance/engine/submission-render.d.ts +12 -0
- package/dist/governance/engine/submission-render.js +92 -0
- package/dist/governance/engine/submissions.d.ts +27 -0
- package/dist/governance/engine/submissions.js +455 -0
- package/dist/governance/engine/visibility.d.ts +104 -0
- package/dist/governance/engine/visibility.js +223 -0
- package/dist/governance/governed-dispatch.d.ts +19 -0
- package/dist/governance/governed-dispatch.js +17 -0
- package/dist/governance/limits.d.ts +107 -0
- package/dist/governance/limits.js +131 -0
- package/dist/governance/posture-transition.d.ts +38 -0
- package/dist/governance/posture-transition.js +44 -0
- package/dist/governance/posture.d.ts +35 -0
- package/dist/governance/posture.js +59 -0
- package/dist/governance/profiles.d.ts +48 -0
- package/dist/governance/profiles.js +140 -0
- package/dist/governance/prompts/orchestrator-block.d.ts +40 -0
- package/dist/governance/prompts/orchestrator-block.js +128 -0
- package/dist/governance/prompts/plan-addendum.d.ts +22 -0
- package/dist/governance/prompts/plan-addendum.js +60 -0
- package/dist/governance/prompts/refusals.d.ts +48 -0
- package/dist/governance/prompts/refusals.js +82 -0
- package/dist/governance/prompts/role-blocks.d.ts +40 -0
- package/dist/governance/prompts/role-blocks.js +255 -0
- package/dist/governance/report-reader.d.ts +31 -0
- package/dist/governance/report-reader.js +57 -0
- package/dist/governance/roles.d.ts +83 -0
- package/dist/governance/roles.js +142 -0
- package/dist/governance/rules/claims.d.ts +83 -0
- package/dist/governance/rules/claims.js +250 -0
- package/dist/governance/rules/elimination.d.ts +66 -0
- package/dist/governance/rules/elimination.js +105 -0
- package/dist/governance/rules/events-table.d.ts +46 -0
- package/dist/governance/rules/events-table.js +94 -0
- package/dist/governance/rules/failure-analysis.d.ts +28 -0
- package/dist/governance/rules/failure-analysis.js +93 -0
- package/dist/governance/rules/ledger-replay.d.ts +53 -0
- package/dist/governance/rules/ledger-replay.js +53 -0
- package/dist/governance/rules/ledger-state.d.ts +85 -0
- package/dist/governance/rules/ledger-state.js +175 -0
- package/dist/governance/rules/ledger.d.ts +228 -0
- package/dist/governance/rules/ledger.js +560 -0
- package/dist/governance/rules/rca.d.ts +68 -0
- package/dist/governance/rules/rca.js +220 -0
- package/dist/governance/rules/settlement.d.ts +129 -0
- package/dist/governance/rules/settlement.js +363 -0
- package/dist/governance/rules/suspicion.d.ts +66 -0
- package/dist/governance/rules/suspicion.js +169 -0
- package/dist/governance/store/artifacts.d.ts +81 -0
- package/dist/governance/store/artifacts.js +173 -0
- package/dist/governance/store/atomic.d.ts +79 -0
- package/dist/governance/store/atomic.js +119 -0
- package/dist/governance/store/events-log.d.ts +35 -0
- package/dist/governance/store/events-log.js +86 -0
- package/dist/governance/store/run-lock.d.ts +51 -0
- package/dist/governance/store/run-lock.js +122 -0
- package/dist/governance/store/run-store.d.ts +229 -0
- package/dist/governance/store/run-store.js +644 -0
- package/dist/governance/store/scoreboard-export.d.ts +53 -0
- package/dist/governance/store/scoreboard-export.js +65 -0
- package/dist/governance/tools/child-tools.d.ts +31 -0
- package/dist/governance/tools/child-tools.js +65 -0
- package/dist/governance/tools/guard.d.ts +71 -0
- package/dist/governance/tools/guard.js +194 -0
- package/dist/governance/tools/inspector-tools.d.ts +63 -0
- package/dist/governance/tools/inspector-tools.js +424 -0
- package/dist/governance/tools/lead-tools.d.ts +42 -0
- package/dist/governance/tools/lead-tools.js +226 -0
- package/dist/governance/tools/normalize-util.d.ts +101 -0
- package/dist/governance/tools/normalize-util.js +230 -0
- package/dist/governance/tools/scan-incomplete.d.ts +79 -0
- package/dist/governance/tools/scan-incomplete.js +486 -0
- package/dist/governance/tools/shared-tools.d.ts +44 -0
- package/dist/governance/tools/shared-tools.js +125 -0
- package/dist/governance/tools/submit-normalizers.d.ts +28 -0
- package/dist/governance/tools/submit-normalizers.js +474 -0
- package/dist/governance/tools/submit-tools.d.ts +26 -0
- package/dist/governance/tools/submit-tools.js +171 -0
- package/dist/governance/types.d.ts +661 -0
- package/dist/governance/types.js +27 -0
- package/dist/proc/kill-tree.d.ts +19 -1
- package/dist/proc/kill-tree.js +32 -5
- package/dist/proc/limits.d.ts +19 -0
- package/dist/proc/limits.js +19 -0
- package/dist/proc/supervisor.js +8 -1
- package/dist/session/validate-session.js +32 -1
- package/dist/team/runtime.d.ts +8 -0
- package/dist/team/runtime.js +9 -0
- package/dist/team/subagent.d.ts +23 -0
- package/dist/team/subagent.js +14 -3
- package/dist/team/types.d.ts +6 -0
- package/dist/tools/bounded-spawn.d.ts +56 -0
- package/dist/tools/bounded-spawn.js +76 -0
- package/dist/tools/index.d.ts +30 -7
- package/dist/tools/index.js +14 -0
- package/dist/tools/plan-tools.d.ts +14 -2
- package/dist/tools/plan-tools.js +5 -2
- package/dist/tools/search-tools.js +52 -44
- package/dist/ui/App.js +145 -25
- package/dist/ui/BottomStatusRow.js +1 -1
- package/dist/ui/Composer.d.ts +7 -1
- package/dist/ui/Composer.js +9 -6
- package/dist/ui/GovernancePanel.d.ts +50 -0
- package/dist/ui/GovernancePanel.js +77 -0
- package/dist/ui/GovernanceRun.d.ts +18 -0
- package/dist/ui/GovernanceRun.js +11 -0
- package/dist/ui/ScrollbackShell.d.ts +35 -7
- package/dist/ui/ScrollbackShell.js +1 -1
- package/dist/ui/StatusBar.d.ts +15 -2
- package/dist/ui/StatusBar.js +10 -4
- package/dist/ui/Transcript.js +3 -0
- package/dist/ui/entries/GovernanceCard.d.ts +30 -0
- package/dist/ui/entries/GovernanceCard.js +32 -0
- package/dist/ui/governance-copy.d.ts +69 -0
- package/dist/ui/governance-copy.js +104 -0
- package/dist/ui/governance-status.d.ts +145 -0
- package/dist/ui/governance-status.js +326 -0
- package/dist/ui/interaction-copy.d.ts +4 -0
- package/dist/ui/interaction-copy.js +5 -0
- package/dist/ui/interaction-hints.d.ts +17 -0
- package/dist/ui/interaction-hints.js +14 -2
- package/dist/ui/layout/governance-board.d.ts +121 -0
- package/dist/ui/layout/governance-board.js +382 -0
- package/dist/ui/layout/governance-card.d.ts +53 -0
- package/dist/ui/layout/governance-card.js +134 -0
- package/dist/ui/layout/governance-chip.d.ts +38 -0
- package/dist/ui/layout/governance-chip.js +64 -0
- package/dist/ui/layout/governance-panel.d.ts +85 -0
- package/dist/ui/layout/governance-panel.js +358 -0
- package/dist/ui/layout/governance-roster.d.ts +65 -0
- package/dist/ui/layout/governance-roster.js +275 -0
- package/dist/ui/layout/status-detail-layout.js +3 -3
- package/dist/ui/layout/status-layout.d.ts +5 -2
- package/dist/ui/layout/status-layout.js +10 -6
- package/dist/ui/layout/virtual-window.js +11 -0
- package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
- package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
- package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
- package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
- package/dist/ui/overlays/HelpOverlay.js +4 -3
- package/dist/ui/overlays/QuestionOverlay.d.ts +9 -1
- package/dist/ui/overlays/QuestionOverlay.js +4 -2
- package/dist/ui/overlays/SettingsScreen.d.ts +7 -0
- package/dist/ui/overlays/SettingsScreen.js +21 -1
- package/dist/ui/overlays/governance-settings.d.ts +79 -0
- package/dist/ui/overlays/governance-settings.js +140 -0
- package/dist/ui/overlays/model-profile-state.d.ts +6 -1
- package/dist/ui/overlays/model-profile-state.js +10 -0
- package/dist/ui/palettes.d.ts +17 -0
- package/dist/ui/palettes.js +9 -0
- package/dist/ui/scrollback/LiveTail.d.ts +3 -1
- package/dist/ui/scrollback/budget.d.ts +12 -6
- package/dist/ui/scrollback/budget.js +11 -4
- package/dist/ui/scrollback/live-preview.js +2 -0
- package/dist/ui/scrollback/settled-boundary.js +3 -0
- package/dist/ui/scrollback/tail-anchor.d.ts +5 -2
- package/dist/ui/scrollback/tail-anchor.js +3 -1
- package/dist/ui/shortcuts.js +2 -2
- package/dist/ui/theme.d.ts +7 -0
- package/dist/ui/theme.js +1 -0
- package/dist/ui/transcript-text.js +9 -0
- package/dist/ui/use-wheel-routing.js +3 -1
- package/package.json +2 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The posture transition rule (governance-mode 4.2, D-23) as a pure function.
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned). No React, no I/O.
|
|
5
|
+
*
|
|
6
|
+
* It is the governance twin of `AgentController.setAgentMode`'s "tighten at once, loosen
|
|
7
|
+
* later" rule, extended with the one case the two-state mode never had: a governed STAGE in
|
|
8
|
+
* flight. Children read the lead's LIVE gate mode, so tightening to plan mid-stage would
|
|
9
|
+
* deny every running child its next write (RV-2); any change is therefore deferred until
|
|
10
|
+
* the stage ends, and Esc is the only way to stop it now.
|
|
11
|
+
*/
|
|
12
|
+
import { composePosture, splitPosture } from './posture.js';
|
|
13
|
+
export function decidePostureTransition(input) {
|
|
14
|
+
const { current, target } = input;
|
|
15
|
+
const want = splitPosture(target);
|
|
16
|
+
const stay = (pending, why) => ({
|
|
17
|
+
mode: current.mode,
|
|
18
|
+
governOn: current.governOn,
|
|
19
|
+
pending,
|
|
20
|
+
deferredBecause: why,
|
|
21
|
+
});
|
|
22
|
+
if (want.mode === current.mode && want.governance === current.governOn) {
|
|
23
|
+
return stay(null, null);
|
|
24
|
+
}
|
|
25
|
+
// D-23: a governed stage is in flight - defer EVERY change, tightening included.
|
|
26
|
+
if (current.governOn && input.stageRunning)
|
|
27
|
+
return stay(target, 'stage');
|
|
28
|
+
const adopt = () => ({
|
|
29
|
+
mode: want.mode,
|
|
30
|
+
governOn: want.governance,
|
|
31
|
+
pending: null,
|
|
32
|
+
deferredBecause: null,
|
|
33
|
+
});
|
|
34
|
+
// Tightening to plan is always safe and immediate.
|
|
35
|
+
if (want.mode === 'plan')
|
|
36
|
+
return adopt();
|
|
37
|
+
if (input.force || !input.running)
|
|
38
|
+
return adopt();
|
|
39
|
+
return stay(target, 'running');
|
|
40
|
+
}
|
|
41
|
+
/** The posture a (mode, governOn) pair denotes; re-exported so callers import one module. */
|
|
42
|
+
export function postureOf(mode, governOn) {
|
|
43
|
+
return composePosture(mode, governOn);
|
|
44
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Posture - the user-visible composite of (gate mode, governance on)
|
|
3
|
+
* (governance-mode section 4.1).
|
|
4
|
+
*
|
|
5
|
+
* Pure: no React, no I/O, no `node:*`. ASCII ONLY (`governance/` is glyph-scanned).
|
|
6
|
+
*
|
|
7
|
+
* WHY A COMPOSITE AND NOT A THIRD/FOURTH `AgentMode` (D-1). `AgentMode` is
|
|
8
|
+
* `'build' | 'plan'` and 25+ sites key off that pair (`=== 'plan'`,
|
|
9
|
+
* `Record<AgentMode, ...>`, the plan gate, the subagent `getMode`). Widening it needs a
|
|
10
|
+
* silent-failure audit of every one of them (a miss means "writable when it should be
|
|
11
|
+
* read-only"). Two orthogonal dimensions leave every existing path untouched.
|
|
12
|
+
*/
|
|
13
|
+
import type { AgentMode } from '../agent/agent-mode.js';
|
|
14
|
+
export type Posture = 'build' | 'plan' | 'govern' | 'plan_govern';
|
|
15
|
+
/** Full Shift+Tab cycle: BUILD -> PLAN -> GOVERN -> PLAN+GOVERN -> BUILD. */
|
|
16
|
+
export declare const POSTURES_FULL: readonly Posture[];
|
|
17
|
+
/** The classic two-state cycle, used whenever governance is unavailable or switched off. */
|
|
18
|
+
export declare const POSTURES_CLASSIC: readonly Posture[];
|
|
19
|
+
export declare const POSTURE_LABEL: Record<Posture, string>;
|
|
20
|
+
/** Lower-case spelling for the `shift+tab <next>` hint clause. */
|
|
21
|
+
export declare function postureHintWord(posture: Posture): string;
|
|
22
|
+
/** (gate mode, governance on) -> posture. Exhaustive; the one place the mapping lives. */
|
|
23
|
+
export declare function composePosture(mode: AgentMode, governanceOn: boolean): Posture;
|
|
24
|
+
/** posture -> (gate mode, governance on). Inverse of `composePosture`. */
|
|
25
|
+
export declare function splitPosture(posture: Posture): {
|
|
26
|
+
mode: AgentMode;
|
|
27
|
+
governance: boolean;
|
|
28
|
+
};
|
|
29
|
+
/** True when the posture has governance switched on. */
|
|
30
|
+
export declare function isGovernancePosture(posture: Posture): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The next posture in `cycle`. A `current` outside the cycle (e.g. `govern` while the
|
|
33
|
+
* cycle is classic) advances to `'build'` - never throws, never loops on itself.
|
|
34
|
+
*/
|
|
35
|
+
export declare function nextPosture(current: Posture, cycle: readonly Posture[]): Posture;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Posture - the user-visible composite of (gate mode, governance on)
|
|
3
|
+
* (governance-mode section 4.1).
|
|
4
|
+
*
|
|
5
|
+
* Pure: no React, no I/O, no `node:*`. ASCII ONLY (`governance/` is glyph-scanned).
|
|
6
|
+
*
|
|
7
|
+
* WHY A COMPOSITE AND NOT A THIRD/FOURTH `AgentMode` (D-1). `AgentMode` is
|
|
8
|
+
* `'build' | 'plan'` and 25+ sites key off that pair (`=== 'plan'`,
|
|
9
|
+
* `Record<AgentMode, ...>`, the plan gate, the subagent `getMode`). Widening it needs a
|
|
10
|
+
* silent-failure audit of every one of them (a miss means "writable when it should be
|
|
11
|
+
* read-only"). Two orthogonal dimensions leave every existing path untouched.
|
|
12
|
+
*/
|
|
13
|
+
/** Full Shift+Tab cycle: BUILD -> PLAN -> GOVERN -> PLAN+GOVERN -> BUILD. */
|
|
14
|
+
export const POSTURES_FULL = ['build', 'plan', 'govern', 'plan_govern'];
|
|
15
|
+
/** The classic two-state cycle, used whenever governance is unavailable or switched off. */
|
|
16
|
+
export const POSTURES_CLASSIC = ['build', 'plan'];
|
|
17
|
+
export const POSTURE_LABEL = {
|
|
18
|
+
build: 'BUILD',
|
|
19
|
+
plan: 'PLAN',
|
|
20
|
+
govern: 'GOVERN',
|
|
21
|
+
plan_govern: 'PLAN+GOVERN',
|
|
22
|
+
};
|
|
23
|
+
/** Lower-case spelling for the `shift+tab <next>` hint clause. */
|
|
24
|
+
export function postureHintWord(posture) {
|
|
25
|
+
return POSTURE_LABEL[posture].toLowerCase();
|
|
26
|
+
}
|
|
27
|
+
/** (gate mode, governance on) -> posture. Exhaustive; the one place the mapping lives. */
|
|
28
|
+
export function composePosture(mode, governanceOn) {
|
|
29
|
+
if (mode === 'plan')
|
|
30
|
+
return governanceOn ? 'plan_govern' : 'plan';
|
|
31
|
+
return governanceOn ? 'govern' : 'build';
|
|
32
|
+
}
|
|
33
|
+
/** posture -> (gate mode, governance on). Inverse of `composePosture`. */
|
|
34
|
+
export function splitPosture(posture) {
|
|
35
|
+
switch (posture) {
|
|
36
|
+
case 'build':
|
|
37
|
+
return { mode: 'build', governance: false };
|
|
38
|
+
case 'plan':
|
|
39
|
+
return { mode: 'plan', governance: false };
|
|
40
|
+
case 'govern':
|
|
41
|
+
return { mode: 'build', governance: true };
|
|
42
|
+
case 'plan_govern':
|
|
43
|
+
return { mode: 'plan', governance: true };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/** True when the posture has governance switched on. */
|
|
47
|
+
export function isGovernancePosture(posture) {
|
|
48
|
+
return posture === 'govern' || posture === 'plan_govern';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The next posture in `cycle`. A `current` outside the cycle (e.g. `govern` while the
|
|
52
|
+
* cycle is classic) advances to `'build'` - never throws, never loops on itself.
|
|
53
|
+
*/
|
|
54
|
+
export function nextPosture(current, cycle) {
|
|
55
|
+
const index = cycle.indexOf(current);
|
|
56
|
+
if (index < 0)
|
|
57
|
+
return 'build';
|
|
58
|
+
return cycle[(index + 1) % cycle.length];
|
|
59
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain profiles (governance-mode 6.6): the persona prefix each governed child opens with.
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* NAMED BY DOMAIN, NOT BY EMPLOYER (N3). The reference `team-profiles.md` casts each team
|
|
7
|
+
* as engineers of a named company; shipping that would imply an affiliation that does not
|
|
8
|
+
* exist, for the same reason `palettes.ts` names themes by hue. What carries over is the
|
|
9
|
+
* ROLE POSITIONING: what a reviewer of that domain checks first, what a tester of that
|
|
10
|
+
* domain refuses to take on faith. The persona sentence is a nudge, not an identity claim.
|
|
11
|
+
*
|
|
12
|
+
* Each of `developer` / `reviewer` / `tester` is bounded by `PROFILE_PREFIX_MAX_CHARS` so a
|
|
13
|
+
* profile can never crowd out the scoring protocol and the brief inside the child prompt;
|
|
14
|
+
* `governance-prompts.test.ts` pins the bound for every profile.
|
|
15
|
+
*/
|
|
16
|
+
import type { GovRole, ProfileId } from './types.js';
|
|
17
|
+
/** Upper bound for every persona prefix (6.6). */
|
|
18
|
+
export declare const PROFILE_PREFIX_MAX_CHARS = 600;
|
|
19
|
+
export interface GovernanceProfile {
|
|
20
|
+
id: ProfileId;
|
|
21
|
+
/** Short name for settings and `/gov` output. */
|
|
22
|
+
label: string;
|
|
23
|
+
/** One line: what the profile is for. */
|
|
24
|
+
description: string;
|
|
25
|
+
developer: string;
|
|
26
|
+
reviewer: string;
|
|
27
|
+
tester: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Shared by every profile: the inspector is domain-independent and there is exactly one per
|
|
31
|
+
* run (6.6). It states the mandate that 6.4 repeats in operational form.
|
|
32
|
+
*/
|
|
33
|
+
export declare const INSPECTOR_PREFIX: string;
|
|
34
|
+
/** True when `value` names a shipped profile. */
|
|
35
|
+
export declare function isProfileId(value: unknown): value is ProfileId;
|
|
36
|
+
/**
|
|
37
|
+
* The profile for `id`; anything unknown (including `undefined`) resolves to `general`.
|
|
38
|
+
*
|
|
39
|
+
* Falling back instead of throwing is deliberate: the id arrives from a persisted run or a
|
|
40
|
+
* config file, and an unreadable profile must not take a whole stage down. The engine
|
|
41
|
+
* validates the orchestrator's `profile` argument at `start` and rejects bad values loudly
|
|
42
|
+
* THERE; this function only has to be safe for data that already passed that gate.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getProfile(id: ProfileId | string | undefined): GovernanceProfile;
|
|
45
|
+
/** All shipped profiles, in the order the settings UI lists them. */
|
|
46
|
+
export declare function listProfiles(): GovernanceProfile[];
|
|
47
|
+
/** The persona prefix for one role of one profile. */
|
|
48
|
+
export declare function profilePrefix(profile: GovernanceProfile, role: GovRole): string;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain profiles (governance-mode 6.6): the persona prefix each governed child opens with.
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* NAMED BY DOMAIN, NOT BY EMPLOYER (N3). The reference `team-profiles.md` casts each team
|
|
7
|
+
* as engineers of a named company; shipping that would imply an affiliation that does not
|
|
8
|
+
* exist, for the same reason `palettes.ts` names themes by hue. What carries over is the
|
|
9
|
+
* ROLE POSITIONING: what a reviewer of that domain checks first, what a tester of that
|
|
10
|
+
* domain refuses to take on faith. The persona sentence is a nudge, not an identity claim.
|
|
11
|
+
*
|
|
12
|
+
* Each of `developer` / `reviewer` / `tester` is bounded by `PROFILE_PREFIX_MAX_CHARS` so a
|
|
13
|
+
* profile can never crowd out the scoring protocol and the brief inside the child prompt;
|
|
14
|
+
* `governance-prompts.test.ts` pins the bound for every profile.
|
|
15
|
+
*/
|
|
16
|
+
/** Upper bound for every persona prefix (6.6). */
|
|
17
|
+
export const PROFILE_PREFIX_MAX_CHARS = 600;
|
|
18
|
+
/**
|
|
19
|
+
* Shared by every profile: the inspector is domain-independent and there is exactly one per
|
|
20
|
+
* run (6.6). It states the mandate that 6.4 repeats in operational form.
|
|
21
|
+
*/
|
|
22
|
+
export const INSPECTOR_PREFIX = 'You are the independent Inspector in a three-powers governance system. You are the ' +
|
|
23
|
+
'fourth power, separate from development, review and testing. Your mandate is impartial ' +
|
|
24
|
+
'enforcement: fair token accounting, rule-based arbitration and objective findings. You ' +
|
|
25
|
+
'have full visibility into all agent outputs. You are not subject to GT evaluation. You ' +
|
|
26
|
+
'operate strictly by the rules you are given.';
|
|
27
|
+
const GENERAL = {
|
|
28
|
+
id: 'general',
|
|
29
|
+
label: 'General',
|
|
30
|
+
description: 'General-purpose software: services, libraries, tooling, infrastructure.',
|
|
31
|
+
developer: 'You are a senior software engineer with 10+ years of production experience. You ' +
|
|
32
|
+
'follow disciplined engineering practice: a clear design before code, readable and ' +
|
|
33
|
+
'maintainable structure, comprehensive tests, clean abstractions. You write ' +
|
|
34
|
+
'production-grade code with proper error handling, logging and monitoring hooks.',
|
|
35
|
+
reviewer: 'You are a senior code reviewer who enforces strict readability and maintainability ' +
|
|
36
|
+
'standards: every change must be readable, well tested and honest about its limits. ' +
|
|
37
|
+
'You check adherence to the project style, abstraction boundaries, meaningful naming ' +
|
|
38
|
+
'and complete error handling. You reject code that would not survive a rigorous ' +
|
|
39
|
+
'readability review. Your reviews are specific, actionable and cite concrete practice.',
|
|
40
|
+
tester: 'You are a senior test engineer. You test at the right level (unit, integration, end ' +
|
|
41
|
+
'to end), aim for meaningful coverage rather than line counts, and keep tests fast, ' +
|
|
42
|
+
'reliable and maintainable. Your tests serve as living documentation. You verify edge ' +
|
|
43
|
+
'cases, error paths and boundary conditions, and you trace every spec requirement to ' +
|
|
44
|
+
'at least one test.',
|
|
45
|
+
};
|
|
46
|
+
const ML = {
|
|
47
|
+
id: 'ml',
|
|
48
|
+
label: 'ML / data',
|
|
49
|
+
description: 'Machine learning systems, data pipelines, algorithm-heavy features.',
|
|
50
|
+
developer: 'You are a senior engineer specializing in AI and ML systems. You bring research rigor ' +
|
|
51
|
+
'to production code: reproducible experiments, documented model assumptions, efficient ' +
|
|
52
|
+
'data pipelines, and careful handling of numerical precision and edge cases.',
|
|
53
|
+
reviewer: 'You are a senior ML code reviewer. You focus on numerical correctness, ' +
|
|
54
|
+
'reproducibility and scientific rigor. You verify that model assumptions are ' +
|
|
55
|
+
'documented, random seeds are controlled, data transformations preserve semantics, and ' +
|
|
56
|
+
'pipeline stages handle edge cases (empty batches, NaN values, shape mismatches). You ' +
|
|
57
|
+
'enforce a clean separation between experiment configuration and implementation.',
|
|
58
|
+
tester: 'You are a senior ML test engineer. You design tests for ML systems: deterministic ' +
|
|
59
|
+
'unit tests with fixed seeds, property-based tests for mathematical invariants, ' +
|
|
60
|
+
'integration tests for data pipelines, and validation tests that keep model outputs ' +
|
|
61
|
+
'inside expected distributions. You check numerical stability, data leakage between ' +
|
|
62
|
+
'train and test splits, and regression in model behavior.',
|
|
63
|
+
};
|
|
64
|
+
const PRODUCT = {
|
|
65
|
+
id: 'product',
|
|
66
|
+
label: 'Product',
|
|
67
|
+
description: 'Consumer products, real-time features, React-style frontends, mobile-first.',
|
|
68
|
+
developer: 'You are a senior engineer experienced in high-scale distributed systems and consumer ' +
|
|
69
|
+
'products. You prioritize rapid iteration, user-facing quality, real-time performance ' +
|
|
70
|
+
'and mobile-first design, and you build on scalable data layers and component-based ' +
|
|
71
|
+
'frontends.',
|
|
72
|
+
reviewer: 'You are a senior code reviewer focused on performance at scale and user experience. ' +
|
|
73
|
+
'You check for unnecessary re-renders, inefficient queries, missing loading and error ' +
|
|
74
|
+
'states, accessibility violations and responsiveness problems. You enforce ' +
|
|
75
|
+
'ship-fast-but-safely: code must be functional, performant and user-friendly even in ' +
|
|
76
|
+
'rapid iteration cycles.',
|
|
77
|
+
tester: 'You are a senior QA engineer. You test real-world user scenarios at scale: ' +
|
|
78
|
+
'concurrent users, flaky networks, diverse device sizes, and edge cases such as empty ' +
|
|
79
|
+
'feeds, blocked users and rate limits. You write automated tests and manual test ' +
|
|
80
|
+
'plans, and verify component rendering, response handling and real-time update ' +
|
|
81
|
+
'propagation.',
|
|
82
|
+
};
|
|
83
|
+
const API_SECURITY = {
|
|
84
|
+
id: 'api-security',
|
|
85
|
+
label: 'API / security',
|
|
86
|
+
description: 'API platforms, payment-like flows, developer tools, security-critical code.',
|
|
87
|
+
developer: 'You are a senior engineer focused on API design excellence and security-first ' +
|
|
88
|
+
'development. You write bulletproof error handling, keep strict backward ' +
|
|
89
|
+
'compatibility, produce clear API documentation, and treat every input as potentially ' +
|
|
90
|
+
'malicious.',
|
|
91
|
+
reviewer: 'You are a senior API reviewer. You enforce high API quality standards: consistent ' +
|
|
92
|
+
'naming, idempotency keys, proper status codes, structured error objects with ' +
|
|
93
|
+
'actionable messages, backward compatibility, and input validation that assumes ' +
|
|
94
|
+
'hostile input. You reject any change that would break existing integrations or ' +
|
|
95
|
+
'expose sensitive data, and you verify that every error path returns a structured, ' +
|
|
96
|
+
'developer-friendly response.',
|
|
97
|
+
tester: 'You are a senior QA engineer for security-critical systems with zero tolerance for ' +
|
|
98
|
+
'silent errors. You test idempotency behavior, races between concurrent requests, ' +
|
|
99
|
+
'invalid and malicious inputs, graceful degradation under partial failure, and exact ' +
|
|
100
|
+
'money arithmetic (never floating point). You cover every error code and verify API ' +
|
|
101
|
+
'versioning behavior and sensitive-data handling.',
|
|
102
|
+
};
|
|
103
|
+
const PROFILES = {
|
|
104
|
+
general: GENERAL,
|
|
105
|
+
ml: ML,
|
|
106
|
+
product: PRODUCT,
|
|
107
|
+
'api-security': API_SECURITY,
|
|
108
|
+
};
|
|
109
|
+
/** True when `value` names a shipped profile. */
|
|
110
|
+
export function isProfileId(value) {
|
|
111
|
+
return typeof value === 'string' && Object.prototype.hasOwnProperty.call(PROFILES, value);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* The profile for `id`; anything unknown (including `undefined`) resolves to `general`.
|
|
115
|
+
*
|
|
116
|
+
* Falling back instead of throwing is deliberate: the id arrives from a persisted run or a
|
|
117
|
+
* config file, and an unreadable profile must not take a whole stage down. The engine
|
|
118
|
+
* validates the orchestrator's `profile` argument at `start` and rejects bad values loudly
|
|
119
|
+
* THERE; this function only has to be safe for data that already passed that gate.
|
|
120
|
+
*/
|
|
121
|
+
export function getProfile(id) {
|
|
122
|
+
return isProfileId(id) ? PROFILES[id] : GENERAL;
|
|
123
|
+
}
|
|
124
|
+
/** All shipped profiles, in the order the settings UI lists them. */
|
|
125
|
+
export function listProfiles() {
|
|
126
|
+
return [GENERAL, ML, PRODUCT, API_SECURITY];
|
|
127
|
+
}
|
|
128
|
+
/** The persona prefix for one role of one profile. */
|
|
129
|
+
export function profilePrefix(profile, role) {
|
|
130
|
+
switch (role) {
|
|
131
|
+
case 'DEV':
|
|
132
|
+
return profile.developer;
|
|
133
|
+
case 'REV':
|
|
134
|
+
return profile.reviewer;
|
|
135
|
+
case 'TEST':
|
|
136
|
+
return profile.tester;
|
|
137
|
+
case 'INSP':
|
|
138
|
+
return INSPECTOR_PREFIX;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Orchestrator's `<governance_mode>` system-prompt block (governance-mode 6.2).
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* THE PROSE IS THE SPEC'S, ADOPTED VERBATIM; the numbers are not. Every figure the model
|
|
7
|
+
* reads here (work-package ceiling, phases, rework rounds, fix cycles, budget) is passed in
|
|
8
|
+
* by the caller from the LIVE config clamped against `GOV_LIMITS`, never written as a
|
|
9
|
+
* literal: a prompt that says "4 WPs" while the engine allows 6 makes the model refuse work
|
|
10
|
+
* the engine would accept (the `planModeMaxAskRounds` lesson, 6.1).
|
|
11
|
+
*
|
|
12
|
+
* THE PLAN-PHASE VARIANT. In PLAN+GOVERN the block is spliced in BEFORE the plan is
|
|
13
|
+
* approved. The system prompt is captured by value, so it cannot be re-issued at approval;
|
|
14
|
+
* the full block therefore ships from the start, preceded by one paragraph that says the
|
|
15
|
+
* tools are suspended and that `task` stays available for read-only research (the gate
|
|
16
|
+
* refuses `task` only when the gate mode is `build`, 6.1).
|
|
17
|
+
*/
|
|
18
|
+
import { type Posture } from '../posture.js';
|
|
19
|
+
import { GOVERNANCE_BLOCK_VERSION } from '../limits.js';
|
|
20
|
+
export { GOVERNANCE_BLOCK_VERSION };
|
|
21
|
+
/** The live policy values the block quotes. All are clamped here against `GOV_LIMITS`. */
|
|
22
|
+
export interface OrchestratorLimits {
|
|
23
|
+
maxWorkPackages: number;
|
|
24
|
+
maxPhases: number;
|
|
25
|
+
maxRework: number;
|
|
26
|
+
maxFixCycles: number;
|
|
27
|
+
/** Team token budget; 0 or absent means unlimited. */
|
|
28
|
+
budgetTokens?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface OrchestratorBlockOptions {
|
|
31
|
+
posture: Posture;
|
|
32
|
+
limits: OrchestratorLimits;
|
|
33
|
+
}
|
|
34
|
+
/** The single paragraph that prefixes the full block while the plan is still being made. */
|
|
35
|
+
export declare const PLAN_PHASE_NOTICE: string;
|
|
36
|
+
/**
|
|
37
|
+
* The block for a governance posture; `''` for `build` / `plan` (the caller then splices
|
|
38
|
+
* nothing, which is what keeps the governance-off system prompt byte-identical).
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildOrchestratorBlock(options: OrchestratorBlockOptions): string;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Orchestrator's `<governance_mode>` system-prompt block (governance-mode 6.2).
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* THE PROSE IS THE SPEC'S, ADOPTED VERBATIM; the numbers are not. Every figure the model
|
|
7
|
+
* reads here (work-package ceiling, phases, rework rounds, fix cycles, budget) is passed in
|
|
8
|
+
* by the caller from the LIVE config clamped against `GOV_LIMITS`, never written as a
|
|
9
|
+
* literal: a prompt that says "4 WPs" while the engine allows 6 makes the model refuse work
|
|
10
|
+
* the engine would accept (the `planModeMaxAskRounds` lesson, 6.1).
|
|
11
|
+
*
|
|
12
|
+
* THE PLAN-PHASE VARIANT. In PLAN+GOVERN the block is spliced in BEFORE the plan is
|
|
13
|
+
* approved. The system prompt is captured by value, so it cannot be re-issued at approval;
|
|
14
|
+
* the full block therefore ships from the start, preceded by one paragraph that says the
|
|
15
|
+
* tools are suspended and that `task` stays available for read-only research (the gate
|
|
16
|
+
* refuses `task` only when the gate mode is `build`, 6.1).
|
|
17
|
+
*/
|
|
18
|
+
import { isGovernancePosture } from '../posture.js';
|
|
19
|
+
import { GOV_LIMITS, GOVERNANCE_BLOCK_VERSION } from '../limits.js';
|
|
20
|
+
export { GOVERNANCE_BLOCK_VERSION };
|
|
21
|
+
/** The single paragraph that prefixes the full block while the plan is still being made. */
|
|
22
|
+
export const PLAN_PHASE_NOTICE = 'GOVERNANCE MODE is ON but PLAN mode is active: gov_run and gov_dispatch are suspended ' +
|
|
23
|
+
'until your plan is approved. Plan for execution by a governed team (see <plan_mode>). ' +
|
|
24
|
+
'After approval you become the Orchestrator and the rules of this block apply. Until ' +
|
|
25
|
+
'then the task tool stays available for read-only research (this overrides the task ' +
|
|
26
|
+
'refusal listed below).';
|
|
27
|
+
function clampInt(value, min, max) {
|
|
28
|
+
const n = Number.isFinite(value) ? Math.floor(value) : min;
|
|
29
|
+
return Math.min(max, Math.max(min, n));
|
|
30
|
+
}
|
|
31
|
+
/** "2-4 WPs" under the default ceiling; never advertises more than the ceiling allows. */
|
|
32
|
+
function preferredRange(maxWorkPackages) {
|
|
33
|
+
if (maxWorkPackages < 2)
|
|
34
|
+
return '1 WP';
|
|
35
|
+
return `2-${Math.min(4, maxWorkPackages)} WPs`;
|
|
36
|
+
}
|
|
37
|
+
function limitsLines(limits) {
|
|
38
|
+
const wps = clampInt(limits.maxWorkPackages, 1, GOV_LIMITS.hardMaxWorkPackages);
|
|
39
|
+
const phases = clampInt(limits.maxPhases, 1, GOV_LIMITS.hardMaxPhases);
|
|
40
|
+
const rework = clampInt(limits.maxRework, 1, GOV_LIMITS.hardMaxRework);
|
|
41
|
+
const fixes = clampInt(limits.maxFixCycles, 1, GOV_LIMITS.hardMaxFixCycles);
|
|
42
|
+
const budget = clampInt(limits.budgetTokens ?? 0, 0, Number.MAX_SAFE_INTEGER);
|
|
43
|
+
const budgetText = budget > 0
|
|
44
|
+
? `The team token budget is ${budget} LLM tokens (team spend only).`
|
|
45
|
+
: 'No team token budget is set.';
|
|
46
|
+
return [
|
|
47
|
+
`Limits: up to ${wps} work packages and ${phases} phases per run. A work package may be`,
|
|
48
|
+
`reworked ${rework} times and a phase gets ${fixes} integration fix cycles before the engine`,
|
|
49
|
+
`escalates to the user; at most ${GOV_LIMITS.hardMaxDispatches} gov_dispatch calls per run.`,
|
|
50
|
+
budgetText,
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
function powersSection() {
|
|
54
|
+
return [
|
|
55
|
+
'GOVERNANCE MODE is ON. You are the Orchestrator of a governed engineering team.',
|
|
56
|
+
'You do not write code.',
|
|
57
|
+
'',
|
|
58
|
+
'The team follows a separation of powers:',
|
|
59
|
+
'- DEV (development): implements one work package each.',
|
|
60
|
+
'- REV (review): reviews independently; may reject, or fix minor issues directly.',
|
|
61
|
+
'- TEST (testing): verifies behavior and traces every requirement to evidence.',
|
|
62
|
+
'- INSP (inspector): the fourth power. Arbitrates disputes, verifies integration, and rules on',
|
|
63
|
+
' scoring claims. It is not scored.',
|
|
64
|
+
'Agents hold GT (governance tokens): a score for this run, unrelated to LLM context tokens.',
|
|
65
|
+
'The rule engine awards and deducts GT automatically from structured verdicts. You cannot',
|
|
66
|
+
'edit scores and you never need to.',
|
|
67
|
+
'',
|
|
68
|
+
'Your tools: gov_run, gov_dispatch, ask_user, todo_write, and every tool that only reads',
|
|
69
|
+
'(read_file, list_dir, glob, grep, skill, skill_find, bash_output, job_wait, job_list).',
|
|
70
|
+
'write_file, edit_file, bash, bash_kill, skill_install, skill_create and task are refused in',
|
|
71
|
+
'this mode on purpose: all implementation happens through dispatched agents.',
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
function startSteps(maxWorkPackages) {
|
|
75
|
+
const wps = clampInt(maxWorkPackages, 1, GOV_LIMITS.hardMaxWorkPackages);
|
|
76
|
+
return [
|
|
77
|
+
'1. Understand the request. Read just enough of the workspace to define work packages (WPs).',
|
|
78
|
+
' Ask the user only when a blocking decision cannot be settled by reading. If the user only',
|
|
79
|
+
' asks a question, answer it directly and do not start a run.',
|
|
80
|
+
'2. Call gov_run {action:"start"} with: goal; spec (the user\'s requirement, or the approved',
|
|
81
|
+
' plan, complete and verbatim); workPackages (id, title, goal, owned files, acceptance',
|
|
82
|
+
' criteria, dependsOn); contracts (every interface two WPs share: producer, consumers,',
|
|
83
|
+
' exact signature or data shape); integrationCommands (test commands the inspector may',
|
|
84
|
+
' run); profile.',
|
|
85
|
+
' - One WP = one agent. Two WPs that can run in the same phase must not own the same file.',
|
|
86
|
+
" - List each WP's test paths among its owned files too: testers may write only there.",
|
|
87
|
+
` - Prefer ${preferredRange(wps)}. Do not split work that is only a few lines.`,
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
function driveSteps() {
|
|
91
|
+
return [
|
|
92
|
+
'3. Drive the run with gov_dispatch. Every gov_run and gov_dispatch result ends with NEXT: the',
|
|
93
|
+
' legal next actions. Follow it; the engine refuses illegal stage orders.',
|
|
94
|
+
'4. Each phase runs: dev -> review -> test -> settle -> integrate (and fix, then integrate',
|
|
95
|
+
' again, if integration fails). Rework loops are automatic: a rejected WP returns to dev',
|
|
96
|
+
' with its required changes attached by the engine.',
|
|
97
|
+
'5. Do not write briefs for review, test, settle or integrate: the engine builds them so each',
|
|
98
|
+
' role sees only what it is allowed to see. For dev and fix you may add a short note per WP.',
|
|
99
|
+
'6. Never relay review comments, test reports or scores between roles.',
|
|
100
|
+
'7. When a result reports an ESCALATION, put the question to the user with ask_user, then',
|
|
101
|
+
' call gov_run {action:"resolve"} with the user\'s ruling.',
|
|
102
|
+
'8. When every phase is integrated, call gov_run {action:"close"} and report to the user:',
|
|
103
|
+
' what was built, what was verified, the final standings, and anything unresolved.',
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The block for a governance posture; `''` for `build` / `plan` (the caller then splices
|
|
108
|
+
* nothing, which is what keeps the governance-off system prompt byte-identical).
|
|
109
|
+
*/
|
|
110
|
+
export function buildOrchestratorBlock(options) {
|
|
111
|
+
if (!isGovernancePosture(options.posture))
|
|
112
|
+
return '';
|
|
113
|
+
const lines = [
|
|
114
|
+
'<governance_mode>',
|
|
115
|
+
...powersSection(),
|
|
116
|
+
'',
|
|
117
|
+
'How to work:',
|
|
118
|
+
...startSteps(options.limits.maxWorkPackages),
|
|
119
|
+
...driveSteps(),
|
|
120
|
+
...limitsLines(options.limits),
|
|
121
|
+
'Limits and budget are printed in every result. If a run is paused, call gov_run',
|
|
122
|
+
'{action:"resume"}.',
|
|
123
|
+
`Version: ${GOVERNANCE_BLOCK_VERSION}`,
|
|
124
|
+
'</governance_mode>',
|
|
125
|
+
];
|
|
126
|
+
const block = lines.join('\n');
|
|
127
|
+
return options.posture === 'plan_govern' ? `${PLAN_PHASE_NOTICE}\n\n${block}` : block;
|
|
128
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PLAN+GOVERN addendum to the `<plan_mode>` block (governance-mode 6.3).
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* WHY THE PLAN IS "THE SPECIFICATION". After `submit_plan` is approved a governed team
|
|
7
|
+
* executes it and the reviewers and testers judge their work AGAINST it. A plan written as
|
|
8
|
+
* a loose outline therefore produces arguments later, at the most expensive stage, so the
|
|
9
|
+
* interview that precedes it is front-loaded and the plan's step shape is prescribed.
|
|
10
|
+
*
|
|
11
|
+
* THE NUMBER COMES FROM THE LIVE CONFIG (6.1). `minRounds` is `governance.minAskRounds`,
|
|
12
|
+
* the same value `beforeSubmit` enforces; a literal here would let the prompt and the
|
|
13
|
+
* refusal disagree (the `planModeMaxAskRounds` lesson).
|
|
14
|
+
*/
|
|
15
|
+
import { GOVERNANCE_PLAN_ADDENDUM_VERSION } from '../limits.js';
|
|
16
|
+
export { GOVERNANCE_PLAN_ADDENDUM_VERSION };
|
|
17
|
+
/**
|
|
18
|
+
* The text appended after the `<plan_mode>` block while the posture is PLAN+GOVERN.
|
|
19
|
+
*
|
|
20
|
+
* Ends with a version line (the block has no tag of its own to carry an attribute).
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildPlanGovernAddendum(minRounds: number): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The PLAN+GOVERN addendum to the `<plan_mode>` block (governance-mode 6.3).
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* WHY THE PLAN IS "THE SPECIFICATION". After `submit_plan` is approved a governed team
|
|
7
|
+
* executes it and the reviewers and testers judge their work AGAINST it. A plan written as
|
|
8
|
+
* a loose outline therefore produces arguments later, at the most expensive stage, so the
|
|
9
|
+
* interview that precedes it is front-loaded and the plan's step shape is prescribed.
|
|
10
|
+
*
|
|
11
|
+
* THE NUMBER COMES FROM THE LIVE CONFIG (6.1). `minRounds` is `governance.minAskRounds`,
|
|
12
|
+
* the same value `beforeSubmit` enforces; a literal here would let the prompt and the
|
|
13
|
+
* refusal disagree (the `planModeMaxAskRounds` lesson).
|
|
14
|
+
*/
|
|
15
|
+
import { GOVERNANCE_PLAN_ADDENDUM_VERSION } from '../limits.js';
|
|
16
|
+
export { GOVERNANCE_PLAN_ADDENDUM_VERSION };
|
|
17
|
+
const TOPIC_LIST = [
|
|
18
|
+
' 1. Goal and success criteria: what must be true when this is done?',
|
|
19
|
+
' 2. Scope: what is explicitly in and out?',
|
|
20
|
+
' 3. Constraints: stack, compatibility, performance, style, forbidden changes.',
|
|
21
|
+
' 4. Quality bar: required tests, security expectations, review strictness.',
|
|
22
|
+
' 5. Team shape and cost: how many parallel work packages are acceptable; any budget ceiling.',
|
|
23
|
+
' 6. Risks and dependencies you found in the workspace that the user must decide on.',
|
|
24
|
+
];
|
|
25
|
+
const PLAN_SHAPE = [
|
|
26
|
+
'Skip nothing the workspace already answers; read first. In the plan: each step is a',
|
|
27
|
+
'candidate work package with its owned files, acceptance criteria and dependencies in the',
|
|
28
|
+
'detail; list shared interfaces under risks or detail with exact signatures; put the',
|
|
29
|
+
'integration test commands in filesTouched-adjacent detail. Do not implement anything.',
|
|
30
|
+
];
|
|
31
|
+
function interviewSentence(rounds) {
|
|
32
|
+
if (rounds <= 0) {
|
|
33
|
+
return ('Before you plan, interview the user as far as the request needs (no minimum number ' +
|
|
34
|
+
'of rounds is enforced). Batch 1-5 questions per round and cover, in this order:');
|
|
35
|
+
}
|
|
36
|
+
return ('Before you plan, interview the user. You must complete at least ' +
|
|
37
|
+
`${rounds} answered ask_user round${rounds === 1 ? '' : 's'} ` +
|
|
38
|
+
'(submit_plan is refused until you do). Batch 1-5 questions per round and cover, in ' +
|
|
39
|
+
'this order:');
|
|
40
|
+
}
|
|
41
|
+
/** Clamp to a non-negative integer; the config clamp already did, this is the last line. */
|
|
42
|
+
function sanitizeRounds(minRounds) {
|
|
43
|
+
return Number.isFinite(minRounds) && minRounds > 0 ? Math.floor(minRounds) : 0;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The text appended after the `<plan_mode>` block while the posture is PLAN+GOVERN.
|
|
47
|
+
*
|
|
48
|
+
* Ends with a version line (the block has no tag of its own to carry an attribute).
|
|
49
|
+
*/
|
|
50
|
+
export function buildPlanGovernAddendum(minRounds) {
|
|
51
|
+
return [
|
|
52
|
+
'PLAN+GOVERN. After you submit_plan and the user approves, a governed team will execute',
|
|
53
|
+
'this plan and the reviewers and testers will judge their work AGAINST IT, so the plan is',
|
|
54
|
+
'the specification.',
|
|
55
|
+
interviewSentence(sanitizeRounds(minRounds)),
|
|
56
|
+
...TOPIC_LIST,
|
|
57
|
+
...PLAN_SHAPE,
|
|
58
|
+
`Governance addendum version: ${GOVERNANCE_PLAN_ADDENDUM_VERSION}`,
|
|
59
|
+
].join('\n');
|
|
60
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusal texts (governance-mode 6.5) - the ONE place these sentences are worded.
|
|
3
|
+
*
|
|
4
|
+
* ASCII ONLY (`governance/` is glyph-scanned).
|
|
5
|
+
*
|
|
6
|
+
* "REFUSAL AS TEACHING", like `planRefusal`: a gated tool is refused with the reason, the
|
|
7
|
+
* legal alternative and an instruction not to route around it. A bare "not allowed" makes
|
|
8
|
+
* the model probe for a bypass; a sentence that names the alternative makes it take it.
|
|
9
|
+
*
|
|
10
|
+
* ERROR VS TEXT. Every refusal here is delivered as a NON-error `textResult` by its caller
|
|
11
|
+
* EXCEPT `governRefusal`, which keeps the plan gate's `errorResult` so the pre-existing
|
|
12
|
+
* "a refused tool did not run" semantics hold for write tools. The others (`gov_run` in the
|
|
13
|
+
* plan phase, `submit_plan` before the interview is long enough, ...) are not a tool
|
|
14
|
+
* FAILURE: an error result invites the model to retry the identical call, whose only
|
|
15
|
+
* possible outcome is the same refusal (the reasoning `team_send` and `ask_user` already
|
|
16
|
+
* follow).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Orchestrator tool refused while governance is on (`write_file`, `edit_file`, `bash`, ...).
|
|
20
|
+
*
|
|
21
|
+
* The `task` variant appends the pointer to the replacement fan-out: a model that is
|
|
22
|
+
* refused `task` otherwise tends to retry it with different arguments.
|
|
23
|
+
*/
|
|
24
|
+
export declare function governRefusal(tool: string): string;
|
|
25
|
+
/** `gov_run` / `gov_dispatch` while the gate mode is plan: suspended until approval. */
|
|
26
|
+
export declare function govPlanPhaseRefusal(): string;
|
|
27
|
+
/** `gov_run` / `gov_dispatch` after `/gov off` (the tools cannot be unregistered mid-session). */
|
|
28
|
+
export declare function govOffRefusal(): string;
|
|
29
|
+
/**
|
|
30
|
+
* The fixed interview topics, in the order the plan addendum asks about them. The wiring
|
|
31
|
+
* classifies answered questions against this list and passes the UNCOVERED ones to
|
|
32
|
+
* `govAskRoundsRefusal`, so the model is told what to ask instead of padding rounds with
|
|
33
|
+
* filler questions.
|
|
34
|
+
*/
|
|
35
|
+
export declare const PLAN_INTERVIEW_TOPICS: readonly string[];
|
|
36
|
+
/**
|
|
37
|
+
* `submit_plan` before the PLAN+GOVERN interview has enough ANSWERED rounds.
|
|
38
|
+
*
|
|
39
|
+
* `uncoveredTopics` is in interview order; only the first few are named. An empty list
|
|
40
|
+
* (every topic touched but the round count is still short) falls back to a generic ask.
|
|
41
|
+
*/
|
|
42
|
+
export declare function govAskRoundsRefusal(done: number, need: number, uncoveredTopics: readonly string[]): string;
|
|
43
|
+
/**
|
|
44
|
+
* The `submit_plan` result when the user approved a plan while governance is on. It is
|
|
45
|
+
* authoritative for the rest of the run (the system prompt is captured by value and cannot
|
|
46
|
+
* be re-issued), so it states the new role and the first call explicitly.
|
|
47
|
+
*/
|
|
48
|
+
export declare const APPROVED_GOVERN_RESULT: string;
|