agent-control-plane-core 0.9.0 → 0.9.2
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/package.json +1 -1
- package/src/adapters/codex.mjs +15 -19
- package/src/fixtures/codex.json +6 -5
- package/types/adapters/codex.d.mts +10 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-control-plane-core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Vendor-neutral control-plane contract for coding agents: a normalized ToolCallEvent/Verdict schema with per-agent adapters (Claude Code, Codex, Amp, Gemini CLI) and a conformance suite.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
package/src/adapters/codex.mjs
CHANGED
|
@@ -54,25 +54,25 @@ export const AGENT = "codex";
|
|
|
54
54
|
export const INTEGRATION_MODE = IntegrationMode.EXTERNAL_HOOK;
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
|
-
* Hook-coverage matrix row (`docs/hook-coverage-matrix.md`). `PreToolUse`
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
57
|
+
* Hook-coverage matrix row (`docs/hook-coverage-matrix.md`). `PreToolUse` fires
|
|
58
|
+
* for the shell tools, `apply_patch`, every MCP tool call and every other
|
|
59
|
+
* function tool ([X1]/[X2], read from Codex's own source at the enforcement
|
|
60
|
+
* floor). It never fires for `write_stdin`, which types into a process an
|
|
61
|
+
* earlier call started, nor for a tool OpenAI runs on its own side, so builtin
|
|
62
|
+
* and MCP are both PARTIAL. A live probe ([X3]/[X4]) fired `PreToolUse` for a
|
|
63
|
+
* SUBAGENT's call and for a call in a RESUMED session, so both are PARTIAL too.
|
|
63
64
|
*
|
|
64
65
|
* These rows describe PRE-TOOL routing, which is the only thing the matrix's
|
|
65
66
|
* [X1]/[X2] sources speak about. `parse` applies them to a pre-tool event only
|
|
66
|
-
* (see {@link vetoableCall});
|
|
67
|
-
*
|
|
68
|
-
* Codex documents it honours.
|
|
67
|
+
* (see {@link vetoableCall}); a `PostToolUse` payload in hand is proof the
|
|
68
|
+
* post-tool hook fired for that call, whatever the pre-tool row says.
|
|
69
69
|
*
|
|
70
70
|
* The SUBAGENT row is the one the classifier now reaches on this host: the same
|
|
71
71
|
* probe found `agent_id`/`agent_type` present on a subagent's `PreToolUse`
|
|
72
72
|
* payload and ABSENT on the main thread's, so {@link classifyCallClass} answers
|
|
73
73
|
* SUBAGENT from that payload alone. It is PARTIAL, so such a call stays vetoable
|
|
74
74
|
* — the row's job here is to be honest, not to degrade. An MCP-named call takes
|
|
75
|
-
* the
|
|
75
|
+
* the MCP row either way, subagent or not.
|
|
76
76
|
*
|
|
77
77
|
* The RESUMED row is DECLARATIVE ONLY, for a reason no longer about coverage: a
|
|
78
78
|
* resumed session announces itself on `SessionStart` (`source: "resume"`), not on
|
|
@@ -84,7 +84,7 @@ export const INTEGRATION_MODE = IntegrationMode.EXTERNAL_HOOK;
|
|
|
84
84
|
/** @type {import("../control-plane.mjs").CoverageMap} */
|
|
85
85
|
export const COVERAGE = Object.freeze({
|
|
86
86
|
[CallClass.BUILTIN]: CoverageStatus.PARTIAL,
|
|
87
|
-
[CallClass.MCP]: CoverageStatus.
|
|
87
|
+
[CallClass.MCP]: CoverageStatus.PARTIAL,
|
|
88
88
|
[CallClass.SUBAGENT]: CoverageStatus.PARTIAL,
|
|
89
89
|
[CallClass.RESUMED]: CoverageStatus.PARTIAL,
|
|
90
90
|
});
|
|
@@ -221,17 +221,13 @@ export function canEnforce(version) {
|
|
|
221
221
|
/**
|
|
222
222
|
* Whether an event of `kind` may be marked vetoable, given the tool it names.
|
|
223
223
|
*
|
|
224
|
-
* PRE_TOOL takes the coverage floor
|
|
225
|
-
* MCP-sourced call is un-vetoable regardless of version (COVERAGE.mcp).
|
|
224
|
+
* PRE_TOOL takes the coverage floor ({@link COVERAGE}).
|
|
226
225
|
*
|
|
227
226
|
* POST_TOOL does NOT, and that is deliberate: {@link COVERAGE} records which
|
|
228
227
|
* calls reach `PreToolUse`, and a `PostToolUse` payload in hand is proof the
|
|
229
|
-
* post-tool hook already fired for this call
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* which is a fail-CLOSED error but still a wrong one. It stays gated on
|
|
233
|
-
* GATED_EVENTS and on the version floor, so nothing here can mark an unmodelled
|
|
234
|
-
* or pre-0.135 event vetoable.
|
|
228
|
+
* post-tool hook already fired for this call. It stays gated on GATED_EVENTS
|
|
229
|
+
* and on the version floor, so nothing here can mark an unmodelled or pre-0.135
|
|
230
|
+
* event vetoable.
|
|
235
231
|
* @param {string} kind an {@link EventKind} value
|
|
236
232
|
* @param {string|null} nativeTool
|
|
237
233
|
* @param {Record<string, unknown>} raw the native payload, for `mcp_context`
|
package/src/fixtures/codex.json
CHANGED
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
}
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
|
-
"name": "PreToolUse MCP tool is
|
|
149
|
+
"name": "PreToolUse MCP tool is vetoable (the hook fires for MCP calls)",
|
|
150
150
|
"call_class": "mcp",
|
|
151
151
|
"native": {
|
|
152
152
|
"hook_event_name": "PreToolUse",
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
"input": {
|
|
163
163
|
"title": "hi"
|
|
164
164
|
},
|
|
165
|
-
"this_call_vetoable":
|
|
165
|
+
"this_call_vetoable": true,
|
|
166
166
|
"meta": {
|
|
167
167
|
"agent": "codex",
|
|
168
168
|
"native_event": "PreToolUse",
|
|
@@ -195,15 +195,16 @@
|
|
|
195
195
|
},
|
|
196
196
|
"native": {
|
|
197
197
|
"transport": "external_hook",
|
|
198
|
-
"exit_code":
|
|
199
|
-
"enforced":
|
|
198
|
+
"exit_code": 2,
|
|
199
|
+
"enforced": true,
|
|
200
200
|
"stdout": {
|
|
201
201
|
"hookSpecificOutput": {
|
|
202
202
|
"hookEventName": "PreToolUse",
|
|
203
203
|
"permissionDecision": "deny",
|
|
204
204
|
"permissionDecisionReason": "mcp blocked"
|
|
205
205
|
}
|
|
206
|
-
}
|
|
206
|
+
},
|
|
207
|
+
"stderr": "mcp blocked"
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
}
|
|
@@ -72,25 +72,25 @@ export function createCodexAdapter({ version }?: {
|
|
|
72
72
|
export const AGENT: "codex";
|
|
73
73
|
export const INTEGRATION_MODE: "external_hook";
|
|
74
74
|
/**
|
|
75
|
-
* Hook-coverage matrix row (`docs/hook-coverage-matrix.md`). `PreToolUse`
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
75
|
+
* Hook-coverage matrix row (`docs/hook-coverage-matrix.md`). `PreToolUse` fires
|
|
76
|
+
* for the shell tools, `apply_patch`, every MCP tool call and every other
|
|
77
|
+
* function tool ([X1]/[X2], read from Codex's own source at the enforcement
|
|
78
|
+
* floor). It never fires for `write_stdin`, which types into a process an
|
|
79
|
+
* earlier call started, nor for a tool OpenAI runs on its own side, so builtin
|
|
80
|
+
* and MCP are both PARTIAL. A live probe ([X3]/[X4]) fired `PreToolUse` for a
|
|
81
|
+
* SUBAGENT's call and for a call in a RESUMED session, so both are PARTIAL too.
|
|
81
82
|
*
|
|
82
83
|
* These rows describe PRE-TOOL routing, which is the only thing the matrix's
|
|
83
84
|
* [X1]/[X2] sources speak about. `parse` applies them to a pre-tool event only
|
|
84
|
-
* (see {@link vetoableCall});
|
|
85
|
-
*
|
|
86
|
-
* Codex documents it honours.
|
|
85
|
+
* (see {@link vetoableCall}); a `PostToolUse` payload in hand is proof the
|
|
86
|
+
* post-tool hook fired for that call, whatever the pre-tool row says.
|
|
87
87
|
*
|
|
88
88
|
* The SUBAGENT row is the one the classifier now reaches on this host: the same
|
|
89
89
|
* probe found `agent_id`/`agent_type` present on a subagent's `PreToolUse`
|
|
90
90
|
* payload and ABSENT on the main thread's, so {@link classifyCallClass} answers
|
|
91
91
|
* SUBAGENT from that payload alone. It is PARTIAL, so such a call stays vetoable
|
|
92
92
|
* — the row's job here is to be honest, not to degrade. An MCP-named call takes
|
|
93
|
-
* the
|
|
93
|
+
* the MCP row either way, subagent or not.
|
|
94
94
|
*
|
|
95
95
|
* The RESUMED row is DECLARATIVE ONLY, for a reason no longer about coverage: a
|
|
96
96
|
* resumed session announces itself on `SessionStart` (`source: "resume"`), not on
|