Repository navigation
fix(#499): preflight passed with 6 of 9 publish variables missing, and its disk floor was below the one it delegates to - #527
Merged
Conversation
…gates to Found by a /falsify pass on "we are ready for a 40-lesson forecasting run reaching faoapi", and it is my defect from #524. pod_run_fao_delivery.sh demanded 60GB for EIGHT models plus the pooled ensemble, while pod_run_model.sh — which it delegates to eight times — refuses below 40GB for ONE model ("one model needs ~20GB"). So the orchestrator's preflight could report ready and the delegated script could then refuse partway through the roster, after hours of paid GPU time. That is precisely the failure --preflight exists to prevent, introduced into --preflight. Raised to DISK_FLOOR_GB=80: 40GB transient, which the delegated script enforces per model regardless of what is written here, plus eight models' retained output and the pool. The retained component is an ESTIMATE and the comment now says so rather than implying a measurement. One model's calibration output is ~2.5GB per predictions directory on this machine, but NO FORECASTING RUN HAS EVER COMPLETED ON THIS ROSTER — rusty_bucket's forecasting_log.txt is from 2026-07-20 and lists temporary_crane and temporary_fox at Deployment Status: shadow, a different roster entirely — so the retained size of a forecast is unmeasured. A forecast has one origin against calibration's thirteen so it should be smaller, and "should be" is doing real work in that sentence. Trigger for revising the number: the first completed run, rather than reasoning about it a second time. Guarded by a test that compares this floor against the delegated script's, so the two cannot drift apart again — the defect was not the number, it was that nothing related them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GG2cY2HaqmUMpwUyR5V82K
…fig instead of counting Found by the /falsify pass on the forecasting claim, acting on a suggestion from the views-pipeline-core session. My preflight from #524 checked three environment variables and concluded the publish would work. Measured against the real code, PredictionStoreConfig requires NINE: APPWRITE_ENDPOINT, APPWRITE_DATASTORE_PROJECT_ID, APPWRITE_DATASTORE_API_KEY, APPWRITE_PROD_FORECASTS_BUCKET_ID, APPWRITE_PROD_FORECASTS_BUCKET_NAME, APPWRITE_PROD_FORECASTS_COLLECTION_ID, APPWRITE_PROD_FORECASTS_COLLECTION_NAME, APPWRITE_METADATA_DATABASE_ID, APPWRITE_METADATA_DATABASE_NAME Only the first three are secrets. A missing identifier fails the publish exactly as hard as a missing secret, so the check would have reported ready with six of nine absent — and the run would have failed at the publish, after the entire roster trained. The precise failure this mode exists to prevent, in the mode that exists to prevent it. Twice in one night now, which is its own signal. Adding the six missing names would not fix it. The extra can be absent, the endpoint unreachable, the key expired (#359: 2026-11-17). Preflight now CONSTRUCTS the config and imports the SDK, which answers the actual question instead of a proxy for it. views-pipeline-core suggested this and observed it is what #557 argues the manager should do itself; until it does, doing it by hand costs seconds. Second finding from the same measurement, and an operator trap: pipeline-core no longer auto-loads a .env from the working directory (#346, register C-177) — a library reading whatever .env its caller is standing in is what the Appwrite seam contract §3 forbids. So a correct /root/.secrets sitting beside the operator is NOT enough; the variables must be exported. Without that line the failure presents as wrong credentials rather than unexported ones. Preflight now prints `set -a; . /root/.secrets; set +a`. Both guarded, and the guards assert the construction and the exported-variables note exist rather than re-listing nine names — a guard that enumerates the same thing the code does is the defect that produced this commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GG2cY2HaqmUMpwUyR5V82K
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #524, from a
/falsifypass on "we are ready for a 40-lesson forecasting run reaching faoapi". Both defects are mine, both are in--preflight, and both are the exact failure that mode exists to prevent.1. Preflight checked 3 of 9 publish variables
PredictionStoreConfig.from_environment()requires nine, measured by running it:Only the first three are secrets. A missing identifier fails the publish exactly as hard as a missing secret, so preflight would have reported ready with six of nine absent — and the run would have died at the publish, after the entire roster trained.
Adding the six names would not fix it. The extra can be absent, the endpoint unreachable, the key expired (#359 — 2026-11-17). Preflight now constructs the config and imports the SDK, which answers the question instead of a proxy for it. Suggested by the
views-pipeline-coresession, which noted this is what their #557 argues the manager should do itself; until it does, doing it by hand costs seconds.Operator trap found by the same measurement: pipeline-core no longer auto-loads a
.envfrom the working directory (#346, register C-177) — a library reading whatever.envits caller is standing in is what the Appwrite seam contract §3 forbids. A correct/root/.secretsbeside the operator is not enough; the nine must be exported. Without that line the failure presents as wrong credentials rather than unexported ones. Preflight now printsset -a; . /root/.secrets; set +a.2. The disk floor was below the floor it delegates to
pod_run_fao_delivery.shdemanded 60 GB for eight models plus the pool, whilepod_run_model.sh— which it delegates to eight times — refuses below 40 GB for one ("one model needs ~20GB"). Preflight could report ready and the delegated script refuse partway through the roster, after hours.Raised to
DISK_FLOOR_GB=80. The retained component is an estimate and the comment says so: one model's calibration output is ~2.5 GB per predictions directory here, but no forecasting run has ever completed on this roster, so a forecast's retained size is unmeasured. A forecast has one origin against calibration's thirteen so it should be smaller — "should be" is doing real work there. Trigger to revise: the first completed run.A guard now compares the two floors directly, because the defect was not the number — it was that nothing related them.
Context the audit turned up
The eight-model roster has never completed a forecasting run.
ensembles/rusty_bucket/data/generated/forecasting_log.txtis dated 2026-07-20 and liststemporary_craneandtemporary_foxatDeployment Status: shadow— a different roster. Every hop after training executes for the first time.Separately, #499 B3's entity-coverage claim is wrong for these models and is corrected on that issue: ADR-064's check is never constructed on the PredictionFrame path (
model.py:1653-6,forecasting/stage.py:79). Deliberate per ADR-042, and already recorded in ADR-064's own "deliberately not covered" section — but B3 asserted the opposite.Verification
ruffclean. 8102 passed, 209 skipped, 5 xfailed. The publish-config check was exercised with credentials absent and with fakes present, confirming it fails for the right reason in each case.🤖 Generated with Claude Code
https://claude.ai/code/session_01GG2cY2HaqmUMpwUyR5V82K