Preview/CI reliability follow-ups from the #1793/#1795 sessions
Found 2026-07-09 while landing PR #1793 (script-result spill) and #1795 (preview pipeline self-heal). Each item is independently actionable; the first is the important one.
1. Report the Depot "zero workflows on PR open" race upstream#
PR #1795 opened and Depot's pull_request run (l9j0mj7mt2) finished in
3 seconds with NO jobs and a blank merge sha (depot ci run get showed
Sha empty, head_sha populated, ref refs/pull/1795/merge). The event
reached Depot before GitHub had computed the test-merge ref, so trigger
evaluation resolved no diff and matched zero workflows — including
lint-typecheck.yml and test.yml, which have NO path filter
(pull_request: {}). Result: a PR with no CI at all, reading
MERGEABLE/CLEAN off Cursor Bugbot alone.
This is likely the same root cause as merged PRs falsely showing "preview
skipped" (observed on #1789 the same day). Detection signature: only Bugbot
in gh pr checks minutes after open, plus a seconds-long finished Depot run
for the PR. Workaround: re-fire with an empty commit
(git commit-tree <branch>^{tree} -p <branch> + push).
Draft report for Depot support (support@depot.dev or the shared channel):
Repo iterate/iterate, org 0p91s0lz49. On 2026-07-09T13:21:55Z, run l9j0mj7mt2 (trigger pull_request, ref refs/pull/1795/merge, head_sha 7efc57fe5ffe...) finished in 3s with zero workflows despite the repo having workflows with unfiltered
pull_request: {}triggers registered from the default branch. The run record has an empty merge sha — presumably the pull_request webhook arrived before GitHub computed the test-merge ref, and trigger evaluation treated "no merge ref" as "no changed files / no workflows" instead of retrying or falling back to the head sha. A synchronize event (empty commit) minutes later ran everything normally. Expected: retry merge-ref resolution, fall back to head-sha diffing, or fail visibly — not an empty successful run.
Mitigation landed meanwhile: the "Required CI" repo ruleset (id 18718115,
added 2026-07-09) requires Lint and Typecheck / lint-typecheck and
Test / test on main, so an affected PR is now blocked-with-missing-checks
instead of silently mergeable. (Only always-run checks are required; the
preview check is path-filtered and would deadlock PRs that don't touch its
paths.)
2. Per-distinct-head compare bases in preview deploy selection#
resolvePreviewCompareBaseSha (scripts/preview/preview.ts) picks the FIRST
recorded app entry's headSha as the single diff base. Under diff-based
selection, recorded heads legitimately diverge across apps (an app not
selected for a push keeps its older head), making selection
order-dependent. Correct shape: compare per distinct recorded head and
union the results. Flagged in #1795's "Found, not fixed" — needs a design
pass, not a quick patch.
3. Auth readiness endpoint is not data-aware#
After erase-data on a slot, the auth worker still answers
/api/auth/ok 200 while its D1 is empty (no seeded OAuth clients), so
#1795's liveness probe cannot detect an erased auth directly — it is only
healed via the os dependency edge (an erase always parks os, and os drags
auth into the redeploy). Defense-in-depth: a readiness endpoint that
verifies seeded data exists (e.g. at least one OAuth client row), probed by
selectRecordedGreenAppsNotServing. Mind the deploy ordering: the deploy
smoke must keep using the shallow liveness check, since client seeding runs
after the worker deploys.
4. Spill fallback is one-shot (nicety)#
From #1793: when an oversized script result fails to spill into the agent workspace (e.g. repo not yet seeded), the fallback inline-truncated input is journaled under an idempotency key and never re-rendered — the full result remains only in the journal event. A repair lane (re-spill from the journal on demand, or a fallback message that names the journal offset) would close the gap. Rare in practice; the e2e guards the common cause by waiting for the repo seed.