@junghanacs/entwurf 0.51.0 → 0.53.1
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/AGENTS.md +1 -1
- package/BASELINE.md +116 -397
- package/CHANGELOG.md +191 -2
- package/CONTRIBUTING.md +4 -4
- package/DELIVERY.md +2 -2
- package/ENTWURF-CLI.json +1 -1
- package/ENTWURF.json +10 -4
- package/README.md +11 -8
- package/VERIFY.md +333 -143
- package/demo/README.md +1 -1
- package/demo/demo-baseline.sh +1 -1
- package/demo/demo.sh +1 -1
- package/docs/acp-backend-rail.md +248 -34
- package/docs/setup-clean-host.md +75 -80
- package/mcp/entwurf-bridge/dist/ENTWURF.json +10 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/acp-client.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +90 -14
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +4 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/context.js +15 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/model-ids.js +9 -12
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +41 -56
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +33 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +4 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +34 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +3 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-mailbox-body.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +2 -1
- package/package.json +14 -14
- package/pi/pi-durable/carrier/harness-setup.js +1 -1
- package/pi/pi-durable/carrier/subagent.js +1 -1
- package/pi/pi-durable/overlay/upstream-pin.json +15 -15
- package/pi/settings.reference.json +0 -1
- package/pi-extensions/acp-provider.ts +12 -6
- package/pi-extensions/lib/acp/acp-client.ts +6 -7
- package/pi-extensions/lib/acp/backend-adapter.ts +139 -15
- package/pi-extensions/lib/acp/backend.ts +261 -32
- package/pi-extensions/lib/acp/config.ts +4 -9
- package/pi-extensions/lib/acp/context.ts +17 -0
- package/pi-extensions/lib/acp/event-mapper.ts +236 -17
- package/pi-extensions/lib/acp/model-ids.js +9 -12
- package/pi-extensions/lib/acp/models.ts +46 -57
- package/pi-extensions/lib/acp/tool-surface.ts +34 -6
- package/pi-extensions/lib/entwurf-control-rpc.ts +5 -1
- package/pi-extensions/lib/fresh-call-composition.ts +37 -3
- package/pi-extensions/lib/herdr-fresh-call.ts +3 -1
- package/pi-extensions/lib/meta-mailbox-body.ts +1 -1
- package/pi-extensions/lib/mux-fresh-call.ts +3 -1
- package/pi-extensions/meta-bridge-pi-durable.ts +1 -1
- package/run.sh +62 -120
- package/scripts/check-acp-carrier-augment.ts +3 -21
- package/scripts/check-acp-prompt-lifecycle.ts +24 -3
- package/scripts/check-acp-provider-surface.ts +17 -26
- package/scripts/check-acp-session-reuse.ts +23 -4
- package/scripts/check-acp-stop-reason.ts +22 -3
- package/scripts/check-acp-stream-hooks.ts +24 -3
- package/scripts/check-acp-usage-accounting.ts +53 -24
- package/scripts/check-copilot-receive-arm.ts +19 -2
- package/scripts/check-entwurf-v2-surface.ts +7 -21
- package/scripts/check-fresh-call-dispatch.ts +9 -3
- package/scripts/check-gate-qualification.ts +6 -6
- package/scripts/check-herdr-fresh-call.ts +1 -0
- package/scripts/check-install-surface.ts +6 -0
- package/scripts/check-pi-durable-send.ts +4 -1
- package/scripts/check-probe-ordering.ts +34 -24
- package/scripts/check-release-gate-outcomes.ts +9 -23
- package/scripts/lib/codex-fresh-source-receipts.ts +12 -6
- package/scripts/lib/probe-cli-target.ts +3 -2
- package/scripts/mutants/acp-augment.json +0 -26
- package/scripts/mutants/acp-cortex.json +10 -183
- package/scripts/mutants/acp-foreground-only.json +11 -0
- package/scripts/mutants/acp-launch-namespace.json +3 -1
- package/scripts/mutants/acp-prompt-lifecycle.json +2 -2
- package/scripts/mutants/acp-set-model-readback.json +488 -0
- package/scripts/mutants/agent-guidance.json +2 -2
- package/scripts/mutants/codex-native.json +2 -2
- package/scripts/mutants/control-send-receipt.json +47 -7
- package/scripts/mutants/mux-fresh-call.json +12 -1
- package/scripts/mutants/pack-install.json +4 -4
- package/scripts/mutants/pi-floor.json +8 -10
- package/scripts/mutants/release-gate.json +3 -3
- package/scripts/mutants/v2-surface.json +4 -6
- package/scripts/raw-acp-compaction-measure/probe.ts +8 -2
- package/scripts/smoke-acp-cortex-live.ts +4 -408
- package/scripts/smoke-acp-ordering-probe-live.ts +7 -1
- package/scripts/smoke-acp-session-reuse-live.ts +11 -2
- package/scripts/smoke-acp-v2-send-live.ts +1 -1
- package/scripts/smoke-herdr-raw-install-live.sh +4 -4
- package/scripts/check-acp-cortex.ts +0 -710
|
@@ -260,30 +260,18 @@ function runSubcommand(sub: string, env: Record<string, string | undefined>): {
|
|
|
260
260
|
// is the second skip surface: some smokes never reach their .ts file at all.
|
|
261
261
|
// ===========================================================================
|
|
262
262
|
{
|
|
263
|
-
const viaWrapper = runSubcommand("smoke-
|
|
263
|
+
const viaWrapper = runSubcommand("smoke-entwurf-v2-matrix-live", { LIVE: undefined });
|
|
264
264
|
assert.equal(
|
|
265
265
|
viaWrapper.code,
|
|
266
266
|
LIVE_SKIP_EXIT,
|
|
267
267
|
`[QK:WRAPPER-SKIP-IS-PROTOCOL-EXIT] a run.sh smoke WRAPPER that declines a prerequisite must return the protocol ` +
|
|
268
|
-
`SKIP code, not 0 — got exit ${viaWrapper.code}. The wrapper
|
|
269
|
-
"both decline before their .ts is ever reached), so fixing only the TypeScript " +
|
|
268
|
+
`SKIP code, not 0 — got exit ${viaWrapper.code}. The matrix wrapper declines before its .ts is reached, so fixing only the TypeScript ` +
|
|
270
269
|
`half would leave the aggregate counting those as PASS. Output: ${JSON.stringify(viaWrapper.output.slice(-300))}`,
|
|
271
270
|
);
|
|
272
271
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const missingPrereq = runSubcommand("smoke-acp-cortex-live", {
|
|
277
|
-
LIVE: "1",
|
|
278
|
-
ENTWURF_ACP_CORTEX_CONNECTION: undefined,
|
|
279
|
-
});
|
|
280
|
-
assert.equal(
|
|
281
|
-
missingPrereq.code,
|
|
282
|
-
LIVE_SKIP_EXIT,
|
|
283
|
-
"LIVE=1 with no ENTWURF_ACP_CORTEX_CONNECTION must be a SKIP, not a PASS — this is the exact cell that made a " +
|
|
284
|
-
"cortex-less host look like cortex acceptance. Output: " +
|
|
285
|
-
JSON.stringify(missingPrereq.output.slice(-300)),
|
|
286
|
-
);
|
|
272
|
+
const disabled = runSubcommand("smoke-acp-cortex-live", { LIVE: undefined });
|
|
273
|
+
assert.equal(disabled.code, 2, "disabled Cortex smoke must refuse before a vendor probe");
|
|
274
|
+
assert.match(disabled.output, /cortex-acp-disabled/);
|
|
287
275
|
}
|
|
288
276
|
|
|
289
277
|
// ===========================================================================
|
|
@@ -312,11 +300,9 @@ function runSubcommand(sub: string, env: Record<string, string | undefined>): {
|
|
|
312
300
|
"smoke-agy-native-push-live": ["VERIFY.md", "Aggregate release-gate does not own an agy conversation id"],
|
|
313
301
|
"smoke-codex-native-push-live": ["VERIFY.md", "Aggregate release-gate does not own a loaded Codex thread"],
|
|
314
302
|
"smoke-acp-ordering-probe-live": ["docs/acp-backend-rail.md", "opt-in paired observation"],
|
|
315
|
-
// Cortex
|
|
316
|
-
//
|
|
317
|
-
|
|
318
|
-
// it without the connection still reports protocol SKIP rather than a pass.
|
|
319
|
-
"smoke-acp-cortex-live": ["VERIFY.md", "The release aggregate does not re-certify Cortex"],
|
|
303
|
+
// Cortex ACP is disabled. Its former direct LIVE requirement is historical;
|
|
304
|
+
// the retained command refuses by name without starting a vendor probe.
|
|
305
|
+
"smoke-acp-cortex-live": ["VERIFY.md", "Cortex ACP is disabled"],
|
|
320
306
|
// #116 C4: first evidence precedes promotion. The herdr rail's LIVE acceptance exists and
|
|
321
307
|
// runs on demand, but a rail whose first real acceptance run is days old has not earned a
|
|
322
308
|
// place in the aggregate that blocks every cut — and herdr is an OPTIONAL rail, so a cut
|
|
@@ -1066,7 +1052,7 @@ console.log(
|
|
|
1066
1052
|
"everything else→FAIL (never rounding a skip up), `--cut` refuses a MUST SKIP while a bare diagnostic run stays " +
|
|
1067
1053
|
"exit 0, no LIVE smoke still carries the pre-P1 exit-0 skip shape, and both real skip surfaces were INVOKED and " +
|
|
1068
1054
|
"observed to propagate the code: a smoke with LIVE unset (through run_ts, with its operator-readable marker) and " +
|
|
1069
|
-
"a run.sh wrapper declining its own prerequisite
|
|
1055
|
+
"a run.sh wrapper declining its own prerequisite; the retired Cortex smoke refuses by name; and every " +
|
|
1070
1056
|
"LIVE smoke is either wired into release_gate or excluded by a sentence the docs still carry; and the moved " +
|
|
1071
1057
|
"check-gate-qualification stays reachable only as the schedule/dispatch drift diagnostic (absent from the " +
|
|
1072
1058
|
"default chain, from release_gate, from every push and from the release skill; exactly once in CI) over the " +
|
|
@@ -452,14 +452,20 @@ export function codexSourceToolReceipts(thread: unknown): SourceToolReceipt[] {
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
function exactSenderInfoSuffix(text: string, nonce: string): string | null {
|
|
455
|
-
|
|
455
|
+
// Independent expected frame: never import the producer's guidance as the receipt oracle.
|
|
456
|
+
const guidance =
|
|
457
|
+
"\n\n[entwurf: When a reply is requested, send the result via entwurf_v2 to the requested recipient (default: sender_info.sessionId); a local final is not delivery. Honor routing and no-send instructions; an absent or false wants_reply does not cancel a request. A replyable address alone needs no acknowledgment.]";
|
|
458
|
+
const open = "<sender_info>";
|
|
456
459
|
const suffix = "</sender_info>";
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
const at = text.lastIndexOf(open);
|
|
461
|
+
if (at < 0 || !text.endsWith(suffix)) return null;
|
|
462
|
+
const json = text.slice(at + open.length, -suffix.length);
|
|
463
|
+
if (json.includes("\n") || json.includes(open)) return null;
|
|
460
464
|
try {
|
|
461
|
-
const sender = JSON.parse(json) as { sessionId?: unknown };
|
|
462
|
-
|
|
465
|
+
const sender = JSON.parse(json) as { sessionId?: unknown; replyable?: unknown };
|
|
466
|
+
const prefix = `${nonce}${sender.replyable === true ? guidance : ""}\n\n${open}`;
|
|
467
|
+
if (!text.startsWith(prefix) || !text.endsWith(suffix)) return null;
|
|
468
|
+
return at === prefix.length - open.length && typeof sender.sessionId === "string" ? sender.sessionId : null;
|
|
463
469
|
} catch {
|
|
464
470
|
return null;
|
|
465
471
|
}
|
|
@@ -92,8 +92,9 @@ export function hashFileSha256(path: string): string {
|
|
|
92
92
|
|
|
93
93
|
/** Refuse if the given env carries the upstream override — KEY PRESENCE is the
|
|
94
94
|
* predicate, an empty string included. Upstream consumers disagree about
|
|
95
|
-
* empty (`??` at acp-agent.js:4083
|
|
96
|
-
* truthy check treats it as unset), and
|
|
95
|
+
* empty (0.85.1's `??` at acp-agent.js:4083 treated "" as set and passed it
|
|
96
|
+
* on; 0.106.0's truthy check at dist/claude-cli.js:20 treats it as unset), and
|
|
97
|
+
* the probe refuses the ambiguity
|
|
97
98
|
* instead of picking a side. Used twice: on the runner's own process.env
|
|
98
99
|
* before resolving, and on the COMPOSED spawn env of every ACP child (adapter
|
|
99
100
|
* launch defaults / overlay overrides could inject what process.env did not
|
|
@@ -52,32 +52,6 @@
|
|
|
52
52
|
"signature": "[QK:CARRIER-FRAME-NAMES-CLAUDE-CARRIER]",
|
|
53
53
|
"signatureSource": "scripts/check-acp-carrier-augment.ts"
|
|
54
54
|
},
|
|
55
|
-
{
|
|
56
|
-
"claim": "CARRIER-FRAME-DENIES-CORTEX-CARRIER",
|
|
57
|
-
"title": "the carrier-less rail is told it has a tiny system-prompt carrier — a flat lie, since cortex's buildSessionMeta sends no _meta at all",
|
|
58
|
-
"subject": "pi-extensions/lib/acp/augment.ts",
|
|
59
|
-
"find": [
|
|
60
|
-
"\t\t\t\t\t`The ${params.backend} rail carries no system-prompt carrier at all — entwurf sends no \\`_meta.systemPrompt\\`, so everything entwurf tells you, including any operator engraving above, arrives here as user-message text.`,"
|
|
61
|
-
],
|
|
62
|
-
"replace": [
|
|
63
|
-
"\t\t\t\t\t`The ${params.backend} rail does have a system-prompt carrier (\\`_meta.systemPrompt\\`), and entwurf keeps it deliberately tiny: it carries the operator engraving only.`,"
|
|
64
|
-
],
|
|
65
|
-
"gate": ["bash", "run.sh", "check-acp-carrier-augment"],
|
|
66
|
-
"timeoutSeconds": 60,
|
|
67
|
-
"signature": "[QK:CARRIER-FRAME-DENIES-CORTEX-CARRIER]",
|
|
68
|
-
"signatureSource": "scripts/check-acp-carrier-augment.ts"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"claim": "CARRIER-RAIL-DIFF-IS-SOURCE-PINNED",
|
|
72
|
-
"title": "cortex grows a session carrier while the augment still tells it there is none — the frame becomes a lie and no prose check would notice",
|
|
73
|
-
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
74
|
-
"find": ["\tbuildSessionMeta() {\n\t\treturn undefined;\n\t},"],
|
|
75
|
-
"replace": ["\tbuildSessionMeta() {\n\t\treturn { systemPrompt: \"x\" };\n\t},"],
|
|
76
|
-
"gate": ["bash", "run.sh", "check-acp-carrier-augment"],
|
|
77
|
-
"timeoutSeconds": 60,
|
|
78
|
-
"signature": "[QK:CARRIER-RAIL-DIFF-IS-SOURCE-PINNED]",
|
|
79
|
-
"signatureSource": "scripts/check-acp-carrier-augment.ts"
|
|
80
|
-
},
|
|
81
55
|
{
|
|
82
56
|
"claim": "CARRIER-LEADS-ITS-OWN-BLOCK",
|
|
83
57
|
"title": "the carrier loses its leading boundary — the Claude SDK's fixed sentence swallows the operator engraving again (the measured 2026-07-31 A-join)",
|
|
@@ -3,205 +3,32 @@
|
|
|
3
3
|
"lane": "acp-cortex",
|
|
4
4
|
"mutants": [
|
|
5
5
|
{
|
|
6
|
-
"claim": "
|
|
7
|
-
"title": "dropping a curated row
|
|
8
|
-
"subject": "pi-extensions/lib/acp/model-ids.js",
|
|
9
|
-
"find": [
|
|
10
|
-
"export const SUPPORTED_CORTEX_MODEL_IDS = /** @type {const} */ ([",
|
|
11
|
-
"\t\"cortex-auto\",",
|
|
12
|
-
"\t\"cortex-claude-opus-5\",",
|
|
13
|
-
"\t\"cortex-claude-sonnet-5\",",
|
|
14
|
-
"\t\"cortex-openai-gpt-5.4\",",
|
|
15
|
-
"]);"
|
|
16
|
-
],
|
|
17
|
-
"replace": [
|
|
18
|
-
"export const SUPPORTED_CORTEX_MODEL_IDS = /** @type {const} */ ([",
|
|
19
|
-
"\t\"cortex-auto\",",
|
|
20
|
-
"\t\"cortex-claude-sonnet-5\",",
|
|
21
|
-
"\t\"cortex-openai-gpt-5.4\",",
|
|
22
|
-
"]);"
|
|
23
|
-
],
|
|
24
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
25
|
-
"timeoutSeconds": 300,
|
|
26
|
-
"signature": "[QK:CORTEX-CURATED-FOUR-ROWS]",
|
|
27
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"claim": "CLAUDE-CURATED-THREE-ROWS",
|
|
31
|
-
"title": "dropping a curated CLAUDE row shrinks the operator's model list while the exact-set comparison stays green — expected derives from the same constant, so only the independent count catches it",
|
|
6
|
+
"claim": "CLAUDE-CURATED-FOUR-ROWS",
|
|
7
|
+
"title": "dropping a curated Claude row shrinks the operator's model list",
|
|
32
8
|
"subject": "pi-extensions/lib/acp/model-ids.js",
|
|
33
9
|
"find": [
|
|
34
10
|
"export const SUPPORTED_ANTHROPIC_MODEL_IDS = /** @type {const} */ ([",
|
|
35
11
|
"\t\"claude-sonnet-5-5\",",
|
|
36
12
|
"\t\"claude-opus-5-5\",",
|
|
37
13
|
"\t\"claude-fable-5-1\",",
|
|
14
|
+
"\t\"claude-fable-5-2\",",
|
|
38
15
|
"]);"
|
|
39
16
|
],
|
|
40
17
|
"replace": [
|
|
41
18
|
"export const SUPPORTED_ANTHROPIC_MODEL_IDS = /** @type {const} */ ([",
|
|
42
19
|
"\t\"claude-sonnet-5-5\",",
|
|
43
20
|
"\t\"claude-opus-5-5\",",
|
|
21
|
+
"\t\"claude-fable-5-1\",",
|
|
44
22
|
"]);"
|
|
45
23
|
],
|
|
46
24
|
"gate": ["bash", "run.sh", "check-acp-provider-surface"],
|
|
47
25
|
"timeoutSeconds": 300,
|
|
48
|
-
"signature": "[QK:CLAUDE-CURATED-
|
|
26
|
+
"signature": "[QK:CLAUDE-CURATED-FOUR-ROWS]",
|
|
49
27
|
"signatureSource": "scripts/check-acp-provider-surface.ts"
|
|
50
28
|
},
|
|
51
|
-
{
|
|
52
|
-
"claim": "CORTEX-AUTH-NARROW-CREDENTIAL-CACHE",
|
|
53
|
-
"title": "widening the auth passthrough to the whole cortex/cache leaks operator tool_outputs/tip_history into the child",
|
|
54
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
55
|
-
"find": [
|
|
56
|
-
"\tcortexLinkIfExists(",
|
|
57
|
-
"\t\tjoin(realSnowflake, \"cortex\", \"cache\", \"credential_cache\"),",
|
|
58
|
-
"\t\tjoin(cortexDir, \"cache\", \"credential_cache\"),",
|
|
59
|
-
"\t);"
|
|
60
|
-
],
|
|
61
|
-
"replace": [
|
|
62
|
-
"\trmSync(join(cortexDir, \"cache\"), { recursive: true, force: true });",
|
|
63
|
-
"\tcortexLinkIfExists(join(realSnowflake, \"cortex\", \"cache\"), join(cortexDir, \"cache\"));"
|
|
64
|
-
],
|
|
65
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
66
|
-
"timeoutSeconds": 300,
|
|
67
|
-
"signature": "[QK:CORTEX-AUTH-NARROW-CREDENTIAL-CACHE]",
|
|
68
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"claim": "CORTEX-AUTOUPDATE-OFF",
|
|
72
|
-
"title": "flipping autoUpdate back on lets the cortex runtime replace itself on launch mid-rail (D4)",
|
|
73
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
74
|
-
"find": ["\treturn `${JSON.stringify({ autoUpdate: false }, null, \"\\t\")}\\n`;"],
|
|
75
|
-
"replace": ["\treturn `${JSON.stringify({ autoUpdate: true }, null, \"\\t\")}\\n`;"],
|
|
76
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
77
|
-
"timeoutSeconds": 300,
|
|
78
|
-
"signature": "[QK:CORTEX-AUTOUPDATE-OFF]",
|
|
79
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"claim": "CORTEX-REALHOME-PLATFORM-NEUTRAL",
|
|
83
|
-
"title": "re-deriving realHome absoluteness from the POSIX flavor alone makes a drive/UNC HOME read as relative — the guard would state the host it runs on instead of the contract (PR #77, @yizixu)",
|
|
84
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
85
|
-
"find": ["\tif (!params.realHome || !(isAbsolute(params.realHome) || win32.isAbsolute(params.realHome))) {"],
|
|
86
|
-
"replace": ["\tif (!params.realHome || !params.realHome.startsWith(\"/\")) {"],
|
|
87
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
88
|
-
"timeoutSeconds": 300,
|
|
89
|
-
"signature": "[QK:CORTEX-REALHOME-PLATFORM-NEUTRAL]",
|
|
90
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"claim": "CORTEX-BRIDGE-DUAL-HOME",
|
|
94
|
-
"title": "dropping the bridge-only real-HOME restore leaves the garden store cut off — tools reach the model but see an empty garden (D10)",
|
|
95
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
96
|
-
"find": ["\t\tif (stdio.name === CORTEX_DUAL_HOME_BRIDGE_SERVER) env.HOME = realHome;"],
|
|
97
|
-
"replace": ["\t\tvoid realHome;"],
|
|
98
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
99
|
-
"timeoutSeconds": 300,
|
|
100
|
-
"signature": "[QK:CORTEX-BRIDGE-DUAL-HOME]",
|
|
101
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"claim": "CORTEX-MCP-NON-STDIO-FAILLOUD",
|
|
105
|
-
"title": "silently dropping a non-stdio server advertises a config the session does not have (D9 fail-loud)",
|
|
106
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
107
|
-
"find": [
|
|
108
|
-
"\t\tif (\"type\" in server && (server.type === \"http\" || server.type === \"sse\")) {",
|
|
109
|
-
"\t\t\tthrow new Error(",
|
|
110
|
-
"\t\t\t\t`entwurf: cortex mcp.json projection cannot represent ${server.type} server ` +",
|
|
111
|
-
"\t\t\t\t\t`${JSON.stringify(server.name)} — only stdio entries are measured through ` +",
|
|
112
|
-
"\t\t\t\t\t`$SNOWFLAKE_HOME/cortex/mcp.json (CP0 D9). Remove it from entwurfProvider.mcpServers ` +",
|
|
113
|
-
"\t\t\t\t\t`for cortex models or front it with a stdio bridge.`,",
|
|
114
|
-
"\t\t\t);",
|
|
115
|
-
"\t\t}"
|
|
116
|
-
],
|
|
117
|
-
"replace": [
|
|
118
|
-
"\t\tif (\"type\" in server && (server.type === \"http\" || server.type === \"sse\")) {",
|
|
119
|
-
"\t\t\tcontinue;",
|
|
120
|
-
"\t\t}"
|
|
121
|
-
],
|
|
122
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
123
|
-
"timeoutSeconds": 300,
|
|
124
|
-
"signature": "[QK:CORTEX-MCP-NON-STDIO-FAILLOUD]",
|
|
125
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"claim": "CORTEX-OVERLAY-SESSION-SCOPED",
|
|
129
|
-
"title": "a static shared overlay dir lets two residents overwrite one mcp.json/envelope",
|
|
130
|
-
"subject": "pi-extensions/lib/acp/overlay.ts",
|
|
131
|
-
"find": ["\tconst scopeDir = join(overlaysRoot, cortexOverlayScopeId(params.scopeKey));"],
|
|
132
|
-
"replace": ["\tconst scopeDir = join(overlaysRoot, \"shared\");"],
|
|
133
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
134
|
-
"timeoutSeconds": 300,
|
|
135
|
-
"signature": "[QK:CORTEX-OVERLAY-SESSION-SCOPED]",
|
|
136
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
"claim": "CORTEX-HOME-PRESENCE-REFUSED",
|
|
140
|
-
"title": "a truthy check instead of presence lets an empty-string CORTEX_HOME slip past the refusal (D3 E2b nuance)",
|
|
141
|
-
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
142
|
-
"find": ["\t\tif (\"CORTEX_HOME\" in process.env) {"],
|
|
143
|
-
"replace": ["\t\tif (process.env.CORTEX_HOME) {"],
|
|
144
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
145
|
-
"timeoutSeconds": 300,
|
|
146
|
-
"signature": "[QK:CORTEX-HOME-PRESENCE-REFUSED]",
|
|
147
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
"claim": "CORTEX-LAUNCH-NO-MODEL-PIN",
|
|
151
|
-
"title": "re-introducing the launch -m pin creates a second model authority that drifts from per-turn set-model",
|
|
152
|
-
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
153
|
-
"find": [
|
|
154
|
-
"\tresolveLaunch({ config }) {",
|
|
155
|
-
"\t\tconst settings = config.adapterSettings as CortexAdapterSettings | undefined;",
|
|
156
|
-
"\t\tconst connection = settings?.cortexConnection?.trim() || undefined;",
|
|
157
|
-
"\t\tconst selectionArgs: string[] = [];"
|
|
158
|
-
],
|
|
159
|
-
"replace": [
|
|
160
|
-
"\tresolveLaunch({ config, nativeModelId }) {",
|
|
161
|
-
"\t\tconst settings = config.adapterSettings as CortexAdapterSettings | undefined;",
|
|
162
|
-
"\t\tconst connection = settings?.cortexConnection?.trim() || undefined;",
|
|
163
|
-
"\t\tconst selectionArgs: string[] = [\"-m\", nativeModelId];"
|
|
164
|
-
],
|
|
165
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
166
|
-
"timeoutSeconds": 300,
|
|
167
|
-
"signature": "[QK:CORTEX-LAUNCH-NO-MODEL-PIN]",
|
|
168
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
"claim": "CORTEX-ENFORCE-SET-MODEL",
|
|
172
|
-
"title": "enforcing a constant instead of the native id silently answers with the wrong model (CP0-M)",
|
|
173
|
-
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
174
|
-
"find": [
|
|
175
|
-
"\t\tawait setConfig.call(connection, { sessionId: acpSessionId, configId: \"model\", value: nativeModelId });",
|
|
176
|
-
"\t},",
|
|
177
|
-
"",
|
|
178
|
-
"\t// A connection change must invalidate a reused session (rail: Adapter contract). Flat,"
|
|
179
|
-
],
|
|
180
|
-
"replace": [
|
|
181
|
-
"\t\tawait setConfig.call(connection, { sessionId: acpSessionId, configId: \"model\", value: \"auto\" });",
|
|
182
|
-
"\t},",
|
|
183
|
-
"",
|
|
184
|
-
"\t// A connection change must invalidate a reused session (rail: Adapter contract). Flat,"
|
|
185
|
-
],
|
|
186
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
187
|
-
"timeoutSeconds": 300,
|
|
188
|
-
"signature": "[QK:CORTEX-ENFORCE-SET-MODEL]",
|
|
189
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
190
|
-
},
|
|
191
|
-
{
|
|
192
|
-
"claim": "CORTEX-OVERLAY-KEY-IS-SESSION-KEY",
|
|
193
|
-
"title": "re-deriving the overlay scope from ambient env drops opts.sessionId — two same-process/cwd sessions alias one overlay/mcp.json",
|
|
194
|
-
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
195
|
-
"find": ["\t\tconst overlay = ensureCortexDualHomeOverlay({", "\t\t\tscopeKey: sessionKey,"],
|
|
196
|
-
"replace": ["\t\tconst overlay = ensureCortexDualHomeOverlay({", "\t\t\tscopeKey: piSessionId ?? \"static\","],
|
|
197
|
-
"gate": ["bash", "run.sh", "check-acp-cortex"],
|
|
198
|
-
"timeoutSeconds": 300,
|
|
199
|
-
"signature": "[QK:CORTEX-OVERLAY-KEY-IS-SESSION-KEY]",
|
|
200
|
-
"signatureSource": "scripts/check-acp-cortex.ts"
|
|
201
|
-
},
|
|
202
29
|
{
|
|
203
30
|
"claim": "ACP-OVERLAY-SESSIONKEY-WIRED",
|
|
204
|
-
"title": "passing a cwd-derived key instead of resolveSessionKey's value
|
|
31
|
+
"title": "passing a cwd-derived key instead of resolveSessionKey's value merges distinct sessions' overlay scopes",
|
|
205
32
|
"subject": "pi-extensions/lib/acp/backend.ts",
|
|
206
33
|
"find": [
|
|
207
34
|
"\t\t\tconst overlay = adapter.ensureOverlay({ cwd, modelId: model.id, nativeModelId, config, sessionKey });"
|
|
@@ -215,14 +42,14 @@
|
|
|
215
42
|
"signatureSource": "scripts/check-acp-session-reuse.ts"
|
|
216
43
|
},
|
|
217
44
|
{
|
|
218
|
-
"claim": "
|
|
219
|
-
"title": "
|
|
45
|
+
"claim": "ACP-PROVIDER-CLAUDE-ONLY",
|
|
46
|
+
"title": "the provider entry advertises a retired Cortex row despite the admission fence",
|
|
220
47
|
"subject": "pi-extensions/acp-provider.ts",
|
|
221
48
|
"find": ["\t\tmodels: allCuratedModels(),"],
|
|
222
|
-
"replace": ["\t\tmodels: allCuratedModels()
|
|
49
|
+
"replace": ["\t\tmodels: [...allCuratedModels(), { ...allCuratedModels()[0], id: \"cortex-auto\" }],"],
|
|
223
50
|
"gate": ["bash", "run.sh", "check-acp-provider-surface"],
|
|
224
51
|
"timeoutSeconds": 300,
|
|
225
|
-
"signature": "[QK:
|
|
52
|
+
"signature": "[QK:ACP-PROVIDER-CLAUDE-ONLY]",
|
|
226
53
|
"signatureSource": "scripts/check-acp-provider-surface.ts"
|
|
227
54
|
}
|
|
228
55
|
]
|
|
@@ -12,6 +12,17 @@
|
|
|
12
12
|
"timeoutSeconds": 60,
|
|
13
13
|
"signature": "[QK:ACP-CLAUDE-FOREGROUND-ONLY]",
|
|
14
14
|
"signatureSource": "pi-extensions/lib/acp/backend-adapter.test.ts"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"claim": "ACP-CLAUDE-NO-IDLE-COMPACTION",
|
|
18
|
+
"title": "the claude session settings lose idleCompaction:false — claude-agent-acp 0.101+ sends its own /compact prompt on an idle retained session, a model turn pi never sees",
|
|
19
|
+
"subject": "pi-extensions/lib/acp/tool-surface.ts",
|
|
20
|
+
"find": ["\t\t\tidleCompaction: false,"],
|
|
21
|
+
"replace": [""],
|
|
22
|
+
"gate": ["bash", "run.sh", "check-acp-foreground-only"],
|
|
23
|
+
"timeoutSeconds": 60,
|
|
24
|
+
"signature": "[QK:ACP-CLAUDE-NO-IDLE-COMPACTION]",
|
|
25
|
+
"signatureSource": "pi-extensions/lib/acp/backend-adapter.test.ts"
|
|
15
26
|
}
|
|
16
27
|
]
|
|
17
28
|
}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
"title": "the default launch names the vendor bin directly again — the child re-enters the process-name space a janitor for another harness scans by substring, which is the whole of #72",
|
|
8
8
|
"subject": "pi-extensions/lib/acp/backend-adapter.ts",
|
|
9
9
|
"find": ["\tconst launcher = fileURLToPath(new URL(\"./claude-acp-launch.js\", import.meta.url));"],
|
|
10
|
-
"replace": [
|
|
10
|
+
"replace": [
|
|
11
|
+
"\tconst launcher = require.resolve(\"@agentclientprotocol/claude-agent-acp/package.json\").replace(/package\\.json$/, \"dist/index.js\");"
|
|
12
|
+
],
|
|
11
13
|
"gate": ["bash", "run.sh", "check-acp-launch-namespace"],
|
|
12
14
|
"timeoutSeconds": 240,
|
|
13
15
|
"signature": "[QK:CLAUDE-LAUNCH-IS-NAMESPACED]",
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
"title": "a backend session that died between turns is cleared but never announced — the next turn respawns silently and the operator never learns the session is gone",
|
|
78
78
|
"subject": "pi-extensions/lib/acp/backend.ts",
|
|
79
79
|
"find": [
|
|
80
|
-
"\t\t\tconst priorEnd = takeUnreportedChildEnd(sessionKey);\n\t\t\tif (priorEnd) {\n\t\t\t\tpushAcpLifecycleNotice(\n\t\t\t\t\tstate,\n\t\t\t\t\t`previous ${adapter.backend} session ended between turns (${describeChildEnd(priorEnd)}) — opening a new one`,\n\t\t\t\t);\n\t\t\t}"
|
|
80
|
+
"\t\t\tconst priorEnd = summary ? undefined : takeUnreportedChildEnd(sessionKey);\n\t\t\tif (priorEnd) {\n\t\t\t\tpushAcpLifecycleNotice(\n\t\t\t\t\tstate,\n\t\t\t\t\t`previous ${adapter.backend} session ended between turns (${describeChildEnd(priorEnd)}) — opening a new one`,\n\t\t\t\t);\n\t\t\t}"
|
|
81
81
|
],
|
|
82
|
-
"replace": ["\t\t\
|
|
82
|
+
"replace": ["\t\t\tif (!summary) takeUnreportedChildEnd(sessionKey);"],
|
|
83
83
|
"gate": ["bash", "run.sh", "check-acp-prompt-lifecycle"],
|
|
84
84
|
"timeoutSeconds": 180,
|
|
85
85
|
"signature": "[QK:IDLE-DEATH-ANNOUNCED]",
|