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]>
23 lines
1.3 KiB
SQL
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.';
|