@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.
- 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/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/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/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/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/live-preview.js +2 -0
- package/dist/ui/scrollback/settled-boundary.js +3 -0
- 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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Information boundary (governance-mode 8.3): who may read what, the deterministic
|
|
3
|
+
* `gov_view` exception policy, and paging for `gov_read`.
|
|
4
|
+
*
|
|
5
|
+
* ASCII ONLY (`governance/` is glyph-scanned). Pure.
|
|
6
|
+
*
|
|
7
|
+
* ONE TABLE. `VISIBILITY_MATRIX` is the single source for both `gov_read` and the
|
|
8
|
+
* prompt assembler: a second hand-written copy would drift, and a drift here is a silent
|
|
9
|
+
* information leak (a tester who can read the review comments grades the reviewer's
|
|
10
|
+
* opinion instead of the code - exactly what the boundary exists to prevent).
|
|
11
|
+
*
|
|
12
|
+
* Cells are either one `Access` or `{ own, other }` when the answer depends on whether
|
|
13
|
+
* the viewer wrote the artifact. Artifact KINDS (work / review / test / inspector) map
|
|
14
|
+
* onto the spec's MATERIAL columns in `accessFor`; a review artifact carries both the
|
|
15
|
+
* verdict and the comments, so a viewer's access is the stronger of the two cells.
|
|
16
|
+
*
|
|
17
|
+
* `inspector_report` is not a column in the spec's matrix: settle / integrate reports are
|
|
18
|
+
* the fourth power's own output, so only INSP reads them in full and the lead gets the
|
|
19
|
+
* digest. It is added here, in the table, rather than special-cased in code.
|
|
20
|
+
*/
|
|
21
|
+
import type { GovRole } from '../types.js';
|
|
22
|
+
import type { ArtifactKind, ArtifactRef } from '../store/artifacts.js';
|
|
23
|
+
export type Viewer = GovRole | 'lead';
|
|
24
|
+
/** `own` = the viewer authored the artifact. */
|
|
25
|
+
export type Relation = 'own' | 'other';
|
|
26
|
+
export type Access = 'full' | 'summary' | 'verdict' | 'changes' | 'none';
|
|
27
|
+
export type Material = 'spec' | 'own_submission' | 'dev_submission' | 'review_verdict' | 'review_comments' | 'test_report' | 'inspector_report' | 'standings' | 'event_details';
|
|
28
|
+
type Cell = Access | {
|
|
29
|
+
own: Access;
|
|
30
|
+
other: Access;
|
|
31
|
+
};
|
|
32
|
+
export declare const VIEWERS: readonly Viewer[];
|
|
33
|
+
export declare const MATERIALS: readonly Material[];
|
|
34
|
+
export declare const VISIBILITY_MATRIX: Record<Viewer, Record<Material, Cell>>;
|
|
35
|
+
/** Access to a spec-matrix column. */
|
|
36
|
+
export declare function materialAccess(viewer: Viewer, material: Material, relation: Relation): Access;
|
|
37
|
+
/** What `viewer` may read of an artifact of `kind`. */
|
|
38
|
+
export declare function accessFor(viewer: Viewer, kind: ArtifactKind, relation: Relation): Access;
|
|
39
|
+
export declare function canRead(viewer: Viewer, kind: ArtifactKind, relation: Relation): boolean;
|
|
40
|
+
/** Artifacts `viewer` (acting as `identity`) may see, annotated with the access level. */
|
|
41
|
+
export declare function listReadable(input: {
|
|
42
|
+
viewer: Viewer;
|
|
43
|
+
identity: string;
|
|
44
|
+
refs: readonly ArtifactRef[];
|
|
45
|
+
}): Array<{
|
|
46
|
+
ref: ArtifactRef;
|
|
47
|
+
access: Access;
|
|
48
|
+
}>;
|
|
49
|
+
export interface ViewTarget {
|
|
50
|
+
kind: ArtifactKind;
|
|
51
|
+
relation: Relation;
|
|
52
|
+
/** The file whose review findings are asked for (TEST exception). */
|
|
53
|
+
file?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ViewRequest {
|
|
56
|
+
viewer: GovRole;
|
|
57
|
+
target: ViewTarget;
|
|
58
|
+
reason: string;
|
|
59
|
+
/** `gov_view` requests this child already made. */
|
|
60
|
+
requestsUsed: number;
|
|
61
|
+
/** Files of the requester's failing test cases. */
|
|
62
|
+
failingFiles: readonly string[];
|
|
63
|
+
}
|
|
64
|
+
export type ViewDecisionCode = 'already_allowed' | 'review_findings_same_file' | 'reason_too_short' | 'quota_exhausted' | 'not_allowed' | 'file_not_failing';
|
|
65
|
+
export interface ViewDecision {
|
|
66
|
+
granted: boolean;
|
|
67
|
+
code: ViewDecisionCode;
|
|
68
|
+
message: string;
|
|
69
|
+
/** Whether the engine should count this against the child's one request. */
|
|
70
|
+
consumesRequest: boolean;
|
|
71
|
+
/** For the grant: only findings located in this file are released. */
|
|
72
|
+
scopeFile?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Decide a `gov_view` request. Everything outside the default matrix is denied except
|
|
76
|
+
* one case: a TEST asking for the review findings that sit in the same file as one of its
|
|
77
|
+
* own failing cases. One request per child, reason of at least `viewReasonMinChars`.
|
|
78
|
+
* Malformed requests (short reason) do not burn the request: they are not misconduct.
|
|
79
|
+
*/
|
|
80
|
+
export declare function decideView(request: ViewRequest): ViewDecision;
|
|
81
|
+
/** Keep only the findings located in `file` (path-normalized comparison). */
|
|
82
|
+
export declare function findingsForFile<T extends {
|
|
83
|
+
file: string;
|
|
84
|
+
}>(findings: readonly T[], file: string): T[];
|
|
85
|
+
export interface PageResult {
|
|
86
|
+
text: string;
|
|
87
|
+
offset: number;
|
|
88
|
+
/** null on the last page. */
|
|
89
|
+
nextOffset: number | null;
|
|
90
|
+
total: number;
|
|
91
|
+
/** 1-based. */
|
|
92
|
+
page: number;
|
|
93
|
+
pages: number;
|
|
94
|
+
}
|
|
95
|
+
/** One page of `text` starting at `offset` (clamped), never splitting a surrogate pair. */
|
|
96
|
+
export declare function pageText(text: string, offset?: number, pageChars?: number): PageResult;
|
|
97
|
+
/** Page body plus a one-line footer telling the reader how to continue. */
|
|
98
|
+
export declare function formatPage(id: string, page: PageResult): string;
|
|
99
|
+
/** The `gov_read` list view: id, kind and access level, one per line. */
|
|
100
|
+
export declare function formatReadableList(items: ReadonlyArray<{
|
|
101
|
+
ref: ArtifactRef;
|
|
102
|
+
access: Access;
|
|
103
|
+
}>): string;
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Information boundary (governance-mode 8.3): who may read what, the deterministic
|
|
3
|
+
* `gov_view` exception policy, and paging for `gov_read`.
|
|
4
|
+
*
|
|
5
|
+
* ASCII ONLY (`governance/` is glyph-scanned). Pure.
|
|
6
|
+
*
|
|
7
|
+
* ONE TABLE. `VISIBILITY_MATRIX` is the single source for both `gov_read` and the
|
|
8
|
+
* prompt assembler: a second hand-written copy would drift, and a drift here is a silent
|
|
9
|
+
* information leak (a tester who can read the review comments grades the reviewer's
|
|
10
|
+
* opinion instead of the code - exactly what the boundary exists to prevent).
|
|
11
|
+
*
|
|
12
|
+
* Cells are either one `Access` or `{ own, other }` when the answer depends on whether
|
|
13
|
+
* the viewer wrote the artifact. Artifact KINDS (work / review / test / inspector) map
|
|
14
|
+
* onto the spec's MATERIAL columns in `accessFor`; a review artifact carries both the
|
|
15
|
+
* verdict and the comments, so a viewer's access is the stronger of the two cells.
|
|
16
|
+
*
|
|
17
|
+
* `inspector_report` is not a column in the spec's matrix: settle / integrate reports are
|
|
18
|
+
* the fourth power's own output, so only INSP reads them in full and the lead gets the
|
|
19
|
+
* digest. It is added here, in the table, rather than special-cased in code.
|
|
20
|
+
*/
|
|
21
|
+
import { GOV_LIMITS } from '../limits.js';
|
|
22
|
+
export const VIEWERS = ['DEV', 'REV', 'TEST', 'INSP', 'lead'];
|
|
23
|
+
export const MATERIALS = [
|
|
24
|
+
'spec',
|
|
25
|
+
'own_submission',
|
|
26
|
+
'dev_submission',
|
|
27
|
+
'review_verdict',
|
|
28
|
+
'review_comments',
|
|
29
|
+
'test_report',
|
|
30
|
+
'inspector_report',
|
|
31
|
+
'standings',
|
|
32
|
+
'event_details',
|
|
33
|
+
];
|
|
34
|
+
export const VISIBILITY_MATRIX = {
|
|
35
|
+
DEV: {
|
|
36
|
+
spec: 'full',
|
|
37
|
+
own_submission: 'full',
|
|
38
|
+
dev_submission: 'summary',
|
|
39
|
+
review_verdict: 'none',
|
|
40
|
+
review_comments: 'none',
|
|
41
|
+
test_report: 'none',
|
|
42
|
+
inspector_report: 'none',
|
|
43
|
+
standings: 'full',
|
|
44
|
+
event_details: 'none',
|
|
45
|
+
},
|
|
46
|
+
REV: {
|
|
47
|
+
spec: 'full',
|
|
48
|
+
own_submission: 'full',
|
|
49
|
+
dev_submission: 'full',
|
|
50
|
+
review_verdict: { own: 'full', other: 'none' },
|
|
51
|
+
review_comments: { own: 'full', other: 'none' },
|
|
52
|
+
test_report: 'none',
|
|
53
|
+
inspector_report: 'none',
|
|
54
|
+
standings: 'full',
|
|
55
|
+
event_details: 'none',
|
|
56
|
+
},
|
|
57
|
+
TEST: {
|
|
58
|
+
spec: 'full',
|
|
59
|
+
own_submission: 'full',
|
|
60
|
+
dev_submission: 'changes',
|
|
61
|
+
review_verdict: 'full',
|
|
62
|
+
review_comments: 'none',
|
|
63
|
+
test_report: { own: 'full', other: 'none' },
|
|
64
|
+
inspector_report: 'none',
|
|
65
|
+
standings: 'full',
|
|
66
|
+
event_details: 'none',
|
|
67
|
+
},
|
|
68
|
+
INSP: {
|
|
69
|
+
spec: 'full',
|
|
70
|
+
own_submission: 'full',
|
|
71
|
+
dev_submission: 'full',
|
|
72
|
+
review_verdict: 'full',
|
|
73
|
+
review_comments: 'full',
|
|
74
|
+
test_report: 'full',
|
|
75
|
+
inspector_report: 'full',
|
|
76
|
+
standings: 'full',
|
|
77
|
+
event_details: 'full',
|
|
78
|
+
},
|
|
79
|
+
lead: {
|
|
80
|
+
spec: 'full',
|
|
81
|
+
own_submission: 'none',
|
|
82
|
+
dev_submission: 'summary',
|
|
83
|
+
review_verdict: 'summary',
|
|
84
|
+
review_comments: 'summary',
|
|
85
|
+
test_report: 'summary',
|
|
86
|
+
inspector_report: 'summary',
|
|
87
|
+
standings: 'full',
|
|
88
|
+
event_details: 'full',
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
function resolveCell(cell, relation) {
|
|
92
|
+
return typeof cell === 'string' ? cell : cell[relation];
|
|
93
|
+
}
|
|
94
|
+
/** Access to a spec-matrix column. */
|
|
95
|
+
export function materialAccess(viewer, material, relation) {
|
|
96
|
+
return resolveCell(VISIBILITY_MATRIX[viewer][material], relation);
|
|
97
|
+
}
|
|
98
|
+
const RANK = { none: 0, verdict: 1, changes: 1, summary: 2, full: 3 };
|
|
99
|
+
function stronger(a, b) {
|
|
100
|
+
return RANK[b] > RANK[a] ? b : a;
|
|
101
|
+
}
|
|
102
|
+
function reviewAccess(viewer, relation) {
|
|
103
|
+
if (relation === 'own')
|
|
104
|
+
return materialAccess(viewer, 'own_submission', 'own');
|
|
105
|
+
const comments = materialAccess(viewer, 'review_comments', relation);
|
|
106
|
+
const verdictCell = materialAccess(viewer, 'review_verdict', relation);
|
|
107
|
+
// The verdict column is "conclusion only": a full verdict grant is NOT the full document.
|
|
108
|
+
const verdict = verdictCell === 'full' ? 'verdict' : verdictCell;
|
|
109
|
+
return stronger(comments, verdict);
|
|
110
|
+
}
|
|
111
|
+
/** What `viewer` may read of an artifact of `kind`. */
|
|
112
|
+
export function accessFor(viewer, kind, relation) {
|
|
113
|
+
switch (kind) {
|
|
114
|
+
case 'work':
|
|
115
|
+
return relation === 'own'
|
|
116
|
+
? materialAccess(viewer, 'own_submission', 'own')
|
|
117
|
+
: materialAccess(viewer, 'dev_submission', relation);
|
|
118
|
+
case 'review':
|
|
119
|
+
return reviewAccess(viewer, relation);
|
|
120
|
+
case 'test':
|
|
121
|
+
return relation === 'own'
|
|
122
|
+
? materialAccess(viewer, 'own_submission', 'own')
|
|
123
|
+
: materialAccess(viewer, 'test_report', relation);
|
|
124
|
+
case 'inspector':
|
|
125
|
+
return materialAccess(viewer, 'inspector_report', relation);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export function canRead(viewer, kind, relation) {
|
|
129
|
+
return accessFor(viewer, kind, relation) !== 'none';
|
|
130
|
+
}
|
|
131
|
+
/** Artifacts `viewer` (acting as `identity`) may see, annotated with the access level. */
|
|
132
|
+
export function listReadable(input) {
|
|
133
|
+
const out = [];
|
|
134
|
+
for (const ref of input.refs) {
|
|
135
|
+
const relation = ref.identity === input.identity ? 'own' : 'other';
|
|
136
|
+
const access = accessFor(input.viewer, ref.kind, relation);
|
|
137
|
+
if (access !== 'none')
|
|
138
|
+
out.push({ ref, access });
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
function normalizeFile(file) {
|
|
143
|
+
return file.trim().replace(/\\/g, '/').replace(/^\.\//, '').toLowerCase();
|
|
144
|
+
}
|
|
145
|
+
function deny(code, message, consumesRequest) {
|
|
146
|
+
return { granted: false, code, message: `NOT ACCEPTED: ${message}`, consumesRequest };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Decide a `gov_view` request. Everything outside the default matrix is denied except
|
|
150
|
+
* one case: a TEST asking for the review findings that sit in the same file as one of its
|
|
151
|
+
* own failing cases. One request per child, reason of at least `viewReasonMinChars`.
|
|
152
|
+
* Malformed requests (short reason) do not burn the request: they are not misconduct.
|
|
153
|
+
*/
|
|
154
|
+
export function decideView(request) {
|
|
155
|
+
const { viewer, target } = request;
|
|
156
|
+
if (request.reason.trim().length < GOV_LIMITS.viewReasonMinChars) {
|
|
157
|
+
return deny('reason_too_short', `the reason must be at least ${GOV_LIMITS.viewReasonMinChars} characters; ` +
|
|
158
|
+
'explain what you need and why.', false);
|
|
159
|
+
}
|
|
160
|
+
if (accessFor(viewer, target.kind, target.relation) === 'full') {
|
|
161
|
+
return {
|
|
162
|
+
granted: true,
|
|
163
|
+
code: 'already_allowed',
|
|
164
|
+
message: 'OK: this is already readable with gov_read.',
|
|
165
|
+
consumesRequest: false,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (request.requestsUsed >= GOV_LIMITS.viewRequestsPerChild) {
|
|
169
|
+
return deny('quota_exhausted', 'you have used your gov_view request for this stage.', false);
|
|
170
|
+
}
|
|
171
|
+
if (viewer !== 'TEST' || target.kind !== 'review') {
|
|
172
|
+
return deny('not_allowed', 'that material is outside your information boundary.', true);
|
|
173
|
+
}
|
|
174
|
+
const wanted = normalizeFile(target.file ?? '');
|
|
175
|
+
const failing = request.failingFiles.map(normalizeFile);
|
|
176
|
+
if (wanted === '' || !failing.includes(wanted)) {
|
|
177
|
+
return deny('file_not_failing', 'review findings are only released for a file that holds one of your failing cases.', true);
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
granted: true,
|
|
181
|
+
code: 'review_findings_same_file',
|
|
182
|
+
message: `OK: review findings for ${target.file} are released to you.`,
|
|
183
|
+
consumesRequest: true,
|
|
184
|
+
scopeFile: target.file,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/** Keep only the findings located in `file` (path-normalized comparison). */
|
|
188
|
+
export function findingsForFile(findings, file) {
|
|
189
|
+
const wanted = normalizeFile(file);
|
|
190
|
+
return findings.filter((finding) => normalizeFile(finding.file) === wanted);
|
|
191
|
+
}
|
|
192
|
+
/** One page of `text` starting at `offset` (clamped), never splitting a surrogate pair. */
|
|
193
|
+
export function pageText(text, offset = 0, pageChars = GOV_LIMITS.readPageChars) {
|
|
194
|
+
const total = text.length;
|
|
195
|
+
const start = Number.isInteger(offset) ? Math.min(Math.max(0, offset), total) : 0;
|
|
196
|
+
let end = Math.min(total, start + pageChars);
|
|
197
|
+
const last = text.charCodeAt(end - 1);
|
|
198
|
+
if (end < total && last >= 0xd800 && last <= 0xdbff)
|
|
199
|
+
end -= 1;
|
|
200
|
+
const pages = Math.max(1, Math.ceil(total / pageChars));
|
|
201
|
+
return {
|
|
202
|
+
text: text.slice(start, end),
|
|
203
|
+
offset: start,
|
|
204
|
+
nextOffset: end < total ? end : null,
|
|
205
|
+
total,
|
|
206
|
+
page: Math.min(pages, Math.floor(start / pageChars) + 1),
|
|
207
|
+
pages,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Page body plus a one-line footer telling the reader how to continue. */
|
|
211
|
+
export function formatPage(id, page) {
|
|
212
|
+
const footer = page.nextOffset === null
|
|
213
|
+
? `[end of ${id}; page ${page.page}/${page.pages}]`
|
|
214
|
+
: `[${id}: page ${page.page}/${page.pages}; ` +
|
|
215
|
+
`next: gov_read {"id":"${id}","offset":${page.nextOffset}}]`;
|
|
216
|
+
return `${page.text}\n${footer}`;
|
|
217
|
+
}
|
|
218
|
+
/** The `gov_read` list view: id, kind and access level, one per line. */
|
|
219
|
+
export function formatReadableList(items) {
|
|
220
|
+
if (items.length === 0)
|
|
221
|
+
return 'No artifacts are readable by you yet.';
|
|
222
|
+
return items.map(({ ref, access }) => `${ref.id} [${ref.kind}] ${access}`).join('\n');
|
|
223
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `isGovernedDispatch` - the one predicate that says whether a team dispatch belongs to a
|
|
3
|
+
* governed run (governance-mode section 10.4, RV-3).
|
|
4
|
+
*
|
|
5
|
+
* Pure: no React, no I/O. ASCII ONLY (`governance/` is glyph-scanned).
|
|
6
|
+
*
|
|
7
|
+
* WHY A FUNCTION AND NOT AN INLINE FIELD CHECK. The reducer's `teamStart` must keep a
|
|
8
|
+
* governed dispatch out of the transcript (one run is 10-20 dispatches; a `TeamCard` for
|
|
9
|
+
* each would bury the conversation) while writing the live `state.team` snapshot the
|
|
10
|
+
* panel and `/agents` read. Two call sites need the same answer (the reducer and, later,
|
|
11
|
+
* the card tests), and "does any spec carry governance" is exactly the kind of check that
|
|
12
|
+
* grows a second spelling. The reducer imports ONLY this function.
|
|
13
|
+
*/
|
|
14
|
+
/** The structural slice of a `SubagentSpec` this predicate reads. */
|
|
15
|
+
export interface GovernedSpecLike {
|
|
16
|
+
governance?: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** True when ANY spec of the dispatch is governed (a governed stage is homogeneous). */
|
|
19
|
+
export declare function isGovernedDispatch(specs: readonly GovernedSpecLike[]): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `isGovernedDispatch` - the one predicate that says whether a team dispatch belongs to a
|
|
3
|
+
* governed run (governance-mode section 10.4, RV-3).
|
|
4
|
+
*
|
|
5
|
+
* Pure: no React, no I/O. ASCII ONLY (`governance/` is glyph-scanned).
|
|
6
|
+
*
|
|
7
|
+
* WHY A FUNCTION AND NOT AN INLINE FIELD CHECK. The reducer's `teamStart` must keep a
|
|
8
|
+
* governed dispatch out of the transcript (one run is 10-20 dispatches; a `TeamCard` for
|
|
9
|
+
* each would bury the conversation) while writing the live `state.team` snapshot the
|
|
10
|
+
* panel and `/agents` read. Two call sites need the same answer (the reducer and, later,
|
|
11
|
+
* the card tests), and "does any spec carry governance" is exactly the kind of check that
|
|
12
|
+
* grows a second spelling. The reducer imports ONLY this function.
|
|
13
|
+
*/
|
|
14
|
+
/** True when ANY spec of the dispatch is governed (a governed stage is homogeneous). */
|
|
15
|
+
export function isGovernedDispatch(specs) {
|
|
16
|
+
return specs.some((spec) => spec.governance !== undefined);
|
|
17
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GOV_LIMITS - the single authority on every STRUCTURAL bound governance enforces
|
|
3
|
+
* (governance-mode section 8.5), plus the stable tool-name sets and block versions.
|
|
4
|
+
*
|
|
5
|
+
* ASCII ONLY: `src/governance/**` is inside the glyph scanner's scope
|
|
6
|
+
* (`glyphs.test.ts::inScope`, D-18).
|
|
7
|
+
*
|
|
8
|
+
* TWO KINDS OF NUMBER, exactly like `team/limits.ts`: the entries here are STRUCTURAL
|
|
9
|
+
* (what the store, the digest and the panel can physically carry; a user has no
|
|
10
|
+
* business tuning them) while the `governance.*` config keys (`config/schema.ts`) are
|
|
11
|
+
* POLICY and clamped. `hardMax*` bound a config key and are applied twice: once in
|
|
12
|
+
* `clampGovernanceConfig` and once in the engine, because a clamp that only runs on the
|
|
13
|
+
* read path leaves a bad value on disk.
|
|
14
|
+
*/
|
|
15
|
+
export declare const GOV_LIMITS: {
|
|
16
|
+
/** Ceiling for `governance.maxWorkPackages`. */
|
|
17
|
+
readonly hardMaxWorkPackages: 8;
|
|
18
|
+
/** Ceiling for `governance.maxPhases`. */
|
|
19
|
+
readonly hardMaxPhases: 6;
|
|
20
|
+
/** Ceiling for `governance.maxRework`, INCLUDING L3 `retry` grants. */
|
|
21
|
+
readonly hardMaxRework: 5;
|
|
22
|
+
/** Ceiling for `governance.maxFixCycles`, INCLUDING L3 `retry` grants. */
|
|
23
|
+
readonly hardMaxFixCycles: 5;
|
|
24
|
+
/** `gov_dispatch` calls per run. */
|
|
25
|
+
readonly hardMaxDispatches: 120;
|
|
26
|
+
/** At most this many `retry` grants per WP (resolve.disposition). */
|
|
27
|
+
readonly maxReworkGrantsPerWp: 2;
|
|
28
|
+
/** At most this many extra fix cycles may be granted per phase. */
|
|
29
|
+
readonly maxFixGrantsPerPhase: 1;
|
|
30
|
+
readonly goalChars: 300;
|
|
31
|
+
readonly specChars: 12000;
|
|
32
|
+
readonly wpIdChars: 16;
|
|
33
|
+
readonly wpTitleChars: 80;
|
|
34
|
+
readonly wpGoalChars: 1200;
|
|
35
|
+
readonly wpFilesMax: 12;
|
|
36
|
+
readonly wpAcceptanceMax: 8;
|
|
37
|
+
readonly wpAcceptanceChars: 200;
|
|
38
|
+
readonly contractsMax: 12;
|
|
39
|
+
readonly contractNameChars: 80;
|
|
40
|
+
readonly contractDefinitionChars: 800;
|
|
41
|
+
readonly integrationCommandsMax: 6;
|
|
42
|
+
readonly integrationCommandChars: 300;
|
|
43
|
+
readonly noteChars: 600;
|
|
44
|
+
readonly rulingChars: 1000;
|
|
45
|
+
readonly reasonChars: 300;
|
|
46
|
+
/** `ledger_apply` evidence must carry at least this many characters (D-4). */
|
|
47
|
+
readonly evidenceMinChars: 20;
|
|
48
|
+
readonly evidenceMaxChars: 1200;
|
|
49
|
+
readonly submissionBytes: 64000;
|
|
50
|
+
readonly artifactBytesPerRun: 20000000;
|
|
51
|
+
readonly eventsFileBytes: 8000000;
|
|
52
|
+
readonly historyPerAgent: 200;
|
|
53
|
+
readonly retentionDays: 30;
|
|
54
|
+
readonly pruneMaxPerPass: 200;
|
|
55
|
+
/** Heartbeat of `run.lock` while a stage runs. */
|
|
56
|
+
readonly lockHeartbeatMs: 15000;
|
|
57
|
+
/** A lock whose heartbeat is older than this is stale and may be taken over. */
|
|
58
|
+
readonly lockStaleMs: 60000;
|
|
59
|
+
readonly digestMaxBytes: 6000;
|
|
60
|
+
readonly finalReportMaxBytes: 24000;
|
|
61
|
+
/** Spec excerpt budget inside a child prompt. */
|
|
62
|
+
readonly specExcerptChars: 2000;
|
|
63
|
+
readonly initialTokens: 100;
|
|
64
|
+
readonly respawnTokens: 80;
|
|
65
|
+
readonly maxSingleReward: 20;
|
|
66
|
+
readonly maxSingleDeduction: -40;
|
|
67
|
+
readonly maxIncidentNegative: -50;
|
|
68
|
+
readonly tailEliminationThreshold: 60;
|
|
69
|
+
readonly healthWarnThreshold: 70;
|
|
70
|
+
readonly labelWarnThreshold: 80;
|
|
71
|
+
readonly labelDangerThreshold: 60;
|
|
72
|
+
/** Active members of a role needed before tail elimination is considered. */
|
|
73
|
+
readonly tailEliminationMinRoleSize: 3;
|
|
74
|
+
/** A child may fail validation this many times before the submission counts as absent. */
|
|
75
|
+
readonly maxValidationFailures: 3;
|
|
76
|
+
/** Dispatch retries for a child that finished without a required submission. */
|
|
77
|
+
readonly maxAutoRedispatch: 1;
|
|
78
|
+
/** `gov_view` requests per child, and the minimum reason length. */
|
|
79
|
+
readonly viewRequestsPerChild: 1;
|
|
80
|
+
readonly viewReasonMinChars: 20;
|
|
81
|
+
/** `gov_scan` path cap. */
|
|
82
|
+
readonly scanPathsMax: 40;
|
|
83
|
+
/** `gov_read` page size in characters. */
|
|
84
|
+
readonly readPageChars: 6000;
|
|
85
|
+
/** Budget warning fraction (>= this share of `budgetTokens`). */
|
|
86
|
+
readonly budgetWarnFraction: 0.8;
|
|
87
|
+
/** `skeletonRatio` above this converts D9 into D11. */
|
|
88
|
+
readonly skeletonRatioThreshold: 0.3;
|
|
89
|
+
};
|
|
90
|
+
/** Version of the schema written to `run.json` / `ledger.json`. */
|
|
91
|
+
export declare const GOV_SCHEMA_VERSION = 1;
|
|
92
|
+
/** Block versions: bump on ANY wording change so behavior reports can grep for them. */
|
|
93
|
+
export declare const GOVERNANCE_BLOCK_VERSION = "v1-2026-10-24";
|
|
94
|
+
export declare const GOVERNANCE_ROLE_BLOCK_VERSION = "v1-2026-10-24";
|
|
95
|
+
export declare const GOVERNANCE_PLAN_ADDENDUM_VERSION = "v1-2026-10-24";
|
|
96
|
+
/** The two tools registered into the lead's array (NOT in HOST_TOOL_NAMES, D-22b). */
|
|
97
|
+
export declare const GOV_LEAD_TOOL_NAMES: ReadonlySet<string>;
|
|
98
|
+
/** Every tool a governed child may be handed. Merged into `policyExempt` (7.1 rule 6). */
|
|
99
|
+
export declare const GOV_CHILD_TOOL_NAMES: ReadonlySet<string>;
|
|
100
|
+
/**
|
|
101
|
+
* The lead tools a governed ORCHESTRATOR may not call: the plan-mode blocked set plus
|
|
102
|
+
* `task` (the latter only while the gate mode is `build`). Kept as a literal list so a
|
|
103
|
+
* future change to `PLAN_MODE_BLOCKED_TOOLS` is a deliberate edit, not an accident.
|
|
104
|
+
*/
|
|
105
|
+
export declare const GOVERN_ORCHESTRATOR_REFUSED_TOOLS: readonly string[];
|
|
106
|
+
/** Run directory id: "g" + base36(timeMs) + 3 random [a-z0-9]. */
|
|
107
|
+
export declare const RUN_ID_PATTERN: RegExp;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GOV_LIMITS - the single authority on every STRUCTURAL bound governance enforces
|
|
3
|
+
* (governance-mode section 8.5), plus the stable tool-name sets and block versions.
|
|
4
|
+
*
|
|
5
|
+
* ASCII ONLY: `src/governance/**` is inside the glyph scanner's scope
|
|
6
|
+
* (`glyphs.test.ts::inScope`, D-18).
|
|
7
|
+
*
|
|
8
|
+
* TWO KINDS OF NUMBER, exactly like `team/limits.ts`: the entries here are STRUCTURAL
|
|
9
|
+
* (what the store, the digest and the panel can physically carry; a user has no
|
|
10
|
+
* business tuning them) while the `governance.*` config keys (`config/schema.ts`) are
|
|
11
|
+
* POLICY and clamped. `hardMax*` bound a config key and are applied twice: once in
|
|
12
|
+
* `clampGovernanceConfig` and once in the engine, because a clamp that only runs on the
|
|
13
|
+
* read path leaves a bad value on disk.
|
|
14
|
+
*/
|
|
15
|
+
export const GOV_LIMITS = {
|
|
16
|
+
/** Ceiling for `governance.maxWorkPackages`. */
|
|
17
|
+
hardMaxWorkPackages: 8,
|
|
18
|
+
/** Ceiling for `governance.maxPhases`. */
|
|
19
|
+
hardMaxPhases: 6,
|
|
20
|
+
/** Ceiling for `governance.maxRework`, INCLUDING L3 `retry` grants. */
|
|
21
|
+
hardMaxRework: 5,
|
|
22
|
+
/** Ceiling for `governance.maxFixCycles`, INCLUDING L3 `retry` grants. */
|
|
23
|
+
hardMaxFixCycles: 5,
|
|
24
|
+
/** `gov_dispatch` calls per run. */
|
|
25
|
+
hardMaxDispatches: 120,
|
|
26
|
+
/** At most this many `retry` grants per WP (resolve.disposition). */
|
|
27
|
+
maxReworkGrantsPerWp: 2,
|
|
28
|
+
/** At most this many extra fix cycles may be granted per phase. */
|
|
29
|
+
maxFixGrantsPerPhase: 1,
|
|
30
|
+
// --- Input sizes (tool arguments) ---
|
|
31
|
+
goalChars: 300,
|
|
32
|
+
specChars: 12_000,
|
|
33
|
+
wpIdChars: 16,
|
|
34
|
+
wpTitleChars: 80,
|
|
35
|
+
wpGoalChars: 1_200,
|
|
36
|
+
wpFilesMax: 12,
|
|
37
|
+
wpAcceptanceMax: 8,
|
|
38
|
+
wpAcceptanceChars: 200,
|
|
39
|
+
contractsMax: 12,
|
|
40
|
+
contractNameChars: 80,
|
|
41
|
+
contractDefinitionChars: 800,
|
|
42
|
+
integrationCommandsMax: 6,
|
|
43
|
+
integrationCommandChars: 300,
|
|
44
|
+
noteChars: 600,
|
|
45
|
+
rulingChars: 1_000,
|
|
46
|
+
reasonChars: 300,
|
|
47
|
+
/** `ledger_apply` evidence must carry at least this many characters (D-4). */
|
|
48
|
+
evidenceMinChars: 20,
|
|
49
|
+
evidenceMaxChars: 1_200,
|
|
50
|
+
// --- Storage ---
|
|
51
|
+
submissionBytes: 64_000,
|
|
52
|
+
artifactBytesPerRun: 20_000_000,
|
|
53
|
+
eventsFileBytes: 8_000_000,
|
|
54
|
+
historyPerAgent: 200,
|
|
55
|
+
retentionDays: 30,
|
|
56
|
+
pruneMaxPerPass: 200,
|
|
57
|
+
/** Heartbeat of `run.lock` while a stage runs. */
|
|
58
|
+
lockHeartbeatMs: 15_000,
|
|
59
|
+
/** A lock whose heartbeat is older than this is stale and may be taken over. */
|
|
60
|
+
lockStaleMs: 60_000,
|
|
61
|
+
// --- Reports ---
|
|
62
|
+
digestMaxBytes: 6_000,
|
|
63
|
+
finalReportMaxBytes: 24_000,
|
|
64
|
+
/** Spec excerpt budget inside a child prompt. */
|
|
65
|
+
specExcerptChars: 2_000,
|
|
66
|
+
// --- Ledger parameters (Appendix A fixed parameters) ---
|
|
67
|
+
initialTokens: 100,
|
|
68
|
+
respawnTokens: 80,
|
|
69
|
+
maxSingleReward: 20,
|
|
70
|
+
maxSingleDeduction: -40,
|
|
71
|
+
maxIncidentNegative: -50,
|
|
72
|
+
tailEliminationThreshold: 60,
|
|
73
|
+
healthWarnThreshold: 70,
|
|
74
|
+
labelWarnThreshold: 80,
|
|
75
|
+
labelDangerThreshold: 60,
|
|
76
|
+
/** Active members of a role needed before tail elimination is considered. */
|
|
77
|
+
tailEliminationMinRoleSize: 3,
|
|
78
|
+
// --- Validation ---
|
|
79
|
+
/** A child may fail validation this many times before the submission counts as absent. */
|
|
80
|
+
maxValidationFailures: 3,
|
|
81
|
+
/** Dispatch retries for a child that finished without a required submission. */
|
|
82
|
+
maxAutoRedispatch: 1,
|
|
83
|
+
/** `gov_view` requests per child, and the minimum reason length. */
|
|
84
|
+
viewRequestsPerChild: 1,
|
|
85
|
+
viewReasonMinChars: 20,
|
|
86
|
+
/** `gov_scan` path cap. */
|
|
87
|
+
scanPathsMax: 40,
|
|
88
|
+
/** `gov_read` page size in characters. */
|
|
89
|
+
readPageChars: 6_000,
|
|
90
|
+
/** Budget warning fraction (>= this share of `budgetTokens`). */
|
|
91
|
+
budgetWarnFraction: 0.8,
|
|
92
|
+
/** `skeletonRatio` above this converts D9 into D11. */
|
|
93
|
+
skeletonRatioThreshold: 0.3,
|
|
94
|
+
};
|
|
95
|
+
/** Version of the schema written to `run.json` / `ledger.json`. */
|
|
96
|
+
export const GOV_SCHEMA_VERSION = 1;
|
|
97
|
+
/** Block versions: bump on ANY wording change so behavior reports can grep for them. */
|
|
98
|
+
export const GOVERNANCE_BLOCK_VERSION = 'v1-2026-10-24';
|
|
99
|
+
export const GOVERNANCE_ROLE_BLOCK_VERSION = 'v1-2026-10-24';
|
|
100
|
+
export const GOVERNANCE_PLAN_ADDENDUM_VERSION = 'v1-2026-10-24';
|
|
101
|
+
/** The two tools registered into the lead's array (NOT in HOST_TOOL_NAMES, D-22b). */
|
|
102
|
+
export const GOV_LEAD_TOOL_NAMES = new Set(['gov_run', 'gov_dispatch']);
|
|
103
|
+
/** Every tool a governed child may be handed. Merged into `policyExempt` (7.1 rule 6). */
|
|
104
|
+
export const GOV_CHILD_TOOL_NAMES = new Set([
|
|
105
|
+
'gov_submit_work',
|
|
106
|
+
'gov_submit_review',
|
|
107
|
+
'gov_submit_test',
|
|
108
|
+
'ledger_standings',
|
|
109
|
+
'gov_read',
|
|
110
|
+
'gov_scan',
|
|
111
|
+
'gov_view',
|
|
112
|
+
'ledger_apply',
|
|
113
|
+
'ledger_rule',
|
|
114
|
+
'ledger_settle',
|
|
115
|
+
]);
|
|
116
|
+
/**
|
|
117
|
+
* The lead tools a governed ORCHESTRATOR may not call: the plan-mode blocked set plus
|
|
118
|
+
* `task` (the latter only while the gate mode is `build`). Kept as a literal list so a
|
|
119
|
+
* future change to `PLAN_MODE_BLOCKED_TOOLS` is a deliberate edit, not an accident.
|
|
120
|
+
*/
|
|
121
|
+
export const GOVERN_ORCHESTRATOR_REFUSED_TOOLS = [
|
|
122
|
+
'write_file',
|
|
123
|
+
'edit_file',
|
|
124
|
+
'bash',
|
|
125
|
+
'bash_kill',
|
|
126
|
+
'skill_install',
|
|
127
|
+
'skill_create',
|
|
128
|
+
'task',
|
|
129
|
+
];
|
|
130
|
+
/** Run directory id: "g" + base36(timeMs) + 3 random [a-z0-9]. */
|
|
131
|
+
export const RUN_ID_PATTERN = /^g[a-z0-9]{4,12}$/;
|
|
@@ -0,0 +1,38 @@
|
|
|
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 type { AgentMode } from '../agent/agent-mode.js';
|
|
13
|
+
import { type Posture } from './posture.js';
|
|
14
|
+
export interface PostureTransitionInput {
|
|
15
|
+
/** Gate mode and governance flag as they stand. */
|
|
16
|
+
current: {
|
|
17
|
+
mode: AgentMode;
|
|
18
|
+
governOn: boolean;
|
|
19
|
+
};
|
|
20
|
+
target: Posture;
|
|
21
|
+
/** Informed approval (plan approved): applies immediately. */
|
|
22
|
+
force: boolean;
|
|
23
|
+
/** The lead is mid-run. */
|
|
24
|
+
running: boolean;
|
|
25
|
+
/** A governed stage is in flight (`engine.isStageRunning()`). */
|
|
26
|
+
stageRunning: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface PostureTransitionResult {
|
|
29
|
+
mode: AgentMode;
|
|
30
|
+
governOn: boolean;
|
|
31
|
+
/** The target waiting for `agent_end`, or null. */
|
|
32
|
+
pending: Posture | null;
|
|
33
|
+
/** Why a change was deferred, for the caller's toast. */
|
|
34
|
+
deferredBecause: 'stage' | 'running' | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function decidePostureTransition(input: PostureTransitionInput): PostureTransitionResult;
|
|
37
|
+
/** The posture a (mode, governOn) pair denotes; re-exported so callers import one module. */
|
|
38
|
+
export declare function postureOf(mode: AgentMode, governOn: boolean): Posture;
|