@junghanacs/entwurf 0.13.0 → 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 +5 -3
- package/BASELINE.md +57 -203
- package/CHANGELOG.md +19 -0
- package/CONTRIBUTING.md +1 -1
- package/DELIVERY.md +117 -261
- package/README.md +68 -408
- package/VERIFY.md +58 -87
- 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 +11 -10
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/engraving.js +42 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +4 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +3 -3
- package/mcp/entwurf-bridge/src/index.ts +21 -48
- package/package.json +12 -9
- 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 +42 -3
- package/pi-extensions/lib/acp/backend-adapter.ts +12 -11
- package/pi-extensions/lib/acp/backend.ts +305 -36
- package/pi-extensions/lib/acp/config.ts +1 -1
- package/pi-extensions/lib/acp/engraving.ts +43 -1
- package/pi-extensions/lib/acp/event-mapper.ts +16 -13
- package/pi-extensions/lib/acp/models.ts +4 -4
- package/pi-extensions/lib/acp/overlay.ts +3 -3
- package/prompts/engraving.md +13 -5
- package/run.sh +244 -108
- package/scripts/check-acp-carrier-augment.ts +246 -10
- package/scripts/check-acp-cortex.ts +5 -5
- package/scripts/check-acp-prompt-lifecycle.ts +565 -0
- package/scripts/check-acp-sdk-surface.ts +60 -21
- package/scripts/check-acp-stop-reason.ts +342 -0
- package/scripts/check-entwurf-v2-surface.ts +41 -0
- package/scripts/check-gate-qualification.ts +6 -3
- package/scripts/check-probe-ordering.ts +39 -7
- package/scripts/check-release-gate-outcomes.ts +332 -0
- package/scripts/lib/live-skip.ts +33 -0
- package/scripts/lib/probe-acp-turn.ts +33 -12
- package/scripts/lib/step-outcome.sh +88 -0
- package/scripts/mutants/acp-augment.json +106 -0
- package/scripts/mutants/acp-cortex.json +2 -2
- package/scripts/mutants/acp-prompt-lifecycle.json +100 -0
- package/scripts/mutants/acp-stop-reason.json +80 -0
- package/scripts/mutants/probe-ordering.json +27 -5
- 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 +8 -14
- 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 +2 -2
- 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,6 +145,8 @@ 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
|
|
133
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
|
|
134
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
|
|
@@ -984,9 +1002,10 @@ smoke_entwurf_v2_spawn_live() {
|
|
|
984
1002
|
# 5c-3a watcher's timeout→kill→child-exited→release integration on a live process. It does
|
|
985
1003
|
# NOT spawn a real `pi --entwurf-control` resume (that is the 5d surface matrix). Run once
|
|
986
1004
|
# before 5d and record the result: LIVE=1 ./run.sh smoke-entwurf-v2-spawn-live
|
|
1005
|
+
entwurf_require_step_outcome
|
|
987
1006
|
if [ "${LIVE:-}" != "1" ]; then
|
|
988
|
-
echo "[smoke-entwurf-v2-spawn-live
|
|
989
|
-
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"
|
|
990
1009
|
fi
|
|
991
1010
|
run_ts scripts/smoke-entwurf-v2-spawn-live.ts
|
|
992
1011
|
}
|
|
@@ -1051,6 +1070,18 @@ smoke_acp_memory_containment_live() {
|
|
|
1051
1070
|
run_ts scripts/smoke-acp-memory-containment-live.ts
|
|
1052
1071
|
}
|
|
1053
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
|
+
|
|
1054
1085
|
smoke_acp_provider_live() {
|
|
1055
1086
|
# S2c acceptance smoke (ACP plugin on v2) — OUT of pnpm check, needs LIVE=1.
|
|
1056
1087
|
# Drives the REAL pi PROVIDER path end to end: a real `pi` loads this
|
|
@@ -1181,16 +1212,16 @@ smoke_acp_rgg_live() {
|
|
|
1181
1212
|
|
|
1182
1213
|
smoke_acp_cortex_live() {
|
|
1183
1214
|
# On-demand LIVE smoke for the Cortex (Snowflake Cortex Code) ACP backend — the
|
|
1184
|
-
# first NON-claude adapter on the rail (docs/acp-backend-rail.md
|
|
1215
|
+
# first NON-claude adapter on the rail (docs/acp-backend-rail.md, Cortex audit). OUT of
|
|
1185
1216
|
# `pnpm check` AND OUTSIDE the claude-only aggregate LIVE floor (capability
|
|
1186
1217
|
# dignity, invariant #7): a host with no cortex install / no Snowflake auth must
|
|
1187
1218
|
# not redden a release for a backend it does not run, so this is deliberately
|
|
1188
1219
|
# absent from release-gate's 11-smoke ACP acceptance floor. That is a WIRING
|
|
1189
1220
|
# decision, not a lower evidence bar — a cut that SHIPS cortex still owes a
|
|
1190
1221
|
# deliberate run of this smoke, and the aggregate gate's silence is not a pass
|
|
1191
|
-
# (rail
|
|
1222
|
+
# (ACP rail Cortex verification boundary). Drives one real
|
|
1192
1223
|
# cortex ACP turn through the entwurf provider path (outbound entwurf_v2 +
|
|
1193
|
-
# dual-HOME overlay facts + process-group reclaim — CP2
|
|
1224
|
+
# dual-HOME overlay facts + process-group reclaim — CP2).
|
|
1194
1225
|
# HONEST-SKIP (exit 0) when LIVE!=1 OR `cortex` is not on PATH OR no
|
|
1195
1226
|
# connection is pinned — the live turn needs `cortex` installed with the
|
|
1196
1227
|
# operator's own web-login auth already present (there is no `cortex auth`
|
|
@@ -1202,13 +1233,14 @@ smoke_acp_cortex_live() {
|
|
|
1202
1233
|
# operator settings.json where a default would live. PR #40 called this
|
|
1203
1234
|
# `smoke-cortex`; the canonical family name is smoke-acp-cortex-live.
|
|
1204
1235
|
# LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live
|
|
1236
|
+
entwurf_require_step_outcome
|
|
1205
1237
|
if [ "${LIVE:-}" != "1" ]; then
|
|
1206
|
-
echo "[smoke-acp-cortex-live
|
|
1207
|
-
return
|
|
1238
|
+
echo "[entwurf:skip] smoke-acp-cortex-live — set LIVE=1 (+ ENTWURF_ACP_CORTEX_CONNECTION) to run."
|
|
1239
|
+
return "$ENTWURF_STEP_SKIP_EXIT"
|
|
1208
1240
|
fi
|
|
1209
1241
|
if ! command -v cortex >/dev/null 2>&1; then
|
|
1210
|
-
echo "[smoke-acp-cortex-live
|
|
1211
|
-
return
|
|
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"
|
|
1212
1244
|
fi
|
|
1213
1245
|
run_ts scripts/smoke-acp-cortex-live.ts
|
|
1214
1246
|
}
|
|
@@ -1225,9 +1257,10 @@ smoke_entwurf_v2_matrix_live() {
|
|
|
1225
1257
|
# stay deterministic. Honest skip when LIVE!=1 so the release-gate is runnable unattended.
|
|
1226
1258
|
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.4).
|
|
1227
1259
|
# LIVE=1 ./run.sh smoke-entwurf-v2-matrix-live
|
|
1260
|
+
entwurf_require_step_outcome
|
|
1228
1261
|
if [ "${LIVE:-}" != "1" ]; then
|
|
1229
|
-
echo "[smoke-entwurf-v2-matrix-live
|
|
1230
|
-
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"
|
|
1231
1264
|
fi
|
|
1232
1265
|
run_ts scripts/smoke-entwurf-v2-matrix-live.ts
|
|
1233
1266
|
}
|
|
@@ -1247,9 +1280,10 @@ smoke_entwurf_v2_spawn_resume_live() {
|
|
|
1247
1280
|
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.4);
|
|
1248
1281
|
# ENTWURF_SPAWN_RESUME_ASSISTANT_TIMEOUT_MS (default 180000).
|
|
1249
1282
|
# LIVE=1 ./run.sh smoke-entwurf-v2-spawn-resume-live
|
|
1283
|
+
entwurf_require_step_outcome
|
|
1250
1284
|
if [ "${LIVE:-}" != "1" ]; then
|
|
1251
|
-
echo "[smoke-entwurf-v2-spawn-resume-live
|
|
1252
|
-
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"
|
|
1253
1287
|
fi
|
|
1254
1288
|
run_ts scripts/smoke-entwurf-v2-spawn-resume-live.ts
|
|
1255
1289
|
}
|
|
@@ -1472,12 +1506,13 @@ assert.equal(peerTui, piAi,
|
|
|
1472
1506
|
// floor tracks the devDep pin so a consumer can't install against a pi lacking
|
|
1473
1507
|
// the public trust exports the bridge imports at the pinned minor, AND an upper
|
|
1474
1508
|
// bound at the next minor stops a fresh install from silently pulling a future
|
|
1475
|
-
// pi (past the declared ceiling — 0.
|
|
1509
|
+
// pi (past the declared ceiling — 0.84+ at the current 0.83.0 pin) whose
|
|
1476
1510
|
// internal export surface has drifted from the one we typecheck against.
|
|
1477
1511
|
// pi moves its public surface every minor (the 0.79→0.80 getModels→provider-
|
|
1478
1512
|
// factory churn is exactly this), so an open `>=` floor is exactly how the next
|
|
1479
|
-
// installer re-acquires the drift.
|
|
1480
|
-
//
|
|
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`).
|
|
1481
1516
|
const [piMaj, piMin] = piAi.split('.').map(Number);
|
|
1482
1517
|
assert.equal(piMaj, 0,
|
|
1483
1518
|
`pi pin major must stay 0 for the next-minor ceiling rule (got ${piAi}); revisit check-dep-versions when pi reaches 1.x`);
|
|
@@ -2263,7 +2298,7 @@ check_acp_provider_surface() {
|
|
|
2263
2298
|
check_acp_sdk_surface() {
|
|
2264
2299
|
# Deterministic gate for the S2a ACP SDK dependency surface. Pins the three
|
|
2265
2300
|
# ACP runtime deps to the current oracle versions (@agentclientprotocol/sdk
|
|
2266
|
-
# 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
|
|
2267
2302
|
# peer-resolution that keeps claude-agent-sdk satisfiable (0.100.1, not the
|
|
2268
2303
|
# stale 0.91.1), asserts the wire SDK still value-exports the symbols the raw
|
|
2269
2304
|
# turn needs (silent-rename gate), and forbids any source-level anthropic SDK
|
|
@@ -2308,6 +2343,37 @@ check_acp_event_mapper() {
|
|
|
2308
2343
|
run_ts scripts/check-acp-event-mapper.ts
|
|
2309
2344
|
}
|
|
2310
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
|
+
|
|
2311
2377
|
check_acp_prompt_builder() {
|
|
2312
2378
|
# Deterministic gate for the S2d bootstrapPath-scoped ACP prompt builder (핀4).
|
|
2313
2379
|
# Proves prompt SCOPE follows bootstrapPath: new=full transcript (history
|
|
@@ -2383,11 +2449,11 @@ check_acp_carrier_augment() {
|
|
|
2383
2449
|
check_acp_cortex() {
|
|
2384
2450
|
# Deterministic gate for the Cortex (Snowflake Cortex Code) ACP backend — the
|
|
2385
2451
|
# first non-claude adapter on the rail, landed 0.13.0 on the CP0-measured
|
|
2386
|
-
# contract (docs/acp-backend-rail.md
|
|
2452
|
+
# contract (docs/acp-backend-rail.md, Cortex audit D1–D10). The cortex source is one
|
|
2387
2453
|
# `cortexAdapter` object (backend-adapter.ts) + its curated surface (models.ts)
|
|
2388
2454
|
# + the dual-HOME overlay (overlay.ts); the 결합 규칙 requires the gate to land
|
|
2389
|
-
# WITH it,
|
|
2390
|
-
# deterministic axis lives here. Locks (each
|
|
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
|
|
2391
2457
|
# 4-row curation rides real registry bases and the `cortex-` prefix routes to
|
|
2392
2458
|
# cortexAdapter; launch is `cortex acp serve` with NO -m — the model is
|
|
2393
2459
|
# enforced per turn via session/set_config_option with the native id (E);
|
|
@@ -2776,21 +2842,21 @@ _check_pack_install_impl() {
|
|
|
2776
2842
|
printf '%s\n' '{ "name": "entwurf-install-smoke", "version": "0.0.0", "private": true }' > "$tmp/package.json"
|
|
2777
2843
|
|
|
2778
2844
|
# pi-agent-core is pinned even though we never import it: pi-coding-agent depends
|
|
2779
|
-
# on it by CARET (`^0.
|
|
2845
|
+
# on it by CARET (`^0.83.0`), so with no lockfile in this fresh temp project it
|
|
2780
2846
|
# floats to whatever pi published last — and that newer core then drags a NESTED
|
|
2781
2847
|
# pi-ai of its own. Measured 2026-07-21: pinning only the three we import left
|
|
2782
2848
|
# pi-agent-core@0.80.10 + pi-ai@0.80.10 in the tree while the gate still announced
|
|
2783
2849
|
# "pinned pi 0.80.7". The gate would then be verifying an UNVERIFIED runtime — the
|
|
2784
2850
|
# exact class this cut exists to close. Pin every @earendil-works package that
|
|
2785
2851
|
# constitutes the pi runtime, not just the ones whose types we touch.
|
|
2786
|
-
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)"
|
|
2787
2853
|
local install_log
|
|
2788
2854
|
install_log=$(cd "$tmp" && pnpm add \
|
|
2789
2855
|
"$tgz_path" \
|
|
2790
|
-
"@earendil-works/pi-ai@0.
|
|
2791
|
-
"@earendil-works/pi-coding-agent@0.
|
|
2792
|
-
"@earendil-works/pi-tui@0.
|
|
2793
|
-
"@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" \
|
|
2794
2860
|
"typebox@latest" \
|
|
2795
2861
|
--ignore-workspace --ignore-scripts 2>&1) || {
|
|
2796
2862
|
fail "[check-pack-install] pnpm add failed:"
|
|
@@ -2800,17 +2866,17 @@ _check_pack_install_impl() {
|
|
|
2800
2866
|
|
|
2801
2867
|
# A pin is a wish until the resolved tree is read back. Assert it: EVERY
|
|
2802
2868
|
# @earendil-works pi package present — direct or transitive, top level or nested —
|
|
2803
|
-
# must be the pinned 0.
|
|
2869
|
+
# must be the pinned 0.83.0. Anything else means an unpinned caret floated and the
|
|
2804
2870
|
# rest of this gate would be exercising a runtime nobody verified, while still
|
|
2805
|
-
# printing "pinned pi 0.
|
|
2871
|
+
# printing "pinned pi 0.83.0". Fail loud instead of proving the wrong floor.
|
|
2806
2872
|
local leaked_pi
|
|
2807
|
-
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)
|
|
2808
2874
|
if [ -n "$leaked_pi" ]; then
|
|
2809
|
-
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):"
|
|
2810
2876
|
printf '%s\n' "$leaked_pi" | sed 's/^/ /' >&2
|
|
2811
2877
|
return 1
|
|
2812
2878
|
fi
|
|
2813
|
-
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"
|
|
2814
2880
|
|
|
2815
2881
|
# Resolve the installed package.json and confirm pi.extensions
|
|
2816
2882
|
# arrived intact. If pi.extensions is empty or missing, the
|
|
@@ -3757,7 +3823,7 @@ setup_all() {
|
|
|
3757
3823
|
# native-harness meta-bridge, so a relocate/clone needs ONE command — not the
|
|
3758
3824
|
# install + install-meta-bridge two-pronged split that froze the Claude
|
|
3759
3825
|
# statusLine on the old path (the 2026-06-23 relocation gap). Detection-gated:
|
|
3760
|
-
# 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” — "있으면 설정,
|
|
3761
3827
|
# 없으면 담아준다"); meta-bridge-install.sh is itself idempotent.
|
|
3762
3828
|
if command -v claude >/dev/null 2>&1; then
|
|
3763
3829
|
section "meta-bridge install (native harness detected: Claude Code)"
|
|
@@ -3789,7 +3855,7 @@ setup_all() {
|
|
|
3789
3855
|
wire_agy_hooks
|
|
3790
3856
|
|
|
3791
3857
|
# Deterministic preflight lives in `pnpm check`; live substrate acceptance lives
|
|
3792
|
-
# 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
|
|
3793
3859
|
# verifies the installed MCP bridge boundary only and does NOT run the legacy
|
|
3794
3860
|
# ACP/v1 session-messaging/sentinel gates.
|
|
3795
3861
|
section "v2 install smoke: entwurf-bridge (direct MCP protocol)"
|
|
@@ -3805,7 +3871,7 @@ setup_all() {
|
|
|
3805
3871
|
echo " ./run.sh doctor-agy-statusline"
|
|
3806
3872
|
echo " ./run.sh doctor-agy-hooks"
|
|
3807
3873
|
fi
|
|
3808
|
-
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)."
|
|
3809
3875
|
}
|
|
3810
3876
|
|
|
3811
3877
|
# wire_agy_bridge — detection-gated, NON-FATAL agy (Antigravity) MCP bridge wiring, folded into
|
|
@@ -3989,10 +4055,18 @@ expose_dev_bin() {
|
|
|
3989
4055
|
# - Final release authorization is GLG's, not this script's: a green
|
|
3990
4056
|
# run is necessary, and the operator closes the decision.
|
|
3991
4057
|
release_gate() {
|
|
4058
|
+
entwurf_require_step_outcome
|
|
3992
4059
|
local -a positional=()
|
|
3993
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
|
|
3994
4067
|
for a in "$@"; do
|
|
3995
4068
|
case "$a" in
|
|
4069
|
+
--cut) cut_mode=1 ;;
|
|
3996
4070
|
--allow-skip-gemini) ;; # accepted-but-ignored: gemini removed from the claude-only floor (back-compat for existing scripts)
|
|
3997
4071
|
*) positional+=("$a") ;;
|
|
3998
4072
|
esac
|
|
@@ -4043,27 +4117,36 @@ release_gate() {
|
|
|
4043
4117
|
}
|
|
4044
4118
|
|
|
4045
4119
|
# LIVE-gated MUST step: a release-blocking gate that needs a real backend turn
|
|
4046
|
-
# (auth/model/credit).
|
|
4047
|
-
#
|
|
4048
|
-
#
|
|
4049
|
-
#
|
|
4050
|
-
#
|
|
4051
|
-
#
|
|
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.
|
|
4052
4131
|
run_live_step() {
|
|
4053
4132
|
local name="$1"; shift
|
|
4054
4133
|
section "release-gate step: $name"
|
|
4055
|
-
|
|
4056
|
-
|
|
4134
|
+
local rc=0
|
|
4135
|
+
"$@" || rc=$?
|
|
4136
|
+
case "$(entwurf_step_outcome "$rc")" in
|
|
4137
|
+
PASS)
|
|
4057
4138
|
ok "$name: PASS"
|
|
4058
4139
|
results+=("PASS $name"); pass=$((pass + 1))
|
|
4059
|
-
|
|
4060
|
-
|
|
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)"
|
|
4061
4147
|
results+=("FAIL $name"); failc=$((failc + 1))
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
warn "$name: LIVE!=1 — skipped (opt-in: needs auth/model — NOT a live acceptance run)"
|
|
4065
|
-
results+=("SKIP $name (LIVE!=1)"); skip=$((skip + 1))
|
|
4066
|
-
fi
|
|
4148
|
+
;;
|
|
4149
|
+
esac
|
|
4067
4150
|
}
|
|
4068
4151
|
|
|
4069
4152
|
# BEHAVIOR lane (0.11.0, GLG+GPT+Opus): a SEPARATE advisory counter for
|
|
@@ -4087,19 +4170,32 @@ release_gate() {
|
|
|
4087
4170
|
# deterministic/programmatic must-pass gates above (check-entwurf-v2-*,
|
|
4088
4171
|
# check-bridge) — this lane is autonomous-tool-selection *behavior*, not
|
|
4089
4172
|
# *function*. Residual bypass → 0.11.x usability lane.
|
|
4090
|
-
|
|
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
|
|
4091
4178
|
local -a behavior_results=()
|
|
4092
4179
|
|
|
4093
4180
|
run_behavior_step() {
|
|
4094
4181
|
local name="$1"; shift
|
|
4095
4182
|
section "release-gate BEHAVIOR step (advisory, non-blocking): $name"
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
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
|
|
4103
4199
|
}
|
|
4104
4200
|
|
|
4105
4201
|
# 1. Static floor (deterministic; includes the two folded gates).
|
|
@@ -4137,41 +4233,20 @@ release_gate() {
|
|
|
4137
4233
|
# production runEntwurfV2 deps + real pi control-socket RPC + real mailbox enqueue + v2 lock, not
|
|
4138
4234
|
# per-backend model behavior). Placed right after check-bridge: the MCP/protocol substrate must be
|
|
4139
4235
|
# green first so a matrix-live failure reads as "v2 transport/lock/enqueue", not bridge basics.
|
|
4140
|
-
# Opt-in LIVE: it spawns a real `pi --entwurf-control` (needs auth/model), so
|
|
4141
|
-
# SKIP (not a PASS) — an unattended release-gate stays runnable without
|
|
4142
|
-
# of --allow-skip-gemini (now a no-op back-compat flag on the
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
results+=("PASS smoke-entwurf-v2-matrix-live"); pass=$((pass + 1))
|
|
4148
|
-
else
|
|
4149
|
-
fail "smoke-entwurf-v2-matrix-live: FAIL"
|
|
4150
|
-
results+=("FAIL smoke-entwurf-v2-matrix-live"); failc=$((failc + 1))
|
|
4151
|
-
fi
|
|
4152
|
-
else
|
|
4153
|
-
warn "smoke-entwurf-v2-matrix-live: LIVE!=1 — skipped (v2 substrate sentinel, opt-in: needs auth/model)"
|
|
4154
|
-
results+=("SKIP smoke-entwurf-v2-matrix-live (LIVE!=1)"); skip=$((skip + 1))
|
|
4155
|
-
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
|
|
4156
4243
|
# 0.11.0 (A) acceptance: the FULL spawn-bg resident lifecycle — a real `pi` resume child stands
|
|
4157
4244
|
# its control socket up, does a model turn, lock released ×1. Placed right after matrix-live (the
|
|
4158
4245
|
# transport sentinel): a spawn-resume failure then reads as "resume/resident lifecycle", not
|
|
4159
|
-
# transport basics. Same opt-in LIVE rule
|
|
4160
|
-
#
|
|
4161
|
-
#
|
|
4162
|
-
|
|
4163
|
-
if [ "${LIVE:-}" = "1" ]; then
|
|
4164
|
-
if gate env LIVE=1 bash "$self" smoke-entwurf-v2-spawn-resume-live; then
|
|
4165
|
-
ok "smoke-entwurf-v2-spawn-resume-live: PASS"
|
|
4166
|
-
results+=("PASS smoke-entwurf-v2-spawn-resume-live"); pass=$((pass + 1))
|
|
4167
|
-
else
|
|
4168
|
-
fail "smoke-entwurf-v2-spawn-resume-live: FAIL"
|
|
4169
|
-
results+=("FAIL smoke-entwurf-v2-spawn-resume-live"); failc=$((failc + 1))
|
|
4170
|
-
fi
|
|
4171
|
-
else
|
|
4172
|
-
warn "smoke-entwurf-v2-spawn-resume-live: LIVE!=1 — skipped (0.11.0 A acceptance, opt-in: needs auth/model)"
|
|
4173
|
-
results+=("SKIP smoke-entwurf-v2-spawn-resume-live (LIVE!=1)"); skip=$((skip + 1))
|
|
4174
|
-
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
|
|
4175
4250
|
|
|
4176
4251
|
# 3b. ACP plugin acceptance floor (S0~S2f live). These prove the ACP plugin's
|
|
4177
4252
|
# programmatic transport/provider/backend invariants on the v2 core — NOT
|
|
@@ -4186,18 +4261,35 @@ release_gate() {
|
|
|
4186
4261
|
# → first-user augment delivery + empty-carrier billing-clean (핀1) →
|
|
4187
4262
|
# ACP-target garden guard (deterministic half). Opt-in LIVE: LIVE!=1 is an
|
|
4188
4263
|
# HONEST SKIP via run_live_step (see its note) — a CUT needs LIVE=1, SKIP=0.
|
|
4189
|
-
run_live_step "smoke-acp-socket-citizen-live (S1: turn-free socket citizenship)" gate
|
|
4190
|
-
run_live_step "smoke-acp-raw-turn-live (S2a: pinned ACP pipe + local auth)" gate
|
|
4191
|
-
run_live_step "smoke-acp-overlay-live (S2b: config overlay + hooks:{} + tool meta)" gate
|
|
4192
|
-
run_live_step "smoke-acp-provider-live (S2c/S2f: real pi provider path + progress/L3)" gate
|
|
4193
|
-
run_live_step "smoke-acp-session-reuse-live (S2d: process-scoped reuse + recall)" gate
|
|
4194
|
-
run_live_step "smoke-acp-carrier-augment-live (S2e-1: augment delivery + 핀1 billing)" gate
|
|
4195
|
-
run_live_step "smoke-acp-memory-containment-live (Gate D: no overlay memory leak)" gate
|
|
4196
|
-
run_live_step "smoke-acp-rgg-live (S2e-2: ACP-target garden guard, deterministic half)" gate
|
|
4197
|
-
run_live_step "smoke-acp-mcp-live (S2g: operator mcpServers reach the live ACP session)" gate
|
|
4198
|
-
run_live_step "smoke-acp-skill-live (S2g: operator skillPlugins reach the live ACP session)" gate
|
|
4199
|
-
run_live_step "smoke-acp-bundled-mcp-live (S2g axis 3: bundled entwurf-bridge via 0.11.0 resident/RPC circuit)" gate
|
|
4200
|
-
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
|
|
4201
4293
|
|
|
4202
4294
|
# 4. BEHAVIOR lane (advisory, non-blocking). Model-in-loop gates that probe
|
|
4203
4295
|
# whether the model AUTONOMOUSLY drives the MCP entwurf surface. These never
|
|
@@ -4227,21 +4319,44 @@ release_gate() {
|
|
|
4227
4319
|
if [ "${#behavior_results[@]}" -gt 0 ]; then
|
|
4228
4320
|
printf ' %s\n' "${behavior_results[@]}"
|
|
4229
4321
|
fi
|
|
4230
|
-
echo " BEHAVIOR: PASS=$behavior_pass FAIL=$behavior_failc"
|
|
4322
|
+
echo " BEHAVIOR: PASS=$behavior_pass FAIL=$behavior_failc SKIP=$behavior_skip"
|
|
4231
4323
|
echo " (per-step artifact paths are printed in each step's output above)"
|
|
4232
4324
|
if [ "$behavior_failc" -gt 0 ]; then
|
|
4233
4325
|
echo ""
|
|
4234
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."
|
|
4235
4327
|
fi
|
|
4236
|
-
|
|
4237
|
-
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
|
|
4238
4345
|
echo ""
|
|
4239
|
-
|
|
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
|
|
4240
4353
|
echo " A green MUST gate is necessary but not sufficient; GLG closes the call."
|
|
4241
4354
|
return 1
|
|
4242
4355
|
fi
|
|
4243
|
-
if [ "$
|
|
4244
|
-
|
|
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."
|
|
4245
4360
|
else
|
|
4246
4361
|
ok "release-gate MUST PASS + BEHAVIOR PASS — all green. Necessary condition met — GLG authorizes the cut."
|
|
4247
4362
|
fi
|
|
@@ -4393,6 +4508,9 @@ case "$cmd" in
|
|
|
4393
4508
|
smoke-acp-provider-live)
|
|
4394
4509
|
smoke_acp_provider_live
|
|
4395
4510
|
;;
|
|
4511
|
+
smoke-acp-long-turn-live)
|
|
4512
|
+
smoke_acp_long_turn_live
|
|
4513
|
+
;;
|
|
4396
4514
|
smoke-acp-session-reuse-live)
|
|
4397
4515
|
smoke_acp_session_reuse_live
|
|
4398
4516
|
;;
|
|
@@ -4405,6 +4523,15 @@ case "$cmd" in
|
|
|
4405
4523
|
smoke-acp-bundled-mcp-live)
|
|
4406
4524
|
smoke_acp_bundled_mcp_live
|
|
4407
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
|
+
;;
|
|
4408
4535
|
smoke-acp-v2-send-live)
|
|
4409
4536
|
smoke_acp_v2_send_live
|
|
4410
4537
|
;;
|
|
@@ -4834,6 +4961,12 @@ case "$cmd" in
|
|
|
4834
4961
|
check-acp-event-mapper)
|
|
4835
4962
|
check_acp_event_mapper
|
|
4836
4963
|
;;
|
|
4964
|
+
check-acp-stop-reason)
|
|
4965
|
+
check_acp_stop_reason
|
|
4966
|
+
;;
|
|
4967
|
+
check-acp-prompt-lifecycle)
|
|
4968
|
+
check_acp_prompt_lifecycle
|
|
4969
|
+
;;
|
|
4837
4970
|
check-acp-prompt-builder)
|
|
4838
4971
|
check_acp_prompt_builder
|
|
4839
4972
|
;;
|
|
@@ -4849,6 +4982,9 @@ case "$cmd" in
|
|
|
4849
4982
|
check-acp-session-reuse)
|
|
4850
4983
|
check_acp_session_reuse
|
|
4851
4984
|
;;
|
|
4985
|
+
check-release-gate-outcomes)
|
|
4986
|
+
run_ts scripts/check-release-gate-outcomes.ts
|
|
4987
|
+
;;
|
|
4852
4988
|
check-acp-carrier-augment)
|
|
4853
4989
|
check_acp_carrier_augment
|
|
4854
4990
|
;;
|