Daily — 2026-06-06 (5 autonomous experiments in flight; RunPod cap + smoke-coverage gaps dominate; 0 promoted)
What happened
- Heavy autonomous-
/issueday, mostly machine-driven. Five experiments running at day's end (#501, #503, #506, #507, #508), three parkedblockedawaiting a Thomas decision (#504, #505, #509). Three tasks reachedawaiting_promotionovernight/early (#489 @02:00Z, #498 @05:49Z, #502 @10:25Z) but none were promoted tocompleted— promotion queue grew, nothing cleared. - #506 (FWFT marker on a 27B model): planned + 4 code-review rounds against
Qwen/Qwen3.5-27B, which turned out to be a video-language multimodal model transformers can't load as a causal LM — crashed all 3 arms at first launch on an 8×H200. Thomas redirected toQwen3-32B("Why arent we using qwen 2.5 7b"); relaunched, then hit a silent gate-parse bug + missingflash_attn+ a MooseFS save crash. FWFT arm still training at session end. - #501 (multi-turn drift supplement): two vLLM CUDA OOMs at Phase-4 prompt-logprobs (20:37Z, 21:26Z), relaunched twice; Phase-1 JS sweep ran ~16h vs a ~4h plan estimate. Sweep healthy at ~71/288 cells by 06:24Z.
- RunPod $80/hr account cap was the dominant blocker: #507, #508, #509 each ran their entire plan+review pipeline and then stalled at pod provisioning because four pods (#501/#503/#504/#506) already saturated the cap. Zero GPU wasted, but full pipelines stranded at the last step.
- #503 escalated to Thomas after 4 launch attempts surfaced 5 cumulative upstream/training gaps (the sweep driver had no training phase at all); he picked "add the missing training step," implementer reached round 6-8, relaunched 01:47Z.
- PM session applied 5 of 6 of yesterday's
/dailyproposals (commit cluster this session): RunPod spend-guard (pod_lifecycle.py), planner config-load smoke (planner.md §11), autonomous-session text-menu ban (issue/SKILL.md), session-liveness cross-check (experiment-status.md+stuck-diagnoser.md), and the merge fix. Proposal #1 (data-gen-via-Haiku rule) was left as historical record by choice. ACLAUDE.md"reuse existing experiment code" Critical Rule was also added + pushed (d17329b06).
Proposed workflow improvements
Note: yesterday's proposals #2-#6 were already applied in today's PM session (spend-guard, planner config-load smoke, autonomous text-menu ban, session-liveness cross-check). The proposals below are the new / residual gaps surfaced by today's transcripts. Ordered by leverage.
-
Target:
.claude/agents/experiment-implementer.md+.claude/skills/issue/SKILL.md(Step 6d.0-bis smoke gate) — what: require a real pre-pod end-to-end dry-run, not a fixture/stand-in smoke. This is the single highest-leverage fix — the SAME class of bug burned pod launches in #501, #502, #503, AND #506 today because CPU smokes used canned data / stand-in models / readconfig.jsondirectly. Why: #503's driver had no training phase ("GAP 5: training step missing from driver entirely … each launch closes a gap, surfaces another", 4 launches); #502 crashed on Class-D rewrites the smoke never exercised; #501's Phase-4--smoke"writes hardcodeddelta_g=2.0… no vLLM, no LoRA" and a realcount(MARKER_ID)==1crash was invisible to it; #506 was planned + reviewed 4× against a model nobody everAutoConfig.from_pretrained'd. Proposed edit:+ ## Mandatory pre-pod end-to-end dry-run (before the FIRST pod launch) + A `--smoke` path must exercise the REAL code path, not fabricated constants. Before posting + epm:proposed-tests / passing code-review, assert the smoke: + (a) does a real AutoConfig.from_pretrained(model_id) + architecture-class check (causal-LM, not multimodal/video); + (b) verifies every artifact the run later CONSUMES (adapters, R_train/R_eval, panels, centroids) has a + producing phase in THIS driver, or cites where it was already produced (+ that it is on `main`); + (c) runs >=1 cell of EVERY condition class the production run will execute (e.g. Class-D), at production + max_model_len / gpu_memory_utilization so VRAM-spike (prompt_logprobs) bugs surface at smoke; + (d) checks every per-arm dependency is installed (e.g. FWFT needs flash_attn). + Fabricated-constant smoke stubs (hardcoded delta_g, "Smoke sample 1") are forbidden. -
Target:
.claude/skills/issue/SKILL.md(Step 9b / 10d merge) +CLAUDE.md— what: enforce that parent-experiment shared-infra code merges tomainat clean-result promotion, not just the body. Why: #502's dispatcher + round-4/5/7/8 bug fixes (issue502_dispatch.py,issue502_generate_probes.py) stranded on theissue-502branch blocked both its children today — #509 had to "surgical-checkout a stranded file at SHA 0ab4d16f", and #511 parked at the clarify gate because it would "re-trip the sameKeyError: 'extraction_point'#502 already fixed." #494 also left PR #414 dangling and its branch 318 commits behind. Proposed edit:+ At promotion/merge time, any NON-experiment-specific code the run added under scripts/ or src/ + (shared dispatchers, prep scripts, bug fixes to reused infra) MUST land on `main`. A follow-up/child + task may not be left to cherry-pick a fix stranded on a parent's experiment branch. If the full rebase + is deferred (Guard 3), the shared-infra files specifically are still cherry-picked to `main`. -
Target:
.claude/agents/experiment-implementer.md+.claude/agents/code-reviewer.md— what: when reusing a sibling's dispatcher, assert every recipe constant is actually threaded and every cached keyed artifact covers the chosen key set. Why: #504 and #505 both inherited the #472 dispatcher and hit the SAME root across ~13 / ~6 rounds: recipe constants silently shadowed by the sibling's defaults (#505:LORA_R=16set in constants buttrain_one_celldefaulted to rank 32 → vLLM crash; "three distinct dispatcher recipe-threading bugs share one shadow-constant root cause"), and cachedR_train.json/R_eval.jsonthat didn't cover the newly-picked personas (KeyError 'architect'shipped to launch because both reviewers reasonedpanel ⊆ bank ⇒ panel ⊆ R_eval.keys()). A workflow-fix-candidate for this was emitted in-session. Proposed edit:+ ## Reusing a sibling dispatcher + + Assert every recipe constant (lora_r, alpha, lr, epochs, persona set) is threaded into the inherited + train_one_cell / eval call — not silently shadowed by the sibling's default. + + When consuming a cached KEYED artifact (R_train, R_eval, centroids), verify the consumed key set is a + subset of the artifact's ACTUAL keys, not just of the persona bank. Auto-fill missing keys (train AND + eval) before launch.(code-reviewer gets the mirror lens: "cached-artifact-coverage — a diff consuming a keyed artifact must verify key-set coverage against the artifact, not a superset.")
-
Target:
.claude/agents/critic.md+.claude/agents/code-reviewer.md+.claude/agents/experiment-implementer.md— what: (a) a driver must produce every artifact it consumes; (b) the run driver must be a committed, reviewed repo script, never generated on the pod at launch; (c) gate parsers must raise on a missing key, never fall back to a sentinel that reads as a real outcome. Why: #503's driver consumed adapters it never trained. #506's wrapper "lives only on the pod (created at launch)" — which is structurally WHY its gate-parse bug escaped all 4 review rounds: it parsedcellsinstead ofcell_summaries, fell back to-1.0, reportedstage0_pass=0, and silently skipped Phase 2 for both LoRA arms even though the install actually passed (a fail-fast violation). Proposed edit:+ critic/code-reviewer lens: a sweep/eval driver that LOADS an artifact (adapter, panel, R, centroid) must + contain the phase that PRODUCES it, or cite the producing task + that the artifact is on `main`. + experiment-implementer: the production run driver is a committed repo script reviewed in the diff — do NOT + write/generate the driver on the pod at launch. Gate parsers raise on a missing expected JSON key; never + fall back to a sentinel value that is indistinguishable from a legitimate experimental outcome. -
Target:
.claude/rules/persona-distance-metrics.md— what: mandate a single canonical persona-distance cosine operationalization (globally mean-center the centroid bank, then L2-normalize, then cosine). This is also today's biggest research-integrity flag. Why: early canonical leakage tasks (#66/#77/#99/#228/#311/#380) globally mean-center + L2-normalize before cosine; mid/late tasks (#405/#406/#460/#472/#474/#477/#478/#490 and #504 r1-5) skip mean-centering, compressing the geometry ~6×. Same recipe → ~10-20× different absolute ΔG. Several MODERATE/LOW leakage-predictor calls (esp. open-q 3.4a) are now reanalysis candidates. Proposed edit:+ Canonical persona-distance cosine: globally mean-center the centroid bank, THEN L2-normalize, THEN cosine. + New predictor code MUST assert the mean-centering step ran. Tasks that used raw (un-centered) cosine + (#405/#406/#460/#472/#474/#477/#478/#490/#504-early) are NON-COMPARABLE to the mean-centered line and any + cross-task ranking claim drawn across the two regimes is a reanalysis candidate. -
Target:
.claude/skills/issue-tick/SKILL.md(+scripts/spawn_session.pyautonomous watcher) — what: (a) a/loop-driven or autonomous/issuemust stop re-invoking once the task is at a terminal/park state; (b) detect a "Not logged in" / auth-expired tick and halt +PushNotificationinstead of firing into a dead session. Why: the/loop 10m /issue 494session fired 160 no-op/issue 494invocations after the task parked atawaiting_promotion, and from ~22:32 PT onward 121 consecutive ticks returned'Not logged in · Please run /login'— ~20h of schedule burned silently with zero tool calls and no alert. Proposed edit:+ If task status is already awaiting_promotion/completed/archived, the tick emits "parked — nothing to do, + stopping loop" and tears down the cron / signals the loop driver to stop, instead of re-running cold. + If a tick's assistant turn is an auth/login error ("Not logged in", "Please run /login"), fire + PushNotification and HALT the loop — do not keep re-firing into a logged-out session. -
Target:
CLAUDE.md(Routing experiment intent table) +.claude/skills/issue/SKILL.md— what: define how akind: analysistask that needs new code + a pod run is routed. Why: #509 iskind: analysisbut its plan needed ~300 LOC + an 8×H100 run; the strictanalysis → analyzer (re-analysis only)routing didn't fit, so the orchestrator silently improvised into the experiment-implementer/pod path on its own judgment (undocumented). Proposed edit:+ An `analysis` task that requires NEW code or a pod run is dispatched through the experiment-implementer / + pod path (Step 4+), while keeping the §11 / measurement-validity exemptions of `analysis`. The clarifier + flags an analysis task whose plan implies a pod run so the routing is explicit, not improvised. -
Target:
.claude/skills/issue/SKILL.md(Step 6b) +scripts/spawn_session.py— what: (a) admission-control / sequence autonomous spawns against the RunPod cap so they don't each do hours of planning then stall at provision; (b) pick ONE canonical park state for "provision refused, capacity wait." Why: #507/#508/#509 each completed a full plan+review pipeline before discovering at Step 6 that the cap was saturated. And the park state diverged: #508 stayedrunningwithepm:pod-pending, #509 wentblockedfor the identical cause. (The spend-guard added today refuses early at the pod level but nothing sequences the spawns before they burn planning effort.) Proposed edit:+ Before spawning an autonomous /issue that will need a pod, check projected hourly burn vs + RUNPOD_ACCOUNT_HOURLY_CAP; if the new pod wouldn't fit, queue the spawn rather than letting it plan+review + then stall at Step 6. On a provision-refused-for-capacity outcome, use ONE canonical state (recommend: + status:blocked + epm:pod-pending v1) so the dashboard + re-invocation logic are consistent. -
Target:
.claude/rules/code-style.md(checkpoint-per-phase) +.claude/skills/issue/SKILL.md(compute-deviation watchdog) — what: every multi-phase launcher ships--resume+ skip-if-done guards at plan time; raise the watchdog at the first 2× over-budget projection. Why: #501's launcher had no--resume— after Phase-4 OOM'd, restarting risked re-burning the 16h Phase-1 sweep, so resume had to be patched mid-recovery; and the plan's ~4.1h estimate vs the ~16h+ actual (≈4× under) wasn't caught until hour 16, despite the autonomous cap auto-approving on the wrong estimate. Proposed edit:+ Multi-phase launchers ship --resume + skip-if-done (idempotent per cell/phase) at plan time, not as a + recovery patch. Smoke artifacts write to a namespaced dir so they never poison a production --resume. + Compute-deviation watchdog fires when projected wall time exceeds 2x the plan estimate (extrapolated from + the smoke's per-unit timing), not only at terminal over-run. -
Target:
.claude/skills/issue/SKILL.md(Steps 2b, 5c) +CLAUDE.md(cap-3 rule) — what: four small ensemble-review integrity guards. Why: #508 — Step 2b consistency-checker was skipped beforeepm:planand back-filled "as a safety net." #502 — round-3 was Claude PASS / Codex FAIL with no reconciler ("irregularity"), carried into round 4. #503 — round-3 verdict "was never posted (orchestrator went silent)", forcing a resumed session to reconstruct state. #502/#506 — round counter hit 4 on a "pragmatic call"; unclear whether a NEW post-launch bug resets the per-reviewer cap-3. Proposed edit:+ Step 2b: consistency-checker marker is a HARD precondition of posting epm:plan (assert it exists first). + Step 5c: a PASS-vs-FAIL ensemble round cannot advance without a reconciler verdict marker; always post a + verdict marker (even FAIL/INDETERMINATE) before any status transition. + cap-3: a NEW substantive bug surfacing post-launch RESETS the per-reviewer round counter (failure-driven), + distinct from the same blocker cycling — make the reset explicit so it isn't a per-case judgment call. -
Target:
.claude/agents/planner.md(§9 sizing, §11 cost) +scripts/pod.pyGPU-intent table — what: fix the GPU-h cost model and pod sizing. Why: #505's first estimate was off ~200× ("120 GPU-h" to triple epochs, corrected to ~0.6 because eval, not training, dominates wall-time). #507's plan claimed 4×H200 gives ~1.4× per-GPU throughput (actually ~1.05-1.08×) and mis-counted LoRA optimizer state. #509 specced an 8×H100 (inf-70b) pod for a no-training Qwen-2.5-7B forward-pass bake-off ("fits with massive headroom") — exactly what tipped the account over the cap. Proposed edit:+ Cost estimates separate training-compute from eval-compute; never scale total wall-time linearly with + optimizer steps. Pin per-GPU throughput-scaling + LoRA-vs-full optimizer-state memory to grounded sources. + Pod size = smallest spec that fits the model for the job; an inference/bake-off on a 7B model defaults to + 1x H100, NOT an inherited inf-70b 8-GPU spec. -
Target:
.claude/skills/issue/SKILL.md(worktree handling) +src/explore_persona_space/orchestrate/preflight.py— what: stop concurrent-sessiontask.pyevent commits from poisoning reviewer diffs / preflight / merges. Why: worktree branches ran hundreds of commits behindmainpurely from concurrent task-state commits (#502: 859 behind; #503: 274→16; #506: 121 behind → preflight bypassed). This produced reviewer-diff pollution (72 foreigntasks/paths), a Codex false-positive "event-ledger deletions" Critical, and stranded merges. Proposed edit:+ Rebase the worktree branch onto origin/main at run-launch (or warn) so the end-of-pipeline merge isn't + blocked by hundreds of concurrent task.py commits. + Preflight: classify "N commits behind origin/main" as PASS-with-warning when the delta is task-state-only + (no src/ configs/ scripts/ changes), instead of forcing a manual bypass decision. -
Target:
.claude/rules/marker-leakage-measurement.md(eval-guard constants) — what: make theassert_adapter_actually_appliedthreshold geometry-relative, not an absolute nat value. Why: #504 parkedblockedbecause the eps=0.50-nat eval-guard (inherited from #477's raw-cosine anchor) false-trips on a legitimately-trained adapter under mean-centered geometry, where the same recipe yields 10-20× smaller absolute ΔG. Proposed edit:+ The adapter-applied eval-guard eps scales to the run's OWN source-self ΔG (geometry-relative), not an + absolute nat threshold carried across centering regimes. -
Target:
scripts/poll_pipeline.py+scripts/pod.py— what: stop false "dead" verdicts and reap stale-EXITED pods at provision. Why: #502 — a clean 171s run was marked "dead" because the PID was gone (clean exit indistinguishable from crash); a transient SSH-resolution failure was also marked "dead". #506 — stall-check emitted a1000000000sentinel because its log glob didn't match the per-arm filename. #509 — two stale-EXITED pods (pod-505, pod-489) counted against capacity and were only "flagged," not reaped. Proposed edit:+ Poller checks for a completion sentinel / rc=0 before classifying PID-gone as dead; re-runs `pod.py config + --sync` + retries once before a "dead" verdict on an SSH-resolution failure; fix stall-check log glob. + Provision-time capacity check auto-terminates EXITED pods (or surfaces them as reclaimable $/hr). -
Target:
.claude/agents/experiment-implementer.md+.claude/skills/issue/SKILL.md(Step 5/6 ordering) — what: (a) advisory/equivalence gates must warn, not exit-nonzero underset -eand kill downstream phases; (b) clarify how the GPU-dependent smoke gate is satisfied when the pod is provisioned in Step 6 but the gate is checked in Step 5. Why: #494 — an in-script "byte-identical-within-1e-4" consistency gate hit expected float noise, returned rc=2 underset -e, and aborted Phases 2+3 before they launched (Phase 1 results were valid); and the Step-5 smoke gate demanded a GPU run before the Step-6 pod existed (nvidia-smi: command not found), forcing an out-of-band provision. Proposed edit:+ Advisory / recipe-equivalence checks WARN + record a caveat; they never exit-nonzero under `set -e` in a + chain that gates subsequent phases. (Note: the "byte-identical" framing is itself banned per the + clean-result spec — use a tolerance-band check.) + For GPU-dependent experiments, the Step-5 smoke gate may be satisfied by a pod provisioned at/before + code-review, OR `smoke-run-missing` defers the GPU smoke to the Step 6d.0 parity check.
Other problems & notes
- #506 FWFT
trainer.save_modelcrash —FileNotFoundErroronhub_upload.json+SafetensorError; classic MooseFS quota/race,output_dir/modelsubdir not pre-created under ZeRO-3. | action: experiment-code; workaround applied (pre-createmodel/subdir, relaunch FWFT-only). Worth a permanent pre-create in the FWFT save path. - #506
flash_attnmissing from plan v4 deps — only the FWFT arm needs it; the LoRA arms (default attention) ran fine, so it was the easy dep to miss. | action: covered by proposal 1(d); also addflash_attnto the FWFT config's declared deps. - #505 anchor under-trains (source ΔG 0.82 vs band [14,18] even at EPOCHS=3) — the #477-inherited anchor recipe (rank 16 / LR 5e-6 / 25 steps) doesn't transfer to this setup. | action: genuine research design fork (Thomas asked "can't we just train more steps") — needs an anchor recalibration; #505 is correctly
blockedon Thomas's recipe choice. - #504 Gate-A cosine bands empirically unreachable on Qwen-2.5-7B-Instruct (all 10 candidates landed in [0.78, 0.87] under raw centroid cosine; targets were −0.20/0.10/0.40/0.70). | action: planner should smoke-test target cosine bands against the actual model geometry before baking them into a Gate A. (Note: under proposal-5 mean-centering the bands may become reachable.)
- #502 analyzer first interpretation draft had 4 substantive factual errors (winner-cell-count overclaim, CV R² misquote, parent misname, stylized-count) — both interp critics REVISEd, caught pre-promotion. | action: none — the review loop worked; flag analyzer accuracy if it recurs.
- #502 Class-D rewrite prompt drifted from the canonical i460 v9 prompt (449/450 first-person vs prescribed third-person). | action: data-gen quality; already flagged as a MODERATE-confidence caveat in the body.
- #501
[BATCH_ERROR]sentinels in #377's reused drift corpus broke the deterministic k=14 history slice for the MT02 cell. | action: experiment-code fix shipped (_filter_batch_error_conversations, commit0f6e1fbb8); flag #377's drift corpus as carrying poisoned rows so future reuse pre-filters by default. - vLLM
max_lora_rank ≥ 8floor collided with #504's r=4 smoke cell. | action: one-linemax(8, rank)fix shipped; consider adding the floor to.claude/rules/gotchas.md. - Codex twin stalls / no-shows — #502 (force-cancelled at 693s > 600s cap → NO-SHOW, Claude-only fallback), #505 (round-7
app-server exited unexpectedly, retry recovered), #494 (stale scaffold for a different plan). | action: transient; the fallback/retry rules worked. Monitor frequency; if recurring, fix the scaffold hand-off or raise the stall cap. - Transient API errors — #504 API 500 + repeated 529 Overloaded (~03:25Z), #494 rate-limit "resets 8pm" (~2489 retry fragments). | action: none — self-resolved via retry.
- #494 dangling PR #414 + stale
issue-494branch (318 commits behind main; body/figures pushed directly tomainvia Guard-3 deferred-rebase). | action: clean up PR #414 / the stale branch when promoting #494 (the 3 ahead-commits are one-shot analysis scripts). - "Save to CLAUDE.md" drop — the "data-gen via Claude Code Haiku subagents, not the Anthropic API" rule Thomas asked to save yesterday never landed; no such rule exists today. | action: Thomas chose to leave it as historical record this session; if he still wants it, it needs a fresh add + a landing-check on
main. - Bare
pythonerrors (#501 SSH one-liner, #509-creation session) — recurs despite theuv run pythonmemory note. | action: see "My thoughts" — a PreToolUse Bash guard would end this class; hooks are out of scope for daily proposals.
My thoughts
Highlighted results
- no results promoted today