@probelabs/probe 0.6.0-rc331 → 0.6.0-rc332
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/bin/binaries/{probe-v0.6.0-rc331-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc332-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc331-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc332-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc331-x86_64-apple-darwin.tar.gz → probe-v0.6.0-rc332-x86_64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc331-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc332-x86_64-pc-windows-msvc.zip} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc331-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc332-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.d.ts +105 -4
- package/build/agent/ProbeAgent.js +209 -12
- package/build/agent/bashExecutor.js +36 -101
- package/build/agent/engines/codex.js +367 -88
- package/build/agent/engines/governed-answer-failure.js +152 -0
- package/build/agent/engines/governed-codex-profile.js +198 -0
- package/build/agent/governance/acknowledgedJsonlChannel.js +328 -0
- package/build/agent/governance/atomicTerminalReceipt.js +188 -0
- package/build/agent/governance/index.d.ts +130 -0
- package/build/agent/governance/index.js +8 -0
- package/build/agent/mcp/built-in-server.js +152 -53
- package/build/agent/mcp/index.d.ts +65 -0
- package/build/agent/mcp/index.js +6 -1
- package/build/agent/probeTool.js +1 -1
- package/build/agent/processSupervisor.js +351 -0
- package/build/agent/tools.js +14 -8
- package/build/index.js +2 -0
- package/cjs/agent/ProbeAgent.cjs +13238 -11968
- package/cjs/index.cjs +75955 -74126
- package/index.d.ts +149 -4
- package/package.json +6 -2
- package/src/agent/ProbeAgent.d.ts +105 -4
- package/src/agent/ProbeAgent.js +209 -12
- package/src/agent/bashExecutor.js +36 -101
- package/src/agent/engines/codex.js +367 -88
- package/src/agent/engines/governed-answer-failure.js +152 -0
- package/src/agent/engines/governed-codex-profile.js +198 -0
- package/src/agent/governance/acknowledgedJsonlChannel.js +328 -0
- package/src/agent/governance/atomicTerminalReceipt.js +188 -0
- package/src/agent/governance/index.d.ts +130 -0
- package/src/agent/governance/index.js +8 -0
- package/src/agent/mcp/built-in-server.js +152 -53
- package/src/agent/mcp/index.d.ts +65 -0
- package/src/agent/mcp/index.js +6 -1
- package/src/agent/probeTool.js +1 -1
- package/src/agent/processSupervisor.js +351 -0
- package/src/agent/tools.js +14 -8
- package/src/index.js +2 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const GOVERNED_ANSWER_FAILURE_STAGES = new Set([
|
|
2
|
+
'native_event_grammar', 'provider_engine', 'schema_result_validation', 'unknown',
|
|
3
|
+
]);
|
|
4
|
+
const GOVERNED_NATIVE_EVENT_FAILURE_BOUNDARIES = new Set([
|
|
5
|
+
'raw_item_predicate', 'live_envelope_session',
|
|
6
|
+
]);
|
|
7
|
+
const GOVERNED_NATIVE_EVENT_FAILURE_SUBREASONS = new Set([
|
|
8
|
+
'session_sequence', 'envelope_shape', 'correlation', 'attestation',
|
|
9
|
+
]);
|
|
10
|
+
const GOVERNED_NATIVE_EVENT_FAILURE_CORRELATION_OPERANDS = new Set([
|
|
11
|
+
'thread_id', 'response_id',
|
|
12
|
+
]);
|
|
13
|
+
const GOVERNED_NATIVE_EVENT_FAILURE_ATTESTATION_PREDICATES = new Set([
|
|
14
|
+
'event_shape', 'jsonrpc', 'params_shape', 'response_id', 'meta_shape', 'session_shape',
|
|
15
|
+
'session_identity', 'model', 'model_provider', 'approval_policy', 'approvals_reviewer',
|
|
16
|
+
'reasoning_effort', 'rollout_path', 'cwd', 'permission_shape', 'session_type', 'permission_type',
|
|
17
|
+
'network',
|
|
18
|
+
'filesystem_shape', 'filesystem_type', 'entries', 'entry', 'access', 'path_shape',
|
|
19
|
+
'path_type', 'value_shape', 'kind', 'native_tool_evidence', 'internal_contract',
|
|
20
|
+
]);
|
|
21
|
+
const GOVERNED_SCHEMA_RESULT_VALIDATION_SUBREASONS = new Set([
|
|
22
|
+
'response_json', 'schema_definition', 'schema_mismatch', 'result_identity',
|
|
23
|
+
]);
|
|
24
|
+
const GOVERNED_SCHEMA_RESULT_VALIDATION_KEYWORDS = new Set([
|
|
25
|
+
'required', 'additionalProperties', 'type', 'pattern', 'enum', 'minItems', 'maxItems',
|
|
26
|
+
'multiple', 'unknown',
|
|
27
|
+
]);
|
|
28
|
+
const GOVERNED_ATTESTATION_ERROR_PREDICATES = new Map([
|
|
29
|
+
['Invalid event', 'event_shape'], ['Invalid event.method', 'event_shape'],
|
|
30
|
+
['Invalid event.jsonrpc', 'jsonrpc'], ['Invalid event.params', 'params_shape'],
|
|
31
|
+
['Invalid event.params.id', 'response_id'], ['Invalid event._meta', 'meta_shape'],
|
|
32
|
+
['Invalid requestId', 'meta_shape'], ['Invalid event.msg', 'session_shape'],
|
|
33
|
+
['Invalid session identity', 'session_identity'], ['Invalid msg.model', 'model'],
|
|
34
|
+
['Invalid msg.model_provider_id', 'model_provider'], ['Invalid msg.approval_policy', 'approval_policy'],
|
|
35
|
+
['Invalid msg.approvals_reviewer', 'approvals_reviewer'],
|
|
36
|
+
['Invalid msg.reasoning_effort', 'reasoning_effort'], ['Invalid rollout_path', 'rollout_path'],
|
|
37
|
+
['Invalid msg.cwd', 'cwd'], ['Invalid cwd', 'cwd'],
|
|
38
|
+
['Invalid permission_profile', 'permission_shape'], ['Invalid permission_profile.type', 'permission_type'],
|
|
39
|
+
['Invalid permission_profile.network', 'network'], ['Invalid file_system', 'filesystem_shape'],
|
|
40
|
+
['Invalid file_system.type', 'filesystem_type'], ['Invalid file_system.entries', 'entries'],
|
|
41
|
+
['Invalid file_system entry', 'entry'], ['Invalid file_system entry access', 'access'],
|
|
42
|
+
['Invalid permission path', 'path_shape'], ['Invalid permission path type', 'path_type'],
|
|
43
|
+
['Invalid permission path value', 'value_shape'], ['Invalid permission path kind', 'kind'],
|
|
44
|
+
['Invalid msg.type', 'session_type'],
|
|
45
|
+
['Invalid native tool evidence', 'native_tool_evidence'],
|
|
46
|
+
['Invalid native tool total', 'native_tool_evidence'],
|
|
47
|
+
['Invalid native tool aggregates', 'native_tool_evidence'],
|
|
48
|
+
['Invalid native tool aggregate', 'native_tool_evidence'],
|
|
49
|
+
['Invalid undeclared native tool evidence', 'native_tool_evidence'],
|
|
50
|
+
['Invalid native tool status', 'native_tool_evidence'],
|
|
51
|
+
['Invalid native tool count', 'native_tool_evidence'],
|
|
52
|
+
['Invalid attester input', 'internal_contract'], ['Invalid events', 'internal_contract'],
|
|
53
|
+
['Invalid canonical JSON value', 'internal_contract'], ['Invalid profile', 'internal_contract'],
|
|
54
|
+
['Invalid profile.version', 'internal_contract'], ['Invalid profile.profileId', 'internal_contract'],
|
|
55
|
+
['Invalid profile.engine', 'internal_contract'], ['Invalid profile.model', 'internal_contract'],
|
|
56
|
+
['Invalid profile.reasoningEffort', 'internal_contract'], ['Invalid profile.sandbox', 'internal_contract'],
|
|
57
|
+
['Invalid profile.approvalPolicy', 'internal_contract'], ['Invalid profile.fallback', 'internal_contract'],
|
|
58
|
+
['Invalid profile.retries', 'internal_contract'], ['Invalid profile.probeTools', 'internal_contract'],
|
|
59
|
+
['Invalid profile.probeTools[0]', 'internal_contract'], ['Invalid profile.probeTools[1]', 'internal_contract'],
|
|
60
|
+
['Invalid profile.probeTools[2]', 'internal_contract'], ['Invalid profile.probeMcpTools', 'internal_contract'],
|
|
61
|
+
['Invalid profile.probeMcpTools[0]', 'internal_contract'],
|
|
62
|
+
['Invalid profile.probeMcpTools[1]', 'internal_contract'],
|
|
63
|
+
['Invalid profile.probeMcpTools[2]', 'internal_contract'],
|
|
64
|
+
['Invalid profile.codexNativeTools', 'internal_contract'],
|
|
65
|
+
['Invalid profile.codexNativeTools[0]', 'internal_contract'],
|
|
66
|
+
['Invalid profile capability overlap', 'internal_contract'],
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
function governedAttestationPredicate(error) {
|
|
70
|
+
return error instanceof TypeError ? GOVERNED_ATTESTATION_ERROR_PREDICATES.get(error.message) ?? null : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export class GovernedAnswerFailure extends Error {
|
|
74
|
+
constructor(stage, nativeEventFailureBoundary = null, nativeEventFailureSubreason = null,
|
|
75
|
+
nativeEventFailureCorrelationOperand = null, nativeEventFailureAttestationPredicate = null,
|
|
76
|
+
schemaResultValidationSubreason = null, schemaResultValidationKeyword = null) {
|
|
77
|
+
super();
|
|
78
|
+
delete this.stack;
|
|
79
|
+
const answerFailureStage = GOVERNED_ANSWER_FAILURE_STAGES.has(stage) ? stage : 'unknown';
|
|
80
|
+
Object.defineProperty(this, 'name', { value: 'GovernedAnswerFailure' });
|
|
81
|
+
Object.defineProperty(this, 'answerFailureStage', {
|
|
82
|
+
value: answerFailureStage,
|
|
83
|
+
enumerable: true,
|
|
84
|
+
});
|
|
85
|
+
if (answerFailureStage === 'native_event_grammar') Object.defineProperty(this, 'nativeEventFailureBoundary', {
|
|
86
|
+
value: GOVERNED_NATIVE_EVENT_FAILURE_BOUNDARIES.has(nativeEventFailureBoundary)
|
|
87
|
+
? nativeEventFailureBoundary : null,
|
|
88
|
+
enumerable: true,
|
|
89
|
+
});
|
|
90
|
+
if (answerFailureStage === 'native_event_grammar' &&
|
|
91
|
+
nativeEventFailureBoundary === 'live_envelope_session') {
|
|
92
|
+
Object.defineProperty(this, 'nativeEventFailureSubreason', {
|
|
93
|
+
value: GOVERNED_NATIVE_EVENT_FAILURE_SUBREASONS.has(nativeEventFailureSubreason)
|
|
94
|
+
? nativeEventFailureSubreason : null,
|
|
95
|
+
enumerable: true,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (answerFailureStage === 'native_event_grammar' &&
|
|
99
|
+
nativeEventFailureBoundary === 'live_envelope_session' &&
|
|
100
|
+
nativeEventFailureSubreason === 'correlation') {
|
|
101
|
+
Object.defineProperty(this, 'nativeEventFailureCorrelationOperand', {
|
|
102
|
+
value: GOVERNED_NATIVE_EVENT_FAILURE_CORRELATION_OPERANDS.has(nativeEventFailureCorrelationOperand)
|
|
103
|
+
? nativeEventFailureCorrelationOperand : null,
|
|
104
|
+
enumerable: true,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (answerFailureStage === 'native_event_grammar' &&
|
|
108
|
+
nativeEventFailureBoundary === 'live_envelope_session' &&
|
|
109
|
+
nativeEventFailureSubreason === 'attestation') {
|
|
110
|
+
Object.defineProperty(this, 'nativeEventFailureAttestationPredicate', {
|
|
111
|
+
value: GOVERNED_NATIVE_EVENT_FAILURE_ATTESTATION_PREDICATES.has(nativeEventFailureAttestationPredicate)
|
|
112
|
+
? nativeEventFailureAttestationPredicate : null,
|
|
113
|
+
enumerable: true,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (answerFailureStage === 'schema_result_validation') {
|
|
117
|
+
const sanitizedSubreason = GOVERNED_SCHEMA_RESULT_VALIDATION_SUBREASONS.has(schemaResultValidationSubreason)
|
|
118
|
+
? schemaResultValidationSubreason : null;
|
|
119
|
+
Object.defineProperty(this, 'schemaResultValidationSubreason', {
|
|
120
|
+
value: sanitizedSubreason,
|
|
121
|
+
enumerable: true,
|
|
122
|
+
});
|
|
123
|
+
Object.defineProperty(this, 'schemaResultValidationKeyword', {
|
|
124
|
+
value: sanitizedSubreason === 'schema_mismatch'
|
|
125
|
+
? GOVERNED_SCHEMA_RESULT_VALIDATION_KEYWORDS.has(schemaResultValidationKeyword)
|
|
126
|
+
? schemaResultValidationKeyword : 'unknown'
|
|
127
|
+
: null,
|
|
128
|
+
enumerable: true,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
Object.freeze(this);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function governedAnswerFailure(stage, nativeEventFailureBoundary = null, nativeEventFailureSubreason = null,
|
|
136
|
+
nativeEventFailureCorrelationOperand = null, nativeEventFailureAttestationPredicate = null,
|
|
137
|
+
schemaResultValidationSubreason = null, schemaResultValidationKeyword = null) {
|
|
138
|
+
return new GovernedAnswerFailure(stage, nativeEventFailureBoundary, nativeEventFailureSubreason,
|
|
139
|
+
nativeEventFailureCorrelationOperand, nativeEventFailureAttestationPredicate,
|
|
140
|
+
schemaResultValidationSubreason, schemaResultValidationKeyword);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function normalizeGovernedAnswerFailure(error, fallback = 'unknown', nativeEventFailureBoundary = null,
|
|
144
|
+
nativeEventFailureSubreason = null, nativeEventFailureCorrelationOperand = null,
|
|
145
|
+
schemaResultValidationSubreason = null, schemaResultValidationKeyword = null) {
|
|
146
|
+
return error instanceof GovernedAnswerFailure ? error
|
|
147
|
+
: governedAnswerFailure(fallback, nativeEventFailureBoundary, nativeEventFailureSubreason,
|
|
148
|
+
nativeEventFailureCorrelationOperand,
|
|
149
|
+
fallback === 'native_event_grammar' && nativeEventFailureBoundary === 'live_envelope_session' &&
|
|
150
|
+
nativeEventFailureSubreason === 'attestation' ? governedAttestationPredicate(error) : null,
|
|
151
|
+
schemaResultValidationSubreason, schemaResultValidationKeyword);
|
|
152
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { realpathSync, statSync } from 'node:fs';
|
|
3
|
+
import { isAbsolute, normalize } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const PROFILE_KEYS = ['version', 'profileId', 'engine', 'model', 'reasoningEffort', 'sandbox', 'approvalPolicy', 'cwd', 'probeTools', 'fallback', 'retries'];
|
|
6
|
+
const PROFILE_V2_KEYS = ['version', 'profileId', 'engine', 'model', 'reasoningEffort', 'sandbox', 'approvalPolicy', 'cwd', 'probeMcpTools', 'codexNativeTools', 'fallback', 'retries'];
|
|
7
|
+
const PROFILE_VALUES = {
|
|
8
|
+
version: 'probe.governed-codex-profile/v1', profileId: 'luna-xhigh-readonly-v1', engine: 'codex',
|
|
9
|
+
model: 'gpt-5.6-luna', reasoningEffort: 'xhigh', sandbox: 'read-only', approvalPolicy: 'never',
|
|
10
|
+
fallback: false, retries: 0,
|
|
11
|
+
};
|
|
12
|
+
const PROFILE_V2_VALUES = { ...PROFILE_VALUES, version: 'probe.governed-codex-profile/v2', profileId: 'luna-xhigh-readonly-native-exec-v1' };
|
|
13
|
+
// This profile admits the pinned Codex `exec` capability inside the attested read-only sandbox.
|
|
14
|
+
// It does not claim that commands supplied to `exec` are semantically safe.
|
|
15
|
+
const PROBE_TOOLS = ['search', 'extract', 'listFiles'];
|
|
16
|
+
const CODEX_NATIVE_TOOLS = ['exec'];
|
|
17
|
+
const ENABLED_TOOLS = ['mcp__probe__search', 'mcp__probe__extract', 'mcp__probe__listFiles'];
|
|
18
|
+
const SESSION_MSG_KEYS = ['type', 'session_id', 'thread_id', 'model', 'model_provider_id', 'approval_policy',
|
|
19
|
+
'approvals_reviewer', 'permission_profile', 'reasoning_effort', 'rollout_path', 'cwd'];
|
|
20
|
+
const SESSION_SERVICE_TIERS = ['default', 'priority', 'flex'];
|
|
21
|
+
const FEATURE_NAMES = [
|
|
22
|
+
'shell_tool', 'multi_agent', 'multi_agent_v2', 'enable_fanout', 'apps', 'enable_mcp_apps',
|
|
23
|
+
'tool_suggest', 'plugins', 'in_app_browser', 'browser_use', 'browser_use_full_cdp_access',
|
|
24
|
+
'browser_use_external', 'computer_use', 'remote_plugin', 'plugin_sharing', 'image_generation',
|
|
25
|
+
'skill_mcp_dependency_install', 'hooks', 'request_permissions_tool', 'standalone_web_search',
|
|
26
|
+
];
|
|
27
|
+
const SAFE_ID = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
28
|
+
const ROLLOUT = /\/sessions\/(\d{4})\/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/rollout-(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])T([01]\d|2[0-3])-([0-5]\d)-([0-5]\d)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.jsonl$/;
|
|
29
|
+
|
|
30
|
+
function invalid(label) { throw new TypeError(`Invalid ${label}`); }
|
|
31
|
+
function enumerableKeys(value) {
|
|
32
|
+
return Reflect.ownKeys(value).filter((key) => Object.prototype.propertyIsEnumerable.call(value, key));
|
|
33
|
+
}
|
|
34
|
+
function exactObject(value, keys, label) {
|
|
35
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) invalid(label);
|
|
36
|
+
const proto = Object.getPrototypeOf(value);
|
|
37
|
+
if (proto !== Object.prototype && proto !== null) invalid(label);
|
|
38
|
+
const actual = enumerableKeys(value);
|
|
39
|
+
if (actual.some((key) => typeof key !== 'string') || actual.length !== keys.length || keys.some((key) => !actual.includes(key))) invalid(label);
|
|
40
|
+
for (const key of keys) if (!Object.prototype.hasOwnProperty.call(Object.getOwnPropertyDescriptor(value, key), 'value')) invalid(label);
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function exactArray(value, length, label) {
|
|
44
|
+
if (!Array.isArray(value) || value.length !== length) invalid(label);
|
|
45
|
+
const keys = enumerableKeys(value);
|
|
46
|
+
if (keys.length !== length || keys.some((key, index) => key !== String(index))) invalid(label);
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
function deepFreeze(value) {
|
|
50
|
+
if (value && typeof value === 'object' && !Object.isFrozen(value)) {
|
|
51
|
+
for (const key of Reflect.ownKeys(value)) deepFreeze(value[key]);
|
|
52
|
+
Object.freeze(value);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
}
|
|
56
|
+
function canonicalJson(value) {
|
|
57
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean') return JSON.stringify(value);
|
|
58
|
+
if (typeof value === 'number' && Number.isFinite(value)) return JSON.stringify(value);
|
|
59
|
+
if (Array.isArray(value)) return `[${value.map(canonicalJson).join(',')}]`;
|
|
60
|
+
if (value && typeof value === 'object') {
|
|
61
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(',')}}`;
|
|
62
|
+
}
|
|
63
|
+
invalid('canonical JSON value');
|
|
64
|
+
}
|
|
65
|
+
function digest(value) { return createHash('sha256').update(canonicalJson(value), 'utf8').digest('hex'); }
|
|
66
|
+
function canonicalCwd(value) {
|
|
67
|
+
if (typeof value !== 'string' || !isAbsolute(value) || value.includes('\0')) invalid('cwd');
|
|
68
|
+
try {
|
|
69
|
+
const resolved = realpathSync(value);
|
|
70
|
+
if (!statSync(resolved).isDirectory()) invalid('cwd');
|
|
71
|
+
return resolved;
|
|
72
|
+
} catch { invalid('cwd'); }
|
|
73
|
+
}
|
|
74
|
+
function requireValue(actual, expected, label) { if (!Object.is(actual, expected)) invalid(label); }
|
|
75
|
+
|
|
76
|
+
export function validateGovernedCodexProfile(input) {
|
|
77
|
+
const version = input && Object.getOwnPropertyDescriptor(input, 'version')?.value;
|
|
78
|
+
const v2 = version === PROFILE_V2_VALUES.version, values = v2 ? PROFILE_V2_VALUES : PROFILE_VALUES;
|
|
79
|
+
const profile = exactObject(input, v2 ? PROFILE_V2_KEYS : PROFILE_KEYS, 'profile');
|
|
80
|
+
for (const [key, value] of Object.entries(values)) requireValue(profile[key], value, `profile.${key}`);
|
|
81
|
+
const probeKey = v2 ? 'probeMcpTools' : 'probeTools';
|
|
82
|
+
exactArray(profile[probeKey], PROBE_TOOLS.length, `profile.${probeKey}`);
|
|
83
|
+
PROBE_TOOLS.forEach((tool, index) => requireValue(profile[probeKey][index], tool, `profile.${probeKey}[${index}]`));
|
|
84
|
+
if (v2) {
|
|
85
|
+
exactArray(profile.codexNativeTools, CODEX_NATIVE_TOOLS.length, 'profile.codexNativeTools');
|
|
86
|
+
CODEX_NATIVE_TOOLS.forEach((tool, index) => requireValue(profile.codexNativeTools[index], tool, `profile.codexNativeTools[${index}]`));
|
|
87
|
+
if (profile.probeMcpTools.some((tool) => profile.codexNativeTools.includes(tool))) invalid('profile capability overlap');
|
|
88
|
+
}
|
|
89
|
+
return deepFreeze({
|
|
90
|
+
version: values.version, profileId: values.profileId, engine: values.engine,
|
|
91
|
+
model: values.model, reasoningEffort: values.reasoningEffort, sandbox: values.sandbox,
|
|
92
|
+
approvalPolicy: values.approvalPolicy, cwd: canonicalCwd(profile.cwd),
|
|
93
|
+
...(v2 ? { probeMcpTools: [...PROBE_TOOLS], codexNativeTools: [...CODEX_NATIVE_TOOLS] } : { probeTools: [...PROBE_TOOLS] }),
|
|
94
|
+
fallback: false, retries: 0,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function validateMcp(input) {
|
|
99
|
+
const mcp = exactObject(input, ['name', 'url'], 'mcp');
|
|
100
|
+
if (typeof mcp.name !== 'string' || !/^probe_[0-9a-f]{16}$/.test(mcp.name) || typeof mcp.url !== 'string') invalid('mcp');
|
|
101
|
+
const raw = /^http:\/\/127\.0\.0\.1:([0-9]{1,5})\/mcp$/.exec(mcp.url);
|
|
102
|
+
let parsed;
|
|
103
|
+
try { parsed = new URL(mcp.url); } catch { invalid('mcp.url'); }
|
|
104
|
+
const port = raw && Number(raw[1]);
|
|
105
|
+
if (!raw || String(port) !== raw[1] || port < 1 || port > 65535 || parsed.protocol !== 'http:' || parsed.hostname !== '127.0.0.1' || (parsed.port !== raw[1] && !(port === 80 && parsed.port === '')) || parsed.pathname !== '/mcp' || parsed.username || parsed.password || parsed.search || parsed.hash) invalid('mcp.url');
|
|
106
|
+
return mcp;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function buildGovernedCodexInitialToolArgs(input) {
|
|
110
|
+
exactObject(input, ['profile', 'prompt', 'mcp'], 'builder input');
|
|
111
|
+
const profile = validateGovernedCodexProfile(input.profile);
|
|
112
|
+
if (typeof input.prompt !== 'string' || Buffer.byteLength(input.prompt, 'utf8') < 1 || Buffer.byteLength(input.prompt, 'utf8') > 131072) invalid('prompt');
|
|
113
|
+
const mcp = validateMcp(input.mcp);
|
|
114
|
+
const features = Object.fromEntries(FEATURE_NAMES.map((name) => [name, false]));
|
|
115
|
+
const tools = Object.fromEntries(ENABLED_TOOLS.map((name) => [name, { approval_mode: 'approve' }]));
|
|
116
|
+
const server = { url: mcp.url, default_tools_approval_mode: 'prompt', enabled_tools: [...ENABLED_TOOLS], tools };
|
|
117
|
+
return deepFreeze({
|
|
118
|
+
prompt: input.prompt, model: profile.model,
|
|
119
|
+
config: { model_reasoning_effort: profile.reasoningEffort, web_search: 'disabled', features, skills: { include_instructions: false }, mcp_servers: { [mcp.name]: server } },
|
|
120
|
+
cwd: profile.cwd, sandbox: profile.sandbox, 'approval-policy': profile.approvalPolicy,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function validatePermission(input) {
|
|
125
|
+
const permission = exactObject(input, ['type', 'file_system', 'network'], 'permission_profile');
|
|
126
|
+
requireValue(permission.type, 'managed', 'permission_profile.type');
|
|
127
|
+
requireValue(permission.network, 'restricted', 'permission_profile.network');
|
|
128
|
+
const fileSystem = exactObject(permission.file_system, ['type', 'entries'], 'file_system');
|
|
129
|
+
requireValue(fileSystem.type, 'restricted', 'file_system.type');
|
|
130
|
+
exactArray(fileSystem.entries, 1, 'file_system.entries');
|
|
131
|
+
const entry = exactObject(fileSystem.entries[0], ['access', 'path'], 'file_system entry');
|
|
132
|
+
requireValue(entry.access, 'read', 'file_system entry access');
|
|
133
|
+
const path = exactObject(entry.path, ['type', 'value'], 'permission path');
|
|
134
|
+
requireValue(path.type, 'special', 'permission path type');
|
|
135
|
+
const value = exactObject(path.value, ['kind'], 'permission path value');
|
|
136
|
+
requireValue(value.kind, 'root', 'permission path kind');
|
|
137
|
+
return { type: 'managed', file_system: { type: 'restricted', entries: [{ access: 'read', path: { type: 'special', value: { kind: 'root' } } }] }, network: 'restricted' };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function validateRollout(value) {
|
|
141
|
+
if (typeof value !== 'string' || Buffer.byteLength(value, 'utf8') > 4096 || value.includes('\0') || !isAbsolute(value) || normalize(value) !== value) invalid('rollout_path');
|
|
142
|
+
const match = ROLLOUT.exec(value);
|
|
143
|
+
if (!match || match.index + match[0].length !== value.length || match[1] !== match[4] || match[2] !== match[5] || match[3] !== match[6]) invalid('rollout_path');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function attestGovernedCodexSession(input) {
|
|
147
|
+
exactObject(input, ['profile', 'events'], 'attester input');
|
|
148
|
+
const profile = validateGovernedCodexProfile(input.profile);
|
|
149
|
+
const v2 = profile.version === PROFILE_V2_VALUES.version;
|
|
150
|
+
if (v2) {
|
|
151
|
+
exactArray(input.events, 2, 'events');
|
|
152
|
+
} else exactArray(input.events, 1, 'events');
|
|
153
|
+
const event = exactObject(input.events[0], ['jsonrpc', 'method', 'params'], 'event');
|
|
154
|
+
requireValue(event.jsonrpc, '2.0', 'event.jsonrpc'); requireValue(event.method, 'codex/event', 'event.method');
|
|
155
|
+
const params = exactObject(event.params, ['_meta', 'id', 'msg'], 'event.params'); requireValue(params.id, '', 'event.params.id');
|
|
156
|
+
const meta = exactObject(params._meta, ['requestId', 'threadId'], 'event._meta'); requireValue(meta.requestId, 2, 'requestId');
|
|
157
|
+
const hasServiceTier = Object.prototype.propertyIsEnumerable.call(params.msg, 'service_tier');
|
|
158
|
+
const msg = exactObject(params.msg, hasServiceTier ? [...SESSION_MSG_KEYS, 'service_tier'] : SESSION_MSG_KEYS, 'event.msg');
|
|
159
|
+
if (hasServiceTier && !SESSION_SERVICE_TIERS.includes(msg.service_tier)) invalid('event.msg');
|
|
160
|
+
for (const id of [meta.threadId, msg.session_id, msg.thread_id]) if (typeof id !== 'string' || !SAFE_ID.test(id)) invalid('session identity');
|
|
161
|
+
if (meta.threadId !== msg.session_id || msg.session_id !== msg.thread_id) invalid('session identity');
|
|
162
|
+
requireValue(msg.type, 'session_configured', 'msg.type'); requireValue(msg.model, profile.model, 'msg.model');
|
|
163
|
+
requireValue(msg.model_provider_id, 'openai', 'msg.model_provider_id'); requireValue(msg.approval_policy, profile.approvalPolicy, 'msg.approval_policy');
|
|
164
|
+
requireValue(msg.approvals_reviewer, 'user', 'msg.approvals_reviewer'); requireValue(msg.reasoning_effort, profile.reasoningEffort, 'msg.reasoning_effort');
|
|
165
|
+
validateRollout(msg.rollout_path);
|
|
166
|
+
if (canonicalCwd(msg.cwd) !== profile.cwd) invalid('msg.cwd');
|
|
167
|
+
const permission = validatePermission(msg.permission_profile);
|
|
168
|
+
const cwdDigest = digest(profile.cwd);
|
|
169
|
+
if (v2) {
|
|
170
|
+
const nativeTools = exactObject(input.events[1], ['total', 'tools'], 'native tool evidence');
|
|
171
|
+
if (!Number.isSafeInteger(nativeTools.total) || nativeTools.total < 0 || nativeTools.total > 256) invalid('native tool total');
|
|
172
|
+
exactArray(nativeTools.tools, nativeTools.total === 0 ? 0 : 1, 'native tool aggregates');
|
|
173
|
+
if (nativeTools.total > 0) {
|
|
174
|
+
const aggregate = exactObject(nativeTools.tools[0], ['name', 'status', 'count'], 'native tool aggregate');
|
|
175
|
+
if (!profile.codexNativeTools.includes(aggregate.name)) invalid('undeclared native tool evidence');
|
|
176
|
+
requireValue(aggregate.status, 'completed', 'native tool status');
|
|
177
|
+
if (!Number.isSafeInteger(aggregate.count) || aggregate.count !== nativeTools.total) invalid('native tool count');
|
|
178
|
+
}
|
|
179
|
+
return deepFreeze({
|
|
180
|
+
version: 'probe.governed-codex-attestation/v3', profileId: profile.profileId,
|
|
181
|
+
requested: { profileDigest: digest(profile), cwdDigest, probeMcpToolsDigest: digest(profile.probeMcpTools),
|
|
182
|
+
codexNativeToolsDigest: digest(profile.codexNativeTools), probeMcpTools: [...profile.probeMcpTools],
|
|
183
|
+
codexNativeTools: [...profile.codexNativeTools], model: profile.model, reasoningEffort: profile.reasoningEffort,
|
|
184
|
+
sandbox: profile.sandbox, approvalPolicy: profile.approvalPolicy },
|
|
185
|
+
observed: { source: 'session_configured+raw_response_item', model: msg.model, modelProviderId: msg.model_provider_id,
|
|
186
|
+
reasoningEffort: msg.reasoning_effort, approvalPolicy: msg.approval_policy, cwdDigest,
|
|
187
|
+
permissionProfileDigest: digest(permission), filesystem: 'restricted-read-root', network: permission.network,
|
|
188
|
+
nativeTools: { total: nativeTools.total, tools: nativeTools.tools.map((item) => ({ ...item })) } },
|
|
189
|
+
correlation: { requestId: 2, eventCount: nativeTools.total + 1 }, usage: { status: 'unavailable' },
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return deepFreeze({
|
|
193
|
+
version: 'probe.governed-codex-attestation/v1', profileId: profile.profileId,
|
|
194
|
+
requested: { profileDigest: digest(profile), cwdDigest, probeToolsDigest: digest(profile.probeTools), model: profile.model, reasoningEffort: profile.reasoningEffort, sandbox: profile.sandbox, approvalPolicy: profile.approvalPolicy },
|
|
195
|
+
observed: { source: 'session_configured', model: msg.model, modelProviderId: msg.model_provider_id, reasoningEffort: msg.reasoning_effort, approvalPolicy: msg.approval_policy, cwdDigest, permissionProfileDigest: digest(permission), filesystem: 'restricted-read-root', network: permission.network },
|
|
196
|
+
correlation: { requestId: 2, eventCount: 1 }, usage: { status: 'unavailable' },
|
|
197
|
+
});
|
|
198
|
+
}
|