@junghanacs/entwurf 0.12.10 → 0.13.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 +6 -3
- package/BASELINE.md +56 -163
- package/CHANGELOG.md +35 -0
- package/CONTRIBUTING.md +4 -2
- package/DELIVERY.md +117 -261
- package/README.md +74 -399
- package/VERIFY.md +59 -85
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +231 -0
- package/docs/external-mcp-host.md +132 -0
- package/docs/fresh-cut-policy.md +99 -0
- package/docs/setup-clean-host.md +123 -328
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +21 -48
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/acp-client.js +12 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +155 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +16 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/engraving.js +42 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +66 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +190 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +12 -4
- package/mcp/entwurf-bridge/src/index.ts +21 -48
- package/package.json +14 -9
- package/pi/settings.reference.json +1 -1
- package/pi-extensions/acp-provider.ts +20 -10
- package/pi-extensions/entwurf-control.ts +20 -49
- package/pi-extensions/lib/acp/acp-client.ts +22 -0
- package/pi-extensions/lib/acp/augment.ts +99 -2
- package/pi-extensions/lib/acp/backend-adapter.ts +190 -14
- package/pi-extensions/lib/acp/backend.ts +310 -37
- package/pi-extensions/lib/acp/config.ts +19 -5
- package/pi-extensions/lib/acp/engraving.ts +46 -2
- package/pi-extensions/lib/acp/event-mapper.ts +26 -16
- package/pi-extensions/lib/acp/models.ts +69 -7
- package/pi-extensions/lib/acp/overlay.ts +234 -5
- package/pi-extensions/lib/acp/tool-surface.ts +12 -4
- package/prompts/engraving.md +13 -5
- package/run.sh +386 -119
- package/scripts/check-acp-carrier-augment.ts +246 -10
- package/scripts/check-acp-cortex.ts +668 -0
- package/scripts/check-acp-prompt-lifecycle.ts +565 -0
- package/scripts/check-acp-provider-surface.ts +50 -6
- package/scripts/check-acp-sdk-surface.ts +60 -21
- package/scripts/check-acp-session-reuse.ts +64 -1
- package/scripts/check-acp-stop-reason.ts +342 -0
- package/scripts/check-entwurf-v2-surface.ts +41 -0
- package/scripts/check-gate-qualification.ts +7 -2
- package/scripts/check-probe-cli-shim.ts +879 -0
- package/scripts/check-probe-ordering.ts +2482 -0
- package/scripts/check-release-gate-outcomes.ts +332 -0
- package/scripts/check-shell-quote.ts +4 -4
- package/scripts/fixtures/probe-cli-shim +20 -0
- package/scripts/fixtures/probe-mcp-server.ts +168 -12
- package/scripts/lib/live-skip.ts +33 -0
- package/scripts/lib/probe-acp-turn.ts +228 -0
- package/scripts/lib/probe-cli-shim.ts +464 -0
- package/scripts/lib/probe-cli-target.ts +165 -0
- package/scripts/lib/probe-event-log.ts +383 -0
- package/scripts/lib/probe-verdict.ts +1213 -0
- package/scripts/lib/step-outcome.sh +88 -0
- package/scripts/mutants/acp-augment.json +106 -0
- package/scripts/mutants/acp-cortex.json +196 -0
- package/scripts/mutants/acp-prompt-lifecycle.json +100 -0
- package/scripts/mutants/acp-stop-reason.json +80 -0
- package/scripts/mutants/probe-ordering.json +1054 -0
- package/scripts/mutants/release-gate.json +105 -0
- package/scripts/mutants/v2-surface.json +26 -15
- package/scripts/smoke-acp-bundled-mcp-live.ts +4 -3
- package/scripts/smoke-acp-carrier-augment-live.ts +2 -2
- package/scripts/smoke-acp-cortex-live.ts +386 -0
- package/scripts/smoke-acp-long-turn-live.ts +185 -0
- package/scripts/smoke-acp-mcp-live.ts +2 -2
- package/scripts/smoke-acp-memory-containment-live.ts +2 -2
- package/scripts/smoke-acp-ordering-probe-live.ts +848 -0
- package/scripts/smoke-acp-overlay-live.ts +2 -2
- package/scripts/smoke-acp-provider-live.ts +2 -2
- package/scripts/smoke-acp-raw-turn-live.ts +3 -3
- package/scripts/smoke-acp-session-reuse-live.ts +2 -2
- package/scripts/smoke-acp-skill-live.ts +2 -2
- package/scripts/smoke-acp-socket-citizen-live.ts +4 -3
- package/scripts/smoke-acp-v2-send-live.ts +4 -3
- package/scripts/smoke-agy-native-push-live.ts +4 -3
- package/scripts/smoke-claude-native-resume-live.sh +13 -3
- package/scripts/smoke-entwurf-chain-live.ts +352 -0
- package/scripts/smoke-entwurf-v2-matrix-live.ts +2 -2
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +2 -4
- package/scripts/smoke-meta-install-state.sh +4 -0
package/run.sh
CHANGED
|
@@ -51,6 +51,22 @@ PROVIDER_ID="entwurf"
|
|
|
51
51
|
# surfaces). Under an installed package it REFUSES rather than falling back to raw
|
|
52
52
|
# .ts — a fallback would just re-raise the fence error with a worse message.
|
|
53
53
|
# check-install-surface pins both halves statically.
|
|
54
|
+
# Release-gate STEP OUTCOME protocol (P1) — loaded LAZILY, never at top level.
|
|
55
|
+
#
|
|
56
|
+
# Only two surfaces need it: `release_gate`, which classifies each step's exit
|
|
57
|
+
# code, and the LIVE smoke wrappers, which return `$ENTWURF_STEP_SKIP_EXIT` when
|
|
58
|
+
# a prerequisite is missing. Both are dev-only. Sourcing it unconditionally at
|
|
59
|
+
# the top made EVERY subcommand depend on `scripts/lib/` being present, and
|
|
60
|
+
# check-fresh-cut-gate I9c caught the consequence immediately: on an installed
|
|
61
|
+
# tree assembled without that path, run.sh died with a bash "No such file"
|
|
62
|
+
# instead of printing the refusal it is supposed to print. An operator verb must
|
|
63
|
+
# never fail on a dev-only dependency, so the load happens where it is used.
|
|
64
|
+
entwurf_require_step_outcome() {
|
|
65
|
+
[ -n "${ENTWURF_STEP_SKIP_EXIT:-}" ] && return 0
|
|
66
|
+
# shellcheck source=scripts/lib/step-outcome.sh
|
|
67
|
+
. "$REPO_DIR/scripts/lib/step-outcome.sh"
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
run_ts() {
|
|
55
71
|
local rel="$1"; shift
|
|
56
72
|
case "$REPO_DIR" in
|
|
@@ -73,7 +89,7 @@ usage() {
|
|
|
73
89
|
cat <<'EOF'
|
|
74
90
|
Usage:
|
|
75
91
|
./run.sh setup [project-dir] # ONE confident install: pnpm install + install + meta-bridge (if native harness) + v2 install smoke (LIVE substrate = release-gate)
|
|
76
|
-
./run.sh release-gate [project-dir] [--allow-skip-gemini] # SINGLE release gate: full static (pnpm check) + the v2-native live gates (v2 matrix/spawn-resume-live, check-bridge, RGG) + the ACP plugin acceptance floor (12 LIVE smokes: socket-citizen/raw-turn/overlay/provider/session-reuse/carrier-augment/memory-containment/rgg/mcp/skill/bundled-mcp/v2-send). TWO-TIER summary: MUST (release-blocking, owns the exit code — "green" applies here) + BEHAVIOR (advisory, non-blocking: RGG positives model-in-loop turn).
|
|
92
|
+
./run.sh release-gate [project-dir] [--cut] [--allow-skip-gemini] # SINGLE release gate: full static (pnpm check) + the v2-native live gates (v2 matrix/spawn-resume-live, check-bridge, RGG) + the ACP plugin acceptance floor (12 LIVE smokes: socket-citizen/raw-turn/overlay/provider/session-reuse/carrier-augment/memory-containment/rgg/mcp/skill/bundled-mcp/v2-send) + the two axes the aggregate used to omit silently (spawn-live/claude-native-resume; Cortex stays a documented on-demand direct call) + the cross-harness delivery chain (smoke-entwurf-chain-live). TWO-TIER summary: MUST (release-blocking, owns the exit code — "green" applies here) + BEHAVIOR (advisory, non-blocking: RGG positives model-in-loop turn). STEP OUTCOME protocol: every step is INVOKED and reports its own PASS / SKIP (exit 97, a prerequisite it does not have) / FAIL — a skip is never counted as a pass. Without --cut this is the unattended diagnostic (SKIPs reported, exit 0). WITH --cut it is read as release acceptance and ANY MUST SKIP is red, which is what makes "a CUT needs LIVE=1, SKIP=0" executable instead of prose. --allow-skip-gemini accepted-but-ignored (back-compat). final cut authorization is GLG's.
|
|
77
93
|
./run.sh check-bridge # entwurf-bridge direct MCP smoke + protocol/negative-path test.sh (live substrate = v2 live smokes)
|
|
78
94
|
./run.sh check-entwurf-bridge-boot # deterministic gate (5d-5-pre, G1a/G1b, IN pnpm check): boot start.sh under strip-types + assert v2 fence graph loads + entwurf_v2 registered/schema; tools/list only, no auth/side-effect
|
|
79
95
|
./run.sh check-entwurf-bridge-pi-free # deterministic gate (0.12.1 A, IN pnpm check): static — bridge index eager value-import closure must carry no @earendil-works/pi-* (type-only + dynamic import excluded); proves the meta-bridge boots pi-free
|
|
@@ -129,7 +145,11 @@ Usage:
|
|
|
129
145
|
./run.sh check-meta-doctor-oracle # 0.12.8 (#51): detection power of the release ORACLE — healthy fixture must reach `doctor: PASS`, then 21 planted defects (retired shell form, partial hand-patch, launcher bypass/repoint/provenance loss, malformed exec args, owner type drift, extra leaf/group, doorbell asyncRewake/path/timeout, no live bridge, stale receiver, ambiguous/missing cache, missing hook log/writer, failing CLI probes) must each turn it FAIL naming their own cause, plus a positive case pinning that a long-writing CLI is NOT a false negative. Offline/deterministic (deps: bash+node+python3)
|
|
130
146
|
./run.sh smoke-agy-install-state # agy MCP + exact permission ownership regression: isolated HOME+XDG, adopt/state/inverse, symlink refuse, setup degrade. Offline/deterministic
|
|
131
147
|
./run.sh check-agy-permission-matrix # AGY permission CONTRACT SPACE as a literal table (55 cells): parser-state × operation × settings × ownership × precedence with stated exclusion rules; expectations are hand-written literals, never read from the SUT. Offline/deterministic (deps: python3)
|
|
148
|
+
./run.sh smoke-entwurf-chain-live # LIVE cross-harness delivery chain: native Claude Code -> pi GPT -> pi ACP Sonnet -> mailbox terminus, proving sender identity/replyable at every hop and a real read receipt at the end. Prerequisites (claude on PATH, pi credentials per backend) report protocol SKIP, never a pass
|
|
149
|
+
./run.sh check-release-gate-outcomes # release-gate STEP OUTCOME protocol (P1): one skip exit code shared by the shell + TS halves, classifier never rounds a skip up to a pass, `--cut` refuses a MUST SKIP while a bare diagnostic stays exit 0, no LIVE smoke keeps the old exit-0 skip shape, and both real skip surfaces are INVOKED and observed to propagate the code
|
|
132
150
|
./run.sh check-gate-qualification # kill-proof qualification (the gate-of-gates): runner self-test (classifier truth table + synthetic negatives incl. wrong-reason/hang/control-red/impurity) + committed mutant manifests (scripts/mutants/*.json) run in an isolated snapshot repo under control→mutant→restore→control; the real checkout is never written. Evidence = claim IDs + killed mutant IDs, never assertion counts
|
|
151
|
+
./run.sh check-probe-ordering # §11-7 ordering-probe deterministic gate: raw-client SAMENESS pinned to backend.ts (sequence/args/timeouts/permission policy — the probe may never measure a lookalike), phase attribution incl. set-model, probe-mode fixture wire markers (delay honored, probeRunId REQUIRED, smoke-acp-mcp-live legacy compat), event-log door integrity (reserved keys refused at write; unknown marker name, broken sort axis, or a payload the classifier cannot judge on is MALFORMED, never a quiet event), and the §11-7 paired-verdict truth table (P0/I0 outside the space, phase-qualified D, B promotion ladder, C, A two-delay rule). Offline/deterministic; kill-proofed via scripts/mutants/probe-ordering.json
|
|
152
|
+
./run.sh check-probe-cli-shim # §11-7-c B-name-snapshot PRODUCER gate: the CLI shim driven as a REAL process against fake CLIs (no API, no cost). Proves what a defect would buy — FABRICATED evidence (a malformed init is never reported as an empty name set; the boot report carries the true target path+sha256 the classifier verifies against the roster), a DESTROYED turn (byte transparency across mid-UTF8/CRLF/oversized/unterminated framing, exit-code fidelity, signal re-raise, inbound signal forwarding, stderr passthrough, stdout backpressure), and LEAKED operator state (exact-allowlist env scrub, no argv/env/prompt body in the log). Offline/deterministic; kill-proofed via scripts/mutants/probe-ordering.json
|
|
133
153
|
./run.sh smoke-agy-statusline-state # agy ambient garden-id statusLine install/doctor/inverse regression. Offline/deterministic
|
|
134
154
|
./run.sh smoke-agy-hooks-state # agy PreInvocation birth/sender hook install/doctor/inverse + direct stdin→meta-record regression. Offline/deterministic
|
|
135
155
|
./run.sh smoke-user-scope-citizen # 0.12.6 install-boundary: pi packages[] registration SSOT (register-pi-package.py) — idempotent + preserves unrelated + normalizes stale + remove symmetry + fails loud. Offline/hermetic (deps: bash+python3)
|
|
@@ -982,9 +1002,10 @@ smoke_entwurf_v2_spawn_live() {
|
|
|
982
1002
|
# 5c-3a watcher's timeout→kill→child-exited→release integration on a live process. It does
|
|
983
1003
|
# NOT spawn a real `pi --entwurf-control` resume (that is the 5d surface matrix). Run once
|
|
984
1004
|
# before 5d and record the result: LIVE=1 ./run.sh smoke-entwurf-v2-spawn-live
|
|
1005
|
+
entwurf_require_step_outcome
|
|
985
1006
|
if [ "${LIVE:-}" != "1" ]; then
|
|
986
|
-
echo "[smoke-entwurf-v2-spawn-live
|
|
987
|
-
return
|
|
1007
|
+
echo "[entwurf:skip] smoke-entwurf-v2-spawn-live — set LIVE=1 to run (spawns real children + opens a real unix socket)."
|
|
1008
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
988
1009
|
fi
|
|
989
1010
|
run_ts scripts/smoke-entwurf-v2-spawn-live.ts
|
|
990
1011
|
}
|
|
@@ -1049,6 +1070,18 @@ smoke_acp_memory_containment_live() {
|
|
|
1049
1070
|
run_ts scripts/smoke-acp-memory-containment-live.ts
|
|
1050
1071
|
}
|
|
1051
1072
|
|
|
1073
|
+
smoke_acp_long_turn_live() {
|
|
1074
|
+
# 0.13.1 LIVE acceptance for the prompt-lifecycle contract — OUT of pnpm check,
|
|
1075
|
+
# needs LIVE=1. Drives ONE real pi provider turn whose tool work (default
|
|
1076
|
+
# 3 x 240s foreground wait) deliberately outlasts the RETIRED 600s prompt cutoff, and
|
|
1077
|
+
# requires it to finish as ONE turn: the nonce arrives, elapsed > 600000ms, the
|
|
1078
|
+
# persisted transcript shows exactly ONE cold ACP bootstrap (no replay), and no
|
|
1079
|
+
# retry/timeout is reported anywhere. Takes >12 minutes by construction.
|
|
1080
|
+
# Overrides: ENTWURF_ACP_LONG_TURN_{MODEL,SLEEP_SECONDS,ROUNDS,HORIZON_MS}.
|
|
1081
|
+
# LIVE=1 ./run.sh smoke-acp-long-turn-live
|
|
1082
|
+
run_ts scripts/smoke-acp-long-turn-live.ts
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1052
1085
|
smoke_acp_provider_live() {
|
|
1053
1086
|
# S2c acceptance smoke (ACP plugin on v2) — OUT of pnpm check, needs LIVE=1.
|
|
1054
1087
|
# Drives the REAL pi PROVIDER path end to end: a real `pi` loads this
|
|
@@ -1177,6 +1210,41 @@ smoke_acp_rgg_live() {
|
|
|
1177
1210
|
(cd "$REPO_DIR" && ENTWURF_LIVE_TARGET="$target" SMOKE_RGG_POSITIVE=0 bash scripts/smoke-resident-garden-guard.sh)
|
|
1178
1211
|
}
|
|
1179
1212
|
|
|
1213
|
+
smoke_acp_cortex_live() {
|
|
1214
|
+
# On-demand LIVE smoke for the Cortex (Snowflake Cortex Code) ACP backend — the
|
|
1215
|
+
# first NON-claude adapter on the rail (docs/acp-backend-rail.md, Cortex audit). OUT of
|
|
1216
|
+
# `pnpm check` AND OUTSIDE the claude-only aggregate LIVE floor (capability
|
|
1217
|
+
# dignity, invariant #7): a host with no cortex install / no Snowflake auth must
|
|
1218
|
+
# not redden a release for a backend it does not run, so this is deliberately
|
|
1219
|
+
# absent from release-gate's 11-smoke ACP acceptance floor. That is a WIRING
|
|
1220
|
+
# decision, not a lower evidence bar — a cut that SHIPS cortex still owes a
|
|
1221
|
+
# deliberate run of this smoke, and the aggregate gate's silence is not a pass
|
|
1222
|
+
# (ACP rail Cortex verification boundary). Drives one real
|
|
1223
|
+
# cortex ACP turn through the entwurf provider path (outbound entwurf_v2 +
|
|
1224
|
+
# dual-HOME overlay facts + process-group reclaim — CP2).
|
|
1225
|
+
# HONEST-SKIP (exit 0) when LIVE!=1 OR `cortex` is not on PATH OR no
|
|
1226
|
+
# connection is pinned — the live turn needs `cortex` installed with the
|
|
1227
|
+
# operator's own web-login auth already present (there is no `cortex auth`
|
|
1228
|
+
# subcommand — CP0 D6), reached through the overlay's narrow credential
|
|
1229
|
+
# symlinks — narrow in WHICH paths are reachable (D5), not read-only: a symlink
|
|
1230
|
+
# carries no write protection (AGENTS §ACP Plugin Boundary: entwurf never
|
|
1231
|
+
# provides/proxies the Snowflake credential). The connection must ride the adapter seam
|
|
1232
|
+
# (ENTWURF_ACP_CORTEX_CONNECTION) because the dual-HOME overlay denies the
|
|
1233
|
+
# operator settings.json where a default would live. PR #40 called this
|
|
1234
|
+
# `smoke-cortex`; the canonical family name is smoke-acp-cortex-live.
|
|
1235
|
+
# LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live
|
|
1236
|
+
entwurf_require_step_outcome
|
|
1237
|
+
if [ "${LIVE:-}" != "1" ]; then
|
|
1238
|
+
echo "[entwurf:skip] smoke-acp-cortex-live — set LIVE=1 (+ ENTWURF_ACP_CORTEX_CONNECTION) to run."
|
|
1239
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
1240
|
+
fi
|
|
1241
|
+
if ! command -v cortex >/dev/null 2>&1; then
|
|
1242
|
+
echo "[entwurf:skip] smoke-acp-cortex-live — cortex not on PATH (install Snowflake Cortex Code and complete its own login flow)."
|
|
1243
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
1244
|
+
fi
|
|
1245
|
+
run_ts scripts/smoke-acp-cortex-live.ts
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1180
1248
|
smoke_entwurf_v2_matrix_live() {
|
|
1181
1249
|
# LIVE sentinel for 0.11 Stage 0 step 5d-5 (D4-b) — kept OUT of `pnpm check`. The deterministic
|
|
1182
1250
|
# sibling (check-entwurf-v2-matrix) fixes every (target kind → transport → lock) cell over fakes
|
|
@@ -1189,9 +1257,10 @@ smoke_entwurf_v2_matrix_live() {
|
|
|
1189
1257
|
# stay deterministic. Honest skip when LIVE!=1 so the release-gate is runnable unattended.
|
|
1190
1258
|
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.4).
|
|
1191
1259
|
# LIVE=1 ./run.sh smoke-entwurf-v2-matrix-live
|
|
1260
|
+
entwurf_require_step_outcome
|
|
1192
1261
|
if [ "${LIVE:-}" != "1" ]; then
|
|
1193
|
-
echo "[smoke-entwurf-v2-matrix-live
|
|
1194
|
-
return
|
|
1262
|
+
echo "[entwurf:skip] smoke-entwurf-v2-matrix-live — set LIVE=1 to run (spawns a real pi --entwurf-control + opens a real socket)."
|
|
1263
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
1195
1264
|
fi
|
|
1196
1265
|
run_ts scripts/smoke-entwurf-v2-matrix-live.ts
|
|
1197
1266
|
}
|
|
@@ -1211,9 +1280,10 @@ smoke_entwurf_v2_spawn_resume_live() {
|
|
|
1211
1280
|
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.4);
|
|
1212
1281
|
# ENTWURF_SPAWN_RESUME_ASSISTANT_TIMEOUT_MS (default 180000).
|
|
1213
1282
|
# LIVE=1 ./run.sh smoke-entwurf-v2-spawn-resume-live
|
|
1283
|
+
entwurf_require_step_outcome
|
|
1214
1284
|
if [ "${LIVE:-}" != "1" ]; then
|
|
1215
|
-
echo "[smoke-entwurf-v2-spawn-resume-live
|
|
1216
|
-
return
|
|
1285
|
+
echo "[entwurf:skip] smoke-entwurf-v2-spawn-resume-live — set LIVE=1 to run (spawns a real pi resume child + opens a real socket)."
|
|
1286
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
1217
1287
|
fi
|
|
1218
1288
|
run_ts scripts/smoke-entwurf-v2-spawn-resume-live.ts
|
|
1219
1289
|
}
|
|
@@ -1436,12 +1506,13 @@ assert.equal(peerTui, piAi,
|
|
|
1436
1506
|
// floor tracks the devDep pin so a consumer can't install against a pi lacking
|
|
1437
1507
|
// the public trust exports the bridge imports at the pinned minor, AND an upper
|
|
1438
1508
|
// bound at the next minor stops a fresh install from silently pulling a future
|
|
1439
|
-
// pi (past the declared ceiling — 0.
|
|
1509
|
+
// pi (past the declared ceiling — 0.84+ at the current 0.83.0 pin) whose
|
|
1440
1510
|
// internal export surface has drifted from the one we typecheck against.
|
|
1441
1511
|
// pi moves its public surface every minor (the 0.79→0.80 getModels→provider-
|
|
1442
1512
|
// factory churn is exactly this), so an open `>=` floor is exactly how the next
|
|
1443
|
-
// installer re-acquires the drift.
|
|
1444
|
-
//
|
|
1513
|
+
// installer re-acquires the drift. The floor is also the HARD MINIMUM a consumer
|
|
1514
|
+
// install resolves: at `>=0.83.0` an existing 0.82.x host is upgraded, not kept.
|
|
1515
|
+
// Expected shape: `>=<devDep> <0.<minor+1>` (e.g. `>=0.83.0 <0.84`).
|
|
1445
1516
|
const [piMaj, piMin] = piAi.split('.').map(Number);
|
|
1446
1517
|
assert.equal(piMaj, 0,
|
|
1447
1518
|
`pi pin major must stay 0 for the next-minor ceiling rule (got ${piAi}); revisit check-dep-versions when pi reaches 1.x`);
|
|
@@ -2211,19 +2282,23 @@ EOF
|
|
|
2211
2282
|
}
|
|
2212
2283
|
|
|
2213
2284
|
check_acp_provider_surface() {
|
|
2214
|
-
# Deterministic gate for the
|
|
2215
|
-
# provider lib modules
|
|
2216
|
-
#
|
|
2217
|
-
#
|
|
2218
|
-
#
|
|
2219
|
-
|
|
2285
|
+
# Deterministic gate for the ACP provider registration surface. Loads the REAL
|
|
2286
|
+
# provider lib modules AND compiles + drives the REAL entry against a fake pi,
|
|
2287
|
+
# asserting: one surface name, the no-auth sentinel shape, full
|
|
2288
|
+
# ProviderModelConfig rows on the curated claude anchor, the EXACT curated model
|
|
2289
|
+
# set both adapters contribute (claude 2 + cortex 4 —
|
|
2290
|
+
# [QK:CORTEX-PROVIDER-SIX-ROW-SURFACE], the claim that catches an entry which
|
|
2291
|
+
# silently drops a whole backend), and that streamSimple is the real
|
|
2292
|
+
# streamShellAcp backend (checked BY NAME, never invoked — invoking spawns an
|
|
2293
|
+
# ACP child). Pure, no pi runtime, no API.
|
|
2294
|
+
section "ACP provider surface (registration + both-adapter model set)"
|
|
2220
2295
|
run_ts scripts/check-acp-provider-surface.ts
|
|
2221
2296
|
}
|
|
2222
2297
|
|
|
2223
2298
|
check_acp_sdk_surface() {
|
|
2224
2299
|
# Deterministic gate for the S2a ACP SDK dependency surface. Pins the three
|
|
2225
2300
|
# ACP runtime deps to the current oracle versions (@agentclientprotocol/sdk
|
|
2226
|
-
# 1.3.0 + claude-agent-acp 0.
|
|
2301
|
+
# 1.3.0 + claude-agent-acp 0.64.0 + @anthropic-ai/sdk 0.100.1), locks the
|
|
2227
2302
|
# peer-resolution that keeps claude-agent-sdk satisfiable (0.100.1, not the
|
|
2228
2303
|
# stale 0.91.1), asserts the wire SDK still value-exports the symbols the raw
|
|
2229
2304
|
# turn needs (silent-rename gate), and forbids any source-level anthropic SDK
|
|
@@ -2268,6 +2343,37 @@ check_acp_event_mapper() {
|
|
|
2268
2343
|
run_ts scripts/check-acp-event-mapper.ts
|
|
2269
2344
|
}
|
|
2270
2345
|
|
|
2346
|
+
check_acp_stop_reason() {
|
|
2347
|
+
# Deterministic gate for the ACP stop-reason contract. Drives every member of
|
|
2348
|
+
# the closed ACP terminal set (end_turn / max_tokens / max_turn_requests /
|
|
2349
|
+
# refusal / cancelled), plus an unrecognized reason and an ABSENT one, end to
|
|
2350
|
+
# end through streamAcpTurn against a fake connection — asserting the event
|
|
2351
|
+
# kind, the event reason, and the final message's stopReason / rawStopReason /
|
|
2352
|
+
# errorMessage together. Forbids the collapse-to-"stop" default that reported
|
|
2353
|
+
# refusals and exhausted turn budgets as finished answers. Also pins the
|
|
2354
|
+
# "pending" seed on the freshly created stream state.
|
|
2355
|
+
section "ACP stop reason (terminal set → pi verdict)"
|
|
2356
|
+
run_ts scripts/check-acp-stop-reason.ts
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
check_acp_prompt_lifecycle() {
|
|
2360
|
+
# Deterministic gate for the ACP prompt LIFECYCLE contract. A prompt has no
|
|
2361
|
+
# wall-clock cutoff: it ends when it resolves, when the operator aborts, or
|
|
2362
|
+
# when the child dies / its stdio ends. Drives streamAcpTurn against a fake
|
|
2363
|
+
# ACP child + connection for eight cells — a quiet in-flight turn is not
|
|
2364
|
+
# sealed and later completes on its ORIGINAL prompt; an abort sends ACP
|
|
2365
|
+
# session/cancel first (cancelled→aborted, no signal to a cooperating child);
|
|
2366
|
+
# a wedged agent is torn down after the bounded grace and still returns; a
|
|
2367
|
+
# mid-prompt child death reports exit status + stderr tail on BOTH the new and
|
|
2368
|
+
# the reuse path; a death BETWEEN turns is announced once by the next turn
|
|
2369
|
+
# while a teardown WE performed stays silent — plus pi's own
|
|
2370
|
+
# isRetryableAssistantError as
|
|
2371
|
+
# the oracle that our prompt-phase failure text is not a transient
|
|
2372
|
+
# (cold-replay) error.
|
|
2373
|
+
section "ACP prompt lifecycle (no wall clock; abort/child-death endings)"
|
|
2374
|
+
run_ts scripts/check-acp-prompt-lifecycle.ts
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2271
2377
|
check_acp_prompt_builder() {
|
|
2272
2378
|
# Deterministic gate for the S2d bootstrapPath-scoped ACP prompt builder (핀4).
|
|
2273
2379
|
# Proves prompt SCOPE follows bootstrapPath: new=full transcript (history
|
|
@@ -2340,6 +2446,33 @@ check_acp_carrier_augment() {
|
|
|
2340
2446
|
run_ts scripts/check-acp-carrier-augment.ts
|
|
2341
2447
|
}
|
|
2342
2448
|
|
|
2449
|
+
check_acp_cortex() {
|
|
2450
|
+
# Deterministic gate for the Cortex (Snowflake Cortex Code) ACP backend — the
|
|
2451
|
+
# first non-claude adapter on the rail, landed 0.13.0 on the CP0-measured
|
|
2452
|
+
# contract (docs/acp-backend-rail.md, Cortex audit D1–D10). The cortex source is one
|
|
2453
|
+
# `cortexAdapter` object (backend-adapter.ts) + its curated surface (models.ts)
|
|
2454
|
+
# + the dual-HOME overlay (overlay.ts); the 결합 규칙 requires the gate to land
|
|
2455
|
+
# WITH it, extending the check-acp-* family, so cortex's whole
|
|
2456
|
+
# deterministic axis lives here. Locks (each Cortex-audit D-pinned): the GLG-decided
|
|
2457
|
+
# 4-row curation rides real registry bases and the `cortex-` prefix routes to
|
|
2458
|
+
# cortexAdapter; launch is `cortex acp serve` with NO -m — the model is
|
|
2459
|
+
# enforced per turn via session/set_config_option with the native id (E);
|
|
2460
|
+
# CORTEX_HOME presence (empty included) refuses the spawn (D3); the dual-HOME
|
|
2461
|
+
# overlay isolates HOME+SNOWFLAKE_HOME per session key (P0-1: scope =
|
|
2462
|
+
# backend-passed resolveSessionKey, never ambient), passes through only
|
|
2463
|
+
# connections.toml / optional config.toml / credential_cache (D5/F — never the
|
|
2464
|
+
# whole cache, never skills; symlink-through, no copies — AGENTS §ACP Plugin
|
|
2465
|
+
# Boundary), authors autoUpdate:false (D4), and projects envelope-enriched
|
|
2466
|
+
# explicit servers into cortex/mcp.json with the real HOME restored on
|
|
2467
|
+
# entwurf-bridge alone (D9/D10), non-stdio failing loud; the
|
|
2468
|
+
# CORTEX_ACP_COMMAND override single-quotes shell-metachar connection tokens.
|
|
2469
|
+
# The gate self-manages the tsc-emit layer for the .js-suffixed backend-adapter
|
|
2470
|
+
# imports; no auth, no spawn, no live cortex needed. Kill-qualified via the
|
|
2471
|
+
# `acp-cortex` mutant lane under check-gate-qualification.
|
|
2472
|
+
section "ACP cortex backend (Snowflake Cortex Code — 1st non-claude adapter)"
|
|
2473
|
+
run_ts scripts/check-acp-cortex.ts
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2343
2476
|
check_pack() {
|
|
2344
2477
|
# Dry-run tarball invariant gate for the public npm surface.
|
|
2345
2478
|
#
|
|
@@ -2709,21 +2842,21 @@ _check_pack_install_impl() {
|
|
|
2709
2842
|
printf '%s\n' '{ "name": "entwurf-install-smoke", "version": "0.0.0", "private": true }' > "$tmp/package.json"
|
|
2710
2843
|
|
|
2711
2844
|
# pi-agent-core is pinned even though we never import it: pi-coding-agent depends
|
|
2712
|
-
# on it by CARET (`^0.
|
|
2845
|
+
# on it by CARET (`^0.83.0`), so with no lockfile in this fresh temp project it
|
|
2713
2846
|
# floats to whatever pi published last — and that newer core then drags a NESTED
|
|
2714
2847
|
# pi-ai of its own. Measured 2026-07-21: pinning only the three we import left
|
|
2715
2848
|
# pi-agent-core@0.80.10 + pi-ai@0.80.10 in the tree while the gate still announced
|
|
2716
2849
|
# "pinned pi 0.80.7". The gate would then be verifying an UNVERIFIED runtime — the
|
|
2717
2850
|
# exact class this cut exists to close. Pin every @earendil-works package that
|
|
2718
2851
|
# constitutes the pi runtime, not just the ones whose types we touch.
|
|
2719
|
-
echo "[check-pack-install] pnpm add into $tmp (with 0.
|
|
2852
|
+
echo "[check-pack-install] pnpm add into $tmp (with 0.83.x peers + typebox)"
|
|
2720
2853
|
local install_log
|
|
2721
2854
|
install_log=$(cd "$tmp" && pnpm add \
|
|
2722
2855
|
"$tgz_path" \
|
|
2723
|
-
"@earendil-works/pi-ai@0.
|
|
2724
|
-
"@earendil-works/pi-coding-agent@0.
|
|
2725
|
-
"@earendil-works/pi-tui@0.
|
|
2726
|
-
"@earendil-works/pi-agent-core@0.
|
|
2856
|
+
"@earendil-works/pi-ai@0.83.0" \
|
|
2857
|
+
"@earendil-works/pi-coding-agent@0.83.0" \
|
|
2858
|
+
"@earendil-works/pi-tui@0.83.0" \
|
|
2859
|
+
"@earendil-works/pi-agent-core@0.83.0" \
|
|
2727
2860
|
"typebox@latest" \
|
|
2728
2861
|
--ignore-workspace --ignore-scripts 2>&1) || {
|
|
2729
2862
|
fail "[check-pack-install] pnpm add failed:"
|
|
@@ -2733,17 +2866,17 @@ _check_pack_install_impl() {
|
|
|
2733
2866
|
|
|
2734
2867
|
# A pin is a wish until the resolved tree is read back. Assert it: EVERY
|
|
2735
2868
|
# @earendil-works pi package present — direct or transitive, top level or nested —
|
|
2736
|
-
# must be the pinned 0.
|
|
2869
|
+
# must be the pinned 0.83.0. Anything else means an unpinned caret floated and the
|
|
2737
2870
|
# rest of this gate would be exercising a runtime nobody verified, while still
|
|
2738
|
-
# printing "pinned pi 0.
|
|
2871
|
+
# printing "pinned pi 0.83.0". Fail loud instead of proving the wrong floor.
|
|
2739
2872
|
local leaked_pi
|
|
2740
|
-
leaked_pi=$(ls "$tmp/node_modules/.pnpm" 2>/dev/null | grep '^@earendil-works+pi-' | grep -v '@0\.
|
|
2873
|
+
leaked_pi=$(ls "$tmp/node_modules/.pnpm" 2>/dev/null | grep '^@earendil-works+pi-' | grep -v '@0\.83\.0' || true)
|
|
2741
2874
|
if [ -n "$leaked_pi" ]; then
|
|
2742
|
-
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 0.
|
|
2875
|
+
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 0.83.0):"
|
|
2743
2876
|
printf '%s\n' "$leaked_pi" | sed 's/^/ /' >&2
|
|
2744
2877
|
return 1
|
|
2745
2878
|
fi
|
|
2746
|
-
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works pi package is 0.
|
|
2879
|
+
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works pi package is 0.83.0"
|
|
2747
2880
|
|
|
2748
2881
|
# Resolve the installed package.json and confirm pi.extensions
|
|
2749
2882
|
# arrived intact. If pi.extensions is empty or missing, the
|
|
@@ -2824,18 +2957,45 @@ _check_pack_install_impl() {
|
|
|
2824
2957
|
echo "$loader_out" | tail -10 | sed 's/^/ /' >&2
|
|
2825
2958
|
return 1
|
|
2826
2959
|
fi
|
|
2827
|
-
# Verify the
|
|
2828
|
-
#
|
|
2829
|
-
#
|
|
2830
|
-
#
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2960
|
+
# Verify the EXACT curated surface the installed package registers — both
|
|
2961
|
+
# backends (claude 2 rows + cortex 4 rows = 6), as a SET, not as anchors.
|
|
2962
|
+
#
|
|
2963
|
+
# Why exact-set and not `grep -q <id>`: the cortex ids CONTAIN the claude ids
|
|
2964
|
+
# as substrings (`cortex-claude-sonnet-5` matches a bare `claude-sonnet-5`
|
|
2965
|
+
# grep), so a substring probe could go green on a surface that dropped every
|
|
2966
|
+
# unprefixed Claude row. And an anchor-only probe cannot see a MISSING cortex
|
|
2967
|
+
# row at all — that is exactly the installed-consumer gap this assertion
|
|
2968
|
+
# closes: the source-side sets are pinned by check-acp-cortex /
|
|
2969
|
+
# check-acp-provider-surface, but only THIS gate proves the ids survive the
|
|
2970
|
+
# pack → install → pi-loader path into a real consumer's model list.
|
|
2971
|
+
#
|
|
2972
|
+
# Parse rows whose FIRST field is the provider `entwurf` (pi prints a
|
|
2973
|
+
# `provider model context …` table; the header row's first field is
|
|
2974
|
+
# `provider`, so it drops out) and take the second field as the model id.
|
|
2975
|
+
local loader_ids loader_expected
|
|
2976
|
+
loader_ids=$(awk '$1 == "entwurf" { print $2 }' <<<"$loader_out" | LC_ALL=C sort)
|
|
2977
|
+
loader_expected=$(printf '%s\n' \
|
|
2978
|
+
claude-opus-5 \
|
|
2979
|
+
claude-sonnet-5 \
|
|
2980
|
+
cortex-auto \
|
|
2981
|
+
cortex-claude-opus-5 \
|
|
2982
|
+
cortex-claude-sonnet-5 \
|
|
2983
|
+
cortex-openai-gpt-5.4 | LC_ALL=C sort)
|
|
2984
|
+
if [ "$loader_ids" != "$loader_expected" ]; then
|
|
2985
|
+
fail "[check-pack-install] installed provider model set drifted — expected exactly 6 curated ids (claude 2 + cortex 4):"
|
|
2986
|
+
echo " expected:" >&2
|
|
2987
|
+
echo "$loader_expected" | sed 's/^/ /' >&2
|
|
2988
|
+
echo " actual (entwurf rows):" >&2
|
|
2989
|
+
echo "${loader_ids:-<none>}" | sed 's/^/ /' >&2
|
|
2990
|
+
echo " raw loader output:" >&2
|
|
2991
|
+
echo "$loader_out" | tail -15 | sed 's/^/ /' >&2
|
|
2992
|
+
return 1
|
|
2993
|
+
fi
|
|
2994
|
+
# Name the set on SUCCESS too, not only in the failure branch — same principle as
|
|
2995
|
+
# the pinned-pi version assert above: a gate that cannot name what it proved has
|
|
2996
|
+
# proved nothing, and "6 rows" without the ids cannot be audited from a CI log.
|
|
2997
|
+
echo "[check-pack-install] pi loader smoke pass (entwurf registered; exact 6-row curated set: claude 2 + cortex 4):"
|
|
2998
|
+
echo "$loader_ids" | sed 's/^/ /'
|
|
2839
2999
|
|
|
2840
3000
|
# npm-managed neutral install regression — the README's PRIMARY install path is
|
|
2841
3001
|
# now `npm install @junghanacs/entwurf` (NOT `pi install npm:...`). This layout
|
|
@@ -3663,7 +3823,7 @@ setup_all() {
|
|
|
3663
3823
|
# native-harness meta-bridge, so a relocate/clone needs ONE command — not the
|
|
3664
3824
|
# install + install-meta-bridge two-pronged split that froze the Claude
|
|
3665
3825
|
# statusLine on the old path (the 2026-06-23 relocation gap). Detection-gated:
|
|
3666
|
-
# a pi-only host with no native harness skips it cleanly (
|
|
3826
|
+
# a pi-only host with no native harness skips it cleanly (rail “Shipped adapters” — "있으면 설정,
|
|
3667
3827
|
# 없으면 담아준다"); meta-bridge-install.sh is itself idempotent.
|
|
3668
3828
|
if command -v claude >/dev/null 2>&1; then
|
|
3669
3829
|
section "meta-bridge install (native harness detected: Claude Code)"
|
|
@@ -3695,7 +3855,7 @@ setup_all() {
|
|
|
3695
3855
|
wire_agy_hooks
|
|
3696
3856
|
|
|
3697
3857
|
# Deterministic preflight lives in `pnpm check`; live substrate acceptance lives
|
|
3698
|
-
# in `LIVE=1 ./run.sh release-gate <scratch
|
|
3858
|
+
# in `LIVE=1 ./run.sh release-gate <scratch> --cut`. Setup is the install path, so it
|
|
3699
3859
|
# verifies the installed MCP bridge boundary only and does NOT run the legacy
|
|
3700
3860
|
# ACP/v1 session-messaging/sentinel gates.
|
|
3701
3861
|
section "v2 install smoke: entwurf-bridge (direct MCP protocol)"
|
|
@@ -3711,7 +3871,7 @@ setup_all() {
|
|
|
3711
3871
|
echo " ./run.sh doctor-agy-statusline"
|
|
3712
3872
|
echo " ./run.sh doctor-agy-hooks"
|
|
3713
3873
|
fi
|
|
3714
|
-
echo "Run 'LIVE=1 ./run.sh release-gate <scratch>' for live substrate acceptance."
|
|
3874
|
+
echo "Run 'LIVE=1 ./run.sh release-gate <scratch> --cut' for live substrate acceptance (--cut refuses any MUST SKIP)."
|
|
3715
3875
|
}
|
|
3716
3876
|
|
|
3717
3877
|
# wire_agy_bridge — detection-gated, NON-FATAL agy (Antigravity) MCP bridge wiring, folded into
|
|
@@ -3727,7 +3887,7 @@ wire_agy_bridge() {
|
|
|
3727
3887
|
# whatever agy the CI/dev host happens to have — production leaves it unset (= `command -v
|
|
3728
3888
|
# agy`, no regression). Same override spirit as agy-bridge.sh's AGY_MCP_CONFIG/AGY_BRIDGE_COMMAND.
|
|
3729
3889
|
if ! command -v "${AGY_BIN:-agy}" >/dev/null 2>&1; then
|
|
3730
|
-
echo "[setup] no agy on PATH — skipping agy bridge wiring (no state;
|
|
3890
|
+
echo "[setup] no agy on PATH — skipping agy bridge wiring (no state; this host runs no Antigravity)"
|
|
3731
3891
|
return 0
|
|
3732
3892
|
fi
|
|
3733
3893
|
section "agy bridge install (native harness detected: Antigravity)"
|
|
@@ -3780,7 +3940,7 @@ wire_agy_bridge() {
|
|
|
3780
3940
|
# stable bin entwurf-agy-statusline, exposed by expose_dev_bin above.
|
|
3781
3941
|
wire_agy_statusline() {
|
|
3782
3942
|
if ! command -v "${AGY_BIN:-agy}" >/dev/null 2>&1; then
|
|
3783
|
-
echo "[setup] no agy on PATH — skipping agy statusLine wiring (no state;
|
|
3943
|
+
echo "[setup] no agy on PATH — skipping agy statusLine wiring (no state; this host runs no Antigravity)"
|
|
3784
3944
|
return 0
|
|
3785
3945
|
fi
|
|
3786
3946
|
section "agy statusLine install (native harness detected: Antigravity)"
|
|
@@ -3818,7 +3978,7 @@ wire_agy_statusline() {
|
|
|
3818
3978
|
# garden id after the first invocation.
|
|
3819
3979
|
wire_agy_hooks() {
|
|
3820
3980
|
if ! command -v "${AGY_BIN:-agy}" >/dev/null 2>&1; then
|
|
3821
|
-
echo "[setup] no agy on PATH — skipping agy hooks wiring (no state;
|
|
3981
|
+
echo "[setup] no agy on PATH — skipping agy hooks wiring (no state; this host runs no Antigravity)"
|
|
3822
3982
|
return 0
|
|
3823
3983
|
fi
|
|
3824
3984
|
section "agy hooks install (native harness detected: Antigravity)"
|
|
@@ -3895,10 +4055,18 @@ expose_dev_bin() {
|
|
|
3895
4055
|
# - Final release authorization is GLG's, not this script's: a green
|
|
3896
4056
|
# run is necessary, and the operator closes the decision.
|
|
3897
4057
|
release_gate() {
|
|
4058
|
+
entwurf_require_step_outcome
|
|
3898
4059
|
local -a positional=()
|
|
3899
4060
|
local a
|
|
4061
|
+
# --cut is the EXECUTABLE half of "a CUT needs LIVE=1, SKIP=0" (P1). Without it
|
|
4062
|
+
# this stays the unattended diagnostic it has always been: SKIPs are reported
|
|
4063
|
+
# and the run still exits 0. With it, any MUST SKIP is red — including the
|
|
4064
|
+
# LIVE!=1 case, which needs no separate assertion because every LIVE-gated step
|
|
4065
|
+
# then skips on its own and the skip counter blocks.
|
|
4066
|
+
local cut_mode=0
|
|
3900
4067
|
for a in "$@"; do
|
|
3901
4068
|
case "$a" in
|
|
4069
|
+
--cut) cut_mode=1 ;;
|
|
3902
4070
|
--allow-skip-gemini) ;; # accepted-but-ignored: gemini removed from the claude-only floor (back-compat for existing scripts)
|
|
3903
4071
|
*) positional+=("$a") ;;
|
|
3904
4072
|
esac
|
|
@@ -3949,27 +4117,36 @@ release_gate() {
|
|
|
3949
4117
|
}
|
|
3950
4118
|
|
|
3951
4119
|
# LIVE-gated MUST step: a release-blocking gate that needs a real backend turn
|
|
3952
|
-
# (auth/model/credit).
|
|
3953
|
-
#
|
|
3954
|
-
#
|
|
3955
|
-
#
|
|
3956
|
-
#
|
|
3957
|
-
#
|
|
4120
|
+
# (auth/model/credit). It is ALWAYS INVOKED and the step itself reports whether
|
|
4121
|
+
# it could run — that is the whole point of P1. The old shape asked `LIVE=1?`
|
|
4122
|
+
# here and skipped without calling, which meant the summary asserted a skip it
|
|
4123
|
+
# had never confirmed, while a step that WAS called could still exit 0 on a
|
|
4124
|
+
# missing prerequisite (Cortex without a connection) and be counted PASS.
|
|
4125
|
+
# Now one protocol decides: exit 0 = PASS, $ENTWURF_STEP_SKIP_EXIT = SKIP,
|
|
4126
|
+
# anything else = FAIL. A SKIP is never rounded up, and `--cut` refuses any.
|
|
4127
|
+
#
|
|
4128
|
+
# `LIVE` is NOT forced here — it rides the operator's environment into the
|
|
4129
|
+
# child, so `LIVE=1 ./run.sh release-gate` runs the step for real and a bare
|
|
4130
|
+
# invocation gets the step's own honest skip.
|
|
3958
4131
|
run_live_step() {
|
|
3959
4132
|
local name="$1"; shift
|
|
3960
4133
|
section "release-gate step: $name"
|
|
3961
|
-
|
|
3962
|
-
|
|
4134
|
+
local rc=0
|
|
4135
|
+
"$@" || rc=$?
|
|
4136
|
+
case "$(entwurf_step_outcome "$rc")" in
|
|
4137
|
+
PASS)
|
|
3963
4138
|
ok "$name: PASS"
|
|
3964
4139
|
results+=("PASS $name"); pass=$((pass + 1))
|
|
3965
|
-
|
|
3966
|
-
|
|
4140
|
+
;;
|
|
4141
|
+
SKIP)
|
|
4142
|
+
warn "$name: SKIP — the step declined a prerequisite it does not have (see its [entwurf:skip] line above). NOT a live acceptance."
|
|
4143
|
+
results+=("SKIP $name"); skip=$((skip + 1))
|
|
4144
|
+
;;
|
|
4145
|
+
*)
|
|
4146
|
+
fail "$name: FAIL (exit $rc)"
|
|
3967
4147
|
results+=("FAIL $name"); failc=$((failc + 1))
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
warn "$name: LIVE!=1 — skipped (opt-in: needs auth/model — NOT a live acceptance run)"
|
|
3971
|
-
results+=("SKIP $name (LIVE!=1)"); skip=$((skip + 1))
|
|
3972
|
-
fi
|
|
4148
|
+
;;
|
|
4149
|
+
esac
|
|
3973
4150
|
}
|
|
3974
4151
|
|
|
3975
4152
|
# BEHAVIOR lane (0.11.0, GLG+GPT+Opus): a SEPARATE advisory counter for
|
|
@@ -3993,19 +4170,32 @@ release_gate() {
|
|
|
3993
4170
|
# deterministic/programmatic must-pass gates above (check-entwurf-v2-*,
|
|
3994
4171
|
# check-bridge) — this lane is autonomous-tool-selection *behavior*, not
|
|
3995
4172
|
# *function*. Residual bypass → 0.11.x usability lane.
|
|
3996
|
-
|
|
4173
|
+
# The lane speaks the same STEP OUTCOME protocol (P1) so a missing prerequisite
|
|
4174
|
+
# here is a BEHAVIOR-SKIP, not a fabricated BEHAVIOR-PASS or a misread
|
|
4175
|
+
# BEHAVIOR-FAIL. Advisory semantics are untouched: none of these counters ever
|
|
4176
|
+
# reaches `failc`, and `--cut` reads the MUST skip counter only.
|
|
4177
|
+
local behavior_pass=0 behavior_failc=0 behavior_skip=0
|
|
3997
4178
|
local -a behavior_results=()
|
|
3998
4179
|
|
|
3999
4180
|
run_behavior_step() {
|
|
4000
4181
|
local name="$1"; shift
|
|
4001
4182
|
section "release-gate BEHAVIOR step (advisory, non-blocking): $name"
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4183
|
+
local rc=0
|
|
4184
|
+
"$@" || rc=$?
|
|
4185
|
+
case "$(entwurf_step_outcome "$rc")" in
|
|
4186
|
+
PASS)
|
|
4187
|
+
ok "$name: BEHAVIOR-PASS"
|
|
4188
|
+
behavior_results+=("BEHAVIOR-PASS $name"); behavior_pass=$((behavior_pass + 1))
|
|
4189
|
+
;;
|
|
4190
|
+
SKIP)
|
|
4191
|
+
warn "$name: BEHAVIOR-SKIP — prerequisite absent (advisory lane; not a signal either way)"
|
|
4192
|
+
behavior_results+=("BEHAVIOR-SKIP $name"); behavior_skip=$((behavior_skip + 1))
|
|
4193
|
+
;;
|
|
4194
|
+
*)
|
|
4195
|
+
warn "$name: BEHAVIOR-FAIL (advisory — model-in-loop signal; S7=Bash-bypass stays hard-fail here; NOT a cut blocker)"
|
|
4196
|
+
behavior_results+=("BEHAVIOR-FAIL $name"); behavior_failc=$((behavior_failc + 1))
|
|
4197
|
+
;;
|
|
4198
|
+
esac
|
|
4009
4199
|
}
|
|
4010
4200
|
|
|
4011
4201
|
# 1. Static floor (deterministic; includes the two folded gates).
|
|
@@ -4043,41 +4233,20 @@ release_gate() {
|
|
|
4043
4233
|
# production runEntwurfV2 deps + real pi control-socket RPC + real mailbox enqueue + v2 lock, not
|
|
4044
4234
|
# per-backend model behavior). Placed right after check-bridge: the MCP/protocol substrate must be
|
|
4045
4235
|
# green first so a matrix-live failure reads as "v2 transport/lock/enqueue", not bridge basics.
|
|
4046
|
-
# Opt-in LIVE: it spawns a real `pi --entwurf-control` (needs auth/model), so
|
|
4047
|
-
# SKIP (not a PASS) — an unattended release-gate stays runnable without
|
|
4048
|
-
# of --allow-skip-gemini (now a no-op back-compat flag on the
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
results+=("PASS smoke-entwurf-v2-matrix-live"); pass=$((pass + 1))
|
|
4054
|
-
else
|
|
4055
|
-
fail "smoke-entwurf-v2-matrix-live: FAIL"
|
|
4056
|
-
results+=("FAIL smoke-entwurf-v2-matrix-live"); failc=$((failc + 1))
|
|
4057
|
-
fi
|
|
4058
|
-
else
|
|
4059
|
-
warn "smoke-entwurf-v2-matrix-live: LIVE!=1 — skipped (v2 substrate sentinel, opt-in: needs auth/model)"
|
|
4060
|
-
results+=("SKIP smoke-entwurf-v2-matrix-live (LIVE!=1)"); skip=$((skip + 1))
|
|
4061
|
-
fi
|
|
4236
|
+
# Opt-in LIVE: it spawns a real `pi --entwurf-control` (needs auth/model), so a missing
|
|
4237
|
+
# prerequisite is an HONEST SKIP (not a PASS) — an unattended release-gate stays runnable without
|
|
4238
|
+
# faking coverage. Independent of --allow-skip-gemini (now a no-op back-compat flag on the
|
|
4239
|
+
# claude-only floor; this gates substrate auth). It used to carry its own inline copy of the
|
|
4240
|
+
# PASS/FAIL/SKIP branch; P1 folded it onto `run_live_step` so there is exactly ONE classifier —
|
|
4241
|
+
# a second copy is how a lane silently keeps counting a skip as a pass.
|
|
4242
|
+
run_live_step "smoke-entwurf-v2-matrix-live (D4-c: v2 dispatch substrate sentinel)" gate bash "$self" smoke-entwurf-v2-matrix-live
|
|
4062
4243
|
# 0.11.0 (A) acceptance: the FULL spawn-bg resident lifecycle — a real `pi` resume child stands
|
|
4063
4244
|
# its control socket up, does a model turn, lock released ×1. Placed right after matrix-live (the
|
|
4064
4245
|
# transport sentinel): a spawn-resume failure then reads as "resume/resident lifecycle", not
|
|
4065
|
-
# transport basics. Same opt-in LIVE rule
|
|
4066
|
-
#
|
|
4067
|
-
#
|
|
4068
|
-
|
|
4069
|
-
if [ "${LIVE:-}" = "1" ]; then
|
|
4070
|
-
if gate env LIVE=1 bash "$self" smoke-entwurf-v2-spawn-resume-live; then
|
|
4071
|
-
ok "smoke-entwurf-v2-spawn-resume-live: PASS"
|
|
4072
|
-
results+=("PASS smoke-entwurf-v2-spawn-resume-live"); pass=$((pass + 1))
|
|
4073
|
-
else
|
|
4074
|
-
fail "smoke-entwurf-v2-spawn-resume-live: FAIL"
|
|
4075
|
-
results+=("FAIL smoke-entwurf-v2-spawn-resume-live"); failc=$((failc + 1))
|
|
4076
|
-
fi
|
|
4077
|
-
else
|
|
4078
|
-
warn "smoke-entwurf-v2-spawn-resume-live: LIVE!=1 — skipped (0.11.0 A acceptance, opt-in: needs auth/model)"
|
|
4079
|
-
results+=("SKIP smoke-entwurf-v2-spawn-resume-live (LIVE!=1)"); skip=$((skip + 1))
|
|
4080
|
-
fi
|
|
4246
|
+
# transport basics. Same opt-in LIVE rule. NOTE: a tag REQUIRES `LIVE=1 ./run.sh release-gate
|
|
4247
|
+
# --cut` (or this step direct) to PASS — a SKIP is CI safety, never acceptance, and `--cut` is
|
|
4248
|
+
# what now enforces that instead of prose.
|
|
4249
|
+
run_live_step "smoke-entwurf-v2-spawn-resume-live (0.11.0 A: full spawn-bg resident lifecycle)" gate bash "$self" smoke-entwurf-v2-spawn-resume-live
|
|
4081
4250
|
|
|
4082
4251
|
# 3b. ACP plugin acceptance floor (S0~S2f live). These prove the ACP plugin's
|
|
4083
4252
|
# programmatic transport/provider/backend invariants on the v2 core — NOT
|
|
@@ -4092,18 +4261,35 @@ release_gate() {
|
|
|
4092
4261
|
# → first-user augment delivery + empty-carrier billing-clean (핀1) →
|
|
4093
4262
|
# ACP-target garden guard (deterministic half). Opt-in LIVE: LIVE!=1 is an
|
|
4094
4263
|
# HONEST SKIP via run_live_step (see its note) — a CUT needs LIVE=1, SKIP=0.
|
|
4095
|
-
run_live_step "smoke-acp-socket-citizen-live (S1: turn-free socket citizenship)" gate
|
|
4096
|
-
run_live_step "smoke-acp-raw-turn-live (S2a: pinned ACP pipe + local auth)" gate
|
|
4097
|
-
run_live_step "smoke-acp-overlay-live (S2b: config overlay + hooks:{} + tool meta)" gate
|
|
4098
|
-
run_live_step "smoke-acp-provider-live (S2c/S2f: real pi provider path + progress/L3)" gate
|
|
4099
|
-
run_live_step "smoke-acp-session-reuse-live (S2d: process-scoped reuse + recall)" gate
|
|
4100
|
-
run_live_step "smoke-acp-carrier-augment-live (S2e-1: augment delivery + 핀1 billing)" gate
|
|
4101
|
-
run_live_step "smoke-acp-memory-containment-live (Gate D: no overlay memory leak)" gate
|
|
4102
|
-
run_live_step "smoke-acp-rgg-live (S2e-2: ACP-target garden guard, deterministic half)" gate
|
|
4103
|
-
run_live_step "smoke-acp-mcp-live (S2g: operator mcpServers reach the live ACP session)" gate
|
|
4104
|
-
run_live_step "smoke-acp-skill-live (S2g: operator skillPlugins reach the live ACP session)" gate
|
|
4105
|
-
run_live_step "smoke-acp-bundled-mcp-live (S2g axis 3: bundled entwurf-bridge via 0.11.0 resident/RPC circuit)" gate
|
|
4106
|
-
run_live_step "smoke-acp-v2-send-live (S2g axis 4: an ACP model SENDS via entwurf_v2, landing as itself)" gate
|
|
4264
|
+
run_live_step "smoke-acp-socket-citizen-live (S1: turn-free socket citizenship)" gate bash "$self" smoke-acp-socket-citizen-live
|
|
4265
|
+
run_live_step "smoke-acp-raw-turn-live (S2a: pinned ACP pipe + local auth)" gate bash "$self" smoke-acp-raw-turn-live
|
|
4266
|
+
run_live_step "smoke-acp-overlay-live (S2b: config overlay + hooks:{} + tool meta)" gate bash "$self" smoke-acp-overlay-live
|
|
4267
|
+
run_live_step "smoke-acp-provider-live (S2c/S2f: real pi provider path + progress/L3)" gate bash "$self" smoke-acp-provider-live
|
|
4268
|
+
run_live_step "smoke-acp-session-reuse-live (S2d: process-scoped reuse + recall)" gate bash "$self" smoke-acp-session-reuse-live
|
|
4269
|
+
run_live_step "smoke-acp-carrier-augment-live (S2e-1: augment delivery + 핀1 billing)" gate bash "$self" smoke-acp-carrier-augment-live
|
|
4270
|
+
run_live_step "smoke-acp-memory-containment-live (Gate D: no overlay memory leak)" gate bash "$self" smoke-acp-memory-containment-live
|
|
4271
|
+
run_live_step "smoke-acp-rgg-live (S2e-2: ACP-target garden guard, deterministic half)" gate bash "$self" smoke-acp-rgg-live
|
|
4272
|
+
run_live_step "smoke-acp-mcp-live (S2g: operator mcpServers reach the live ACP session)" gate bash "$self" smoke-acp-mcp-live
|
|
4273
|
+
run_live_step "smoke-acp-skill-live (S2g: operator skillPlugins reach the live ACP session)" gate bash "$self" smoke-acp-skill-live
|
|
4274
|
+
run_live_step "smoke-acp-bundled-mcp-live (S2g axis 3: bundled entwurf-bridge via 0.11.0 resident/RPC circuit)" gate bash "$self" smoke-acp-bundled-mcp-live
|
|
4275
|
+
run_live_step "smoke-acp-v2-send-live (S2g axis 4: an ACP model SENDS via entwurf_v2, landing as itself)" gate bash "$self" smoke-acp-v2-send-live
|
|
4276
|
+
|
|
4277
|
+
# 3c. The axes the aggregate used to leave out with no stated reason (P2,
|
|
4278
|
+
# 2026-07-31). Three LIVE smokes existed and were simply never wired, so a
|
|
4279
|
+
# green cut said nothing about them. Under the P1 outcome protocol wiring
|
|
4280
|
+
# them costs nothing on a host that cannot run them — they SKIP honestly and
|
|
4281
|
+
# `--cut` names the missing prerequisite — while a host that CAN run them now
|
|
4282
|
+
# must. Cortex is deliberately NOT here: its rail needs an external Snowflake
|
|
4283
|
+
# connection the HOST owns, so wiring it would block every cut taken without
|
|
4284
|
+
# that account; it stays a required DIRECT call for a Cortex-rail cut instead
|
|
4285
|
+
# (VERIFY 「Cortex is an on-demand axis」). Same for `smoke-acp-long-turn-live`,
|
|
4286
|
+
# `smoke-agy-native-push-live` and `smoke-acp-ordering-probe-live`: >12min by
|
|
4287
|
+
# construction, no aggregate-owned agy conversation id, and an opt-in instrument
|
|
4288
|
+
# rather than acceptance. check-release-gate-outcomes pins that every LIVE smoke
|
|
4289
|
+
# is either wired here or excluded by a reason the docs still carry.
|
|
4290
|
+
run_live_step "smoke-entwurf-v2-spawn-live (5c-3c: spawn-bg OS substrate on real children/sockets)" gate bash "$self" smoke-entwurf-v2-spawn-live
|
|
4291
|
+
run_live_step "smoke-claude-native-resume-live (native Claude Code resume + meta-bridge neutrality)" gate bash "$self" smoke-claude-native-resume-live
|
|
4292
|
+
run_live_step "smoke-entwurf-chain-live (P3: Claude Code -> pi GPT -> pi ACP Sonnet -> mailbox, identity + receipt)" gate bash "$self" smoke-entwurf-chain-live
|
|
4107
4293
|
|
|
4108
4294
|
# 4. BEHAVIOR lane (advisory, non-blocking). Model-in-loop gates that probe
|
|
4109
4295
|
# whether the model AUTONOMOUSLY drives the MCP entwurf surface. These never
|
|
@@ -4133,21 +4319,44 @@ release_gate() {
|
|
|
4133
4319
|
if [ "${#behavior_results[@]}" -gt 0 ]; then
|
|
4134
4320
|
printf ' %s\n' "${behavior_results[@]}"
|
|
4135
4321
|
fi
|
|
4136
|
-
echo " BEHAVIOR: PASS=$behavior_pass FAIL=$behavior_failc"
|
|
4322
|
+
echo " BEHAVIOR: PASS=$behavior_pass FAIL=$behavior_failc SKIP=$behavior_skip"
|
|
4137
4323
|
echo " (per-step artifact paths are printed in each step's output above)"
|
|
4138
4324
|
if [ "$behavior_failc" -gt 0 ]; then
|
|
4139
4325
|
echo ""
|
|
4140
4326
|
warn "BEHAVIOR FAIL present ($behavior_failc) — advisory model-in-loop signal (e.g. S7 Bash-bypass / entwurf_self not autonomously called). Tracked, NOT a cut blocker; see the 0.11.x usability lane."
|
|
4141
4327
|
fi
|
|
4142
|
-
|
|
4143
|
-
if [ "$
|
|
4328
|
+
echo ""
|
|
4329
|
+
if [ "$cut_mode" = "1" ]; then
|
|
4330
|
+
echo " mode: --cut (a MUST SKIP is a BLOCKER — this run is being read as release acceptance)"
|
|
4331
|
+
else
|
|
4332
|
+
echo " mode: diagnostic (MUST SKIPs are reported, not blocking — re-run with --cut to read this as acceptance)"
|
|
4333
|
+
fi
|
|
4334
|
+
# The verdict as one greppable token, so release evidence can distinguish a
|
|
4335
|
+
# step that RAN AND BROKE from one that NEVER RAN without reading prose. The
|
|
4336
|
+
# counters above stay literal — a policy block is `FAIL=0 SKIP=n` plus
|
|
4337
|
+
# `BLOCKED (MUST SKIP)`, never a synthesized failure.
|
|
4338
|
+
echo " $(entwurf_release_verdict "$failc" "$skip" "$cut_mode")"
|
|
4339
|
+
|
|
4340
|
+
# Exit authority — MUST tier only, BEHAVIOR never blocks. The releasable
|
|
4341
|
+
# decision lives in scripts/lib/step-outcome.sh so it is one testable function
|
|
4342
|
+
# rather than a branch re-derived here (and re-derived wrong: the pre-P1 branch
|
|
4343
|
+
# read `failc` alone, so a run with 14 SKIPs still printed "all green").
|
|
4344
|
+
if ! entwurf_release_releasable "$failc" "$skip" "$cut_mode"; then
|
|
4144
4345
|
echo ""
|
|
4145
|
-
|
|
4346
|
+
if [ "$failc" -gt 0 ]; then
|
|
4347
|
+
fail "release-gate MUST NOT green — $failc release-blocking step(s) failed. Current release is NOT releasable."
|
|
4348
|
+
else
|
|
4349
|
+
fail "release-gate --cut REFUSED — $skip release-blocking step(s) SKIPPED, so this run does not prove they were called."
|
|
4350
|
+
echo " A skipped step is not acceptance. Supply each missing prerequisite (usually LIVE=1 plus the"
|
|
4351
|
+
echo " per-step env the [entwurf:skip] lines above name) and re-run, or drop --cut to keep this a diagnostic."
|
|
4352
|
+
fi
|
|
4146
4353
|
echo " A green MUST gate is necessary but not sufficient; GLG closes the call."
|
|
4147
4354
|
return 1
|
|
4148
4355
|
fi
|
|
4149
|
-
if [ "$
|
|
4150
|
-
|
|
4356
|
+
if [ "$skip" -gt 0 ]; then
|
|
4357
|
+
warn "release-gate MUST has no failures, but $skip step(s) SKIPPED — this is a DIAGNOSTIC run, not live acceptance. A cut needs \`LIVE=1 ./run.sh release-gate <scratch> --cut\` with SKIP=0."
|
|
4358
|
+
elif [ "$behavior_failc" -gt 0 ]; then
|
|
4359
|
+
ok "release-gate MUST PASS (all release-blocking steps ran and are green); BEHAVIOR FAIL present (advisory). Necessary condition met — GLG authorizes the cut."
|
|
4151
4360
|
else
|
|
4152
4361
|
ok "release-gate MUST PASS + BEHAVIOR PASS — all green. Necessary condition met — GLG authorizes the cut."
|
|
4153
4362
|
fi
|
|
@@ -4299,6 +4508,9 @@ case "$cmd" in
|
|
|
4299
4508
|
smoke-acp-provider-live)
|
|
4300
4509
|
smoke_acp_provider_live
|
|
4301
4510
|
;;
|
|
4511
|
+
smoke-acp-long-turn-live)
|
|
4512
|
+
smoke_acp_long_turn_live
|
|
4513
|
+
;;
|
|
4302
4514
|
smoke-acp-session-reuse-live)
|
|
4303
4515
|
smoke_acp_session_reuse_live
|
|
4304
4516
|
;;
|
|
@@ -4311,6 +4523,15 @@ case "$cmd" in
|
|
|
4311
4523
|
smoke-acp-bundled-mcp-live)
|
|
4312
4524
|
smoke_acp_bundled_mcp_live
|
|
4313
4525
|
;;
|
|
4526
|
+
smoke-entwurf-chain-live)
|
|
4527
|
+
# P3 — the cross-harness delivery CHAIN on real authenticated rails:
|
|
4528
|
+
# native Claude Code -> pi GPT -> pi ACP Claude Sonnet -> mailbox terminus,
|
|
4529
|
+
# with sender identity at every hop and a read receipt at the end. Needs
|
|
4530
|
+
# `claude` on PATH plus pi credentials for both pi backends; each missing
|
|
4531
|
+
# prerequisite is an honest protocol SKIP, never a pass.
|
|
4532
|
+
# LIVE=1 ./run.sh smoke-entwurf-chain-live
|
|
4533
|
+
run_ts scripts/smoke-entwurf-chain-live.ts
|
|
4534
|
+
;;
|
|
4314
4535
|
smoke-acp-v2-send-live)
|
|
4315
4536
|
smoke_acp_v2_send_live
|
|
4316
4537
|
;;
|
|
@@ -4320,6 +4541,9 @@ case "$cmd" in
|
|
|
4320
4541
|
smoke-acp-rgg-live)
|
|
4321
4542
|
smoke_acp_rgg_live
|
|
4322
4543
|
;;
|
|
4544
|
+
smoke-acp-cortex-live)
|
|
4545
|
+
smoke_acp_cortex_live
|
|
4546
|
+
;;
|
|
4323
4547
|
smoke-acp-socket-citizen-live)
|
|
4324
4548
|
smoke_acp_socket_citizen_live
|
|
4325
4549
|
;;
|
|
@@ -4452,6 +4676,37 @@ case "$cmd" in
|
|
|
4452
4676
|
# control-red/impurity all must classify red before any real manifest counts.
|
|
4453
4677
|
run_ts scripts/check-gate-qualification.ts
|
|
4454
4678
|
;;
|
|
4679
|
+
check-probe-ordering)
|
|
4680
|
+
# §11-7 ordering-probe gate (docs/acp-backend-rail.md §11-7): the raw-client seam is
|
|
4681
|
+
# only admissible "bound by a gate asserting it issues the same calls, arguments, and
|
|
4682
|
+
# order as the backend's real sequence" — this is that gate. Sameness over a recording
|
|
4683
|
+
# fake + backend.ts SOURCE pins (order/clientInfo/timeouts/permission policy), phase
|
|
4684
|
+
# attribution (set-model included), the probe-mode fixture's wire instrumentation
|
|
4685
|
+
# (real child, raw JSON-RPC, no API), the shared log's contract at its door — envelope
|
|
4686
|
+
# (the evidence line's own runId/marker/sort axis cannot be rewritten by a payload) AND
|
|
4687
|
+
# payload (every field the classifier judges on is typed there) — and the PURE
|
|
4688
|
+
# paired-verdict truth table.
|
|
4689
|
+
run_ts scripts/check-probe-ordering.ts
|
|
4690
|
+
;;
|
|
4691
|
+
check-probe-cli-shim)
|
|
4692
|
+
# §11-7-c producer gate (docs/acp-backend-rail.md §11-7-c condition 5: "Byte-transparency,
|
|
4693
|
+
# backpressure, and exit/signal propagation are proved by a fake-CLI deterministic gate").
|
|
4694
|
+
# The shim sits on the production spawn path of a paid LIVE turn, so this drives it as a
|
|
4695
|
+
# REAL process against fake CLIs and asks what each defect would buy: fabricated absence
|
|
4696
|
+
# evidence (a malformed init reported as an empty name set, a boot report that does not
|
|
4697
|
+
# name what was actually exec'd), a destroyed turn (mangled bytes, a swallowed signal, a
|
|
4698
|
+
# crash reported as exit 0), or leaked operator state (a prefix env scrub, argv/env/prompt
|
|
4699
|
+
# body in the shared log). No API, no network, no cost.
|
|
4700
|
+
run_ts scripts/check-probe-cli-shim.ts
|
|
4701
|
+
;;
|
|
4702
|
+
smoke-acp-ordering-probe-live)
|
|
4703
|
+
# §11-7 ordering probe — LIVE paired-run instrument, OUT of pnpm check. Control
|
|
4704
|
+
# (delay=0, must be visible AND callable) + interventions D1/D2 against the SAME
|
|
4705
|
+
# pins/config/fixture; classifies A/A-withheld/B/C/D-<phase> or P0/I0, preserves
|
|
4706
|
+
# the shared NDJSON log + classification under .probe-artifacts/ (gitignored).
|
|
4707
|
+
# LIVE=1 ./run.sh smoke-acp-ordering-probe-live
|
|
4708
|
+
run_ts scripts/smoke-acp-ordering-probe-live.ts
|
|
4709
|
+
;;
|
|
4455
4710
|
smoke-agy-statusline-state)
|
|
4456
4711
|
# #46 Task 1 regression gate for the agy statusLine install adapter: install→doctor→uninstall
|
|
4457
4712
|
# in an ISOLATED HOME+XDG with a fake stable bin (entwurf-agy-statusline) + fake pgrep —
|
|
@@ -4706,6 +4961,12 @@ case "$cmd" in
|
|
|
4706
4961
|
check-acp-event-mapper)
|
|
4707
4962
|
check_acp_event_mapper
|
|
4708
4963
|
;;
|
|
4964
|
+
check-acp-stop-reason)
|
|
4965
|
+
check_acp_stop_reason
|
|
4966
|
+
;;
|
|
4967
|
+
check-acp-prompt-lifecycle)
|
|
4968
|
+
check_acp_prompt_lifecycle
|
|
4969
|
+
;;
|
|
4709
4970
|
check-acp-prompt-builder)
|
|
4710
4971
|
check_acp_prompt_builder
|
|
4711
4972
|
;;
|
|
@@ -4721,9 +4982,15 @@ case "$cmd" in
|
|
|
4721
4982
|
check-acp-session-reuse)
|
|
4722
4983
|
check_acp_session_reuse
|
|
4723
4984
|
;;
|
|
4985
|
+
check-release-gate-outcomes)
|
|
4986
|
+
run_ts scripts/check-release-gate-outcomes.ts
|
|
4987
|
+
;;
|
|
4724
4988
|
check-acp-carrier-augment)
|
|
4725
4989
|
check_acp_carrier_augment
|
|
4726
4990
|
;;
|
|
4991
|
+
check-acp-cortex)
|
|
4992
|
+
check_acp_cortex
|
|
4993
|
+
;;
|
|
4727
4994
|
check-fresh-cut-gate)
|
|
4728
4995
|
# SOURCE cell of the generation-boundary proof: a host whose store the live
|
|
4729
4996
|
# schema cannot read must be refused BEFORE any write, told the fresh-cut
|