@junghanacs/entwurf 0.41.0 → 0.41.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/AGENTS.md +1 -1
- package/BASELINE.md +7 -5
- package/CHANGELOG.md +426 -0
- package/DELIVERY.md +37 -20
- package/README.md +83 -81
- package/VERIFY.md +10 -10
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +1 -1
- package/docs/external-mcp-host.md +1 -1
- package/docs/setup-clean-host.md +95 -29
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +14 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +10 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +23 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +7 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +3 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +21 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +4 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +5 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +6 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/register.js +13 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +2 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-receive.js +25 -17
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +94 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +57 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +2 -2
- package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +12 -12
- package/mcp/entwurf-bridge/src/index.ts +14 -11
- package/native/win32-x64/entwurf_win.node +0 -0
- package/native/win32-x64/manifest.json +2 -2
- package/package.json +15 -14
- package/pi/pi-durable/carrier/tui.js +18 -3
- package/pi/pi-durable/overlay/upstream-pin.json +12 -12
- package/pi-extensions/lib/acp/backend-adapter.ts +5 -3
- package/pi-extensions/lib/acp/backend.ts +12 -9
- package/pi-extensions/lib/entwurf-self-address.ts +13 -0
- package/pi-extensions/lib/entwurf-v2-contract.ts +25 -2
- package/pi-extensions/lib/entwurf-v2-decider.ts +7 -0
- package/pi-extensions/lib/entwurf-v2-surface.ts +3 -0
- package/pi-extensions/lib/fresh-call-composition.ts +21 -10
- package/pi-extensions/lib/herdr-fresh-call.ts +4 -2
- package/pi-extensions/lib/meta-sender-identity.ts +4 -0
- package/pi-extensions/lib/mux-fresh-call.ts +6 -4
- package/pi-extensions/lib/native-push/register.ts +17 -2
- package/pi-extensions/lib/omp-fresh-preflight.ts +2 -2
- package/pi-extensions/lib/pi-durable-fresh-preflight.ts +1 -1
- package/pi-extensions/lib/remote-pair-receive.ts +27 -19
- package/pi-extensions/lib/remote-pair-send.ts +117 -30
- package/pi-extensions/meta-bridge-omp.ts +69 -7
- package/pi-extensions/meta-bridge-pi-durable.ts +3 -3
- package/run.sh +218 -49
- package/scripts/check-agy-sender-identity.ts +6 -4
- package/scripts/check-entwurf-self-address.ts +34 -3
- package/scripts/check-entwurf-v2-contract.ts +24 -2
- package/scripts/check-entwurf-v2-production.ts +45 -31
- package/scripts/check-gate-qualification.ts +11 -9
- package/scripts/check-native-push-adapter.ts +4 -0
- package/scripts/check-native-push-register.ts +32 -82
- package/scripts/check-remote-pair-installed.ts +2 -2
- package/scripts/dev-bin.sh +112 -1
- package/scripts/lib/chain-terminus-publication.ts +58 -0
- package/scripts/lib/codex-fresh-live-protocol.ts +33 -2
- package/scripts/lib/codex-fresh-source-receipts.ts +112 -3
- package/scripts/lib/pi-durable-fresh-live-receipts.ts +29 -1
- package/scripts/mutants/chain-terminus-publication.json +17 -0
- package/scripts/mutants/codex-native.json +98 -0
- package/scripts/mutants/control-send-receipt.json +3 -3
- package/scripts/mutants/mux-fresh-call.json +16 -1
- package/scripts/mutants/native-push-paused.json +17 -0
- package/scripts/mutants/omp-fresh.json +13 -2
- package/scripts/mutants/pack-install.json +50 -4
- package/scripts/mutants/pi-durable.json +60 -0
- package/scripts/mutants/pi-floor.json +5 -5
- package/scripts/mutants/remote-pair-display.json +3 -3
- package/scripts/mutants/remote-pair-receive.json +41 -11
- package/scripts/mutants/remote-pair-roundtrip.json +67 -7
- package/scripts/mutants/remote-pair-send.json +156 -17
- package/scripts/mutants/remote-pair-transport.json +4 -4
- package/scripts/mutants/source-install.json +66 -0
- package/scripts/remote-pair-receive.ts +12 -12
- package/scripts/smoke-agy-install-state.sh +121 -0
- package/scripts/smoke-agy-native-push-live.ts +13 -0
- package/scripts/smoke-codex-fresh-live.ts +52 -28
- package/scripts/smoke-entwurf-chain-live.ts +7 -9
- package/scripts/smoke-herdr-fresh-call-live.ts +4 -4
- package/scripts/smoke-herdr-plugin-build-live.ts +179 -50
- package/scripts/smoke-herdr-raw-install-live.sh +10 -3
- package/scripts/smoke-mux-lifecycle-live.ts +140 -8
- package/scripts/smoke-omp-fresh-live.ts +5 -4
- package/scripts/smoke-pi-durable-fresh-live.ts +29 -7
- package/scripts/smoke-setup-verdict.sh +27 -2
|
@@ -52,8 +52,9 @@ export function buildCodexInstruction(input: CodexInstructionInput): string {
|
|
|
52
52
|
// DIRECTORY must come from this Codex's own record (#95 lane C), which is a fact only
|
|
53
53
|
// because its thread now opens where its pane is rather than where the app-server sits.
|
|
54
54
|
// Omitting the parameter is the whole point — passing one would prove neither.
|
|
55
|
-
'NO cwd parameter and NO placement parameter, and task "
|
|
56
|
-
|
|
55
|
+
'NO cwd parameter and NO placement parameter, and task "Your automatic callback is the whole task and there is ' +
|
|
56
|
+
"no result to send. After it succeeds, end the turn: no message, no report, no further tool call. Do not open " +
|
|
57
|
+
'another sibling."\n' +
|
|
57
58
|
"2. Stop and wait for the Pi callback delivered into this Codex thread. Accept only a callback whose body " +
|
|
58
59
|
"repeats the exact nonce from your LAUNCH receipt and whose sender envelope carries a garden id on its `session:` line.\n" +
|
|
59
60
|
`3. Only after that match, call public mcp__entwurf_bridge__entwurf_v2 once with target ${input.callerGid}, ` +
|
|
@@ -69,6 +70,36 @@ export function buildCodexInstruction(input: CodexInstructionInput): string {
|
|
|
69
70
|
);
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
/**
|
|
74
|
+
* The initial Pi's own fresh-call task: its bootstrap, then a passive wait.
|
|
75
|
+
*
|
|
76
|
+
* `[GLG 직접, 2026-10-24]` a fresh sibling may check its caller with the public read-only listing,
|
|
77
|
+
* then calls back, then works — the same promise the shared framing makes. This task used to say
|
|
78
|
+
* "Your FIRST tool call must be … callback … and nothing before it" and forbade rechecking
|
|
79
|
+
* "identity with shell or other tools", which forbade the very check the framing offers. What it
|
|
80
|
+
* still asks for is narrower and fixture-specific: no shell recheck of what session-info already
|
|
81
|
+
* says, the zero-argument callback (no target or nonce to copy — the address rides the launch
|
|
82
|
+
* env), no other tool before it, and no tool used to wait. `[측정 2026-10-24, r3]` a `bash true`
|
|
83
|
+
* before the callback is still refused by the order audit (`assertBootstrapOrder`).
|
|
84
|
+
*
|
|
85
|
+
* THIS ONE LAUNCH TAKES THE OPTION. `[GLG 직접, 2026-10-24]` the shared framing OFFERS the check; the
|
|
86
|
+
* four impact LIVEs that followed measured it taken zero times, so the positive path had only unit
|
|
87
|
+
* evidence. This guided task asks the initial Pi to take it — one peers call, its result, then the
|
|
88
|
+
* callback — and the smoke requires a peers prefix of at least one (`minPeersPrefix`). It is a
|
|
89
|
+
* fixture's choice of the offered option, not a product rule, and a PASS here is evidence that the
|
|
90
|
+
* path works end to end, not evidence of any sibling's own judgement.
|
|
91
|
+
*/
|
|
92
|
+
export function buildInitialPiBootstrapTask(initialPiWaitToken: string): string {
|
|
93
|
+
return (
|
|
94
|
+
"Session-info already supplies device, time and cwd; do not recheck them with shell. " +
|
|
95
|
+
"This launch is a guided caller check: first call mcp__entwurf_bridge__entwurf_peers once (read-only, no " +
|
|
96
|
+
"arguments) to corroborate your caller, and only after its result call mcp__entwurf_bridge__entwurf_callback " +
|
|
97
|
+
"with no arguments. Use no other tool before the callback. " +
|
|
98
|
+
`After your required callback receipt, end the turn and wait passively for one addressed message containing ${initialPiWaitToken}. ` +
|
|
99
|
+
"That message is the only authority to open the Codex sibling. Do not call shell, sleep, terminal, or any tool to wait."
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
72
103
|
export interface InitialPiPhaseOneInput {
|
|
73
104
|
initialPiWaitToken: string;
|
|
74
105
|
codexWaitToken: string;
|
|
@@ -9,6 +9,11 @@ export interface SourceToolReceipt {
|
|
|
9
9
|
text: string;
|
|
10
10
|
status: SourceToolStatus;
|
|
11
11
|
isError: boolean;
|
|
12
|
+
/** Pi only: the transcript row index of this call's assistant message. Rows are appended in
|
|
13
|
+
* order, so this is a source fact about WHEN the call was recorded. Codex leaves it unset. */
|
|
14
|
+
callOrdinal?: number;
|
|
15
|
+
/** Pi only: the transcript row index of this call's toolResult. Unset while pending and on Codex. */
|
|
16
|
+
resultOrdinal?: number;
|
|
12
17
|
}
|
|
13
18
|
|
|
14
19
|
export interface ExpectedSourceToolCall {
|
|
@@ -104,6 +109,107 @@ export function assertExactSourceToolCalls(
|
|
|
104
109
|
if (remaining.length > 0) throw new Error(`${label}: missing source calls ${JSON.stringify(remaining)}`);
|
|
105
110
|
}
|
|
106
111
|
|
|
112
|
+
/** The callback a fresh sibling makes before its task, and the one read-only check it may make first. */
|
|
113
|
+
export interface BootstrapOrderExpectation {
|
|
114
|
+
/** Exact arguments of the read-only `entwurf_peers` check the framing offers before the callback. */
|
|
115
|
+
peersArguments: Record<string, unknown>;
|
|
116
|
+
/** The callback role: zero-argument `entwurf_callback`, or Codex's `entwurf_v2` to the caller. */
|
|
117
|
+
callback: ExpectedSourceToolCall;
|
|
118
|
+
/** A GUIDED launch that asked for the check requires at least this many peers checks. Absent = 0:
|
|
119
|
+
* the check is optional everywhere else, and a fixture's guided task is not a product rule. */
|
|
120
|
+
minPeersPrefix?: number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Bootstrap arguments: `entwurf_v2` keeps its schema default (absent `wants_reply` IS false — see
|
|
125
|
+
* `normalizeSourceArguments`), because Codex's callback IS that verb and a model that omits the key
|
|
126
|
+
* has obeyed it. Every other verb compared here is byte-exact: `entwurf_callback` is ZERO-argument,
|
|
127
|
+
* so `{ wants_reply: false }` is a model supplying a parameter the verb does not have, and the peers
|
|
128
|
+
* check is held to the exact call the framing offers.
|
|
129
|
+
*/
|
|
130
|
+
function bootstrapArgumentsMatch(toolName: string, expected: Record<string, unknown>, actual: Record<string, unknown>) {
|
|
131
|
+
return toolName === "entwurf_v2" ? sourceArgumentsMatch(expected, actual) : isDeepStrictEqual(expected, actual);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* The bootstrap order of one fresh sibling, judged on its source receipts IN CALL ORDER:
|
|
136
|
+
* zero or more successful exact `entwurf_peers` checks, then exactly one successful exact callback,
|
|
137
|
+
* then the rest — which is returned for the existing exact-once role audit. `[GLG 직접, 2026-10-24]`
|
|
138
|
+
* checking the caller and then calling back is the right order; nothing else may come first.
|
|
139
|
+
*
|
|
140
|
+
* Refused: any other call before the callback (a `bash true`, a task role), a peers check with other
|
|
141
|
+
* arguments or that did not succeed, a missing / pending / failed callback, a callback with drifted
|
|
142
|
+
* arguments, a peers check or a second exact callback AFTER the callback, and — where the source
|
|
143
|
+
* records it — a callback CALLED before a peers check's RESULT was recorded, or a later call recorded
|
|
144
|
+
* before the callback's RESULT.
|
|
145
|
+
*
|
|
146
|
+
* WHAT THE ORDER PROVES DEPENDS ON THE SOURCE. Pi rows carry `callOrdinal`/`resultOrdinal`, so on Pi
|
|
147
|
+
* this proves every peers result was recorded before the callback was called, and the callback's
|
|
148
|
+
* result before every later call. Codex `thread/read` gives item order and a status read at audit
|
|
149
|
+
* time, nothing more, so on Codex this proves CALL ORDER and completion-at-audit only; that a peers
|
|
150
|
+
* result preceded the callback call, and that the callback result preceded the next call, are both
|
|
151
|
+
* UNVERIFIED there.
|
|
152
|
+
* The peers check is never filtered out by position: it is admitted only as a prefix.
|
|
153
|
+
*
|
|
154
|
+
* SCOPE. This is the audit's condition for the short fixture tasks that call it ("use no other tool
|
|
155
|
+
* before the callback"), not a universal list of what a fresh sibling may do; a sibling whose own
|
|
156
|
+
* check does not hold up may also hold the callback, which these fixtures then see as no callback.
|
|
157
|
+
*/
|
|
158
|
+
export function assertBootstrapOrder(
|
|
159
|
+
receipts: readonly SourceToolReceipt[],
|
|
160
|
+
expected: BootstrapOrderExpectation,
|
|
161
|
+
label: string,
|
|
162
|
+
): SourceToolReceipt[] {
|
|
163
|
+
let at = 0;
|
|
164
|
+
for (; at < receipts.length && receipts[at]?.toolName === "entwurf_peers"; at++) {
|
|
165
|
+
const check = receipts[at] as SourceToolReceipt;
|
|
166
|
+
if (!isDeepStrictEqual(check.arguments, expected.peersArguments))
|
|
167
|
+
throw new Error(
|
|
168
|
+
`${label}: pre-callback entwurf_peers arguments differ\nexpected=${JSON.stringify(expected.peersArguments)}\nactual=${JSON.stringify(check.arguments)}`,
|
|
169
|
+
);
|
|
170
|
+
if (check.status !== "completed" || check.isError)
|
|
171
|
+
throw new Error(`${label}: pre-callback entwurf_peers ${check.isError ? "failed" : check.status}`);
|
|
172
|
+
}
|
|
173
|
+
const callback = receipts[at];
|
|
174
|
+
if (callback === undefined) throw new Error(`${label}: no callback after ${at} pre-callback check(s)`);
|
|
175
|
+
const minPeers = expected.minPeersPrefix ?? 0;
|
|
176
|
+
if (at < minPeers)
|
|
177
|
+
throw new Error(`${label}: the guided caller check was not made (peers prefix=${at}, required ≥ ${minPeers})`);
|
|
178
|
+
const role = expected.callback;
|
|
179
|
+
if (
|
|
180
|
+
callback.toolName !== role.toolName ||
|
|
181
|
+
!bootstrapArgumentsMatch(role.toolName, role.arguments, callback.arguments)
|
|
182
|
+
)
|
|
183
|
+
throw new Error(
|
|
184
|
+
`${label}: unexpected pre-callback call ${callback.toolName} ${JSON.stringify(callback.arguments)} — only the read-only entwurf_peers check may precede ${role.toolName} ${JSON.stringify(role.arguments)}`,
|
|
185
|
+
);
|
|
186
|
+
if (callback.status !== "completed" || callback.isError)
|
|
187
|
+
throw new Error(`${label}: the callback ${callback.isError ? "failed" : `remained ${callback.status}`}`);
|
|
188
|
+
// A check is a check only if its answer was in hand before the callback was made.
|
|
189
|
+
for (const check of receipts.slice(0, at)) {
|
|
190
|
+
if (
|
|
191
|
+
check.resultOrdinal !== undefined &&
|
|
192
|
+
callback.callOrdinal !== undefined &&
|
|
193
|
+
!(check.resultOrdinal < callback.callOrdinal)
|
|
194
|
+
)
|
|
195
|
+
throw new Error(`${label}: ${callback.toolName} was called before the entwurf_peers result was recorded`);
|
|
196
|
+
}
|
|
197
|
+
const rest = receipts.slice(at + 1);
|
|
198
|
+
for (const later of rest) {
|
|
199
|
+
if (later.toolName === "entwurf_peers")
|
|
200
|
+
throw new Error(`${label}: entwurf_peers after the callback — the check is offered only before it`);
|
|
201
|
+
if (later.toolName === role.toolName && bootstrapArgumentsMatch(role.toolName, role.arguments, later.arguments))
|
|
202
|
+
throw new Error(`${label}: duplicate callback ${later.toolName}`);
|
|
203
|
+
if (
|
|
204
|
+
callback.resultOrdinal !== undefined &&
|
|
205
|
+
later.callOrdinal !== undefined &&
|
|
206
|
+
later.callOrdinal < callback.resultOrdinal
|
|
207
|
+
)
|
|
208
|
+
throw new Error(`${label}: ${later.toolName} was called before the callback result was recorded`);
|
|
209
|
+
}
|
|
210
|
+
return rest;
|
|
211
|
+
}
|
|
212
|
+
|
|
107
213
|
/** The only production leaf that turns joined source receipts into cleanup window authority. */
|
|
108
214
|
export function sourceCleanupWindows(receipts: readonly SourceToolReceipt[]): string[] {
|
|
109
215
|
const windows: string[] = [];
|
|
@@ -199,9 +305,9 @@ function piSourceVerb(nativeName: string): string {
|
|
|
199
305
|
/** Join Pi's own toolCall and toolResult rows by native id, retaining pending calls.
|
|
200
306
|
* Native-name equality is checked before translating the exact current Pi dialect. */
|
|
201
307
|
export function piSourceToolReceipts(entries: readonly unknown[]): SourceToolReceipt[] {
|
|
202
|
-
const calls = new Map<string, { toolName: string; arguments: Record<string, unknown
|
|
203
|
-
const results = new Map<string, { toolName: string; text: string; isError: boolean }>();
|
|
204
|
-
for (const raw of entries) {
|
|
308
|
+
const calls = new Map<string, { toolName: string; arguments: Record<string, unknown>; callOrdinal: number }>();
|
|
309
|
+
const results = new Map<string, { toolName: string; text: string; isError: boolean; resultOrdinal: number }>();
|
|
310
|
+
for (const [ordinal, raw] of entries.entries()) {
|
|
205
311
|
if (typeof raw !== "object" || raw === null) continue;
|
|
206
312
|
const entry = raw as { type?: unknown; message?: unknown };
|
|
207
313
|
if (entry.type !== "message" || typeof entry.message !== "object" || entry.message === null) continue;
|
|
@@ -229,6 +335,7 @@ export function piSourceToolReceipts(entries: readonly unknown[]): SourceToolRec
|
|
|
229
335
|
calls.set(block.id, {
|
|
230
336
|
toolName: block.name,
|
|
231
337
|
arguments: block.arguments as Record<string, unknown>,
|
|
338
|
+
callOrdinal: ordinal,
|
|
232
339
|
});
|
|
233
340
|
}
|
|
234
341
|
}
|
|
@@ -242,6 +349,7 @@ export function piSourceToolReceipts(entries: readonly unknown[]): SourceToolRec
|
|
|
242
349
|
toolName: message.toolName,
|
|
243
350
|
text: textContent(message.content),
|
|
244
351
|
isError: message.isError,
|
|
352
|
+
resultOrdinal: ordinal,
|
|
245
353
|
});
|
|
246
354
|
}
|
|
247
355
|
}
|
|
@@ -263,6 +371,7 @@ export function piSourceToolReceipts(entries: readonly unknown[]): SourceToolRec
|
|
|
263
371
|
text: result.text,
|
|
264
372
|
status: result.isError ? "failed" : "completed",
|
|
265
373
|
isError: result.isError,
|
|
374
|
+
resultOrdinal: result.resultOrdinal,
|
|
266
375
|
});
|
|
267
376
|
}
|
|
268
377
|
return joined;
|
|
@@ -11,8 +11,12 @@
|
|
|
11
11
|
* its entry kinds — `pi.system` (tool offering, applied as toolsAdded/toolsRemoved in order),
|
|
12
12
|
* `pi.assistant` (the model that answered, and the tool calls in order) and `pi.tool-result` (each
|
|
13
13
|
* call's settled result, joined by toolCallId).
|
|
14
|
+
*
|
|
15
|
+
* Each call also carries the native ENTRY ids of its call and of its result (`callOrdinal` /
|
|
16
|
+
* `resultOrdinal`). Entries are read in id order, so the ids order what the store recorded — the same
|
|
17
|
+
* fact Pi's transcript row index gives the bootstrap-order leaf (`assertBootstrapOrder`).
|
|
14
18
|
*/
|
|
15
|
-
import { piCallbackSenders } from "./codex-fresh-source-receipts.ts";
|
|
19
|
+
import { piCallbackSenders, type SourceToolReceipt } from "./codex-fresh-source-receipts.ts";
|
|
16
20
|
|
|
17
21
|
/** The one Pi transcript row whose exact payload arrived from `expectedSender`, or null. */
|
|
18
22
|
export function piExactDeliveryRow(
|
|
@@ -43,6 +47,10 @@ export interface PdToolCall {
|
|
|
43
47
|
name: string;
|
|
44
48
|
arguments: Record<string, unknown>;
|
|
45
49
|
result: { text: string; isError: boolean } | null;
|
|
50
|
+
/** Native entry id of the assistant row that made this call. */
|
|
51
|
+
callOrdinal: number;
|
|
52
|
+
/** Native entry id of the tool-result row joined to it, or null while none is recorded. */
|
|
53
|
+
resultOrdinal: number | null;
|
|
46
54
|
}
|
|
47
55
|
export interface PdRootView {
|
|
48
56
|
offering: string[];
|
|
@@ -98,6 +106,8 @@ export function pdRootView(entries: readonly PdNativeRow[], rootConversationId:
|
|
|
98
106
|
name: b.name,
|
|
99
107
|
arguments: (b.arguments ?? {}) as Record<string, unknown>,
|
|
100
108
|
result: null,
|
|
109
|
+
callOrdinal: row.id,
|
|
110
|
+
resultOrdinal: null,
|
|
101
111
|
};
|
|
102
112
|
calls.push(call);
|
|
103
113
|
byId.set(b.id, call);
|
|
@@ -115,12 +125,30 @@ export function pdRootView(entries: readonly PdNativeRow[], rootConversationId:
|
|
|
115
125
|
)
|
|
116
126
|
.join("");
|
|
117
127
|
call.result = { text, isError: message.isError === true };
|
|
128
|
+
call.resultOrdinal = row.id;
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
return { offering, models: [...models], calls };
|
|
122
133
|
}
|
|
123
134
|
|
|
135
|
+
/**
|
|
136
|
+
* The root calls as source receipts, in call order, for the bootstrap-order leaf: a call with no joined
|
|
137
|
+
* result is PENDING, an errored result is FAILED. pd's verbs are its own bare tool names, so no
|
|
138
|
+
* dialect translation happens here.
|
|
139
|
+
*/
|
|
140
|
+
export function pdSourceToolReceipts(calls: readonly PdToolCall[]): SourceToolReceipt[] {
|
|
141
|
+
return calls.map((call) => ({
|
|
142
|
+
toolName: call.name,
|
|
143
|
+
arguments: call.arguments,
|
|
144
|
+
text: call.result?.text ?? "",
|
|
145
|
+
status: call.result === null ? "pending" : call.result.isError ? "failed" : "completed",
|
|
146
|
+
isError: call.result?.isError ?? false,
|
|
147
|
+
callOrdinal: call.callOrdinal,
|
|
148
|
+
...(call.resultOrdinal === null ? {} : { resultOrdinal: call.resultOrdinal }),
|
|
149
|
+
}));
|
|
150
|
+
}
|
|
151
|
+
|
|
124
152
|
/** The doorbell submission for exactly this mailbox message, on the root conversation. */
|
|
125
153
|
export function pdDoorbellSubmission(
|
|
126
154
|
submissions: readonly PdNativeSubmissionRow[],
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "chain-terminus-publication",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "CHAIN-TERMINUS-WAITS-FOR-SIGNAL",
|
|
7
|
+
"title": "the terminus wait stops at the first body again, so smoke-entwurf-chain-live checks the doorbell while enqueueMetaMessage is still between its .msg write and its inbox.signal write and reports a false RED",
|
|
8
|
+
"subject": "scripts/lib/chain-terminus-publication.ts",
|
|
9
|
+
"find": ["\t\tif (msgs.length > 0 && signalled) break;"],
|
|
10
|
+
"replace": ["\t\tif (msgs.length > 0) break;"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-chain-terminus-publication"],
|
|
12
|
+
"timeoutSeconds": 120,
|
|
13
|
+
"signature": "[QK:CHAIN-TERMINUS-WAITS-FOR-SIGNAL]",
|
|
14
|
+
"signatureSource": "test/chain-terminus-publication.test.ts"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -1066,6 +1066,104 @@
|
|
|
1066
1066
|
"timeoutSeconds": 180,
|
|
1067
1067
|
"signature": "[QK:CODEX-SOCKET-LISTEN-ROW-ONLY]",
|
|
1068
1068
|
"signatureSource": "test/codex-socket-listener.test.ts"
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
"claim": "BOOTSTRAP-PEERS-PREFIX-THEN-EXACT-CALLBACK",
|
|
1072
|
+
"title": "the bootstrap ORDER removed: everything before the first callback is skipped instead of only an exact peers check, so `bash true → callback → task` — the r3 RED — passes again, and a task call made before the callback is no longer refused",
|
|
1073
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1074
|
+
"find": ["\tfor (; at < receipts.length && receipts[at]?.toolName === \"entwurf_peers\"; at++) {"],
|
|
1075
|
+
"replace": [
|
|
1076
|
+
"\tfor (; at < receipts.length && receipts[at]?.toolName !== expected.callback.toolName; at++) {\n\t\tif (receipts[at]?.toolName !== \"entwurf_peers\") continue;"
|
|
1077
|
+
],
|
|
1078
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1079
|
+
"timeoutSeconds": 180,
|
|
1080
|
+
"signature": "[QK:BOOTSTRAP-PEERS-PREFIX-THEN-EXACT-CALLBACK]",
|
|
1081
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
"claim": "BOOTSTRAP-PEERS-ONLY-AS-PREFIX",
|
|
1085
|
+
"title": "the peers check filtered out wherever it appears instead of admitted only as a prefix — a check after the callback disappears from the audit, which is the position-independent filter the contract forbids",
|
|
1086
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1087
|
+
"find": ["\tconst rest = receipts.slice(at + 1);"],
|
|
1088
|
+
"replace": ["\tconst rest = receipts.slice(at + 1).filter((r) => r.toolName !== \"entwurf_peers\");"],
|
|
1089
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1090
|
+
"timeoutSeconds": 180,
|
|
1091
|
+
"signature": "[QK:BOOTSTRAP-PEERS-ONLY-AS-PREFIX]",
|
|
1092
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
"claim": "BOOTSTRAP-ZERO-ARG-CALLBACK-STRICT",
|
|
1096
|
+
"title": "the v2 wants_reply default stretched over the zero-argument callback: `entwurf_callback {wants_reply:false}` reads as `{}`, so a model supplying a parameter the verb does not have passes as the exact callback",
|
|
1097
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1098
|
+
"find": [
|
|
1099
|
+
"\treturn toolName === \"entwurf_v2\" ? sourceArgumentsMatch(expected, actual) : isDeepStrictEqual(expected, actual);"
|
|
1100
|
+
],
|
|
1101
|
+
"replace": ["\treturn sourceArgumentsMatch(expected, actual);"],
|
|
1102
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1103
|
+
"timeoutSeconds": 180,
|
|
1104
|
+
"signature": "[QK:BOOTSTRAP-ZERO-ARG-CALLBACK-STRICT]",
|
|
1105
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
"claim": "BOOTSTRAP-CODEX-V2-CALLBACK-DEFAULT",
|
|
1109
|
+
"title": "deep-strict comparison forced onto Codex's entwurf_v2 callback too — a Codex callback that omits wants_reply (schema default false) is refused, resurrecting the 2026-09-16 default-false RED",
|
|
1110
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1111
|
+
"find": [
|
|
1112
|
+
"\treturn toolName === \"entwurf_v2\" ? sourceArgumentsMatch(expected, actual) : isDeepStrictEqual(expected, actual);"
|
|
1113
|
+
],
|
|
1114
|
+
"replace": ["\treturn isDeepStrictEqual(expected, actual);"],
|
|
1115
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1116
|
+
"timeoutSeconds": 180,
|
|
1117
|
+
"signature": "[QK:BOOTSTRAP-CODEX-V2-CALLBACK-DEFAULT]",
|
|
1118
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
"claim": "BOOTSTRAP-PI-RESULT-BEFORE-TASK-CALL",
|
|
1122
|
+
"title": "the Pi result-ordinal check dropped: a task call made in the same assistant row as the callback — before the callback result existed — passes on call order alone",
|
|
1123
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1124
|
+
"find": ["\t\t\tcallback.resultOrdinal !== undefined &&"],
|
|
1125
|
+
"replace": ["\t\t\tfalse &&"],
|
|
1126
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1127
|
+
"timeoutSeconds": 180,
|
|
1128
|
+
"signature": "[QK:BOOTSTRAP-PI-RESULT-BEFORE-TASK-CALL]",
|
|
1129
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1130
|
+
},
|
|
1131
|
+
{
|
|
1132
|
+
"claim": "CODEX-LIVE-INITIAL-PI-BOOTSTRAP-TASK",
|
|
1133
|
+
"title": "the initial Pi's task restored to the retired forced-first wording — `Your FIRST tool call must be … callback … and nothing before it` with a blanket identity-recheck ban — so the LIVE task forbids the read-only caller check the shared framing offers and the order audit admits",
|
|
1134
|
+
"subject": "scripts/lib/codex-fresh-live-protocol.ts",
|
|
1135
|
+
"find": [
|
|
1136
|
+
"\t\t\"This launch is a guided caller check: first call mcp__entwurf_bridge__entwurf_peers once (read-only, no \" +\n\t\t\"arguments) to corroborate your caller, and only after its result call mcp__entwurf_bridge__entwurf_callback \" +\n\t\t\"with no arguments. Use no other tool before the callback. \" +"
|
|
1137
|
+
],
|
|
1138
|
+
"replace": [
|
|
1139
|
+
"\t\t\"Do not recheck identity with other tools. Your FIRST tool call must be mcp__entwurf_bridge__entwurf_callback with no arguments, and nothing before it. \" +"
|
|
1140
|
+
],
|
|
1141
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1142
|
+
"timeoutSeconds": 180,
|
|
1143
|
+
"signature": "[QK:CODEX-LIVE-INITIAL-PI-BOOTSTRAP-TASK]",
|
|
1144
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
"claim": "BOOTSTRAP-PI-PEERS-RESULT-BEFORE-CALLBACK",
|
|
1148
|
+
"title": "the peers-result-before-callback ordinal check dropped: a callback made in the same assistant row as the peers check — before its answer existed — passes as if the caller had been checked",
|
|
1149
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1150
|
+
"find": ["\t\t\tcheck.resultOrdinal !== undefined &&"],
|
|
1151
|
+
"replace": ["\t\t\tfalse &&"],
|
|
1152
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1153
|
+
"timeoutSeconds": 180,
|
|
1154
|
+
"signature": "[QK:BOOTSTRAP-PI-PEERS-RESULT-BEFORE-CALLBACK]",
|
|
1155
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
"claim": "BOOTSTRAP-GUIDED-PEERS-REQUIRED",
|
|
1159
|
+
"title": "the guided launch's required check ignored: a guided initial Pi that called back without the peers check it was asked for passes, so a zero-check PASS is counted as the positive path",
|
|
1160
|
+
"subject": "scripts/lib/codex-fresh-source-receipts.ts",
|
|
1161
|
+
"find": ["\tif (at < minPeers)"],
|
|
1162
|
+
"replace": ["\tif (false && at < minPeers)"],
|
|
1163
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
1164
|
+
"timeoutSeconds": 180,
|
|
1165
|
+
"signature": "[QK:BOOTSTRAP-GUIDED-PEERS-REQUIRED]",
|
|
1166
|
+
"signatureSource": "test/codex-fresh-live-protocol.test.ts"
|
|
1069
1167
|
}
|
|
1070
1168
|
]
|
|
1071
1169
|
}
|
|
@@ -166,10 +166,10 @@
|
|
|
166
166
|
"title": "the pi queue oracle's public coordinate is dropped from `check:vitest`, so the file that proves every claim the receipt makes about a receiver's queues is green only when somebody runs `pnpm test` by hand — the discovery door deliberately does not select `test/**`, so nothing else would notice",
|
|
167
167
|
"subject": "package.json",
|
|
168
168
|
"find": [
|
|
169
|
-
"\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit\""
|
|
169
|
+
"\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit && ./run.sh check-chain-terminus-publication\""
|
|
170
170
|
],
|
|
171
171
|
"replace": [
|
|
172
|
-
"\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit\""
|
|
172
|
+
"\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-tests-beside-behavior && ./run.sh check-remote-pair-installed-audit && ./run.sh check-chain-terminus-publication\""
|
|
173
173
|
],
|
|
174
174
|
"gate": ["bash", "run.sh", "check-tests-beside-behavior"],
|
|
175
175
|
"timeoutSeconds": 600,
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"claim": "PI-CORE-PIN-TRACKS-FLOOR",
|
|
182
182
|
"title": "the queue oracle's pi-agent-core pin drifts off the floor the rest of the pi runtime is pinned to, so the oracle keeps answering honestly — about a pi nobody in this repo runs",
|
|
183
183
|
"subject": "package.json",
|
|
184
|
-
"find": ["\"@earendil-works/pi-agent-core\": \"1.
|
|
184
|
+
"find": ["\"@earendil-works/pi-agent-core\": \"1.4.0\","],
|
|
185
185
|
"replace": ["\"@earendil-works/pi-agent-core\": \"0.87.1\","],
|
|
186
186
|
"gate": ["bash", "run.sh", "check-dep-versions"],
|
|
187
187
|
"timeoutSeconds": 300,
|
|
@@ -69,7 +69,9 @@
|
|
|
69
69
|
"claim": "FRESHCALL-CALLBACK-PRECEDES-TASK",
|
|
70
70
|
"title": "the task is framed before the callback instruction, so a sibling that stalls in the task never names itself",
|
|
71
71
|
"subject": "pi-extensions/lib/fresh-call-composition.ts",
|
|
72
|
-
"find": [
|
|
72
|
+
"find": [
|
|
73
|
+
"\t\t\t\t\t`BEFORE THE TASK, and before reading files or running commands: call ${birthTool} with no arguments.`"
|
|
74
|
+
],
|
|
73
75
|
"replace": ["\t\t\t\t\t`FINAL ACTION, after completing the task: call ${birthTool} with no arguments.`"],
|
|
74
76
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
75
77
|
"timeoutSeconds": 120,
|
|
@@ -766,6 +768,19 @@
|
|
|
766
768
|
"timeoutSeconds": 60,
|
|
767
769
|
"signature": "[QK:PIIMPORT-CARRIER-FENCE]",
|
|
768
770
|
"signatureSource": "run.sh"
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
"claim": "PD-FRESH-LIVE-BOOTSTRAP-ORDER",
|
|
774
|
+
"title": "a pd call with no joined result read as COMPLETED instead of pending, so a callback whose result the native store never recorded passes pd's bootstrap order",
|
|
775
|
+
"subject": "scripts/lib/pi-durable-fresh-live-receipts.ts",
|
|
776
|
+
"find": ["\t\tstatus: call.result === null ? \"pending\" : call.result.isError ? \"failed\" : \"completed\","],
|
|
777
|
+
"replace": [
|
|
778
|
+
"\t\tstatus: call.result === null ? \"completed\" : call.result.isError ? \"failed\" : \"completed\","
|
|
779
|
+
],
|
|
780
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
781
|
+
"timeoutSeconds": 120,
|
|
782
|
+
"signature": "[QK:PD-FRESH-LIVE-BOOTSTRAP-ORDER]",
|
|
783
|
+
"signatureSource": "test/pi-durable-fresh-live-receipts.test.ts"
|
|
769
784
|
}
|
|
770
785
|
]
|
|
771
786
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"lane": "native-push-paused",
|
|
4
|
+
"mutants": [
|
|
5
|
+
{
|
|
6
|
+
"claim": "AGY-NATIVE-PUSH-PAUSED",
|
|
7
|
+
"title": "the paused native-push backend set is emptied, so agy dispatch, sender replyability and register_native reach the agy language server again, whose measured external callers were refused for a missing CSRF token (#128, #152)",
|
|
8
|
+
"subject": "pi-extensions/lib/entwurf-v2-contract.ts",
|
|
9
|
+
"find": ["export const NATIVE_PUSH_PAUSED_BACKENDS: readonly NativePushBackend[] = [\"antigravity\"];"],
|
|
10
|
+
"replace": ["export const NATIVE_PUSH_PAUSED_BACKENDS: readonly NativePushBackend[] = [];"],
|
|
11
|
+
"gate": ["bash", "run.sh", "check-native-push-paused"],
|
|
12
|
+
"timeoutSeconds": 120,
|
|
13
|
+
"signature": "[QK:AGY-NATIVE-PUSH-PAUSED]",
|
|
14
|
+
"signatureSource": "pi-extensions/lib/native-push/paused.test.ts"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -169,8 +169,8 @@
|
|
|
169
169
|
"claim": "OMP-BOOTSTRAP-CALLBACK-ONLY",
|
|
170
170
|
"title": "the task folded back into the stage-one prompt, so the sibling is asked to call back AND to work in one message. This is the prompt the failed LIVE actually ran, minus the missing tool: a competing goal beside the callback is what the two-stage split exists to remove, and nothing about argv or readiness would notice it coming back",
|
|
171
171
|
"subject": "pi-extensions/meta-bridge-omp.ts",
|
|
172
|
-
"find": ["\t\t\tsend(buildOmpCallbackOnlyPrompt());"],
|
|
173
|
-
"replace": ["\t\t\tsend(`${buildOmpCallbackOnlyPrompt()}\\n\\n${payload.task}`);"],
|
|
172
|
+
"find": ["\t\t\tsend(buildOmpCallbackOnlyPrompt(opts.callerGardenId));"],
|
|
173
|
+
"replace": ["\t\t\tsend(`${buildOmpCallbackOnlyPrompt(opts.callerGardenId)}\\n\\n${payload.task}`);"],
|
|
174
174
|
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
175
175
|
"timeoutSeconds": 300,
|
|
176
176
|
"signature": "[QK:OMP-BOOTSTRAP-CALLBACK-ONLY]",
|
|
@@ -295,6 +295,17 @@
|
|
|
295
295
|
"timeoutSeconds": 300,
|
|
296
296
|
"signature": "[QK:OMP-BOOTSTRAP-EPOCH-ENDS-BEFORE-ENVELOPE]",
|
|
297
297
|
"signatureSource": "test/omp-fresh-bootstrap.contract.test.ts"
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"claim": "OMP-BOOTSTRAP-CALLER-TARGET-REQUIRED",
|
|
301
|
+
"title": "a requested omp bootstrap with no well-formed caller target proceeds anyway — the stage silently drops the caller check (or names `undefined` as the caller) and the task is still released, instead of a named refusal",
|
|
302
|
+
"subject": "pi-extensions/meta-bridge-omp.ts",
|
|
303
|
+
"find": ["\tif (!caller.ok) {"],
|
|
304
|
+
"replace": ["\tif (false && !caller.ok) {"],
|
|
305
|
+
"gate": ["bash", "run.sh", "check-mux-fresh-call"],
|
|
306
|
+
"timeoutSeconds": 300,
|
|
307
|
+
"signature": "[QK:OMP-BOOTSTRAP-CALLER-TARGET-REQUIRED]",
|
|
308
|
+
"signatureSource": "test/omp-fresh-bootstrap.contract.test.ts"
|
|
298
309
|
}
|
|
299
310
|
]
|
|
300
311
|
}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"claim": "PACK-INSTALL-PIN-MATCHER-BOUNDED",
|
|
7
7
|
"title": "the pin-leak matcher loses its version boundary and blesses substring lookalikes \u2014 @0.85.10 reads as the pinned 0.85.1 and the gate announces a verified tree it never verified (independent review, 2026-08-25)",
|
|
8
8
|
"subject": "run.sh",
|
|
9
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.
|
|
10
|
-
"replace": [" grep '^@earendil-works+' | grep -v '@
|
|
9
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.4\\.0(_|$)' || true"],
|
|
10
|
+
"replace": [" grep '^@earendil-works+' | grep -v '@1\\.4\\.0' || true"],
|
|
11
11
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
12
12
|
"timeoutSeconds": 120,
|
|
13
13
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED]",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"claim": "PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE",
|
|
18
18
|
"title": "the pin-leak matcher narrows back to the pi-* families and goes blind to a non-pi member of the same runtime closure \u2014 @earendil-works/chord (new in pi 0.85.0, a runtime dependency of pi-coding-agent/pi-agent-core/pi-client/pi-protocol) floats unpinned while the gate prints a verified pin (measured 2026-09-06 on a real 0.85.1 install tree)",
|
|
19
19
|
"subject": "run.sh",
|
|
20
|
-
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.
|
|
21
|
-
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.
|
|
20
|
+
"find": [" grep '^@earendil-works+' | grep -Ev '@1\\.4\\.0(_|$)' || true"],
|
|
21
|
+
"replace": [" grep '^@earendil-works+pi-' | grep -Ev '@1\\.4\\.0(_|$)' || true"],
|
|
22
22
|
"gate": ["bash", "run.sh", "check-pack-pin-matcher"],
|
|
23
23
|
"timeoutSeconds": 120,
|
|
24
24
|
"signature": "[QK:PACK-INSTALL-PIN-MATCHER-COVERS-CLOSURE]",
|
|
@@ -60,6 +60,52 @@
|
|
|
60
60
|
"timeoutSeconds": 120,
|
|
61
61
|
"signature": "[QK:WIN32-PACK-DIGEST]",
|
|
62
62
|
"signatureSource": "run.sh"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"claim": "PACK-INSTALL-ARGV-LEAK-CAUGHT",
|
|
66
|
+
"title": "the dispatcher-verb refusal goes back to the retired verdict, `printf | grep -qF` under pipefail refusing only when that pipeline exits 0, so a leak ahead of more output SIGPIPEs the producer and the cell passes \u2014 killed deterministically only because the self-test front-loads the leak ahead of ~260 KB, past the default 64 KiB pipe buffer (its teeth control measures that); on the real small stand-in output the same restoration would survive",
|
|
67
|
+
"subject": "run.sh",
|
|
68
|
+
"find": [" grep -qF -- \"$token\" <<<\"$out\" || argv_search_rc=$?"],
|
|
69
|
+
"replace": [" printf '%s' \"$out\" | grep -qF -- \"$token\" || argv_search_rc=1"],
|
|
70
|
+
"gate": ["bash", "run.sh", "check-pack-argv-matcher"],
|
|
71
|
+
"timeoutSeconds": 120,
|
|
72
|
+
"signature": "[QK:PACK-INSTALL-ARGV-LEAK-CAUGHT]",
|
|
73
|
+
"signatureSource": "run.sh"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"claim": "PACK-INSTALL-ARGV-CLEAN-PASSES",
|
|
77
|
+
"title": "the dispatcher-verb refusal stops accepting a clean search (grep rc=1), so every installed copilot / codex-app-server launch is refused, silently",
|
|
78
|
+
"subject": "run.sh",
|
|
79
|
+
"find": [" 1) return 0 ;;"],
|
|
80
|
+
"replace": [" 1) ;;"],
|
|
81
|
+
"gate": ["bash", "run.sh", "check-pack-argv-matcher"],
|
|
82
|
+
"timeoutSeconds": 120,
|
|
83
|
+
"signature": "[QK:PACK-INSTALL-ARGV-CLEAN-PASSES]",
|
|
84
|
+
"signatureSource": "run.sh"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"claim": "PACK-INSTALL-ARGV-SEARCH-ERROR-REFUSED",
|
|
88
|
+
"title": "a failed dispatcher-verb search (grep rc=2) is accepted as clean, so a search that never ran lets the leak refusal pass",
|
|
89
|
+
"subject": "run.sh",
|
|
90
|
+
"find": [
|
|
91
|
+
" *) fail \"[check-pack-install] installed 'entwurf $label': the dispatcher-verb search itself failed (rc=$argv_search_rc) \u2014 refused, never read as no leak\" ;;"
|
|
92
|
+
],
|
|
93
|
+
"replace": [" *) return 0 ;;"],
|
|
94
|
+
"gate": ["bash", "run.sh", "check-pack-argv-matcher"],
|
|
95
|
+
"timeoutSeconds": 120,
|
|
96
|
+
"signature": "[QK:PACK-INSTALL-ARGV-SEARCH-ERROR-REFUSED]",
|
|
97
|
+
"signatureSource": "run.sh"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"claim": "PACK-INSTALL-ARGV-CELLS-BOUND",
|
|
101
|
+
"title": "the copilot leak refusal of check-pack-install goes back to its own `printf | grep -qF` instead of returning through the proved verdict, so the self-test stays green while the heavy cell regains the SIGPIPE window (the codex-app-server call is held by the same text check, with no mutant of its own)",
|
|
102
|
+
"subject": "run.sh",
|
|
103
|
+
"find": [" pack_install_refuse_argv_leak copilot \"$op_out\" 'ARG<copilot>' || return 1"],
|
|
104
|
+
"replace": [" if printf '%s' \"$op_out\" | grep -qF 'ARG<copilot>'; then return 1; fi"],
|
|
105
|
+
"gate": ["bash", "run.sh", "check-pack-argv-matcher"],
|
|
106
|
+
"timeoutSeconds": 120,
|
|
107
|
+
"signature": "[QK:PACK-INSTALL-ARGV-CELLS-BOUND]",
|
|
108
|
+
"signatureSource": "run.sh"
|
|
63
109
|
}
|
|
64
110
|
]
|
|
65
111
|
}
|
|
@@ -1207,6 +1207,66 @@
|
|
|
1207
1207
|
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1208
1208
|
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1209
1209
|
},
|
|
1210
|
+
{
|
|
1211
|
+
"claim": "PI-DURABLE-TASK-SLEEPING-COUNTED",
|
|
1212
|
+
"title": "the badge stops naming sleeping tasks: a background task in its durable backoff is counted but said to be nothing",
|
|
1213
|
+
"subject": "pi/pi-durable/carrier/tui.js",
|
|
1214
|
+
"find": ["\t\t\t...tally(\"sleeping\", (node) => !node.abortRequested && node.state.status === \"sleeping\"),"],
|
|
1215
|
+
"replace": ["\t\t\t// sleeping is not named"],
|
|
1216
|
+
"gate": ["bash", "run.sh", "check-pi-durable-carrier"],
|
|
1217
|
+
"timeoutSeconds": 300,
|
|
1218
|
+
"signature": "[QK:PI-DURABLE-TASK-SLEEPING-COUNTED]",
|
|
1219
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1220
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1221
|
+
},
|
|
1222
|
+
{
|
|
1223
|
+
"claim": "PI-DURABLE-TASK-SLEEPING-SHOWN",
|
|
1224
|
+
"title": "a sleeping task's panel line drops its wake time, so nothing on screen says when the sleeping work comes back",
|
|
1225
|
+
"subject": "pi/pi-durable/carrier/tui.js",
|
|
1226
|
+
"find": ["\t\t\t\t\t? `sleeping ${state.phase} until ${localTime(state.until)}`"],
|
|
1227
|
+
"replace": ["\t\t\t\t\t? `sleeping ${state.phase}`"],
|
|
1228
|
+
"gate": ["bash", "run.sh", "check-pi-durable-carrier"],
|
|
1229
|
+
"timeoutSeconds": 300,
|
|
1230
|
+
"signature": "[QK:PI-DURABLE-TASK-SLEEPING-SHOWN]",
|
|
1231
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1232
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1233
|
+
},
|
|
1234
|
+
{
|
|
1235
|
+
"claim": "PI-DURABLE-TASK-BLOCKED-SHOWN",
|
|
1236
|
+
"title": "the panel stops marking blocked tasks: a task the SDK will not run reads as ordinary pending work",
|
|
1237
|
+
"subject": "pi/pi-durable/carrier/tui.js",
|
|
1238
|
+
"find": ["\t\tnode.blocked !== undefined ? `blocked:${node.blocked}` : \"\","],
|
|
1239
|
+
"replace": ["\t\t\"\","],
|
|
1240
|
+
"gate": ["bash", "run.sh", "check-pi-durable-carrier"],
|
|
1241
|
+
"timeoutSeconds": 300,
|
|
1242
|
+
"signature": "[QK:PI-DURABLE-TASK-BLOCKED-SHOWN]",
|
|
1243
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1244
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1245
|
+
},
|
|
1246
|
+
{
|
|
1247
|
+
"claim": "PI-DURABLE-TASK-BLOCKED-REASON",
|
|
1248
|
+
"title": "every blocked task is said to be parked by the restart limit, whatever reason the SDK gave",
|
|
1249
|
+
"subject": "pi/pi-durable/carrier/tui.js",
|
|
1250
|
+
"find": ["\t\tnode.blocked !== undefined ? `blocked:${node.blocked}` : \"\","],
|
|
1251
|
+
"replace": ["\t\tnode.blocked !== undefined ? `blocked:restart_limit` : \"\","],
|
|
1252
|
+
"gate": ["bash", "run.sh", "check-pi-durable-carrier"],
|
|
1253
|
+
"timeoutSeconds": 300,
|
|
1254
|
+
"signature": "[QK:PI-DURABLE-TASK-BLOCKED-REASON]",
|
|
1255
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1256
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
"claim": "PI-DURABLE-TEST-FIXTURES-NOT-SHIPPED",
|
|
1260
|
+
"title": "package.json drops its fixture negation, so every published tarball carries the test goldens under pi-extensions/**/fixtures/",
|
|
1261
|
+
"subject": "package.json",
|
|
1262
|
+
"find": ["\t\t\"!pi-extensions/**/*.test.ts\",", "\t\t\"!pi-extensions/**/fixtures/**\""],
|
|
1263
|
+
"replace": ["\t\t\"!pi-extensions/**/*.test.ts\""],
|
|
1264
|
+
"gate": ["bash", "run.sh", "check-pi-durable-carrier"],
|
|
1265
|
+
"timeoutSeconds": 300,
|
|
1266
|
+
"signature": "[QK:PI-DURABLE-TEST-FIXTURES-NOT-SHIPPED]",
|
|
1267
|
+
"signatureSource": "pi-extensions/lib/pi-durable-carrier.test.ts",
|
|
1268
|
+
"build": { "argv": ["bash", "scripts/build-bridge.sh"], "output": "mcp/entwurf-bridge/dist" }
|
|
1269
|
+
},
|
|
1210
1270
|
{
|
|
1211
1271
|
"claim": "PI-DURABLE-STREAM-TRANSPORT-WIRE",
|
|
1212
1272
|
"title": "the Harness settings stop carrying the transport: the provider never continues a response, so every request of a long session resends the whole conversation",
|