openplanr 1.16.2 → 1.18.0
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/dist/cli/commands/operate.d.ts +10 -1
- package/dist/cli/commands/operate.d.ts.map +1 -1
- package/dist/cli/commands/operate.js +240 -13
- package/dist/cli/commands/operate.js.map +1 -1
- package/dist/services/ai-service.d.ts +25 -0
- package/dist/services/ai-service.d.ts.map +1 -1
- package/dist/services/ai-service.js +38 -0
- package/dist/services/ai-service.js.map +1 -1
- package/dist/services/operate/advisors.d.ts +82 -1
- package/dist/services/operate/advisors.d.ts.map +1 -1
- package/dist/services/operate/advisors.js +469 -17
- package/dist/services/operate/advisors.js.map +1 -1
- package/dist/services/operate/artifacts.d.ts +27 -1
- package/dist/services/operate/artifacts.d.ts.map +1 -1
- package/dist/services/operate/artifacts.js +103 -1
- package/dist/services/operate/artifacts.js.map +1 -1
- package/dist/services/operate/cadence.d.ts +50 -0
- package/dist/services/operate/cadence.d.ts.map +1 -0
- package/dist/services/operate/cadence.js +56 -0
- package/dist/services/operate/cadence.js.map +1 -0
- package/dist/services/operate/citation-resolution.d.ts +101 -0
- package/dist/services/operate/citation-resolution.d.ts.map +1 -0
- package/dist/services/operate/citation-resolution.js +308 -0
- package/dist/services/operate/citation-resolution.js.map +1 -0
- package/dist/services/operate/config.d.ts +93 -1
- package/dist/services/operate/config.d.ts.map +1 -1
- package/dist/services/operate/config.js +199 -9
- package/dist/services/operate/config.js.map +1 -1
- package/dist/services/operate/decision-brief.d.ts +148 -0
- package/dist/services/operate/decision-brief.d.ts.map +1 -0
- package/dist/services/operate/decision-brief.js +194 -0
- package/dist/services/operate/decision-brief.js.map +1 -0
- package/dist/services/operate/doctor.d.ts.map +1 -1
- package/dist/services/operate/doctor.js +271 -3
- package/dist/services/operate/doctor.js.map +1 -1
- package/dist/services/operate/engine.d.ts +66 -2
- package/dist/services/operate/engine.d.ts.map +1 -1
- package/dist/services/operate/engine.js +219 -7
- package/dist/services/operate/engine.js.map +1 -1
- package/dist/services/operate/event-store.d.ts +35 -1
- package/dist/services/operate/event-store.d.ts.map +1 -1
- package/dist/services/operate/event-store.js +142 -29
- package/dist/services/operate/event-store.js.map +1 -1
- package/dist/services/operate/evidence-cache.d.ts +25 -1
- package/dist/services/operate/evidence-cache.d.ts.map +1 -1
- package/dist/services/operate/evidence-cache.js +62 -1
- package/dist/services/operate/evidence-cache.js.map +1 -1
- package/dist/services/operate/evidence.d.ts +20 -1
- package/dist/services/operate/evidence.d.ts.map +1 -1
- package/dist/services/operate/evidence.js +148 -0
- package/dist/services/operate/evidence.js.map +1 -1
- package/dist/services/operate/index.d.ts +2 -0
- package/dist/services/operate/index.d.ts.map +1 -1
- package/dist/services/operate/index.js +309 -46
- package/dist/services/operate/index.js.map +1 -1
- package/dist/services/operate/interaction/action-service.d.ts +17 -0
- package/dist/services/operate/interaction/action-service.d.ts.map +1 -1
- package/dist/services/operate/interaction/action-service.js +19 -0
- package/dist/services/operate/interaction/action-service.js.map +1 -1
- package/dist/services/operate/interaction/answer-service.d.ts +17 -0
- package/dist/services/operate/interaction/answer-service.d.ts.map +1 -1
- package/dist/services/operate/interaction/answer-service.js +49 -7
- package/dist/services/operate/interaction/answer-service.js.map +1 -1
- package/dist/services/operate/interaction/question-engine.d.ts.map +1 -1
- package/dist/services/operate/interaction/question-engine.js +9 -3
- package/dist/services/operate/interaction/question-engine.js.map +1 -1
- package/dist/services/operate/interaction/question-registry.d.ts +13 -0
- package/dist/services/operate/interaction/question-registry.d.ts.map +1 -1
- package/dist/services/operate/interaction/question-registry.js +116 -26
- package/dist/services/operate/interaction/question-registry.js.map +1 -1
- package/dist/services/operate/interaction/terminal-renderer.d.ts +12 -1
- package/dist/services/operate/interaction/terminal-renderer.d.ts.map +1 -1
- package/dist/services/operate/interaction/terminal-renderer.js +26 -15
- package/dist/services/operate/interaction/terminal-renderer.js.map +1 -1
- package/dist/services/operate/journal.d.ts.map +1 -1
- package/dist/services/operate/journal.js +11 -5
- package/dist/services/operate/journal.js.map +1 -1
- package/dist/services/operate/lifecycle.d.ts +8 -0
- package/dist/services/operate/lifecycle.d.ts.map +1 -1
- package/dist/services/operate/lifecycle.js +19 -1
- package/dist/services/operate/lifecycle.js.map +1 -1
- package/dist/services/operate/maintenance.d.ts +22 -0
- package/dist/services/operate/maintenance.d.ts.map +1 -1
- package/dist/services/operate/maintenance.js +406 -46
- package/dist/services/operate/maintenance.js.map +1 -1
- package/dist/services/operate/migration.d.ts +68 -0
- package/dist/services/operate/migration.d.ts.map +1 -0
- package/dist/services/operate/migration.js +235 -0
- package/dist/services/operate/migration.js.map +1 -0
- package/dist/services/operate/mission-dispatch.d.ts +193 -0
- package/dist/services/operate/mission-dispatch.d.ts.map +1 -0
- package/dist/services/operate/mission-dispatch.js +444 -0
- package/dist/services/operate/mission-dispatch.js.map +1 -0
- package/dist/services/operate/projection-persistence.d.ts +6 -0
- package/dist/services/operate/projection-persistence.d.ts.map +1 -1
- package/dist/services/operate/projection-persistence.js +87 -11
- package/dist/services/operate/projection-persistence.js.map +1 -1
- package/dist/services/operate/projection.d.ts +26 -1
- package/dist/services/operate/projection.d.ts.map +1 -1
- package/dist/services/operate/projection.js +62 -0
- package/dist/services/operate/projection.js.map +1 -1
- package/dist/services/operate/protocol.d.ts +50 -3
- package/dist/services/operate/protocol.d.ts.map +1 -1
- package/dist/services/operate/protocol.js +57 -5
- package/dist/services/operate/protocol.js.map +1 -1
- package/dist/services/operate/read-only-providers.d.ts +37 -0
- package/dist/services/operate/read-only-providers.d.ts.map +1 -1
- package/dist/services/operate/read-only-providers.js +130 -0
- package/dist/services/operate/read-only-providers.js.map +1 -1
- package/dist/services/operate/reports.d.ts +22 -0
- package/dist/services/operate/reports.d.ts.map +1 -1
- package/dist/services/operate/reports.js +226 -1
- package/dist/services/operate/reports.js.map +1 -1
- package/dist/services/operate/routes.d.ts.map +1 -1
- package/dist/services/operate/routes.js +79 -5
- package/dist/services/operate/routes.js.map +1 -1
- package/dist/services/operate/types.d.ts +139 -4
- package/dist/services/operate/types.d.ts.map +1 -1
- package/dist/services/operate/types.js +13 -0
- package/dist/services/operate/types.js.map +1 -1
- package/dist/services/operate/workspace.d.ts +7 -0
- package/dist/services/operate/workspace.d.ts.map +1 -1
- package/dist/services/operate/workspace.js +14 -5
- package/dist/services/operate/workspace.js.map +1 -1
- package/dist/services/runtime-manager-service.d.ts.map +1 -1
- package/dist/services/runtime-manager-service.js +25 -5
- package/dist/services/runtime-manager-service.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { type OperatingEvidenceIndexItem, type OperatingRoleId, type OperatingSensitivity } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Bounded, read-only native mission dispatch (FR2 / E-002).
|
|
4
|
+
*
|
|
5
|
+
* This module owns the two enforcement guarantees the pack path never needed:
|
|
6
|
+
*
|
|
7
|
+
* 1. A native advisory lens receives EXACTLY the Protocol v1.3 read-only tool
|
|
8
|
+
* grant — glob, file read, content search, and read-only git history —
|
|
9
|
+
* confined to its declared, sensitivity-ceiling-narrowed roots. No write,
|
|
10
|
+
* execute, network, or environment capability exists on the surface at all,
|
|
11
|
+
* so a mission agent physically cannot mutate, shell out, egress, or read
|
|
12
|
+
* ambient process state.
|
|
13
|
+
* 2. The sensitivity ceiling is enforced at READ time: even inside a granted
|
|
14
|
+
* root, a file above the role's ceiling is refused. This preserves the
|
|
15
|
+
* pack-era filter-before-handoff guarantee under agent-driven reads.
|
|
16
|
+
*
|
|
17
|
+
* It also owns the per-role dispatch-mode resolution (FR4 / E-004): the derived
|
|
18
|
+
* registry default (`mission`), the per-project `dispatchModeOverrides`, and the
|
|
19
|
+
* FR2-vs-FR4 reconciliation that routes non-enforcing runtimes to the structured
|
|
20
|
+
* provider path. The new mission honeytoken suite exercises every refusal here;
|
|
21
|
+
* the SPEC-002 empty-tool suite continues to govern the pack path unchanged.
|
|
22
|
+
*/
|
|
23
|
+
export type OperatingDispatchMode = 'pack' | 'mission';
|
|
24
|
+
/**
|
|
25
|
+
* The effective isolation a role's dispatch resolves to. Mirrors the isolation
|
|
26
|
+
* vocabulary the pipeline's v1.3 adapter handoff emits so OpenPlanr and the
|
|
27
|
+
* published contract cannot drift:
|
|
28
|
+
* - `enforced-empty-tools` — the v1.2 pack path (empty-tool brief);
|
|
29
|
+
* - `enforced-read-only-bounded` — a native mission lens with the bounded
|
|
30
|
+
* read-only grant, on a runtime that
|
|
31
|
+
* natively enforces tool isolation;
|
|
32
|
+
* - `fail-closed-structured-provider` — mission requested but the runtime
|
|
33
|
+
* cannot enforce the boundary, so the role
|
|
34
|
+
* falls back to the structured provider.
|
|
35
|
+
*/
|
|
36
|
+
export type OperatingDispatchIsolation = 'enforced-empty-tools' | 'enforced-read-only-bounded' | 'fail-closed-structured-provider';
|
|
37
|
+
export interface OperatingDispatchModeResolution {
|
|
38
|
+
roleId: OperatingRoleId;
|
|
39
|
+
/** The configured mode: registry default, overridden by dispatchModeOverrides. */
|
|
40
|
+
mode: OperatingDispatchMode;
|
|
41
|
+
/** The effective isolation after the FR2/FR4 reconciliation. */
|
|
42
|
+
isolation: OperatingDispatchIsolation;
|
|
43
|
+
/** True only when a native, bounded read-only lens is actually dispatched. */
|
|
44
|
+
native: boolean;
|
|
45
|
+
/** Audit note explaining why this isolation was chosen (recorded in provenance). */
|
|
46
|
+
reconciliation: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The bounded read-only capability set for a mission-mode lens. Kept in lockstep
|
|
50
|
+
* with the pipeline's `MISSION_READ_ONLY_TOOLS`: no write, execute, network, or
|
|
51
|
+
* environment tool is present, so a grant assembled from it can never authorize
|
|
52
|
+
* a mutating or escaping action.
|
|
53
|
+
*/
|
|
54
|
+
export declare const MISSION_READ_ONLY_TOOLS: readonly ["file-read", "glob", "content-search", "git-log", "git-show", "git-diff", "git-blame"];
|
|
55
|
+
export type MissionReadOnlyTool = (typeof MISSION_READ_ONLY_TOOLS)[number];
|
|
56
|
+
/**
|
|
57
|
+
* The registry default dispatch mode for a role. The v1.3 role registry carries
|
|
58
|
+
* a `dispatchMode` field; while it is still published without one every role
|
|
59
|
+
* defaults to `mission`, and only a role explicitly marked `pack` opts out —
|
|
60
|
+
* exactly the pipeline's own `role?.dispatchMode ?? 'mission'` convention.
|
|
61
|
+
*/
|
|
62
|
+
export declare function operatingRegistryDispatchMode(role: {
|
|
63
|
+
dispatchMode?: unknown;
|
|
64
|
+
}): OperatingDispatchMode;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the given runtime natively enforces the mission read-only boundary.
|
|
67
|
+
* `claude-code` enforces; `codex` and `cursor` are advisory and do not.
|
|
68
|
+
*/
|
|
69
|
+
export declare function operatingRuntimeEnforcesBoundedReadOnly(runtime: string | undefined): Promise<boolean>;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve one role's effective dispatch isolation.
|
|
72
|
+
*
|
|
73
|
+
* FR4 states Codex SHOULD dispatch natively, but FR2's fail-closed rule
|
|
74
|
+
* overrides it: a runtime whose tool isolation is only advisory (`codex`,
|
|
75
|
+
* `cursor`) cannot guarantee the bounded read-only boundary, so it routes to the
|
|
76
|
+
* structured provider path until its isolation is enforceable. Only a runtime
|
|
77
|
+
* that natively enforces tool isolation (`toolIsolation === 'enforced'`, i.e.
|
|
78
|
+
* `claude-code`) hosting a native-isolated adapter receives a native mission
|
|
79
|
+
* lens; every other combination fails closed here. This is the exact FR2/FR4
|
|
80
|
+
* reconciliation the spec calls out, recorded in the returned `reconciliation`
|
|
81
|
+
* so it appears in the dispatch provenance.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveOperatingDispatchMode(input: {
|
|
84
|
+
roleId: OperatingRoleId;
|
|
85
|
+
registryDefault: OperatingDispatchMode;
|
|
86
|
+
override?: OperatingDispatchMode;
|
|
87
|
+
runtimeEnforcesBoundedReadOnly: boolean;
|
|
88
|
+
adapterNativeCapable: boolean;
|
|
89
|
+
}): OperatingDispatchModeResolution;
|
|
90
|
+
/**
|
|
91
|
+
* Narrow a role's declared read roots by DENY-LISTING any root that contains an
|
|
92
|
+
* evidence item above the role's sensitivity ceiling, so no above-ceiling file
|
|
93
|
+
* is readable even inside a granted root. Pass the FULL (pre-ceiling-filter)
|
|
94
|
+
* evidence index: the narrowing needs to see the above-ceiling items the packet
|
|
95
|
+
* index itself excludes. Combined with the read-time ceiling check on the
|
|
96
|
+
* bounded reader, this is the belt-and-suspenders that preserves the pack-era
|
|
97
|
+
* filter-before-handoff guarantee under agent-driven reads.
|
|
98
|
+
*/
|
|
99
|
+
export declare function narrowMissionRootsToCeiling(input: {
|
|
100
|
+
declaredRoots: readonly string[];
|
|
101
|
+
evidenceIndex: readonly OperatingEvidenceIndexItem[];
|
|
102
|
+
ceiling: OperatingSensitivity;
|
|
103
|
+
}): string[];
|
|
104
|
+
export interface MissionReadBoundary {
|
|
105
|
+
/**
|
|
106
|
+
* Absolute, resolved read roots (already sensitivity-ceiling-narrowed). A read
|
|
107
|
+
* target must resolve inside one of these or it is refused as a root escape.
|
|
108
|
+
*/
|
|
109
|
+
roots: readonly string[];
|
|
110
|
+
/** The role's sensitivity ceiling, enforced at read time. */
|
|
111
|
+
ceiling: OperatingSensitivity;
|
|
112
|
+
/**
|
|
113
|
+
* The sensitivity of a resolved absolute path. In production this is built
|
|
114
|
+
* from the ceiling-filtered evidence index; an in-root path with no explicit
|
|
115
|
+
* classification falls back to `defaultSensitivity`.
|
|
116
|
+
*/
|
|
117
|
+
sensitivityByPath?: ReadonlyMap<string, OperatingSensitivity>;
|
|
118
|
+
/**
|
|
119
|
+
* Sensitivity assumed for an in-root path with no explicit classification.
|
|
120
|
+
* Defaults to the ceiling itself (readable) because the ceiling-filtered index
|
|
121
|
+
* and root narrowing already exclude above-ceiling material; individual
|
|
122
|
+
* above-ceiling files are still refused by the read-time check below.
|
|
123
|
+
*/
|
|
124
|
+
defaultSensitivity?: OperatingSensitivity;
|
|
125
|
+
/** Repository root for read-only git tools. Defaults to the first read root. */
|
|
126
|
+
repositoryRoot?: string;
|
|
127
|
+
}
|
|
128
|
+
export type MissionToolRequest = {
|
|
129
|
+
tool: 'file-read';
|
|
130
|
+
path: string;
|
|
131
|
+
} | {
|
|
132
|
+
tool: 'glob';
|
|
133
|
+
pattern?: string;
|
|
134
|
+
root?: string;
|
|
135
|
+
} | {
|
|
136
|
+
tool: 'content-search';
|
|
137
|
+
query: string;
|
|
138
|
+
root?: string;
|
|
139
|
+
} | {
|
|
140
|
+
tool: 'git-log' | 'git-show' | 'git-diff' | 'git-blame';
|
|
141
|
+
args?: string[];
|
|
142
|
+
path?: string;
|
|
143
|
+
} | {
|
|
144
|
+
tool: string;
|
|
145
|
+
[key: string]: unknown;
|
|
146
|
+
};
|
|
147
|
+
export type MissionToolResult = {
|
|
148
|
+
tool: 'file-read';
|
|
149
|
+
path: string;
|
|
150
|
+
content: string;
|
|
151
|
+
} | {
|
|
152
|
+
tool: 'glob';
|
|
153
|
+
matches: string[];
|
|
154
|
+
} | {
|
|
155
|
+
tool: 'content-search';
|
|
156
|
+
matches: Array<{
|
|
157
|
+
path: string;
|
|
158
|
+
line: number;
|
|
159
|
+
text: string;
|
|
160
|
+
}>;
|
|
161
|
+
} | {
|
|
162
|
+
tool: 'git-log' | 'git-show' | 'git-diff' | 'git-blame';
|
|
163
|
+
output: string;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* The single audited entry point for a mission lens's tool use. Every request is
|
|
167
|
+
* checked against the bounded read-only grant BEFORE any filesystem or git
|
|
168
|
+
* access: a tool outside the grant (write, execute, network, environment, or any
|
|
169
|
+
* unknown surface) is refused, a target outside the declared roots is refused as
|
|
170
|
+
* a path escape, and a target above the sensitivity ceiling is refused at read
|
|
171
|
+
* time. There is deliberately no write/execute/network/environment tool to
|
|
172
|
+
* invoke — those channels do not exist on this surface at all.
|
|
173
|
+
*/
|
|
174
|
+
export declare function invokeMissionTool(boundary: MissionReadBoundary, request: MissionToolRequest): Promise<MissionToolResult>;
|
|
175
|
+
/**
|
|
176
|
+
* The concrete callable tool surface handed to an in-process native harness:
|
|
177
|
+
* exactly the read-only tools, each bound to this boundary. There is no write,
|
|
178
|
+
* execute, network, or environment callable on the returned object, so a harness
|
|
179
|
+
* that walks it can never reach a mutating or escaping capability.
|
|
180
|
+
*/
|
|
181
|
+
export declare function createMissionToolset(boundary: MissionReadBoundary): Record<MissionReadOnlyTool, (request: Omit<MissionToolRequest, 'tool'>) => Promise<MissionToolResult>>;
|
|
182
|
+
/**
|
|
183
|
+
* Fan a per-item dispatch out in parallel where the adapter reports
|
|
184
|
+
* `parallelDispatch: true`, sequentially otherwise. Results are always returned
|
|
185
|
+
* in the SAME order as `items`, so the caller can restore registry order and the
|
|
186
|
+
* reduced events are byte-identical across parallel and sequential dispatch.
|
|
187
|
+
*/
|
|
188
|
+
export declare function runMissionDispatchFanOut<Item, Result>(input: {
|
|
189
|
+
items: readonly Item[];
|
|
190
|
+
parallel: boolean;
|
|
191
|
+
run: (item: Item) => Promise<Result>;
|
|
192
|
+
}): Promise<Result[]>;
|
|
193
|
+
//# sourceMappingURL=mission-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-dispatch.d.ts","sourceRoot":"","sources":["../../../src/services/operate/mission-dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { readdir, readFile, realpath, stat } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { resolveOperatingPipelineRoot } from './protocol.js';
|
|
5
|
+
import { executeGitReadOnly } from './read-only-providers.js';
|
|
6
|
+
import { compareSensitivity } from './redaction.js';
|
|
7
|
+
import { OperateError, } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* The bounded read-only capability set for a mission-mode lens. Kept in lockstep
|
|
10
|
+
* with the pipeline's `MISSION_READ_ONLY_TOOLS`: no write, execute, network, or
|
|
11
|
+
* environment tool is present, so a grant assembled from it can never authorize
|
|
12
|
+
* a mutating or escaping action.
|
|
13
|
+
*/
|
|
14
|
+
export const MISSION_READ_ONLY_TOOLS = Object.freeze([
|
|
15
|
+
'file-read',
|
|
16
|
+
'glob',
|
|
17
|
+
'content-search',
|
|
18
|
+
'git-log',
|
|
19
|
+
'git-show',
|
|
20
|
+
'git-diff',
|
|
21
|
+
'git-blame',
|
|
22
|
+
]);
|
|
23
|
+
function isReadOnlyTool(tool) {
|
|
24
|
+
return MISSION_READ_ONLY_TOOLS.includes(tool);
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Dispatch-mode resolution (FR4 / E-004) + runtime enforceability (FR2)
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* The registry default dispatch mode for a role. The v1.3 role registry carries
|
|
31
|
+
* a `dispatchMode` field; while it is still published without one every role
|
|
32
|
+
* defaults to `mission`, and only a role explicitly marked `pack` opts out —
|
|
33
|
+
* exactly the pipeline's own `role?.dispatchMode ?? 'mission'` convention.
|
|
34
|
+
*/
|
|
35
|
+
export function operatingRegistryDispatchMode(role) {
|
|
36
|
+
return role?.dispatchMode === 'pack' ? 'pack' : 'mission';
|
|
37
|
+
}
|
|
38
|
+
let cachedRuntimeEnforcement = null;
|
|
39
|
+
/**
|
|
40
|
+
* Load the pipeline's runtime registry and derive, per runtime, whether it
|
|
41
|
+
* natively enforces the bounded read-only boundary. The classification is the
|
|
42
|
+
* published `capabilities.toolIsolation === 'enforced'` bit — the same one the
|
|
43
|
+
* pipeline's adapter handoff uses — so it stays a single source of truth rather
|
|
44
|
+
* than a field the registry schema cannot carry.
|
|
45
|
+
*
|
|
46
|
+
* Fails CLOSED: if the mission-capable pipeline root or its runtime module
|
|
47
|
+
* cannot be resolved, nothing is treated as enforcing, so a runtime whose
|
|
48
|
+
* isolation cannot be verified never receives a native lens (DoD).
|
|
49
|
+
*/
|
|
50
|
+
async function loadRuntimeEnforcement() {
|
|
51
|
+
cachedRuntimeEnforcement ??= (async () => {
|
|
52
|
+
try {
|
|
53
|
+
const root = resolveOperatingPipelineRoot({ requireMission: true });
|
|
54
|
+
if (!root)
|
|
55
|
+
return () => false;
|
|
56
|
+
const module = (await import(pathToFileURL(path.join(root, 'lib', 'pipeline', 'runtime.mjs')).href));
|
|
57
|
+
const adapters = module.listRuntimeAdapters();
|
|
58
|
+
return (runtime) => {
|
|
59
|
+
if (!runtime || runtime === 'auto')
|
|
60
|
+
return false;
|
|
61
|
+
let id;
|
|
62
|
+
try {
|
|
63
|
+
id = module.normalizeRuntime(runtime);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const adapter = adapters.find((entry) => entry.id === id);
|
|
69
|
+
return adapter?.capabilities?.toolIsolation === 'enforced';
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return () => false;
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
return cachedRuntimeEnforcement;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether the given runtime natively enforces the mission read-only boundary.
|
|
80
|
+
* `claude-code` enforces; `codex` and `cursor` are advisory and do not.
|
|
81
|
+
*/
|
|
82
|
+
export async function operatingRuntimeEnforcesBoundedReadOnly(runtime) {
|
|
83
|
+
return (await loadRuntimeEnforcement())(runtime);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve one role's effective dispatch isolation.
|
|
87
|
+
*
|
|
88
|
+
* FR4 states Codex SHOULD dispatch natively, but FR2's fail-closed rule
|
|
89
|
+
* overrides it: a runtime whose tool isolation is only advisory (`codex`,
|
|
90
|
+
* `cursor`) cannot guarantee the bounded read-only boundary, so it routes to the
|
|
91
|
+
* structured provider path until its isolation is enforceable. Only a runtime
|
|
92
|
+
* that natively enforces tool isolation (`toolIsolation === 'enforced'`, i.e.
|
|
93
|
+
* `claude-code`) hosting a native-isolated adapter receives a native mission
|
|
94
|
+
* lens; every other combination fails closed here. This is the exact FR2/FR4
|
|
95
|
+
* reconciliation the spec calls out, recorded in the returned `reconciliation`
|
|
96
|
+
* so it appears in the dispatch provenance.
|
|
97
|
+
*/
|
|
98
|
+
export function resolveOperatingDispatchMode(input) {
|
|
99
|
+
const mode = input.override ?? input.registryDefault;
|
|
100
|
+
if (mode === 'pack') {
|
|
101
|
+
return {
|
|
102
|
+
roleId: input.roleId,
|
|
103
|
+
mode,
|
|
104
|
+
isolation: 'enforced-empty-tools',
|
|
105
|
+
native: false,
|
|
106
|
+
reconciliation: input.override === 'pack'
|
|
107
|
+
? 'dispatchModeOverrides rolled this role back to the v1.2 empty-tool pack path'
|
|
108
|
+
: 'registry default selects the v1.2 empty-tool pack path',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (input.runtimeEnforcesBoundedReadOnly && input.adapterNativeCapable) {
|
|
112
|
+
return {
|
|
113
|
+
roleId: input.roleId,
|
|
114
|
+
mode,
|
|
115
|
+
isolation: 'enforced-read-only-bounded',
|
|
116
|
+
native: true,
|
|
117
|
+
reconciliation: 'runtime natively enforces tool isolation; a bounded read-only mission lens is dispatched',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
roleId: input.roleId,
|
|
122
|
+
mode,
|
|
123
|
+
isolation: 'fail-closed-structured-provider',
|
|
124
|
+
native: false,
|
|
125
|
+
reconciliation: input.runtimeEnforcesBoundedReadOnly
|
|
126
|
+
? 'adapter cannot host a bounded native lens; falling back to the structured provider path'
|
|
127
|
+
: 'runtime tool isolation is advisory or unverifiable (FR2 fail-closed overrides FR4); routing to the structured provider path',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Sensitivity-ceiling root narrowing (FR2)
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
/**
|
|
134
|
+
* The top-level path segment a declared read root is derived from. Mission roots
|
|
135
|
+
* are single top-level directory segments (see `deriveOperatingDeclaredRoots`).
|
|
136
|
+
*/
|
|
137
|
+
function topSegment(relativePath) {
|
|
138
|
+
const [top] = relativePath.split('/');
|
|
139
|
+
return top && top.length > 0 ? top : null;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Narrow a role's declared read roots by DENY-LISTING any root that contains an
|
|
143
|
+
* evidence item above the role's sensitivity ceiling, so no above-ceiling file
|
|
144
|
+
* is readable even inside a granted root. Pass the FULL (pre-ceiling-filter)
|
|
145
|
+
* evidence index: the narrowing needs to see the above-ceiling items the packet
|
|
146
|
+
* index itself excludes. Combined with the read-time ceiling check on the
|
|
147
|
+
* bounded reader, this is the belt-and-suspenders that preserves the pack-era
|
|
148
|
+
* filter-before-handoff guarantee under agent-driven reads.
|
|
149
|
+
*/
|
|
150
|
+
export function narrowMissionRootsToCeiling(input) {
|
|
151
|
+
const denied = new Set();
|
|
152
|
+
for (const item of input.evidenceIndex) {
|
|
153
|
+
if (!item.path)
|
|
154
|
+
continue;
|
|
155
|
+
if (compareSensitivity(item.sensitivity, input.ceiling) <= 0)
|
|
156
|
+
continue;
|
|
157
|
+
const top = topSegment(item.path);
|
|
158
|
+
if (top)
|
|
159
|
+
denied.add(top);
|
|
160
|
+
}
|
|
161
|
+
return input.declaredRoots.filter((root) => !denied.has(root)).sort();
|
|
162
|
+
}
|
|
163
|
+
const MAX_MISSION_READ_BYTES = 256 * 1024;
|
|
164
|
+
const MAX_MISSION_WALK_ENTRIES = 5_000;
|
|
165
|
+
function refuseCapability(tool) {
|
|
166
|
+
throw new OperateError('E_OPERATE_PROVIDER_READ_ONLY', `Mission tool "${tool}" is not in the bounded read-only grant; write, execute, ` +
|
|
167
|
+
'network, and environment access are refused.', { tool, allowed: [...MISSION_READ_ONLY_TOOLS] });
|
|
168
|
+
}
|
|
169
|
+
function resolvedRoots(boundary) {
|
|
170
|
+
return boundary.roots.map((root) => path.resolve(root));
|
|
171
|
+
}
|
|
172
|
+
function isContained(roots, absolute) {
|
|
173
|
+
return roots.some((root) => absolute === root || absolute.startsWith(`${root}${path.sep}`));
|
|
174
|
+
}
|
|
175
|
+
function resolveWithinRoots(boundary, requestPath) {
|
|
176
|
+
if (typeof requestPath !== 'string' || requestPath.length === 0) {
|
|
177
|
+
throw new OperateError('E_OPERATE_PATH_ESCAPE', 'Mission read requires a non-empty path.');
|
|
178
|
+
}
|
|
179
|
+
const roots = resolvedRoots(boundary);
|
|
180
|
+
const candidates = path.isAbsolute(requestPath)
|
|
181
|
+
? [path.resolve(requestPath)]
|
|
182
|
+
: roots.map((root) => path.resolve(root, requestPath));
|
|
183
|
+
for (const candidate of candidates) {
|
|
184
|
+
if (isContained(roots, candidate))
|
|
185
|
+
return candidate;
|
|
186
|
+
}
|
|
187
|
+
throw new OperateError('E_OPERATE_PATH_ESCAPE', `Mission read target "${requestPath}" resolves outside the declared read roots.`, { roots: [...boundary.roots] });
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Defeat symlink escapes: after path-based containment, resolve the real target
|
|
191
|
+
* and re-check it against the real roots. Both sides are realpath-resolved so a
|
|
192
|
+
* platform-level symlink on the temp namespace (e.g. macOS `/var`→`/private/var`)
|
|
193
|
+
* does not produce a false escape.
|
|
194
|
+
*/
|
|
195
|
+
async function assertNoSymlinkEscape(boundary, absolute) {
|
|
196
|
+
let real;
|
|
197
|
+
try {
|
|
198
|
+
real = await realpath(absolute);
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Target does not exist yet; the caller's read/stat surfaces the real error.
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const realRoots = await Promise.all(resolvedRoots(boundary).map((root) => realpath(root).catch(() => root)));
|
|
205
|
+
if (!isContained(realRoots, real)) {
|
|
206
|
+
throw new OperateError('E_OPERATE_PATH_ESCAPE', `Mission read target "${absolute}" escapes the declared read roots through a symlink.`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function classify(boundary, absolute) {
|
|
210
|
+
return (boundary.sensitivityByPath?.get(absolute) ?? boundary.defaultSensitivity ?? boundary.ceiling);
|
|
211
|
+
}
|
|
212
|
+
function assertBelowCeiling(boundary, absolute) {
|
|
213
|
+
const sensitivity = classify(boundary, absolute);
|
|
214
|
+
if (compareSensitivity(sensitivity, boundary.ceiling) > 0) {
|
|
215
|
+
throw new OperateError('E_OPERATE_EVIDENCE_REJECTED', `Mission read of "${absolute}" is ${sensitivity}, above the ${boundary.ceiling} ceiling.`, { sensitivity, ceiling: boundary.ceiling });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function readBoundedFile(boundary, requestPath) {
|
|
219
|
+
const absolute = resolveWithinRoots(boundary, requestPath);
|
|
220
|
+
await assertNoSymlinkEscape(boundary, absolute);
|
|
221
|
+
assertBelowCeiling(boundary, absolute);
|
|
222
|
+
const info = await stat(absolute);
|
|
223
|
+
if (!info.isFile()) {
|
|
224
|
+
throw new OperateError('E_OPERATE_EVIDENCE_REJECTED', `Mission read target "${absolute}" is not a file.`);
|
|
225
|
+
}
|
|
226
|
+
if (info.size > MAX_MISSION_READ_BYTES) {
|
|
227
|
+
throw new OperateError('E_OPERATE_EVIDENCE_REJECTED', `Mission read target "${absolute}" exceeds the ${MAX_MISSION_READ_BYTES}-byte read bound.`);
|
|
228
|
+
}
|
|
229
|
+
return readFile(absolute, 'utf8');
|
|
230
|
+
}
|
|
231
|
+
async function* walkRoot(root) {
|
|
232
|
+
let visited = 0;
|
|
233
|
+
const stack = [root];
|
|
234
|
+
while (stack.length > 0) {
|
|
235
|
+
const current = stack.pop();
|
|
236
|
+
const entries = await readdir(current, { withFileTypes: true }).catch(() => null);
|
|
237
|
+
if (!entries)
|
|
238
|
+
continue;
|
|
239
|
+
for (const entry of entries) {
|
|
240
|
+
if (entry.name === '.git' || entry.name === 'node_modules')
|
|
241
|
+
continue;
|
|
242
|
+
const child = path.join(current, entry.name);
|
|
243
|
+
if (entry.isDirectory()) {
|
|
244
|
+
stack.push(child);
|
|
245
|
+
}
|
|
246
|
+
else if (entry.isFile()) {
|
|
247
|
+
visited += 1;
|
|
248
|
+
if (visited > MAX_MISSION_WALK_ENTRIES)
|
|
249
|
+
return;
|
|
250
|
+
yield child;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Render a filesystem path with forward-slash separators so a glob pattern —
|
|
257
|
+
* always authored with `/` — matches identically on every platform. `path.join`
|
|
258
|
+
* yields `\` separators on Windows, which the pattern's `/` can never match, so
|
|
259
|
+
* a recursive `.ts` glob would otherwise return nothing on Windows. Normalizing
|
|
260
|
+
* only the candidate fed to the matcher (never the stored/returned path) keeps
|
|
261
|
+
* the emitted matches in native form for the caller's own containment checks. On
|
|
262
|
+
* POSIX `path.sep` is `/`, so this is a no-op.
|
|
263
|
+
*/
|
|
264
|
+
function toGlobMatchPath(target) {
|
|
265
|
+
return target.split(path.sep).join('/');
|
|
266
|
+
}
|
|
267
|
+
function simplePatternToRegExp(pattern) {
|
|
268
|
+
let out = '';
|
|
269
|
+
let index = 0;
|
|
270
|
+
while (index < pattern.length) {
|
|
271
|
+
const char = pattern[index];
|
|
272
|
+
if (char === '*') {
|
|
273
|
+
if (pattern[index + 1] === '*') {
|
|
274
|
+
out += '.*';
|
|
275
|
+
index += 2;
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
out += '[^/]*';
|
|
279
|
+
index += 1;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
out += char.replace(/[.+^${}()|[\]\\]/g, '\\$&');
|
|
284
|
+
index += 1;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return new RegExp(`${out}$`);
|
|
288
|
+
}
|
|
289
|
+
async function globWithinRoots(boundary, pattern, root) {
|
|
290
|
+
const roots = root ? [resolveWithinRoots(boundary, root)] : resolvedRoots(boundary);
|
|
291
|
+
const matcher = simplePatternToRegExp(pattern || '**/*');
|
|
292
|
+
const matches = [];
|
|
293
|
+
for (const searchRoot of roots) {
|
|
294
|
+
for await (const file of walkRoot(searchRoot)) {
|
|
295
|
+
if (!matcher.test(toGlobMatchPath(file)))
|
|
296
|
+
continue;
|
|
297
|
+
try {
|
|
298
|
+
assertBelowCeiling(boundary, file);
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
matches.push(file);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return [...new Set(matches)].sort();
|
|
307
|
+
}
|
|
308
|
+
async function contentSearchWithinRoots(boundary, query, root) {
|
|
309
|
+
if (typeof query !== 'string' || query.length === 0) {
|
|
310
|
+
throw new OperateError('E_OPERATE_EVIDENCE_REJECTED', 'Mission content-search requires a query.');
|
|
311
|
+
}
|
|
312
|
+
const roots = root ? [resolveWithinRoots(boundary, root)] : resolvedRoots(boundary);
|
|
313
|
+
const hits = [];
|
|
314
|
+
for (const searchRoot of roots) {
|
|
315
|
+
for await (const file of walkRoot(searchRoot)) {
|
|
316
|
+
try {
|
|
317
|
+
assertBelowCeiling(boundary, file);
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
const info = await stat(file).catch(() => null);
|
|
323
|
+
if (!info?.isFile() || info.size > MAX_MISSION_READ_BYTES)
|
|
324
|
+
continue;
|
|
325
|
+
const content = await readFile(file, 'utf8').catch(() => null);
|
|
326
|
+
if (content === null)
|
|
327
|
+
continue;
|
|
328
|
+
content.split(/\r?\n/).forEach((text, index) => {
|
|
329
|
+
if (text.includes(query))
|
|
330
|
+
hits.push({ path: file, line: index + 1, text: text.slice(0, 512) });
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return hits;
|
|
335
|
+
}
|
|
336
|
+
function assertGitArgsBounded(args) {
|
|
337
|
+
for (const argument of args) {
|
|
338
|
+
if (typeof argument !== 'string') {
|
|
339
|
+
throw new OperateError('E_OPERATE_PROVIDER_READ_ONLY', 'Mission git arguments must be strings.');
|
|
340
|
+
}
|
|
341
|
+
if (argument.startsWith('--output') || argument === '-o' || argument.includes('../..')) {
|
|
342
|
+
throw new OperateError('E_OPERATE_PROVIDER_READ_ONLY', 'Mission git arguments cannot redirect output.');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
async function runBoundedGit(boundary, subcommand, request) {
|
|
347
|
+
const repositoryRoot = boundary.repositoryRoot
|
|
348
|
+
? path.resolve(boundary.repositoryRoot)
|
|
349
|
+
: resolvedRoots(boundary)[0];
|
|
350
|
+
if (!repositoryRoot) {
|
|
351
|
+
throw new OperateError('E_OPERATE_PROVIDER_READ_ONLY', 'Mission git tools require a repository root.');
|
|
352
|
+
}
|
|
353
|
+
const extra = request.args ?? [];
|
|
354
|
+
assertGitArgsBounded(extra);
|
|
355
|
+
const args = [subcommand, ...extra];
|
|
356
|
+
if (request.path) {
|
|
357
|
+
// Any path argument stays confined to the declared roots.
|
|
358
|
+
const confined = resolveWithinRoots(boundary, request.path);
|
|
359
|
+
args.push('--', path.relative(repositoryRoot, confined) || '.');
|
|
360
|
+
}
|
|
361
|
+
// `executeGitReadOnly` re-asserts the read-only git allowlist (no mutation,
|
|
362
|
+
// no repository/config overrides) as a second, independent gate.
|
|
363
|
+
return executeGitReadOnly(repositoryRoot, args);
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* The single audited entry point for a mission lens's tool use. Every request is
|
|
367
|
+
* checked against the bounded read-only grant BEFORE any filesystem or git
|
|
368
|
+
* access: a tool outside the grant (write, execute, network, environment, or any
|
|
369
|
+
* unknown surface) is refused, a target outside the declared roots is refused as
|
|
370
|
+
* a path escape, and a target above the sensitivity ceiling is refused at read
|
|
371
|
+
* time. There is deliberately no write/execute/network/environment tool to
|
|
372
|
+
* invoke — those channels do not exist on this surface at all.
|
|
373
|
+
*/
|
|
374
|
+
export async function invokeMissionTool(boundary, request) {
|
|
375
|
+
const tool = String(request.tool ?? '');
|
|
376
|
+
if (!isReadOnlyTool(tool))
|
|
377
|
+
refuseCapability(tool);
|
|
378
|
+
switch (tool) {
|
|
379
|
+
case 'file-read': {
|
|
380
|
+
const requestPath = String(request.path ?? '');
|
|
381
|
+
return {
|
|
382
|
+
tool: 'file-read',
|
|
383
|
+
path: requestPath,
|
|
384
|
+
content: await readBoundedFile(boundary, requestPath),
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
case 'glob': {
|
|
388
|
+
const pattern = request.pattern ?? '**/*';
|
|
389
|
+
const root = request.root;
|
|
390
|
+
return { tool: 'glob', matches: await globWithinRoots(boundary, pattern, root) };
|
|
391
|
+
}
|
|
392
|
+
case 'content-search': {
|
|
393
|
+
const query = String(request.query ?? '');
|
|
394
|
+
const root = request.root;
|
|
395
|
+
return {
|
|
396
|
+
tool: 'content-search',
|
|
397
|
+
matches: await contentSearchWithinRoots(boundary, query, root),
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
case 'git-log':
|
|
401
|
+
case 'git-show':
|
|
402
|
+
case 'git-diff':
|
|
403
|
+
case 'git-blame': {
|
|
404
|
+
const subcommand = tool.slice('git-'.length);
|
|
405
|
+
const typed = request;
|
|
406
|
+
return { tool, output: await runBoundedGit(boundary, subcommand, typed) };
|
|
407
|
+
}
|
|
408
|
+
default:
|
|
409
|
+
return refuseCapability(tool);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* The concrete callable tool surface handed to an in-process native harness:
|
|
414
|
+
* exactly the read-only tools, each bound to this boundary. There is no write,
|
|
415
|
+
* execute, network, or environment callable on the returned object, so a harness
|
|
416
|
+
* that walks it can never reach a mutating or escaping capability.
|
|
417
|
+
*/
|
|
418
|
+
export function createMissionToolset(boundary) {
|
|
419
|
+
const toolset = {};
|
|
420
|
+
for (const tool of MISSION_READ_ONLY_TOOLS) {
|
|
421
|
+
toolset[tool] = (request) => invokeMissionTool(boundary, { ...request, tool });
|
|
422
|
+
}
|
|
423
|
+
return toolset;
|
|
424
|
+
}
|
|
425
|
+
// ---------------------------------------------------------------------------
|
|
426
|
+
// Fan-out orchestration (FR2 parallel/sequential, FR4 determinism)
|
|
427
|
+
// ---------------------------------------------------------------------------
|
|
428
|
+
/**
|
|
429
|
+
* Fan a per-item dispatch out in parallel where the adapter reports
|
|
430
|
+
* `parallelDispatch: true`, sequentially otherwise. Results are always returned
|
|
431
|
+
* in the SAME order as `items`, so the caller can restore registry order and the
|
|
432
|
+
* reduced events are byte-identical across parallel and sequential dispatch.
|
|
433
|
+
*/
|
|
434
|
+
export async function runMissionDispatchFanOut(input) {
|
|
435
|
+
if (input.parallel) {
|
|
436
|
+
return Promise.all(input.items.map((item) => input.run(item)));
|
|
437
|
+
}
|
|
438
|
+
const results = [];
|
|
439
|
+
for (const item of input.items) {
|
|
440
|
+
results.push(await input.run(item));
|
|
441
|
+
}
|
|
442
|
+
return results;
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=mission-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mission-dispatch.js","sourceRoot":"","sources":["../../../src/services/operate/mission-dispatch.ts"],"names":[],"mappings":"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"}
|