GATE: assert exactly ONE system webhook after a dispatcher restart + reviewer engages without the 10-min fallback #67

Closed
opened 2026-07-02 02:20:49 +00:00 by plat · 2 comments
Owner

Two failure modes found while validating today's wb-gate germination (fresh plat.local daughter) both SELF-HEAL: the app still ships and serves 200, so a naive E2E passes while the platform is degraded. Exactly the class of regression the acceptance gate (#46) / CI-1 harness (#21) must assert explicitly, or agents 0.7.6 (#66) fixes them once and nothing keeps them fixed.

(1) exactly ONE system webhook survives a dispatcher restart (#63). Proven live: one kubectl rollout restart deploy/dispatcher → admin hooks id 1 AND id 3, same dispatcher URL, both active → every Forgejo event delivers twice (doubled runs/noise; the RBAC-5 HMAC re-seal can never patch either). Fix in flight: plat/agents#10 (persist the created hook id; GET-by-id on boot). Gate assertion: restart the dispatcher twice, then assert exactly one admin hook targets the dispatcher URL — probe GET /api/v1/admin/hooks/{id} by id, since the LIST endpoint demonstrably returns [] while hooks exist — AND one PR event produces exactly one dispatched run.

(2) reviewer engages without the ~10-min fallback (#57, root-caused today: the liveness probe resolved the preview via loopback from inside the dispatcher pod, so it never confirmed a preview that was already serving 200 with the correct /version sha). Fix in flight: plat/agents#11 (in-cluster DNS first). Gate assertion: on a PR build, the reviewer engages within 3 min of the preview serving 200 with /version == PR head sha, and dispatcher logs contain NO "preview liveness unconfirmed" fallback line.

Fix direction: add both as assertions in the CI-1 validate-coldstart set (#21) and the #46 unattended gate run; validate first on the #66 release-train germination. Feeds #46 — does not block the MVP path.

Two failure modes found while validating today's wb-gate germination (fresh plat.local daughter) both SELF-HEAL: the app still ships and serves 200, so a naive E2E passes while the platform is degraded. Exactly the class of regression the acceptance gate (#46) / CI-1 harness (#21) must assert explicitly, or agents 0.7.6 (#66) fixes them once and nothing keeps them fixed. **(1) exactly ONE system webhook survives a dispatcher restart** (#63). Proven live: one `kubectl rollout restart deploy/dispatcher` → admin hooks id 1 AND id 3, same dispatcher URL, both active → every Forgejo event delivers twice (doubled runs/noise; the RBAC-5 HMAC re-seal can never patch either). Fix in flight: plat/agents#10 (persist the created hook id; GET-by-id on boot). Gate assertion: restart the dispatcher twice, then assert exactly one admin hook targets the dispatcher URL — probe `GET /api/v1/admin/hooks/{id}` by id, since the LIST endpoint demonstrably returns `[]` while hooks exist — AND one PR event produces exactly one dispatched run. **(2) reviewer engages without the ~10-min fallback** (#57, root-caused today: the liveness probe resolved the preview via loopback from inside the dispatcher pod, so it never confirmed a preview that was already serving 200 with the correct /version sha). Fix in flight: plat/agents#11 (in-cluster DNS first). Gate assertion: on a PR build, the reviewer engages within 3 min of the preview serving 200 with `/version` == PR head sha, and dispatcher logs contain NO "preview liveness unconfirmed" fallback line. Fix direction: add both as assertions in the CI-1 `validate-coldstart` set (#21) and the #46 unattended gate run; validate first on the #66 release-train germination. Feeds #46 — does not block the MVP path.
Author
Owner

Second half shipped: nightly app-E2E in the cold-start gate (plat/mitosis#75)

Covered as of that PR (all in scripts/coldstart-assert.sh, the ONE gate both CI and humans run):

  • (1) webhook singleton: already covered — A2 (exactly one admin hook, probed BY ID) + A3 (restart deploy/agents, STILL exactly one; version-aware log check).
  • (2) reviewer engages without the ~10-min fallback: now asserted nightly by --e2e on the CI daughter, with a REAL canary app generated from _app-template and shipped unattended:
    • E4 prime PR auto-merges (builder → preview → reviewer verdict → merge)
    • E5 prod serves 200 in-cluster
    • E6 dispatcher log has zero preview liveness unconfirmed lines
    • E7 builder-finish → reviewer-queued < 120 s (the fallback path takes ~10 min, so it cannot pass this)
    • E8 the app's prod namespace carries plat.sh/app + generated ResourceQuota + NetworkPolicies

Runs on the nightly cron and on any workflow_dispatch with e2e=true, AFTER the standard gate, hard-capped at 35 min. Humans: scripts/coldstart-assert.sh --e2e <ctx> <domain>.

Default-safe: the phase is SKIP until you seal a credential. No secret exists today (the staged host token is flagged compromised-pending-rotation, so it was deliberately NOT wired in). e2e-flagged runs currently print one loud E2E SKIP line and exit 0 — the standard gate still gates.

To turn it on (one command, with a FRESH Claude Code OAuth token):

curl -X PUT -H "Authorization: token $PAT" -H 'Content-Type: application/json' \
  -d '{"data":"<fresh-claude-code-oauth-token>"}' \
  https://git.open-platform.sh/api/v1/repos/plat/mitosis/actions/secrets/E2E_CLAUDE_TOKEN

What happens once sealed: every nightly run (and every e2e=true dispatch) germinates the CI daughter WITH the credential sealed into plat-agents-secrets, then runs E1–E8 above. Rotation = same PUT with a new token; DELETE .../actions/secrets/E2E_CLAUDE_TOKEN returns to loud-SKIP.

The full --e2e path was validated manually on a scratch germination (evidence in the PR body) — marked manual-validation there since CI itself can't run it until the secret is sealed.

## Second half shipped: nightly app-E2E in the cold-start gate (https://git.open-platform.sh/plat/mitosis/pulls/75) **Covered as of that PR** (all in `scripts/coldstart-assert.sh`, the ONE gate both CI and humans run): - **(1) webhook singleton**: already covered — A2 (exactly one admin hook, probed BY ID) + A3 (restart `deploy/agents`, STILL exactly one; version-aware log check). - **(2) reviewer engages without the ~10-min fallback**: now asserted nightly by `--e2e` on the CI daughter, with a REAL canary app generated from `_app-template` and shipped unattended: - E4 prime PR **auto-merges** (builder → preview → reviewer verdict → merge) - E5 prod serves **200 in-cluster** - E6 dispatcher log has **zero** `preview liveness unconfirmed` lines - E7 **builder-finish → reviewer-queued < 120 s** (the fallback path takes ~10 min, so it cannot pass this) - E8 the app's prod namespace carries `plat.sh/app` + generated ResourceQuota + NetworkPolicies Runs on the nightly cron and on any `workflow_dispatch` with `e2e=true`, AFTER the standard gate, hard-capped at 35 min. Humans: `scripts/coldstart-assert.sh --e2e <ctx> <domain>`. **Default-safe: the phase is SKIP until you seal a credential.** No secret exists today (the staged host token is flagged compromised-pending-rotation, so it was deliberately NOT wired in). e2e-flagged runs currently print one loud `E2E SKIP` line and exit 0 — the standard gate still gates. **To turn it on** (one command, with a FRESH Claude Code OAuth token): ```sh curl -X PUT -H "Authorization: token $PAT" -H 'Content-Type: application/json' \ -d '{"data":"<fresh-claude-code-oauth-token>"}' \ https://git.open-platform.sh/api/v1/repos/plat/mitosis/actions/secrets/E2E_CLAUDE_TOKEN ``` What happens once sealed: every nightly run (and every `e2e=true` dispatch) germinates the CI daughter WITH the credential sealed into `plat-agents-secrets`, then runs E1–E8 above. Rotation = same PUT with a new token; `DELETE .../actions/secrets/E2E_CLAUDE_TOKEN` returns to loud-SKIP. The full `--e2e` path was validated manually on a scratch germination (evidence in the PR body) — marked manual-validation there since CI itself can't run it until the secret is sealed.
Author
Owner

Both gate assertions this issue asked for are now LIVE in CI (PR #75 merged, its own gate run 14 green): (1) exactly-one-webhook-after-dispatcher-restart = A3, running on every gate since #71; (2) reviewer-engages-without-the-10-min-fallback = E6/E7 in the --e2e mode, proven manually end-to-end (unattended canary shipped in 793s, builder→reviewer gap 34s, zero fallback lines). The nightly E2E activates the moment a FRESH Claude credential is sealed: curl -X PUT -H "Authorization: token <PAT>" -d '{"data":"<token>"}' https://git.open-platform.sh/api/v1/repos/plat/mitosis/actions/secrets/E2E_CLAUDE_TOKEN — until then it SKIPs loudly and exits 0 (the compromised staged token was deliberately NOT wired). Closing: the assertions exist, run, and are proven; activation is a one-command operator step.

Both gate assertions this issue asked for are now LIVE in CI (PR #75 merged, its own gate run 14 green): (1) exactly-one-webhook-after-dispatcher-restart = A3, running on every gate since #71; (2) reviewer-engages-without-the-10-min-fallback = E6/E7 in the --e2e mode, proven manually end-to-end (unattended canary shipped in 793s, builder→reviewer gap 34s, zero fallback lines). The nightly E2E activates the moment a FRESH Claude credential is sealed: `curl -X PUT -H "Authorization: token <PAT>" -d '{"data":"<token>"}' https://git.open-platform.sh/api/v1/repos/plat/mitosis/actions/secrets/E2E_CLAUDE_TOKEN` — until then it SKIPs loudly and exits 0 (the compromised staged token was deliberately NOT wired). Closing: the assertions exist, run, and are proven; activation is a one-command operator step.
plat closed this issue 2026-07-02 17:10:47 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
open-platform/mitosis#67
No description provided.