Red-team pass is done: I found three INFORMATIONAL issues and no CRITICAL ones. Both earlier specialist findings are already fixed in the working tree. `outcome()` now sets refusal to null when the import succeeds, and both suggested tests are in `tests/qm-gstack-smoke.test.ts`. That file passes 14/14 under `env -i`.

**Coverage note:** the one test file (`tests/qm-gstack-smoke.test.ts`, +175, 14 tests) was reviewed in summary mode only. It covers request signing, the `upStack` dummy-key refusal, the smoke call sequence against a fake QM, refusal classification, pack sizing and the S1 staging helpers. All other changed files were read in full. Those are `qm-stack.ts`, `smoke.ts`, `s1-stage.ts`, `Dockerfile.skills`, both READMEs, the receipts, CHANGELOG, VERSION and package.json. I also checked `compose.yaml`, `prepare.sh`, `capture.sh` and `fake-anthropic.ts` at the integration boundaries. The only `sk-` token in the receipts is the `sk-ant-capture-dummy` prefix.

```
{"severity":"INFORMATIONAL","confidence":8,"path":"harnesses/qm/gstack/s1-stage.ts","line":102,"category":"red-team","summary":"If you rerun either script the way the README says, it overwrites the committed receipt with a different gstack commit, even when the run fails. --ref defaults to the checkout HEAD, but --out is a fixed repository path named only after the QM pin (smoke.ts:105, s1-stage.ts:102). Both scripts write the receipt unconditionally (smoke.ts:154, and s1-stage.ts:200 before the ok check). This machine's ~/.local/share/gstack is already at 12dc6782 (1.91.366.0), not the receipt's 21277291 (1.91.345.0). A default rerun today rewrites s1-staging-b6786d67.json against new gstack, adds s1-router-12dc6782.md next to it, and leaves the README's 4,727 / 29,581 / 17-of-63 / 12,186 figures pointing at a receipt that no longer shows them. To reproduce the published receipt, s1-stage's own refusal says to check out 21277291 in the live gstack install, which puts that machine below the crew's 1.91.364.0 floor.","fix":"Default --ref to the pinned 21277291 commit, and tell users in the README and in the refusal message to pass --gstack pointing at a separate `git worktree add <dir> 21277291` instead of checking out the live install. Put the gstack ref in the receipt file name, or refuse to overwrite an existing --out whose gstack.ref differs. On failure, write the receipt to <work>/ rather than to the committed path.","fingerprint":"harnesses/qm/gstack/s1-stage.ts:102:red-team","specialist":"red-team"}
{"severity":"INFORMATIONAL","confidence":7,"path":"harnesses/qm/gstack/s1-stage.ts","line":56,"category":"red-team","summary":"The router gstack-harness prints has a defect that the fixture hides: it lists `open-gstack-browser` twice. One line points at `connect-chrome/SKILL.md`, a symlink that only gstack's setup creates and that is not in git. stage() follows the symlink, so the fixture serves that path, but a QM deployment built from the gstack tree would return `[no such file` there. Under the README's counting rule, that is a 'fixture fault, rerun', so a real router defect would never be counted. The duplicate also inflates the published counts. The receipt's router_skills=62 and the CHANGELOG/README '62 router skills' are 61 distinct skills plus one alias (the manifest has connect-chrome and open-gstack-browser with the same sha256 2dd3227c..., 18,560 chars). The 63 staged files hold the same text twice. The 17 that fit inline is unaffected, because both copies are over the cap.","fix":"Report it to GSTA-36 as a gstack finding: `register generic --print` emits a setup-only alias path under another skill's name. In the fixture, mark the alias in the manifest (alias_of: open-gstack-browser) and state the counts as 61 distinct skills plus 1 alias, or drop the alias line from the staged router. Count a request that routes to connect-chrome as a router defect, not a fixture fault.","fingerprint":"harnesses/qm/gstack/s1-stage.ts:56:red-team","specialist":"red-team"}
{"severity":"INFORMATIONAL","confidence":4,"path":"harnesses/qm/gstack/qm-stack.ts","line":107,"category":"red-team","summary":"The health check cannot tell this run's core from another process on the same port. Core runs with network_mode: host (compose.yaml) and only pg publishes a port. If another process already holds 127.0.0.1:58080 and 55432 is free, `compose up -d` still exits 0, because depends_on waits only for pg. This run's core then fails to bind, and /healthz is answered by whatever holds the port. Every signed call goes to that foreign service and gets refused or garbled answers, and with the default --out (finding 1) that bad receipt replaces the committed one. The trial rig uses the same default port pair.","fix":"After the health check passes, call the signed GET /v1/admin/whoami and confirm a 200 before continuing. Or check that `docker compose ps core` is running and was not restarted.","fingerprint":"harnesses/qm/gstack/qm-stack.ts:107:red-team","specialist":"red-team"}
```