@junghanacs/entwurf 0.41.1 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/BASELINE.md +7 -5
- package/CHANGELOG.md +344 -0
- package/DELIVERY.md +37 -20
- package/ENTWURF.json +236 -0
- package/README.md +75 -65
- package/VERIFY.md +9 -9
- package/docs/external-mcp-host.md +1 -1
- package/docs/setup-clean-host.md +59 -33
- package/mcp/entwurf-bridge/dist/ENTWURF.json +236 -0
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +32 -190
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/agent-guidance.js +299 -0
- 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 +23 -24
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +15 -11
- 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 +29 -24
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +18 -16
- 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 +101 -32
- 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 +23 -45
- package/mcp/entwurf-bridge/dist/scripts/remote-pair-receive.js +12 -12
- package/mcp/entwurf-bridge/src/index.ts +126 -321
- package/native/win32-x64/entwurf_win.node +0 -0
- package/native/win32-x64/manifest.json +2 -2
- package/package.json +5 -4
- package/pi-extensions/lib/agent-guidance.ts +341 -0
- 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 +27 -30
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +15 -16
- 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 +29 -30
- package/pi-extensions/lib/mux-resume-call.ts +18 -19
- 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 +124 -34
- package/pi-extensions/meta-bridge-omp.ts +69 -7
- package/pi-extensions/meta-bridge-pi-durable.ts +23 -64
- package/run.sh +182 -22
- package/scripts/build-bridge.sh +10 -0
- package/scripts/check-agy-sender-identity.ts +6 -4
- package/scripts/check-capability-bundle-reach.ts +86 -0
- package/scripts/check-entwurf-self-address.ts +37 -6
- package/scripts/check-entwurf-v2-contract.ts +24 -2
- package/scripts/check-entwurf-v2-production.ts +45 -31
- package/scripts/check-entwurf-v2-surface.ts +94 -98
- package/scripts/check-gate-qualification.ts +17 -13
- package/scripts/check-mux-resume-call.ts +20 -3
- 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 +30 -0
- package/scripts/lib/codex-fresh-source-receipts.ts +112 -3
- package/scripts/lib/pi-durable-fresh-live-receipts.ts +29 -1
- package/scripts/mutants/agent-guidance.json +160 -0
- package/scripts/mutants/bridge-boot-resume.json +6 -8
- package/scripts/mutants/capability-bundle-reach.json +124 -0
- package/scripts/mutants/chain-terminus-publication.json +17 -0
- package/scripts/mutants/codex-native.json +98 -0
- package/scripts/mutants/control-send-receipt.json +23 -6
- package/scripts/mutants/mux-fresh-call.json +30 -4
- package/scripts/mutants/mux-resume-call.json +28 -3
- package/scripts/mutants/native-push-paused.json +17 -0
- package/scripts/mutants/omp-fresh.json +13 -2
- package/scripts/mutants/pack-install.json +46 -0
- package/scripts/mutants/pi-durable.json +17 -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 +177 -19
- package/scripts/mutants/remote-pair-transport.json +4 -4
- package/scripts/mutants/self-address.json +10 -10
- package/scripts/mutants/source-install.json +66 -0
- package/scripts/mutants/v2-surface.json +50 -64
- package/scripts/mutants/v2-visible-resume.json +11 -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 +50 -27
- 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-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
|
@@ -430,9 +430,9 @@ ok(
|
|
|
430
430
|
// cannot enforce it — these semantic fixtures (the SSOT predicate the 5b decider
|
|
431
431
|
// mints against) do.
|
|
432
432
|
eq(
|
|
433
|
-
"?6: PRE_PROBE_REJECT_REASONS = bad-target/target-locked/target-address-conflict/record-less-socket",
|
|
433
|
+
"?6: PRE_PROBE_REJECT_REASONS = bad-target/target-locked/target-address-conflict/record-less-socket/native-push-paused",
|
|
434
434
|
[...PRE_PROBE_REJECT_REASONS],
|
|
435
|
-
["bad-target", "target-locked", "target-address-conflict", "record-less-socket"],
|
|
435
|
+
["bad-target", "target-locked", "target-address-conflict", "record-less-socket", "native-push-paused"],
|
|
436
436
|
);
|
|
437
437
|
// the partition is exhaustive + disjoint: every reject reason is pre-probe XOR not.
|
|
438
438
|
for (const r of ENTWURF_V2_REJECT_REASONS) {
|
|
@@ -467,6 +467,28 @@ ok(
|
|
|
467
467
|
"taxonomy: record-less-socket is NOT a resolver reason (target-resolution stage, not a table cell)",
|
|
468
468
|
!(RESOLVER_REJECT_REASONS as readonly string[]).includes("record-less-socket"),
|
|
469
469
|
);
|
|
470
|
+
|
|
471
|
+
// #152: native-push-paused — a native-push backend paused by policy (antigravity: its LS
|
|
472
|
+
// refused entwurf's measured external agentapi calls for a missing CSRF token). The decider refuses it BEFORE
|
|
473
|
+
// any adapter probe, so it is pre-probe (null liveness), never a resolver table cell and
|
|
474
|
+
// never one of the post-probe native-push outcomes it must not impersonate (dead /
|
|
475
|
+
// indeterminate).
|
|
476
|
+
ok(
|
|
477
|
+
"taxonomy: native-push-paused is in the enum (#152)",
|
|
478
|
+
(ENTWURF_V2_REJECT_REASONS as readonly string[]).includes("native-push-paused"),
|
|
479
|
+
);
|
|
480
|
+
ok(
|
|
481
|
+
"?6: native-push-paused is pre-probe (#152 — refused before any adapter probe)",
|
|
482
|
+
isPreProbeReject("native-push-paused"),
|
|
483
|
+
);
|
|
484
|
+
ok(
|
|
485
|
+
"taxonomy: native-push-paused is NOT a resolver reason (#152)",
|
|
486
|
+
!(RESOLVER_REJECT_REASONS as readonly string[]).includes("native-push-paused"),
|
|
487
|
+
);
|
|
488
|
+
ok(
|
|
489
|
+
"taxonomy: native-push-paused is NOT a post-probe native-push reject (#152 — not dead, not indeterminate)",
|
|
490
|
+
!(NATIVE_PUSH_REJECT_REASONS as readonly string[]).includes("native-push-paused"),
|
|
491
|
+
);
|
|
470
492
|
ok(
|
|
471
493
|
"taxonomy: the retired socket-only-no-resume-authority is GONE from the enum (#50 C4)",
|
|
472
494
|
!(ENTWURF_V2_REJECT_REASONS as readonly string[]).includes("socket-only-no-resume-authority"),
|
|
@@ -344,45 +344,54 @@ async function main(): Promise<void> {
|
|
|
344
344
|
ok("A2: a quarantined target is never lock-acquired", spies.acquire.length === 0);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
// ── A3: native-push
|
|
347
|
+
// ── A3: antigravity native-push is PAUSED (#152) — the production factory refuses it ─
|
|
348
|
+
// The agy LS refused entwurf's measured external agentapi calls (missing CSRF token), so the public dispatch
|
|
349
|
+
// must stop at the decider with the named pre-probe reject: no adapter resolved, nothing
|
|
350
|
+
// probed or sent, no lock, no mailbox, and no sender envelope asked for. The probe fake is
|
|
351
|
+
// configured ALIVE on purpose — a regression that reached it would deliver, not hide.
|
|
348
352
|
{
|
|
349
353
|
const { deps, spies } = makeSpiedFactory({
|
|
350
354
|
backend: "antigravity",
|
|
351
355
|
nativePushProbe: { status: "alive", route: { backend: "antigravity", lsAddress: "127.0.0.1:5599" } },
|
|
352
356
|
});
|
|
353
357
|
const result = await runEntwurfV2({ target: GID, intent: "fire-and-forget", message: "hi agy" }, deps);
|
|
354
|
-
ok("A3: antigravity ff → native-push delivered", result.kind === "executed" && result.transport === "native-push");
|
|
355
|
-
ok("A3: decider probed the native-push adapter once (decide side)", spies.nativePushProbe.length === 1);
|
|
356
|
-
ok("A3: executor sent via the native-push adapter once (execute side)", spies.nativePushSend.length === 1);
|
|
357
|
-
ok("A3: send used the DECIDER-probed route", spies.nativePushSend[0]?.route === "127.0.0.1:5599");
|
|
358
|
-
ok("A3: send carried the dispatch message", spies.nativePushSend[0]?.content.includes("hi agy") === true);
|
|
359
358
|
ok(
|
|
360
|
-
"A3:
|
|
361
|
-
|
|
359
|
+
"A3: antigravity ff → rejected native-push-paused (#152), observedLiveness null",
|
|
360
|
+
result.kind === "rejected" &&
|
|
361
|
+
result.receipt.reason === "native-push-paused" &&
|
|
362
|
+
result.receipt.observedLiveness === null,
|
|
362
363
|
);
|
|
363
|
-
ok("A3: native-push
|
|
364
|
-
ok(
|
|
364
|
+
ok("A3: paused agy resolved NO native-push adapter (neither hand)", spies.nativePushResolve.length === 0);
|
|
365
|
+
ok(
|
|
366
|
+
"A3: paused agy probed and sent nothing",
|
|
367
|
+
spies.nativePushProbe.length === 0 && spies.nativePushSend.length === 0,
|
|
368
|
+
);
|
|
369
|
+
ok("A3: paused agy took no lock and enqueued no mailbox", spies.acquire.length === 0 && spies.enqueue.length === 0);
|
|
370
|
+
ok("A3: paused agy never asked the sender provider (no execute phase)", spies.senderCalls.length === 0);
|
|
365
371
|
}
|
|
372
|
+
// ── A3c: native-push wiring — ONE injected adapter feeds BOTH decider + executor (Codex,
|
|
373
|
+
// the active native-push backend while agy is paused) ─
|
|
366
374
|
{
|
|
375
|
+
const socketPath = "/home/operator/.codex/app-server-control/app-server-control.sock";
|
|
367
376
|
const { deps, spies } = makeSpiedFactory({
|
|
368
377
|
backend: "codex",
|
|
369
|
-
nativePushProbe: {
|
|
370
|
-
status: "alive",
|
|
371
|
-
route: { backend: "codex", socketPath: "/home/operator/.codex/app-server-control/app-server-control.sock" },
|
|
372
|
-
},
|
|
378
|
+
nativePushProbe: { status: "alive", route: { backend: "codex", socketPath } },
|
|
373
379
|
});
|
|
374
380
|
const result = await runEntwurfV2({ target: GID, intent: "fire-and-forget", message: "hi codex" }, deps);
|
|
375
381
|
ok(
|
|
376
382
|
"[QK:CODEX-NATIVE-PRODUCTION-WIRING] Codex ff → native-push delivered",
|
|
377
383
|
result.kind === "executed" && result.transport === "native-push",
|
|
378
384
|
);
|
|
385
|
+
ok("A3c: decider probed the native-push adapter once (decide side)", spies.nativePushProbe.length === 1);
|
|
386
|
+
ok("A3c: executor sent via the native-push adapter once (execute side)", spies.nativePushSend.length === 1);
|
|
379
387
|
ok(
|
|
380
|
-
"A3c:
|
|
381
|
-
spies.
|
|
388
|
+
"A3c: send used the DECIDER-probed route (the planted Codex UDS)",
|
|
389
|
+
spies.nativePushSend[0]?.route === socketPath,
|
|
382
390
|
);
|
|
391
|
+
ok("A3c: send carried the dispatch message", spies.nativePushSend[0]?.content.includes("hi codex") === true);
|
|
383
392
|
ok(
|
|
384
|
-
"A3c:
|
|
385
|
-
spies.
|
|
393
|
+
"A3c: BOTH hands resolved the SAME adapter (for 'codex')",
|
|
394
|
+
spies.nativePushResolve.length === 2 && spies.nativePushResolve.every((b) => b === "codex"),
|
|
386
395
|
);
|
|
387
396
|
ok(
|
|
388
397
|
"A3c: Codex native-push remains lock-free and mailbox-free",
|
|
@@ -394,16 +403,20 @@ async function main(): Promise<void> {
|
|
|
394
403
|
// Codex thread arrived as bare text, so the receiving citizen could not name who called it
|
|
395
404
|
// and the callback was uncorrelatable. Direct injection has neither the control socket's RPC
|
|
396
405
|
// framing nor a mailbox file, so the envelope must ride IN the body — the same bytes
|
|
397
|
-
// `formatMetaMailboxBody` gives the mailbox rail. ONE rail
|
|
398
|
-
//
|
|
406
|
+
// `formatMetaMailboxBody` gives the mailbox rail. ONE rail, no per-backend branch; it is
|
|
407
|
+
// proven on Codex, the native-push backend public dispatch still reaches while agy is
|
|
408
|
+
// paused (#152).
|
|
399
409
|
{
|
|
400
|
-
const route = {
|
|
410
|
+
const route = {
|
|
411
|
+
backend: "codex",
|
|
412
|
+
socketPath: "/home/operator/.codex/app-server-control/app-server-control.sock",
|
|
413
|
+
} as const;
|
|
401
414
|
const { deps, spies } = makeSpiedFactory({
|
|
402
|
-
backend: "
|
|
415
|
+
backend: "codex",
|
|
403
416
|
nativePushProbe: { status: "alive", route },
|
|
404
417
|
});
|
|
405
418
|
const { result, executeEvents } = await runInTwoPhases(
|
|
406
|
-
{ target: GID, intent: "fire-and-forget", message: "hi
|
|
419
|
+
{ target: GID, intent: "fire-and-forget", message: "hi codex", wantsReply: true },
|
|
407
420
|
deps,
|
|
408
421
|
spies,
|
|
409
422
|
);
|
|
@@ -417,12 +430,12 @@ async function main(): Promise<void> {
|
|
|
417
430
|
result.kind === "executed" && spies.senderCalls.length === 1,
|
|
418
431
|
);
|
|
419
432
|
ok(
|
|
420
|
-
"[QK:NATIVE-PUSH-SENDER-ENVELOPE]
|
|
421
|
-
spies.nativePushSend[0]?.content === formatMetaMailboxBody(SENDER, "hi
|
|
433
|
+
"[QK:NATIVE-PUSH-SENDER-ENVELOPE] native-push direct injection carries the mailbox-serialized trusted envelope",
|
|
434
|
+
spies.nativePushSend[0]?.content === formatMetaMailboxBody(SENDER, "hi codex", true),
|
|
422
435
|
);
|
|
423
436
|
ok(
|
|
424
437
|
"A3d: the enveloped body is NOT the raw plan message (an envelope was actually added)",
|
|
425
|
-
spies.nativePushSend[0]?.content !== "hi
|
|
438
|
+
spies.nativePushSend[0]?.content !== "hi codex",
|
|
426
439
|
);
|
|
427
440
|
ok(
|
|
428
441
|
"A3d: wants_reply rides the envelope on this rail",
|
|
@@ -439,7 +452,7 @@ async function main(): Promise<void> {
|
|
|
439
452
|
);
|
|
440
453
|
}
|
|
441
454
|
{
|
|
442
|
-
// Same rail,
|
|
455
|
+
// Same rail, wants_reply=false — the envelope is still rendered, without the reply line.
|
|
443
456
|
const route = {
|
|
444
457
|
backend: "codex",
|
|
445
458
|
socketPath: "/home/operator/.codex/app-server-control/app-server-control.sock",
|
|
@@ -447,7 +460,7 @@ async function main(): Promise<void> {
|
|
|
447
460
|
const { deps, spies } = makeSpiedFactory({ backend: "codex", nativePushProbe: { status: "alive", route } });
|
|
448
461
|
const result = await runEntwurfV2({ target: GID, intent: "fire-and-forget", message: "hi codex" }, deps);
|
|
449
462
|
ok(
|
|
450
|
-
"A3d:
|
|
463
|
+
"A3d: wants_reply=false direct injection carries the mailbox-serialized envelope for that flag",
|
|
451
464
|
result.kind === "executed" &&
|
|
452
465
|
spies.nativePushSend[0]?.content === formatMetaMailboxBody(SENDER, "hi codex", false),
|
|
453
466
|
);
|
|
@@ -503,14 +516,15 @@ async function main(): Promise<void> {
|
|
|
503
516
|
}
|
|
504
517
|
|
|
505
518
|
{
|
|
506
|
-
//
|
|
519
|
+
// codex + dead probe → reject native-push-target-dead, NO send. (agy never reaches a
|
|
520
|
+
// probe while paused, #152 — A3.)
|
|
507
521
|
const { deps, spies } = makeSpiedFactory({
|
|
508
|
-
backend: "
|
|
522
|
+
backend: "codex",
|
|
509
523
|
nativePushProbe: { status: "dead", reason: "no host" },
|
|
510
524
|
});
|
|
511
525
|
const result = await runEntwurfV2({ target: GID, intent: "fire-and-forget", message: "x" }, deps);
|
|
512
526
|
ok(
|
|
513
|
-
"A3b:
|
|
527
|
+
"A3b: codex ff + dead → rejected native-push-target-dead",
|
|
514
528
|
result.kind === "rejected" && result.receipt.reason === "native-push-target-dead",
|
|
515
529
|
);
|
|
516
530
|
ok("A3b: no send attempted on a dead target", spies.nativePushSend.length === 0);
|
|
@@ -21,6 +21,12 @@ import assert from "node:assert/strict";
|
|
|
21
21
|
import * as fs from "node:fs/promises";
|
|
22
22
|
import * as path from "node:path";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
|
+
import {
|
|
25
|
+
ENTWURF_DELIVERY_RESULT_CLAUSES,
|
|
26
|
+
ENTWURF_REJECT_HINTS,
|
|
27
|
+
ENTWURF_SLOTTED_REJECT_HINTS,
|
|
28
|
+
ENTWURF_TOOL_GUIDANCE,
|
|
29
|
+
} from "../pi-extensions/lib/agent-guidance.ts";
|
|
24
30
|
import type { EntwurfV2RunResult } from "../pi-extensions/lib/entwurf-v2-runner.ts";
|
|
25
31
|
import {
|
|
26
32
|
actionableRejectHint,
|
|
@@ -28,17 +34,7 @@ import {
|
|
|
28
34
|
type SurfaceEntwurfV2Params,
|
|
29
35
|
toDispatchInput,
|
|
30
36
|
} from "../pi-extensions/lib/entwurf-v2-surface.ts";
|
|
31
|
-
|
|
32
|
-
/** Cut ONE model-facing string out of a registration block so two descriptions in the same
|
|
33
|
-
* block cannot satisfy an assertion for each other (round-4 masking, 2026-07-27). Returns ""
|
|
34
|
-
* when either marker is missing, which the callers' `length > 120` guard turns into a loud
|
|
35
|
-
* failure rather than a silent pass. */
|
|
36
|
-
function sliceDescription(block: string, startMarker: string, endMarker: string): string {
|
|
37
|
-
const s = block.indexOf(startMarker);
|
|
38
|
-
if (s === -1) return "";
|
|
39
|
-
const e = block.indexOf(endMarker, s + startMarker.length);
|
|
40
|
-
return e === -1 ? "" : block.slice(s, e);
|
|
41
|
-
}
|
|
37
|
+
import { FRESH_CUT_PRESCRIPTION } from "../pi-extensions/lib/meta-session.ts";
|
|
42
38
|
|
|
43
39
|
let passed = 0;
|
|
44
40
|
function ok(label: string, cond: boolean): void {
|
|
@@ -47,17 +43,6 @@ function ok(label: string, cond: boolean): void {
|
|
|
47
43
|
passed++;
|
|
48
44
|
}
|
|
49
45
|
|
|
50
|
-
/**
|
|
51
|
-
* Collapse a model-facing string's SOURCE form into the text the model actually reads:
|
|
52
|
-
* drop TS string-concat glue between adjacent literals and normalize whitespace.
|
|
53
|
-
*/
|
|
54
|
-
function modelText(slice: string): string {
|
|
55
|
-
return slice
|
|
56
|
-
.replace(/["']\s*\+\s*["']/g, "")
|
|
57
|
-
.replace(/\s+/g, " ")
|
|
58
|
-
.trim();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
46
|
/**
|
|
62
47
|
* F-2 (2026-07-27): the two model-facing surfaces described the lock, `mode`, and the
|
|
63
48
|
* unsupported-citizen outcome set in ways the code does not support. Measured against
|
|
@@ -77,13 +62,11 @@ function modelText(slice: string): string {
|
|
|
77
62
|
* Applied to BOTH surfaces from one predicate so they cannot drift apart again.
|
|
78
63
|
*/
|
|
79
64
|
function assertRailSemantics(tag: string, longDescRaw: string, intentDescRaw: string, modeDescRaw: string): void {
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
const intentDesc = modelText(intentDescRaw);
|
|
86
|
-
const modeDesc = modelText(modeDescRaw);
|
|
65
|
+
// Inputs are decoded product strings, not TS scaffolding. Keep these semantic predicates
|
|
66
|
+
// separate from the exact, unnormalized pre-extraction byte oracle beside the reader.
|
|
67
|
+
const longDesc = longDescRaw;
|
|
68
|
+
const intentDesc = intentDescRaw;
|
|
69
|
+
const modeDesc = modeDescRaw;
|
|
87
70
|
ok(
|
|
88
71
|
`${tag} — long description scopes the per-target lock to the control-socket DOMAIN [QK:V2SURF-MCP-LOCK-DOMAIN]`,
|
|
89
72
|
/control-socket-DOMAIN\s+dispatch/.test(longDesc) && /lock-free/.test(longDesc),
|
|
@@ -155,7 +138,7 @@ function assertRailSemantics(tag: string, longDescRaw: string, intentDescRaw: st
|
|
|
155
138
|
* DORMANT HONESTY — the model-facing replacement for the retired `V2SURF-MERGED-REJECT` claim,
|
|
156
139
|
* whose subject (two distinct OWNED rejects) left with the `owned-outcome` intent.
|
|
157
140
|
*
|
|
158
|
-
* After the visible-first cut a dormant socket-domain citizen
|
|
141
|
+
* After the visible-first cut a dormant socket-domain citizen rejects delivery by v2, and
|
|
159
142
|
* these four strings are the only place a caller learns that BEFORE spending a dispatch. So each
|
|
160
143
|
* one must, on its own:
|
|
161
144
|
* - name the reason it will actually get back (`dormant-fire-forget-unsupported`);
|
|
@@ -175,7 +158,7 @@ function assertRailSemantics(tag: string, longDescRaw: string, intentDescRaw: st
|
|
|
175
158
|
* run unlabelled behind it — still real assertions, just not this claim's signature.
|
|
176
159
|
*/
|
|
177
160
|
function assertDormantHonesty(tag: string, rawText: string): void {
|
|
178
|
-
const text =
|
|
161
|
+
const text = rawText;
|
|
179
162
|
const at = text.indexOf("owned-outcome");
|
|
180
163
|
ok(
|
|
181
164
|
`${tag} — names the withdrawn intent owned-outcome and says "withdrawn" beside it (not as an offer) [QK:V2SURF-DORMANT-HONESTY]`,
|
|
@@ -192,18 +175,23 @@ function assertDormantHonesty(tag: string, rawText: string): void {
|
|
|
192
175
|
* PEERS DEAD-ROW HONESTY. `entwurf_peers` is a FACT surface and stays one: this claim must never
|
|
193
176
|
* be satisfiable by adding a per-row action/routing field, which is why it is asserted on the
|
|
194
177
|
* DESCRIPTION and paired with a negative that forbids the row-level fix. What the description owes
|
|
195
|
-
* a caller is that `dead` is a reported fact carrying no invitation
|
|
196
|
-
*
|
|
178
|
+
* a caller is that `dead` is a reported fact carrying no delivery invitation. A separately
|
|
179
|
+
* requested, proven-dormant Pi/Claude lifecycle can reopen the same id without submitting a prompt.
|
|
197
180
|
*/
|
|
198
181
|
function assertPeersDeadRowHonesty(tag: string, rawBlock: string): void {
|
|
199
|
-
const text =
|
|
182
|
+
const text = rawBlock;
|
|
200
183
|
ok(
|
|
201
|
-
`${tag} — entwurf_peers
|
|
202
|
-
/REPORTED FACT/.test(text) &&
|
|
184
|
+
`${tag} — entwurf_peers reports dead delivery unavailable, no action grant, and separate explicit-operator promptless resume [QK:V2SURF-PEERS-DEAD-ROW]`,
|
|
185
|
+
/REPORTED FACT/.test(text) &&
|
|
186
|
+
/grants no action/.test(text) &&
|
|
187
|
+
/not an invitation to dispatch/.test(text) &&
|
|
188
|
+
/no entwurf_v2 delivery is available while it is dormant/.test(text) &&
|
|
189
|
+
/Only on an explicit operator request, the separate entwurf_resume_call/.test(text) &&
|
|
190
|
+
/proven-dormant Pi or Claude Code citizen under the same id, submitting no prompt/.test(text),
|
|
203
191
|
);
|
|
204
192
|
ok(
|
|
205
|
-
`${tag} — entwurf_peers
|
|
206
|
-
/dormant/.test(text) &&
|
|
193
|
+
`${tag} — entwurf_peers does not turn delivery dormancy into a ban on every lifecycle verb`,
|
|
194
|
+
/dormant/.test(text) && !/unreachable by any verb/.test(text),
|
|
207
195
|
);
|
|
208
196
|
// The forbidden repair: teaching the row itself to carry a verb. The facts-only rule is what
|
|
209
197
|
// keeps this surface from becoming a second dispatch table, so a description that promised a
|
|
@@ -214,14 +202,6 @@ function assertPeersDeadRowHonesty(tag: string, rawBlock: string): void {
|
|
|
214
202
|
);
|
|
215
203
|
}
|
|
216
204
|
|
|
217
|
-
/**
|
|
218
|
-
* Containment-disjointness is NOT enough to prove a description slice is tight. Round 5
|
|
219
|
-
* (2026-07-27) shipped a "long description" slice of 4,468 chars that SPANNED the parameter
|
|
220
|
-
* entries because a bare `description:` marker matched the `target` param first — and two
|
|
221
|
-
* over-wide slices can still be mutually non-containing. So pin the ABSENCE of every
|
|
222
|
-
* parameter marker in the long-description slice: if the slice ever swallows the schema
|
|
223
|
-
* again, this fails instead of silently satisfying the schema's own text.
|
|
224
|
-
*/
|
|
225
205
|
/**
|
|
226
206
|
* HOST TRUNCATION CAP. Measured 2026-07-30 on both Claude ACP and stock Claude Code: a tool
|
|
227
207
|
* description longer than this is cut mid-sentence and the tail is replaced with `… [truncated]`.
|
|
@@ -230,30 +210,12 @@ function assertPeersDeadRowHonesty(tag: string, rawBlock: string): void {
|
|
|
230
210
|
* to choose an intent. Every other assertion in this file checks that a sentence is PRESENT in
|
|
231
211
|
* source; none of them can see that the host threw half of it away. This one can.
|
|
232
212
|
*
|
|
233
|
-
* Judged on
|
|
234
|
-
*
|
|
235
|
-
* length the host actually measures.
|
|
213
|
+
* Judged on the decoded JSON string, with no source scaffolding or whitespace normalization.
|
|
214
|
+
* Exact current fields are checked separately against frozen originals plus reviewed literal amendments.
|
|
236
215
|
*/
|
|
237
216
|
const HOST_DESCRIPTION_CAP = 2048;
|
|
238
217
|
|
|
239
|
-
|
|
240
|
-
* The string the HOST measures, recovered from either surface's source scaffolding: drop the
|
|
241
|
-
* `description:` key and the outer template-literal / string-literal fence, and unescape `\"`.
|
|
242
|
-
* Counting the raw slice instead would charge the text for punctuation the model never sees —
|
|
243
|
-
* and the two surfaces carry DIFFERENT punctuation, so the cap would mean two different things.
|
|
244
|
-
*/
|
|
245
|
-
function renderedDescription(raw: string): string {
|
|
246
|
-
const flat = modelText(raw);
|
|
247
|
-
// Anchor on the description's own first word rather than on scaffolding: the two surfaces put
|
|
248
|
-
// DIFFERENT preludes in front of it (the MCP slice starts at the tool name), and counting those
|
|
249
|
-
// would report a number the host never measures — a cap gate that cites the wrong length gets
|
|
250
|
-
// quoted as if it were the real one.
|
|
251
|
-
const from = flat.indexOf("CANONICAL");
|
|
252
|
-
return (from >= 0 ? flat.slice(from) : flat).replace(/[`"],?$/, "").replace(/\\"/g, '"');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function assertDescriptionFitsHostCap(tag: string, longDescRaw: string): void {
|
|
256
|
-
const rendered = renderedDescription(longDescRaw);
|
|
218
|
+
function assertDescriptionFitsHostCap(tag: string, rendered: string): void {
|
|
257
219
|
ok(
|
|
258
220
|
`${tag} — long description fits the host's ${HOST_DESCRIPTION_CAP}-char cap (${rendered.length}) ` +
|
|
259
221
|
"[QK:V2SURF-DESC-FITS-HOST-CAP]",
|
|
@@ -261,12 +223,6 @@ function assertDescriptionFitsHostCap(tag: string, longDescRaw: string): void {
|
|
|
261
223
|
);
|
|
262
224
|
}
|
|
263
225
|
|
|
264
|
-
function assertLongDescExcludesParams(tag: string, longDesc: string, markers: readonly string[]): void {
|
|
265
|
-
for (const marker of markers) {
|
|
266
|
-
ok(`${tag} — long description slice excludes the \`${marker}\` parameter marker`, !longDesc.includes(marker));
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
226
|
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
|
271
227
|
const REPO = path.join(HERE, "..");
|
|
272
228
|
const SURFACE_SRC = path.join(REPO, "pi-extensions/lib/entwurf-v2-surface.ts");
|
|
@@ -587,9 +543,24 @@ async function main(): Promise<void> {
|
|
|
587
543
|
!/DELIVERED|\bdelivered\b/.test(dirtyRefused.text) &&
|
|
588
544
|
// and every one of them keeps the thing the operator must act on
|
|
589
545
|
[dirtyBusy, dirtyMailbox, dirtyRefused].every(
|
|
590
|
-
(r) =>
|
|
546
|
+
(r) =>
|
|
547
|
+
r.isError &&
|
|
548
|
+
r.text.includes("DIRTY") &&
|
|
549
|
+
r.text.includes("do NOT retry automatically") &&
|
|
550
|
+
r.text.includes("operator resolve the lock") &&
|
|
551
|
+
!r.text.includes("would double-deliver"),
|
|
591
552
|
),
|
|
592
553
|
);
|
|
554
|
+
// #154 E1a: the two static clauses of this receipt are authored in root ENTWURF.json; the
|
|
555
|
+
// syntax around them stays here, so the whole rendered line is compared, not a fragment.
|
|
556
|
+
const dirtyClause = ENTWURF_DELIVERY_RESULT_CLAUSES["dirty-lock"];
|
|
557
|
+
ok(
|
|
558
|
+
"[QK:V2SURF-DELIVERY-RESULT-CLAUSES-FROM-ROOT] the dirty-lock receipt renders the root finalized-rejected and dirty-lock clauses byte for byte inside its code-owned syntax",
|
|
559
|
+
dirtyBusy.text ===
|
|
560
|
+
`entwurf_v2 control-socket finalized as queued-steer, and ${dirtyClause}\n error: release boom` &&
|
|
561
|
+
dirtyRefused.text ===
|
|
562
|
+
`entwurf_v2 control-socket finalized as rejected (compacting) — ${ENTWURF_DELIVERY_RESULT_CLAUSES["finalized-rejected"]}, and ${dirtyClause}\n error: release boom`,
|
|
563
|
+
);
|
|
593
564
|
|
|
594
565
|
// plain execution-failed → error
|
|
595
566
|
const failed: EntwurfV2RunResult = {
|
|
@@ -683,6 +654,25 @@ async function main(): Promise<void> {
|
|
|
683
654
|
rls.includes("restart it under the current runtime") &&
|
|
684
655
|
rls.includes("meta-bridge-fresh-cut"),
|
|
685
656
|
);
|
|
657
|
+
// #154 E1b: the text on either side of the fix command is authored in root ENTWURF.json and the
|
|
658
|
+
// command comes from its owner, so the WHOLE hint is compared against that composition — the
|
|
659
|
+
// phrase checks above stay, and a hand-kept copy of the text that still carries them dies here.
|
|
660
|
+
const rlsRoot = ENTWURF_SLOTTED_REJECT_HINTS["record-less-socket"];
|
|
661
|
+
ok(
|
|
662
|
+
"[QK:V2SURF-RECORD-LESS-SOCKET-HINT-FROM-ROOT] the record-less-socket hint is exactly the root text before the fix command, the command from its meta-session owner, and the root text after it",
|
|
663
|
+
rls === `${rlsRoot.beforeFreshCutPrescription}${FRESH_CUT_PRESCRIPTION}${rlsRoot.afterFreshCutPrescription}`,
|
|
664
|
+
);
|
|
665
|
+
// #154 C1-B: the five static hints are authored in root ENTWURF.json. This is the WIRING
|
|
666
|
+
// claim — what the surface returns is the Root value for every declared reason — compared
|
|
667
|
+
// against the loaded Root, never a fixture, so a Root prose mutant still dies at its own
|
|
668
|
+
// semantic QK above. The C0 byte oracle lives beside the reader (GUIDANCE-REJECT-HINTS-ORIGINAL).
|
|
669
|
+
const unwired = Object.entries(ENTWURF_REJECT_HINTS)
|
|
670
|
+
.filter(([reason, text]) => actionableRejectHint(reason) !== text)
|
|
671
|
+
.map(([reason]) => reason);
|
|
672
|
+
ok(
|
|
673
|
+
`2D: every static reject hint the surface renders is the root ENTWURF.json value [QK:V2SURF-REJECT-HINTS-FROM-ROOT] (unwired: ${JSON.stringify(unwired)})`,
|
|
674
|
+
Object.keys(ENTWURF_REJECT_HINTS).length === 5 && unwired.length === 0,
|
|
675
|
+
);
|
|
686
676
|
}
|
|
687
677
|
|
|
688
678
|
// ── 6: RETIRED — parseEntwurfPrefixRootsEnv / ENTWURF_PREFIX_ROOTS ────────
|
|
@@ -776,14 +766,10 @@ async function main(): Promise<void> {
|
|
|
776
766
|
// Same shipped-rail completeness rule as the pi-native surface (4), and split the SAME
|
|
777
767
|
// two ways: the long tool description and the `intent` param description must EACH be
|
|
778
768
|
// true on their own (see the round-4 masking note in block 4).
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
const mcpSchemaStart = v2Block.indexOf("\t{");
|
|
782
|
-
ok("5: MCP — schema boundary marker is present (slice cannot silently widen)", mcpSchemaStart > 0);
|
|
783
|
-
const mcpLongDesc = v2Block.slice(0, mcpSchemaStart);
|
|
784
|
-
const mcpIntentDesc = sliceDescription(v2Block, "intent: z", "message: z");
|
|
769
|
+
const mcpLongDesc = ENTWURF_TOOL_GUIDANCE.entwurf_v2.descriptions.mcp;
|
|
770
|
+
const mcpIntentDesc = ENTWURF_TOOL_GUIDANCE.entwurf_v2.parameters.intent;
|
|
785
771
|
ok(
|
|
786
|
-
"5: MCP — long/intent
|
|
772
|
+
"5: MCP — long/intent strings are disjoint (neither can satisfy the other's claim)",
|
|
787
773
|
mcpLongDesc.length > 0 &&
|
|
788
774
|
mcpIntentDesc.length > 0 &&
|
|
789
775
|
!mcpLongDesc.includes(mcpIntentDesc) &&
|
|
@@ -799,11 +785,12 @@ async function main(): Promise<void> {
|
|
|
799
785
|
}
|
|
800
786
|
ok("5: MCP — long description denies native-push a mailbox", /NO mailbox/.test(mcpLongDesc));
|
|
801
787
|
ok(
|
|
802
|
-
"5: MCP — long description
|
|
803
|
-
/
|
|
788
|
+
"5: MCP — long description says a live socket can receive fire-and-forget, and unsupported is not reachability",
|
|
789
|
+
/A live socket can receive fire-and-forget/.test(mcpLongDesc) &&
|
|
790
|
+
/not reachability/.test(mcpLongDesc) &&
|
|
791
|
+
!/liveness=alive\s*→\s*fire-and-forget/.test(mcpLongDesc),
|
|
804
792
|
);
|
|
805
|
-
|
|
806
|
-
const mcpModeDesc = sliceDescription(v2Block, "mode: z", "wants_reply: z");
|
|
793
|
+
const mcpModeDesc = ENTWURF_TOOL_GUIDANCE.entwurf_v2.parameters.mode;
|
|
807
794
|
assertRailSemantics("5: MCP", mcpLongDesc, mcpIntentDesc, mcpModeDesc);
|
|
808
795
|
assertDescriptionFitsHostCap("5: MCP", mcpLongDesc);
|
|
809
796
|
|
|
@@ -817,21 +804,20 @@ async function main(): Promise<void> {
|
|
|
817
804
|
"5: MCP — entwurf_peers block has a REAL end boundary (next server.tool present)",
|
|
818
805
|
peersStart !== -1 && peersAfter > peersStart,
|
|
819
806
|
);
|
|
820
|
-
const
|
|
821
|
-
ok("5: MCP — entwurf_peers block is isolated (non-vacuous)", peersBlock.length > 200);
|
|
807
|
+
const peersText = ENTWURF_TOOL_GUIDANCE.entwurf_peers.descriptions.mcp;
|
|
822
808
|
ok(
|
|
823
809
|
"5: MCP — entwurf_peers names the THIRD answer (a reject), not just the two allow rails",
|
|
824
|
-
/mailbox-undeliverable/.test(
|
|
810
|
+
/mailbox-undeliverable/.test(peersText) && /native-push-target-dead/.test(peersText),
|
|
825
811
|
);
|
|
826
812
|
ok(
|
|
827
813
|
"5: MCP — entwurf_peers no longer claims `unsupported` does NOT mean unreachable",
|
|
828
|
-
!/does NOT mean unreachable/.test(
|
|
814
|
+
!/does NOT mean unreachable/.test(peersText),
|
|
829
815
|
);
|
|
830
816
|
// Visible-first cut, operator-surface half: a dormant citizen still gets a row here, and a
|
|
831
817
|
// caller who reads "it is in the list" as "I can dispatch to it" spends a dispatch to find
|
|
832
818
|
// out otherwise. The FACT stays a fact — no per-row action field, no routing verb, which is
|
|
833
819
|
// the rule this surface exists under — so the correction has to live in the description.
|
|
834
|
-
assertPeersDeadRowHonesty("5: MCP",
|
|
820
|
+
assertPeersDeadRowHonesty("5: MCP", peersText);
|
|
835
821
|
|
|
836
822
|
// F-7: entwurf_inbox_read described itself as draining "your own" inbox while the handler
|
|
837
823
|
// passes the CALLER-SUPPLIED gardenId straight to readMetaInbox with no comparison against
|
|
@@ -845,7 +831,7 @@ async function main(): Promise<void> {
|
|
|
845
831
|
inboxStart !== -1 && inboxAfter > inboxStart,
|
|
846
832
|
);
|
|
847
833
|
const inboxBlock = src.slice(inboxStart, inboxAfter);
|
|
848
|
-
const inboxText =
|
|
834
|
+
const inboxText = ENTWURF_TOOL_GUIDANCE.entwurf_inbox_read.descriptions.mcp;
|
|
849
835
|
ok("5: MCP — entwurf_inbox_read block is isolated (non-vacuous)", inboxText.length > 200);
|
|
850
836
|
ok(
|
|
851
837
|
"5: MCP — entwurf_inbox_read states the garden id is CALLER-SUPPLIED and unverified [QK:V2SURF-INBOX-SCOPE-HONESTY]",
|
|
@@ -971,20 +957,27 @@ async function main(): Promise<void> {
|
|
|
971
957
|
// rail's four boundaries are the ONLY receiver-acceptance values; a mailbox answers with an
|
|
972
958
|
// ENQUEUE receipt and native-push with an INJECTION, and folding those into the boundary union
|
|
973
959
|
// would tell a caller that `mailbox-enqueued` is something a receiver observed about its own
|
|
974
|
-
// queues.
|
|
960
|
+
// queues. The socket dispatch may re-resolve to a mailbox leg and report mailbox-enqueued;
|
|
961
|
+
// that exception must name the leg, not silently invent a fifth receiver queue boundary.
|
|
962
|
+
// Missing either rail is red — the earlier draft listed `mailbox-enqueued` beside the
|
|
975
963
|
// four and left native-push out entirely, and nothing noticed.
|
|
976
964
|
{
|
|
977
|
-
const outcomeSites = [
|
|
965
|
+
const outcomeSites = [
|
|
966
|
+
{
|
|
967
|
+
rel: "ENTWURF.json tools.entwurf_v2.descriptions.mcp",
|
|
968
|
+
text: ENTWURF_TOOL_GUIDANCE.entwurf_v2.descriptions.mcp,
|
|
969
|
+
},
|
|
970
|
+
];
|
|
978
971
|
const missing: string[] = [];
|
|
979
|
-
for (const rel of outcomeSites) {
|
|
980
|
-
const text = await fs.readFile(path.join(REPO, rel), "utf8");
|
|
972
|
+
for (const { rel, text } of outcomeSites) {
|
|
981
973
|
const at = text.indexOf("reports ONE");
|
|
982
974
|
const blurb = at < 0 ? "" : text.slice(at, at + 900);
|
|
983
975
|
if (!/acceptance boundary/i.test(blurb)) missing.push(`${rel}: control receiver acceptance boundary`);
|
|
984
976
|
for (const b of ["sent", "queued-steer", "queued-follow-up", "accepted-unknown-boundary"]) {
|
|
985
977
|
if (!blurb.includes(b)) missing.push(`${rel}: boundary ${b}`);
|
|
986
978
|
}
|
|
987
|
-
if (
|
|
979
|
+
if (!blurb.includes("those four, or `mailbox-enqueued` on a re-resolved mailbox leg"))
|
|
980
|
+
missing.push(`${rel}: the four receiver boundaries and the explicitly re-resolved mailbox leg`);
|
|
988
981
|
if (!/mailbox ENQUEUE/i.test(blurb)) missing.push(`${rel}: mailbox enqueue receipt`);
|
|
989
982
|
if (!/native-push INJECTION/i.test(blurb)) missing.push(`${rel}: native-push injection`);
|
|
990
983
|
if (!/rejection|rejected/i.test(blurb)) missing.push(`${rel}: rejection`);
|
|
@@ -994,7 +987,7 @@ async function main(): Promise<void> {
|
|
|
994
987
|
}
|
|
995
988
|
}
|
|
996
989
|
ok(
|
|
997
|
-
`[QK:SEND-OUTCOME-LIST-NAMES-EVERY-RAIL] the tool description names each rail's own result — the control receiver's four acceptance boundaries (
|
|
990
|
+
`[QK:SEND-OUTCOME-LIST-NAMES-EVERY-RAIL] the tool description names each rail's own result — the control receiver's four acceptance boundaries (or mailbox-enqueued on an explicitly re-resolved mailbox leg), the mailbox ENQUEUE receipt, the native-push INJECTION, a rejection, and accepted-but-lock-dirty — so a caller is never told that one rail's vocabulary describes another's (missing: ${JSON.stringify(missing)})`,
|
|
998
991
|
missing.length === 0,
|
|
999
992
|
);
|
|
1000
993
|
}
|
|
@@ -1029,7 +1022,10 @@ async function main(): Promise<void> {
|
|
|
1029
1022
|
];
|
|
1030
1023
|
const gaps: string[] = [];
|
|
1031
1024
|
for (const rel of sites) {
|
|
1032
|
-
const text =
|
|
1025
|
+
const text =
|
|
1026
|
+
rel === "mcp/entwurf-bridge/src/index.ts"
|
|
1027
|
+
? ENTWURF_TOOL_GUIDANCE.entwurf_v2.parameters.mode
|
|
1028
|
+
: await fs.readFile(path.join(REPO, rel), "utf8");
|
|
1033
1029
|
for (const axis of axes) if (!axis.holds(text)) gaps.push(`${rel}: ${axis.name}`);
|
|
1034
1030
|
if (/steer \((?:interrupt|immediate)|interrupt the current turn|steer = interrupt/i.test(text)) {
|
|
1035
1031
|
gaps.push(`${rel}: still claims steer interrupts`);
|
|
@@ -3446,6 +3446,7 @@ let manifestCount: number;
|
|
|
3446
3446
|
"acp-stream-hooks": 10,
|
|
3447
3447
|
"acp-usage-accounting": 12,
|
|
3448
3448
|
"acp-vendor-rejection": 4,
|
|
3449
|
+
"agent-guidance": 14,
|
|
3449
3450
|
"agy-permission": 6,
|
|
3450
3451
|
"bridge-boot-resume": 5,
|
|
3451
3452
|
"bridge-command-boot": 12,
|
|
@@ -3453,13 +3454,16 @@ let manifestCount: number;
|
|
|
3453
3454
|
"cc-retire-request": 15,
|
|
3454
3455
|
"entwurf-v2-retire": 32,
|
|
3455
3456
|
"capability-cache": 3,
|
|
3457
|
+
"capability-bundle-reach": 7,
|
|
3456
3458
|
"codex-app-server-launch": 10,
|
|
3457
3459
|
"codex-caller-seat": 28,
|
|
3458
3460
|
"pi-retire-request": 6,
|
|
3459
3461
|
"retirement-event": 16,
|
|
3460
3462
|
"control-retire": 9,
|
|
3461
|
-
"control-send-receipt":
|
|
3462
|
-
"codex-native":
|
|
3463
|
+
"control-send-receipt": 20,
|
|
3464
|
+
"codex-native": 95,
|
|
3465
|
+
"native-push-paused": 1,
|
|
3466
|
+
"chain-terminus-publication": 1,
|
|
3463
3467
|
"compaction-send-guard": 7,
|
|
3464
3468
|
"control-socket-disconnect": 4,
|
|
3465
3469
|
"demo-reproducibility": 12,
|
|
@@ -3470,7 +3474,7 @@ let manifestCount: number;
|
|
|
3470
3474
|
"pi-bridge-sender": 4,
|
|
3471
3475
|
"pi-mcp-bridge": 2,
|
|
3472
3476
|
"pi-mcp-register": 3,
|
|
3473
|
-
"pi-durable":
|
|
3477
|
+
"pi-durable": 95,
|
|
3474
3478
|
"copilot-receive": 20,
|
|
3475
3479
|
"entwurf-peers": 1,
|
|
3476
3480
|
"fresh-call-dispatch": 15,
|
|
@@ -3491,33 +3495,33 @@ let manifestCount: number;
|
|
|
3491
3495
|
"meta-identity": 9,
|
|
3492
3496
|
"meta-retire": 4,
|
|
3493
3497
|
"mux-boundary": 16,
|
|
3494
|
-
"mux-fresh-call":
|
|
3498
|
+
"mux-fresh-call": 67,
|
|
3495
3499
|
"mux-launcher-fence": 8,
|
|
3496
3500
|
"mux-parent-artifact": 3,
|
|
3497
|
-
"pack-install":
|
|
3501
|
+
"pack-install": 9,
|
|
3498
3502
|
"pi-package-ownership": 8,
|
|
3499
3503
|
"qualification-ledger": 42,
|
|
3500
|
-
"mux-resume-call":
|
|
3504
|
+
"mux-resume-call": 15,
|
|
3501
3505
|
"omp-birth": 13,
|
|
3502
|
-
"omp-fresh":
|
|
3506
|
+
"omp-fresh": 25,
|
|
3503
3507
|
"omp-receive": 11,
|
|
3504
3508
|
"probe-ordering": 1,
|
|
3505
3509
|
"release-gate": 21,
|
|
3506
3510
|
"remote-pair-display": 3,
|
|
3507
3511
|
"remote-pair-installed-audit": 2,
|
|
3508
|
-
"remote-pair-receive":
|
|
3509
|
-
"remote-pair-roundtrip":
|
|
3510
|
-
"remote-pair-send":
|
|
3512
|
+
"remote-pair-receive": 10,
|
|
3513
|
+
"remote-pair-roundtrip": 9,
|
|
3514
|
+
"remote-pair-send": 22,
|
|
3511
3515
|
"remote-pair-transport": 4,
|
|
3512
3516
|
"retired-sent-surface": 2,
|
|
3513
3517
|
"resume-args": 6,
|
|
3514
3518
|
"resume-launch-identity": 10,
|
|
3515
3519
|
"self-address": 8,
|
|
3516
3520
|
"setup-verdict": 14,
|
|
3517
|
-
"source-install":
|
|
3521
|
+
"source-install": 8,
|
|
3518
3522
|
"typing-call-fence": 1,
|
|
3519
|
-
"v2-surface":
|
|
3520
|
-
"v2-visible-resume":
|
|
3523
|
+
"v2-surface": 16,
|
|
3524
|
+
"v2-visible-resume": 41,
|
|
3521
3525
|
"win32-preview": 19,
|
|
3522
3526
|
};
|
|
3523
3527
|
const laneTally: Record<string, number> = {};
|