@junghanacs/entwurf 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +299 -0
- package/DELIVERY.md +4 -3
- package/README.md +99 -67
- package/VERIFY.md +13 -7
- package/docs/acp-backend-rail.md +1 -1
- package/docs/external-mcp-host.md +147 -9
- package/docs/setup-clean-host.md +221 -16
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +65 -20
- package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +17 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +1 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +172 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +152 -17
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/omp-fresh-preflight.js +271 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +988 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-receive-omp.js +574 -0
- package/mcp/entwurf-bridge/dist/scripts/omp-receive-facts.js +84 -0
- package/mcp/entwurf-bridge/src/index.ts +65 -19
- package/mcp/entwurf-bridge/tsconfig.build.json +19 -3
- package/mcp/tsconfig.json +10 -0
- package/package.json +14 -4
- package/pi/entwurf-capabilities.json +1 -0
- package/pi/meta-bridge-omp/entwurf-meta-omp/package.json +7 -0
- package/pi/omp-receive/entwurf-receive-omp/package.json +7 -0
- package/pi-extensions/entwurf-control.ts +12 -9
- package/pi-extensions/lib/entwurf-self-address.ts +18 -7
- package/pi-extensions/lib/meta-sender-identity.ts +1 -1
- package/pi-extensions/lib/meta-session.ts +219 -5
- package/pi-extensions/lib/mux-fresh-call.ts +171 -17
- package/pi-extensions/lib/omp-fresh-preflight.ts +275 -0
- package/pi-extensions/meta-bridge-omp.ts +1244 -0
- package/pi-extensions/meta-bridge-receive-omp.ts +666 -0
- package/run.sh +1041 -174
- package/scripts/agy-bridge.sh +4 -2
- package/scripts/check-copilot-birth-hook.ts +700 -23
- package/scripts/check-entwurf-self-address.ts +31 -0
- package/scripts/check-fresh-cut-gate.sh +12 -4
- package/scripts/check-gate-qualification.ts +8 -2
- package/scripts/check-harness-admission-parity.ts +143 -0
- package/scripts/check-meta-doctor-oracle.sh +20 -0
- package/scripts/check-omp-birth-hook.ts +1049 -0
- package/scripts/check-omp-fresh-preflight.ts +181 -0
- package/scripts/check-omp-receive-arm.ts +516 -0
- package/scripts/check-setup-qualification.sh +126 -0
- package/scripts/copilot-bridge-doctor.sh +104 -71
- package/scripts/copilot-bridge-install.sh +180 -20
- package/scripts/copilot-bridge-oracle.sh +223 -0
- package/scripts/copilot-bridge-uninstall.sh +137 -0
- package/scripts/dev-bin.sh +50 -9
- package/scripts/fake-copilot-vendor.sh +67 -0
- package/scripts/inventory-verification-surface.ts +1 -1
- package/scripts/meta-bridge-hook-log.sh +9 -1
- package/scripts/mutants/copilot-birth.json +96 -5
- package/scripts/mutants/mux-fresh-call.json +22 -22
- package/scripts/mutants/omp-birth.json +173 -0
- package/scripts/mutants/omp-fresh.json +300 -0
- package/scripts/mutants/omp-receive.json +135 -0
- package/scripts/mutants/pi-package-ownership.json +92 -0
- package/scripts/mutants/self-address.json +34 -0
- package/scripts/mutants/setup-verdict.json +148 -0
- package/scripts/mutants/source-install.json +32 -0
- package/scripts/omp-bridge-doctor.sh +315 -0
- package/scripts/omp-bridge-install.sh +221 -0
- package/scripts/omp-bridge-oracle.sh +154 -0
- package/scripts/omp-bridge-uninstall.sh +57 -0
- package/scripts/omp-mcp-bridge.sh +320 -0
- package/scripts/omp-mcp-config.py +392 -0
- package/scripts/omp-receive-doctor.sh +246 -0
- package/scripts/omp-receive-facts.ts +106 -0
- package/scripts/omp-receive-install.sh +228 -0
- package/scripts/omp-receive-uninstall.sh +60 -0
- package/scripts/omp-tool-surface.py +349 -0
- package/scripts/pi_settings_io.py +22 -0
- package/scripts/raw-omp-measure/README.md +420 -0
- package/scripts/raw-omp-measure/probe-extension.ts +76 -0
- package/scripts/raw-omp-measure/probe-receive-surface.ts +250 -0
- package/scripts/raw-omp-measure/source-audit.md +414 -0
- package/scripts/register-pi-package.py +525 -7
- package/scripts/register-pi-provider.py +162 -12
- package/scripts/smoke-agy-install-state.sh +86 -30
- package/scripts/smoke-agy-statusline-state.sh +9 -6
- package/scripts/smoke-omp-bridge-state.sh +221 -0
- package/scripts/smoke-omp-fresh-live.ts +497 -0
- package/scripts/smoke-omp-mcp-state.sh +327 -0
- package/scripts/smoke-omp-receive-live.ts +340 -0
- package/scripts/smoke-omp-receive-state.sh +196 -0
- package/scripts/smoke-setup-verdict.sh +291 -0
- package/scripts/smoke-user-scope-citizen.sh +388 -1
- package/scripts/tsconfig.json +2 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# smoke-setup-verdict.sh — the smallest aggregate `setup` verdict fixture (#86 C1).
|
|
3
|
+
#
|
|
4
|
+
# The aggregate composition had ZERO automated consumers before this file: no
|
|
5
|
+
# living layer executed `entwurf setup` at all, so the false-green shape (WARN
|
|
6
|
+
# swallowing + unconditional "DONE ... green") had only a human operator as its
|
|
7
|
+
# gate. This fixture drives the REAL `run.sh setup` end to end in a sandbox and
|
|
8
|
+
# pins exactly the #86 C1 acceptance cells:
|
|
9
|
+
#
|
|
10
|
+
# S-1 all-harness-absent → core PASS, pi/claude/agy SKIP, computed green,
|
|
11
|
+
# zero harness writes, credential store untouched
|
|
12
|
+
# S-2 pi below floor → detected FAIL (never SKIP), nonzero, no Pi wiring
|
|
13
|
+
# S-3 pi at floor → presence completes project+user wiring, green,
|
|
14
|
+
# credential store still byte-identical
|
|
15
|
+
# S-4 agy detected+corrupt→ named component FAIL + NON-GREEN + nonzero exit,
|
|
16
|
+
# core and later components still attempted
|
|
17
|
+
# S-5 installed mode → the installed-vs-source branch is a NAMED verdict
|
|
18
|
+
# printed before anything else, and never reaches
|
|
19
|
+
# the source pnpm bootstrap
|
|
20
|
+
#
|
|
21
|
+
# Mutation attribution does NOT live here (round 3): the setup-verdict lane's
|
|
22
|
+
# QK signatures and kill cells moved to the snapshot-safe oracle
|
|
23
|
+
# scripts/check-setup-qualification.sh, so this file carries no [QK] tokens.
|
|
24
|
+
# This fixture is the BEHAVIOR authority only — S-2/S-4 still exercise the same
|
|
25
|
+
# below-floor and false-green shapes as living end-to-end evidence.
|
|
26
|
+
#
|
|
27
|
+
# Deterministic: no model, no network, no cost. Presence probes are pinned via
|
|
28
|
+
# PI_BIN / CLAUDE_BIN / AGY_BIN (the same hermetic seam smoke-agy-install-state
|
|
29
|
+
# uses), and every write root is sandboxed: HOME, XDG roots, the pi agent dir,
|
|
30
|
+
# and the dev-bin dir. The source bootstrap (`pnpm install --frozen-lockfile`)
|
|
31
|
+
# runs against the ALREADY-INSTALLED checkout, which is a verified no-op under a
|
|
32
|
+
# sandbox HOME (measured 2026-08-26).
|
|
33
|
+
set -euo pipefail
|
|
34
|
+
|
|
35
|
+
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
36
|
+
REPO_DIR="$(cd "$HERE/.." && pwd)"
|
|
37
|
+
|
|
38
|
+
case "$REPO_DIR" in
|
|
39
|
+
*/node_modules/*)
|
|
40
|
+
echo "entwurf: 'smoke-setup-verdict' is a dev-clone-only surface — run it from a checkout." >&2
|
|
41
|
+
exit 1
|
|
42
|
+
;;
|
|
43
|
+
esac
|
|
44
|
+
|
|
45
|
+
# Same snapshot-purity rule as the sibling install smokes: run.sh paths import
|
|
46
|
+
# scripts/*.py and CPython would mint scripts/__pycache__/*.pyc inside the
|
|
47
|
+
# gate-qualification snapshot, ending the run IMPURE.
|
|
48
|
+
export PYTHONDONTWRITEBYTECODE=1
|
|
49
|
+
|
|
50
|
+
SB="$(mktemp -d -t entwurf-setup-verdict.XXXXXX)"
|
|
51
|
+
cleanup() { rm -rf "$SB"; }
|
|
52
|
+
trap cleanup EXIT
|
|
53
|
+
|
|
54
|
+
export HOME="$SB/home"
|
|
55
|
+
export XDG_DATA_HOME="$SB/home/.local/share"
|
|
56
|
+
export XDG_STATE_HOME="$SB/home/.local/state"
|
|
57
|
+
export XDG_CACHE_HOME="$SB/home/.cache"
|
|
58
|
+
export XDG_CONFIG_HOME="$SB/home/.config"
|
|
59
|
+
export PI_CODING_AGENT_DIR="$SB/home/.pi/agent"
|
|
60
|
+
export ENTWURF_DEV_BIN_DIR="$SB/bin"
|
|
61
|
+
export PATH="$SB/bin:$PATH"
|
|
62
|
+
mkdir -p "$HOME" "$PI_CODING_AGENT_DIR" "$SB/bin" "$SB/harness"
|
|
63
|
+
|
|
64
|
+
# Presence pins: default every harness to a definitely-absent path; each cell
|
|
65
|
+
# re-pins what it needs. Production leaves these unset.
|
|
66
|
+
ABSENT="$SB/harness/definitely-absent"
|
|
67
|
+
export PI_BIN="$ABSENT" CLAUDE_BIN="$ABSENT" AGY_BIN="$ABSENT" COPILOT_BIN="$ABSENT"
|
|
68
|
+
|
|
69
|
+
PASS=0
|
|
70
|
+
ok() { PASS=$((PASS + 1)); printf ' ok %s\n' "$*"; }
|
|
71
|
+
die() { printf 'FAIL: %s\n' "$*" >&2; exit 1; }
|
|
72
|
+
want() { # $1 = label, $2 = shell condition
|
|
73
|
+
if eval "$2"; then ok "$1"; else die "$1"; fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
AUTH="$PI_CODING_AGENT_DIR/auth.json"
|
|
77
|
+
seed_auth() {
|
|
78
|
+
printf '{\n "anthropic": {\n "type": "oauth",\n "access": "sandbox-oauth-token"\n }\n}\n' > "$AUTH"
|
|
79
|
+
AUTH_BEFORE="$(sha256sum "$AUTH" | cut -d' ' -f1)"
|
|
80
|
+
}
|
|
81
|
+
want_auth_untouched() { # $1 = cell label prefix
|
|
82
|
+
want "$1: credential store is byte-identical (no read-modify-write)" \
|
|
83
|
+
"[ \"\$(sha256sum '$AUTH' | cut -d' ' -f1)\" = '$AUTH_BEFORE' ]"
|
|
84
|
+
want "$1: no auth.json.bak was written" "[ ! -e '$AUTH.bak' ]"
|
|
85
|
+
want "$1: no 'entwurf' credential alias appeared" \
|
|
86
|
+
"! grep -q '\"entwurf\"' '$AUTH'"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# ── S-1: all harnesses absent → core PASS, three SKIPs, computed green, zero writes ──
|
|
90
|
+
echo "[smoke-setup-verdict] S-1 all-harness-absent setup"
|
|
91
|
+
PROJ1="$SB/proj1"; mkdir -p "$PROJ1"
|
|
92
|
+
seed_auth
|
|
93
|
+
set +e; OUT="$(bash "$REPO_DIR/run.sh" setup "$PROJ1" 2>&1)"; RC=$?; set -e
|
|
94
|
+
want "S-1: all-absent setup exits 0 (core green is still green)" "[ '$RC' -eq 0 ]"
|
|
95
|
+
want "S-1: mode is a named source-checkout branch, printed first" \
|
|
96
|
+
"printf '%s' \"\$OUT\" | head -n 1 | grep -q 'mode: source checkout'"
|
|
97
|
+
want "S-1: pi absent is an explicit zero-state SKIP" "printf '%s' \"\$OUT\" | grep -q 'pi: SKIP'"
|
|
98
|
+
want "S-1: claude absent is an explicit zero-state SKIP" "printf '%s' \"\$OUT\" | grep -q 'claude: SKIP'"
|
|
99
|
+
want "S-1: agy absent is an explicit zero-state SKIP" "printf '%s' \"\$OUT\" | grep -q 'agy: SKIP'"
|
|
100
|
+
want "S-1: copilot absent is an explicit zero-state SKIP" "printf '%s' \"\$OUT\" | grep -q 'copilot: SKIP'"
|
|
101
|
+
want "S-1: core bridge boundary validated (PASS)" "printf '%s' \"\$OUT\" | grep -q 'core: PASS'"
|
|
102
|
+
want "S-1: final verdict is computed, not unconditional" \
|
|
103
|
+
"printf '%s' \"\$OUT\" | grep -q 'result: green (computed from the component outcomes above)'"
|
|
104
|
+
want "S-1: the retired unconditional green line is gone" \
|
|
105
|
+
"! printf '%s' \"\$OUT\" | grep -q 'pi adapter + detected native bridges + v2 install smoke) green'"
|
|
106
|
+
want "S-1: zero Pi wiring written for an absent pi" "[ ! -e '$PROJ1/.pi' ]"
|
|
107
|
+
want "S-1: no user-scope pi settings were created" "[ ! -e '$PI_CODING_AGENT_DIR/settings.json' ]"
|
|
108
|
+
want "S-1: no agy config was created" "[ ! -e '$HOME/.gemini' ]"
|
|
109
|
+
want "S-1: no Copilot config/units were created" "[ ! -e '$HOME/.copilot' ]"
|
|
110
|
+
want_auth_untouched "S-1"
|
|
111
|
+
|
|
112
|
+
# ── S-2: pi resolvable but BELOW floor → detected FAIL, never SKIP, no writes ──
|
|
113
|
+
echo "[smoke-setup-verdict] S-2 pi below floor"
|
|
114
|
+
PROJ2="$SB/proj2"; mkdir -p "$PROJ2"
|
|
115
|
+
printf '#!/usr/bin/env bash\necho 0.1.0\n' > "$SB/harness/pi-stale"; chmod +x "$SB/harness/pi-stale"
|
|
116
|
+
seed_auth
|
|
117
|
+
set +e; OUT="$(PI_BIN="$SB/harness/pi-stale" bash "$REPO_DIR/run.sh" setup "$PROJ2" 2>&1)"; RC=$?; set -e
|
|
118
|
+
# Assertion ORDER is part of the kill contract: the verdict-label check runs
|
|
119
|
+
# FIRST so the PI-FLOOR-SKIP mutant dies on its own token, and the exit-code
|
|
120
|
+
# check runs SECOND so the FALSE-GREEN mutant (labels intact, exit flipped)
|
|
121
|
+
# dies on its token instead of a mislabeled line.
|
|
122
|
+
want "S-2: below-floor pi is a detected FAIL naming the supported range" \
|
|
123
|
+
"printf '%s' \"\$OUT\" | grep -q 'pi: FAIL' && printf '%s' \"\$OUT\" | grep -q 'outside the supported range'"
|
|
124
|
+
want "S-2: a detected component FAIL owns a nonzero setup exit" "[ '$RC' -ne 0 ]"
|
|
125
|
+
want "S-2: a stale pi is never relabeled SKIP" "! printf '%s' \"\$OUT\" | grep -q 'pi: SKIP'"
|
|
126
|
+
want "S-2: summary is NON-GREEN and names the failed component" \
|
|
127
|
+
"printf '%s' \"\$OUT\" | grep -q 'NON-GREEN (FAIL: pi)'"
|
|
128
|
+
want "S-2: no Pi wiring was written for the refused pi" "[ ! -e '$PROJ2/.pi' ]"
|
|
129
|
+
want_auth_untouched "S-2"
|
|
130
|
+
|
|
131
|
+
# ── S-2b: pi resolvable but --version CRASHES → computed FAIL, never a set -e abort ──
|
|
132
|
+
# Review defect (2026-08-26): an unreadable detected pi must reach the verdict
|
|
133
|
+
# engine and the summary, not kill setup before them.
|
|
134
|
+
echo "[smoke-setup-verdict] S-2b pi present but version unreadable"
|
|
135
|
+
PROJ2B="$SB/proj2b"; mkdir -p "$PROJ2B"
|
|
136
|
+
printf '#!/usr/bin/env bash\necho "pi exploded" >&2\nexit 1\n' > "$SB/harness/pi-broken"; chmod +x "$SB/harness/pi-broken"
|
|
137
|
+
seed_auth
|
|
138
|
+
set +e; OUT="$(PI_BIN="$SB/harness/pi-broken" bash "$REPO_DIR/run.sh" setup "$PROJ2B" 2>&1)"; RC=$?; set -e
|
|
139
|
+
want "S-2b: unreadable pi version makes setup exit nonzero via the computed verdict" "[ '$RC' -ne 0 ]"
|
|
140
|
+
want "S-2b: unreadable pi is a detected FAIL naming the unreadable version" \
|
|
141
|
+
"printf '%s' \"\$OUT\" | grep -q 'pi: FAIL' && printf '%s' \"\$OUT\" | grep -q 'unreadable version'"
|
|
142
|
+
want "S-2b: later components were still attempted (core bridge smoke ran)" \
|
|
143
|
+
"printf '%s' \"\$OUT\" | grep -q 'core: PASS'"
|
|
144
|
+
want "S-2b: summary is NON-GREEN (no set -e abort before the summary)" \
|
|
145
|
+
"printf '%s' \"\$OUT\" | grep -q 'NON-GREEN (FAIL: pi)'"
|
|
146
|
+
want "S-2b: no Pi wiring was written for the unreadable pi" "[ ! -e '$PROJ2B/.pi' ]"
|
|
147
|
+
want_auth_untouched "S-2b"
|
|
148
|
+
|
|
149
|
+
# ── S-3: pi at the pinned floor → presence completes project + user wiring ──
|
|
150
|
+
echo "[smoke-setup-verdict] S-3 pi present at floor"
|
|
151
|
+
PROJ3="$SB/proj3"; mkdir -p "$PROJ3"
|
|
152
|
+
PI_PIN="$(node -e 'console.log(require(process.argv[1]).devDependencies["@earendil-works/pi-coding-agent"])' "$REPO_DIR/package.json")"
|
|
153
|
+
printf '#!/usr/bin/env bash\necho %s\n' "$PI_PIN" > "$SB/harness/pi-ok"; chmod +x "$SB/harness/pi-ok"
|
|
154
|
+
seed_auth
|
|
155
|
+
set +e; OUT="$(PI_BIN="$SB/harness/pi-ok" bash "$REPO_DIR/run.sh" setup "$PROJ3" 2>&1)"; RC=$?; set -e
|
|
156
|
+
want "S-3: pi-present setup exits 0" "[ '$RC' -eq 0 ]"
|
|
157
|
+
want "S-3: pi wiring completed as PASS at pin $PI_PIN" "printf '%s' \"\$OUT\" | grep -q 'pi: PASS'"
|
|
158
|
+
want "S-3: project .pi/settings.json written (Pi-owned wiring gated on presence)" \
|
|
159
|
+
"[ -f '$PROJ3/.pi/settings.json' ] && grep -q 'entwurf' '$PROJ3/.pi/settings.json'"
|
|
160
|
+
want "S-3: user-scope citizen registered" \
|
|
161
|
+
"[ -f '$PI_CODING_AGENT_DIR/settings.json' ] && grep -q 'entwurf' '$PI_CODING_AGENT_DIR/settings.json'"
|
|
162
|
+
want_auth_untouched "S-3"
|
|
163
|
+
|
|
164
|
+
# ── S-4: agy detected + corrupt config → named component FAIL, NON-GREEN, later components attempted ──
|
|
165
|
+
echo "[smoke-setup-verdict] S-4 agy detected but corrupt"
|
|
166
|
+
PROJ4="$SB/proj4"; mkdir -p "$PROJ4"
|
|
167
|
+
printf '#!/usr/bin/env bash\necho fake-agy\n' > "$SB/harness/agy"; chmod +x "$SB/harness/agy"
|
|
168
|
+
mkdir -p "$HOME/.gemini/config"
|
|
169
|
+
printf 'this is not json{{{' > "$HOME/.gemini/config/mcp_config.json"
|
|
170
|
+
seed_auth
|
|
171
|
+
set +e; OUT="$(AGY_BIN="$SB/harness/agy" bash "$REPO_DIR/run.sh" setup "$PROJ4" 2>&1)"; RC=$?; set -e
|
|
172
|
+
want "S-4: detected agy failure owns a nonzero setup exit" "[ '$RC' -ne 0 ]"
|
|
173
|
+
want "S-4: the corrupt agy bridge is a NAMED component FAIL" \
|
|
174
|
+
"printf '%s' \"\$OUT\" | grep -q 'agy-bridge: FAIL'"
|
|
175
|
+
want "S-4: the reason is corrupt-specific (invalid JSON), not a silent skip" \
|
|
176
|
+
"printf '%s' \"\$OUT\" | grep -qi 'invalid JSON'"
|
|
177
|
+
want "S-4: later components were still attempted (core bridge smoke ran)" \
|
|
178
|
+
"printf '%s' \"\$OUT\" | grep -q 'core: PASS'"
|
|
179
|
+
want "S-4: summary is NON-GREEN and computed from the outcomes" \
|
|
180
|
+
"printf '%s' \"\$OUT\" | grep -q 'NON-GREEN' && ! printf '%s' \"\$OUT\" | grep -q 'result: green'"
|
|
181
|
+
want "S-4: the corrupt config was preserved, not clobbered" \
|
|
182
|
+
"[ \"\$(cat '$HOME/.gemini/config/mcp_config.json')\" = 'this is not json{{{' ]"
|
|
183
|
+
want_auth_untouched "S-4"
|
|
184
|
+
rm -rf "$HOME/.gemini" "$SB/harness/agy"
|
|
185
|
+
|
|
186
|
+
# ── S-6: copilot PRESENT → all FOUR units compose independently as PASS (#86 C3b) ──
|
|
187
|
+
# The fake vendor is the shared factory (scripts/fake-copilot-vendor.sh, the
|
|
188
|
+
# same measured answer shapes check-copilot-birth-hook.ts bakes), so the birth
|
|
189
|
+
# installer's real preflight/list/add/install sequence runs end to end against
|
|
190
|
+
# it. The three writer units (MCP/receiver/footer) never touch the vendor; they
|
|
191
|
+
# land in the sandbox HOME/XDG.
|
|
192
|
+
echo "[smoke-setup-verdict] S-6 copilot present — four-unit composition"
|
|
193
|
+
PROJ6="$SB/proj6"; mkdir -p "$PROJ6"
|
|
194
|
+
FAKE_COP="$SB/harness/copilot-fake"
|
|
195
|
+
bash "$REPO_DIR/scripts/fake-copilot-vendor.sh" "$FAKE_COP" "$REPO_DIR/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/.claude-plugin/plugin.json"
|
|
196
|
+
seed_auth
|
|
197
|
+
set +e; OUT="$(COPILOT_BIN="$FAKE_COP/copilot" PATH="$FAKE_COP:$PATH" bash "$REPO_DIR/run.sh" setup "$PROJ6" 2>&1)"; RC=$?; set -e
|
|
198
|
+
want "S-6: copilot-present setup exits 0 (four units + core all green)" "[ '$RC' -eq 0 ]"
|
|
199
|
+
want "S-6: birth unit composed as PASS" "printf '%s' \"\$OUT\" | grep -q 'copilot-birth: PASS'"
|
|
200
|
+
want "S-6: MCP unit composed as PASS" "printf '%s' \"\$OUT\" | grep -q 'copilot-mcp: PASS'"
|
|
201
|
+
want "S-6: receiver unit composed as PASS" "printf '%s' \"\$OUT\" | grep -q 'copilot-receive: PASS'"
|
|
202
|
+
want "S-6: visible-footer unit composed as PASS" "printf '%s' \"\$OUT\" | grep -q 'copilot-statusline: PASS'"
|
|
203
|
+
want "S-6: computed summary is green" \
|
|
204
|
+
"printf '%s' \"\$OUT\" | grep -q 'result: green (computed from the component outcomes above)'"
|
|
205
|
+
want "S-6: the birth install drove the real vendor sequence (marketplace add before plugin install)" \
|
|
206
|
+
"grep -q '^plugin marketplace add ' '$FAKE_COP/calls.log' && grep -q '^plugin install entwurf-meta-receive-copilot@meta-bridge-copilot-local$' '$FAKE_COP/calls.log'"
|
|
207
|
+
want "S-6: all four package-owned install-states exist (each unit keeps its inverse authority)" \
|
|
208
|
+
"[ -f '$XDG_DATA_HOME/entwurf/copilot-bridge/install-state.json' ] && [ -f '$XDG_DATA_HOME/entwurf/copilot-mcp/install-state.json' ] && [ -f '$XDG_DATA_HOME/entwurf/copilot-receive/install-state.json' ] && [ -f '$XDG_DATA_HOME/entwurf/copilot-statusline/install-state.json' ]"
|
|
209
|
+
want "S-6: the receiver unit was deployed from the compiled dist closure" \
|
|
210
|
+
"[ -f '$HOME/.copilot/extensions/entwurf-receive/extension.mjs' ] && [ -f '$HOME/.copilot/extensions/entwurf-receive/lib/meta-session.js' ]"
|
|
211
|
+
want "S-6: MCP config and footer settings landed in the sandbox HOME" \
|
|
212
|
+
"grep -q 'entwurf-bridge' '$HOME/.copilot/mcp-config.json' && grep -q 'entwurf-copilot-statusline' '$HOME/.copilot/settings.json'"
|
|
213
|
+
want_auth_untouched "S-6"
|
|
214
|
+
# Reset the composed Copilot state so the next cell decides on a clean host.
|
|
215
|
+
rm -rf "$HOME/.copilot" "$XDG_DATA_HOME/entwurf/copilot-bridge" "$XDG_DATA_HOME/entwurf/copilot-mcp" \
|
|
216
|
+
"$XDG_DATA_HOME/entwurf/copilot-receive" "$XDG_DATA_HOME/entwurf/copilot-statusline" \
|
|
217
|
+
"$XDG_DATA_HOME/entwurf/meta-bridge-copilot"
|
|
218
|
+
|
|
219
|
+
# ── S-7: copilot present but vendor lists FAIL → birth is a NAMED FAIL, the other ──
|
|
220
|
+
# three units are still attempted (independent outcomes), and the aggregate is
|
|
221
|
+
# NON-GREEN + nonzero. A failing `plugin list` is UNKNOWN, never absence (#86
|
|
222
|
+
# C3a), so the composition must not relabel it SKIP or cosmetic PASS.
|
|
223
|
+
echo "[smoke-setup-verdict] S-7 copilot present, vendor list failing"
|
|
224
|
+
PROJ7="$SB/proj7"; mkdir -p "$PROJ7"
|
|
225
|
+
BROKEN_COP="$SB/harness/copilot-broken"; mkdir -p "$BROKEN_COP"
|
|
226
|
+
printf '#!/usr/bin/env bash\necho "not authenticated" >&2\nexit 1\n' > "$BROKEN_COP/copilot"
|
|
227
|
+
chmod +x "$BROKEN_COP/copilot"
|
|
228
|
+
seed_auth
|
|
229
|
+
set +e; OUT="$(COPILOT_BIN="$BROKEN_COP/copilot" PATH="$BROKEN_COP:$PATH" bash "$REPO_DIR/run.sh" setup "$PROJ7" 2>&1)"; RC=$?; set -e
|
|
230
|
+
want "S-7: the failing-vendor birth is a NAMED component FAIL, never SKIP or PASS" \
|
|
231
|
+
"printf '%s' \"\$OUT\" | grep -q 'copilot-birth: FAIL' && ! printf '%s' \"\$OUT\" | grep -q 'copilot: SKIP'"
|
|
232
|
+
want "S-7: the other three units were still attempted independently" \
|
|
233
|
+
"printf '%s' \"\$OUT\" | grep -q 'copilot-mcp: PASS' && printf '%s' \"\$OUT\" | grep -q 'copilot-receive: PASS' && printf '%s' \"\$OUT\" | grep -q 'copilot-statusline: PASS'"
|
|
234
|
+
want "S-7: the detected birth failure owns a nonzero setup exit" "[ '$RC' -ne 0 ]"
|
|
235
|
+
want "S-7: summary is NON-GREEN naming copilot-birth" \
|
|
236
|
+
"printf '%s' \"\$OUT\" | grep -q 'NON-GREEN (FAIL: copilot-birth)'"
|
|
237
|
+
want "S-7: later components were still attempted (core bridge smoke ran)" \
|
|
238
|
+
"printf '%s' \"\$OUT\" | grep -q 'core: PASS'"
|
|
239
|
+
want "S-7: the refused birth wrote no vendor ownership state" \
|
|
240
|
+
"[ ! -e '$XDG_DATA_HOME/entwurf/copilot-bridge/install-state.json' ]"
|
|
241
|
+
want_auth_untouched "S-7"
|
|
242
|
+
rm -rf "$HOME/.copilot" "$XDG_DATA_HOME/entwurf/copilot-mcp" "$XDG_DATA_HOME/entwurf/copilot-receive" \
|
|
243
|
+
"$XDG_DATA_HOME/entwurf/copilot-statusline"
|
|
244
|
+
|
|
245
|
+
# ── S-5: installed mode is a NAMED first verdict, never the source bootstrap ──
|
|
246
|
+
# A bare copy of run.sh under a fake node_modules root pins the mode seam
|
|
247
|
+
# cheaply: the copy is NOT a runnable installed package (no dist), so this cell
|
|
248
|
+
# asserts only that the installed-vs-source branch is decided and printed before
|
|
249
|
+
# any prerequisite check and the source-only pnpm bootstrap is never reached.
|
|
250
|
+
# The REAL packed installed-package `setup` consumer (all-absent SKIP, computed
|
|
251
|
+
# green, zero writes) lives in check-pack-install's installed all-absent setup
|
|
252
|
+
# row; the no-bootstrap KILL attribution lives in the oracle
|
|
253
|
+
# scripts/check-setup-qualification.sh (round 3).
|
|
254
|
+
echo "[smoke-setup-verdict] S-5 installed-mode named branch (pnpm-scrubbed)"
|
|
255
|
+
FAKE_PKG="$SB/node_modules/@junghanacs/entwurf"
|
|
256
|
+
mkdir -p "$FAKE_PKG" "$SB/proj5"
|
|
257
|
+
cp "$REPO_DIR/run.sh" "$FAKE_PKG/run.sh"; chmod +x "$FAKE_PKG/run.sh"
|
|
258
|
+
cp "$REPO_DIR/package.json" "$FAKE_PKG/package.json"
|
|
259
|
+
# The Missing-pnpm assertion was vacuous while the fixture inherited a PATH that
|
|
260
|
+
# still resolved pnpm (review round 2, 2026-08-26). Build a GENUINELY scrubbed
|
|
261
|
+
# PATH: shim the tools the pre-death setup path needs (resolved BEFORE the
|
|
262
|
+
# scrub, so a host that co-locates pnpm with node — e.g. corepack — still keeps
|
|
263
|
+
# node), then keep only the PATH directories that do NOT carry an executable
|
|
264
|
+
# pnpm, and PROVE the scrub before running the cell.
|
|
265
|
+
SCRUB_SHIMS="$SB/pnpm-scrub-shims"; mkdir -p "$SCRUB_SHIMS"
|
|
266
|
+
for _tool in bash node python3 head tr cut sed grep dirname readlink cat mkdir cp chmod rm env sha256sum; do
|
|
267
|
+
_src="$(command -v "$_tool" 2>/dev/null || true)"
|
|
268
|
+
[ -n "$_src" ] && ln -s "$_src" "$SCRUB_SHIMS/$_tool"
|
|
269
|
+
done
|
|
270
|
+
SCRUBBED_PATH="$SCRUB_SHIMS"
|
|
271
|
+
IFS=':' read -r -a _path_dirs <<<"$PATH"
|
|
272
|
+
for _d in "${_path_dirs[@]}"; do
|
|
273
|
+
[ -n "$_d" ] || continue
|
|
274
|
+
[ -x "$_d/pnpm" ] && continue
|
|
275
|
+
SCRUBBED_PATH="$SCRUBBED_PATH:$_d"
|
|
276
|
+
done
|
|
277
|
+
unset _path_dirs _d _tool _src
|
|
278
|
+
want "S-5: the scrub itself holds — pnpm does NOT resolve on the scrubbed PATH" \
|
|
279
|
+
"! PATH=\"$SCRUBBED_PATH\" command -v pnpm >/dev/null 2>&1"
|
|
280
|
+
want "S-5: the scrub preserved the tools the cell needs (bash/node/python3)" \
|
|
281
|
+
"PATH=\"$SCRUBBED_PATH\" command -v bash >/dev/null && PATH=\"$SCRUBBED_PATH\" command -v node >/dev/null && PATH=\"$SCRUBBED_PATH\" command -v python3 >/dev/null"
|
|
282
|
+
set +e; OUT="$(PATH="$SCRUBBED_PATH" bash "$FAKE_PKG/run.sh" setup "$SB/proj5" 2>&1)"; RC=$?; set -e
|
|
283
|
+
want "S-5: installed mode is the FIRST named line, before any prerequisite check" \
|
|
284
|
+
"printf '%s' \"\$OUT\" | head -n 1 | grep -q 'mode: installed package'"
|
|
285
|
+
want "S-5: installed mode never runs the source pnpm bootstrap" \
|
|
286
|
+
"! printf '%s' \"\$OUT\" | grep -qi 'pnpm install\|Lockfile is up to date\|Progress: resolved'"
|
|
287
|
+
want "S-5: installed setup never requires pnpm merely to decide/compose" \
|
|
288
|
+
"! printf '%s' \"\$OUT\" | grep -q 'Missing command: pnpm'"
|
|
289
|
+
|
|
290
|
+
echo ""
|
|
291
|
+
echo "smoke-setup-verdict: $PASS checks passed"
|