Files
clawmates/migrations/0078_phase_judge_blocked.sql
T
Omar SobhandClaude Opus 5 d524107b37
deploy / test (push) Successful in 4m27s
deploy / build (push) Successful in 5m26s
fix(missions): harvest before the checkout, and stop an unreachable judge failing done work
Two bugs from the first real Continuous Research run, both found by running it.

**1. The harvest ran AFTER the checkout.** `on_launch` cloned the vault and then
harvested, so the mission's working copy predated the manifest push. The reader
agent found no `harvest.jsonl` and — being resourceful — queried arXiv itself
and wrote its own. That is exactly what `skills/research/arxiv-daily.md`
forbids: the papers it found are not checked off in `corpus_items`, so the next
run re-offers them, while the 13 the real harvest DID shelve went unread. The
harvest now runs first, so the clone contains the manifest.

The analysis it produced was otherwise very good — it named
`crates/clawhdf5-ann/src/hnsw.rs`, cited the ROADMAP's serial insert loop and
proposed a concrete pre-build probe — which is the behaviour the whole design
is for. It was reading the wrong papers.

**2. An unreachable judge consumed a pass.** `Verdict.error` exists to
distinguish "could not judge" from "judged incomplete" and nothing acted on it.
glm-5.3 returned "transport error: error decoding response body", the phase
counted it as a failed pass, and with two budgeted that single outage failed a
phase whose work was done and committed. The evaluator was right to refuse a
same-family fallback — that would trade independence for availability — so the
fix belongs here: an unreachable judge no longer spends an iteration.

Retrying forever would trade a wrong failure for an invisible hang, so the wait
is bounded by `judge_blocked_since` (migration 0078), mirroring how
`capacity_blocked_since` bounds a phase waiting on a VM slot. Thirty minutes is
many sweep ticks, so a blip recovers inside it; past that the phase FAILS with
the transport reason rather than requeueing, because re-running spends a
container re-doing work that was never the problem.

346 tests pass.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-17 18:14:29 -07:00

23 lines
1.3 KiB
SQL

-- How long a phase has been waiting on a judge it cannot reach.
--
-- `Verdict.error` distinguishes "could not judge" from "judged incomplete", and
-- until now nothing acted on it: an unreachable judge counted as a failed pass,
-- so an outage on the validator's side spent the phase's iteration budget.
-- Mission 01a011bf lost its script phase that way — the work was done and
-- committed, glm-5.3 returned "transport error: error decoding response body",
-- and with two passes budgeted that one unreachable judge failed the phase.
--
-- Not consuming the pass is right, but it cannot mean retrying forever: a
-- permanently unreachable judge would leave the phase `evaluating` in silence,
-- which trades a wrong failure for an invisible hang. This column is the clock
-- that bounds the wait, exactly as `capacity_blocked_since` bounds a phase
-- waiting for a VM slot.
--
-- Set on the first unreachable verdict, cleared the moment a real verdict
-- lands. NULL therefore means "not currently blocked", not "never was".
ALTER TABLE mission_phases
ADD COLUMN IF NOT EXISTS judge_blocked_since TIMESTAMPTZ;
COMMENT ON COLUMN mission_phases.judge_blocked_since IS
'When this phase first got an unreachable-judge verdict. Cleared when a real verdict lands; bounds how long an evaluating phase may wait before it is failed with the transport reason.';