This runbook covers the production release path for CryptoLivePoolPipelines.
Primary production outputs:
data/output/latest_universe.jsondata/output/latest_ranking.csvdata/output/live_pool.jsondata/output/live_pool_legacy.jsondata/output/artifact_manifest.jsondata/output/release_manifest.jsondata/output/release_status_summary.jsondata/output/release_status_summary.mddata/output/monthly_review.jsondata/output/monthly_review.mddata/output/monthly_telegram.txtdata/output/monthly_report_bundle/monthly_report_bundle.jsondata/output/monthly_report_bundle/ai_review_input.mddata/output/monthly_report_bundle/job_summary.md
Primary publish targets:
- GCS current pointers under
crypto-live-pool-pipelines/current - GCS versioned release objects under
crypto-live-pool-pipelines/releases/<version> - Firestore
strategy/CRYPTO_LIVE_POOL_ROTATION_LIVE_POOL
The GCS prefix, Firestore document, and source_project value use the
crypto-live-pool-pipelines v1 artifact namespace.
This repository owns the monthly live-pool membership, ranking, and published symbol order. Downstream runtime repositories should consume the validated artifact contract and preserve that order when passing the pool into strategy code.
Production path:
scripts/download_history.pyscripts/build_live_pool.pyscripts/validate_release_contract.pyscripts/publish_release.pyscripts/write_release_heartbeat.py
Research-only / non-publish path:
scripts/run_research_backtest.pyscripts/run_walkforward_validation.pyscripts/compare_external_data.pyscripts/sweep_external_data_profiles.pyscripts/run_monthly_shadow_build.py
Rules:
- Do not treat shadow outputs, external-data experiments, or research summaries as publish-ready production artifacts.
- Only
core_majorbuild outputs that pass contract validation should be published to downstream systems. - If a manual run uses
--as-of-datefor historical investigation, treat it as replay unless you intentionally publish with--allow-stale.
This repository owns the monthly reporting and publish-status summary layer for the upstream release. These summaries are background evidence for artifact or content health, not a proxy for any AiGateway online service health, and they do not authorize automated trading or unconditional publish decisions.
Operator-facing summary entrypoints:
scripts/run_release_status_summary.pyfor the canonical release-status summary built from the current official artifactsscripts/run_monthly_review_briefing.pyfor the monthly review package; it requires same-cycle shadow outputs so review evidence always includes official and challenger coveragescripts/run_monthly_build_telegram.pyfor the optional short Telegram health notification or local preview textscripts/run_monthly_report_bundle.pyfor the standard monthly report bundle used by Actions artifacts and AI review handoffscripts/write_release_heartbeat.pyfor the lightweight logs-branch heartbeat record- Monthly live-pool ordering uses a deterministic tie-break:
final_score, thenconfidence, thenliquidity_stability, thenavg_quote_vol_180, thensymbol - Monthly review evidence includes the latest official/challenger track composition, overlap against the official pool, next-candidate boundary, and the deterministic tie-break order.
Boundary rules:
- Downstream execution systems should consume the validated release artifacts, not recreate the monthly report layer.
- Downstream systems should not rerank or rebuild the monthly live pool from local runtime indicators.
- Research reports and shadow-track diagnostics stay upstream and are not part of the minimum downstream execution contract.
- Telegram messages from this repository are operational release notifications, not trade execution alerts.
The Monthly Publish schedule remains 15 3 1 * * (03:15 UTC on the first of
each month; 11:15 in Singapore). After successful publication on main and creation
of the existing monthly-review issue, a hosted preflight checks the existing
OPENAI_API_KEY and ANTHROPIC_API_KEY secrets. It never creates or prints secrets.
If either is unavailable to the workflow, preflight logs the missing names and
posts review unavailable; the monthly-dual-api-review job is skipped. Repository
and organization secret visibility can differ, so runtime preflight is authoritative.
The isolated hosted review job downloads the monthly artifact from the same run.
It reads only monthly_report_bundle.json, ai_review_input.md, and
strategy_metrics.json, and issues one OpenAI Chat Completions request and one
Anthropic Messages request. Both are single-turn, with no tools, streaming,
continuations, fallback providers, SDK retries, or CLI agents. A failure in one
provider still permits the other provider's single request; the final comment marks
the failed review review unavailable and the job fails. Missing/oversized materials
or a failed budget check make zero API requests and post the same unavailable notice.
GitHub write failures are not retried because the write may already have succeeded.
| GitHub variable | Default | Accepted range |
|---|---|---|
MONTHLY_REVIEW_MAX_INPUT_TOKENS |
16000 per request |
1,024–128,000 |
MONTHLY_REVIEW_MAX_OUTPUT_TOKENS |
2500 per request |
128–8,192 |
MONTHLY_REVIEW_TIMEOUT_SECONDS |
60 per request |
1–120 seconds |
MONTHLY_REVIEW_MONTHLY_BUDGET_USD |
1.00 |
greater than 0, at most 100 USD |
Input accounting uses a conservative upper bound: the UTF-8 byte lengths of the
system instructions and both published materials, including their headings, plus
256 tokens for fixed message framing. This can reject a report whose actual token
count would be smaller; it never silently truncates evidence or makes a separate
token-count API call. Output limits are sent as OpenAI max_completion_tokens
(including reasoning) and Anthropic max_tokens. Reported usage is also checked;
missing usage, over-cap usage, or a truncated answer is unavailable. A wall-clock
deadline covers each HTTP request and response read. The review job has a twenty-minute
overall deadline. Retries are fixed at zero to preserve the exactly-two-request limit.
Models and standard-service rates are fixed in the review script:
gpt-5.4-mini-2026-03-17
at $0.75/$4.50 per million input/output tokens, and
claude-sonnet-4-6
at $3/$15. Defaults reserve $0.119625 for both calls before either starts,
including a 10% margin for regional processing charges (API token spend, excluding taxes).
Model/rate changes require a reviewed code change; update rates when provider pricing
changes. This budget covers this workflow's calls, not other activity on the API keys.
The durable ledger consists exclusively of reservation comments on existing review
issues. Runs are serialized by monthly-dual-api-review-budget. Before reserving,
the script reads every page of repository issue comments since the UTC month began,
counts current-month reservations authored by github-actions[bot], and rejects
unreadable/incomplete/malformed history, insufficient balance, or an existing
reservation for the same report month. Reservations are never refunded, even after
timeout, cancellation, or partial failure; a failed reservation write makes no API
requests. Do not delete or edit reservation comments, since they preserve the budget
and rerun record. A rerun of an already reserved report is skipped rather than charged
again. If a durable loop verdict already exists, reruns resume only that loop and
read the original Dot task; they never charge the API pair again.
The review job has contents: read, actions: read, issues: write, and
id-token: write, with checkout credentials disabled. OIDC is solely for the
current workload's already approved AIGateway project; it does not add an IAM or
service grant. Remote writes are review state/comments, labels, and issue closure.
The original publisher still owns publication and heartbeat operations. This audit
does not dispatch AIAuditBridge, fix code, create PRs, mutate releases, change live
configuration, or authorize promotion/trading. CryptoStrategies consumes the upstream
pool; these selector/shadow metrics do not prove downstream strategy or live results.
A successful publisher or an open review issue proves material preparation, not
completed API review. Check the separate review job and its comment for both
provider results. The retired CODEX_AUDIT_* settings do not enable remediation.
- Refresh or verify local data:
.venv/bin/python scripts/download_history.py --top-liquid 90 --force-exchange-info- Build the production pool:
.venv/bin/python scripts/build_live_pool.py --universe-mode core_major- Run explicit contract validation:
.venv/bin/python scripts/validate_release_contract.py --mode core_major --expected-pool-size 5 --require-manifest --require-artifact-manifest- Run publish preflight without external writes:
.venv/bin/python scripts/publish_release.py --dry-run --mode core_major- Generate the canonical release-status summary:
.venv/bin/python scripts/run_release_status_summary.pyBefore the review package is generated, confirm the monthly shadow build has produced both
data/output/monthly_shadow_build_summary.json and
data/output/shadow_candidate_tracks/track_summary.csv. The hosted monthly publish
workflow runs this shadow build automatically before the review step.
- Generate the monthly review package:
.venv/bin/python scripts/run_monthly_review_briefing.py- Render the Telegram preview text without sending:
.venv/bin/python scripts/run_monthly_build_telegram.py --print-only --output-path data/output/monthly_telegram.txt- Assemble the monthly report bundle:
.venv/bin/python scripts/run_monthly_report_bundle.py- Only after steps 1-8 pass, run the real publish path through the workflow or a controlled manual execution.
requirements-lock.txtis present and matches the intended release dependency set.- Local artifacts are non-empty and pass
scripts/validate_release_contract.py. live_pool.json,live_pool_legacy.json, andrelease_manifest.jsonagree onas_of_date,version,mode,pool_size, andsource_project;artifact_manifest.jsonagrees onas_of_date,version,mode,source_project, andsymbol_count.GCP_PROJECT_ID,GCS_BUCKET,FIRESTORE_COLLECTION, andFIRESTORE_DOCUMENTare set correctly for real publish.- Historical backfills use
--allow-staleexplicitly; do not silently publish stale artifacts.
Symptoms:
validate_release_contract.pyexits non-zeropublish_release.pyfails during preflight
Actions:
- Re-run
scripts/build_live_pool.py - Inspect
data/output/latest_universe.json,latest_ranking.csv,live_pool.json,live_pool_legacy.json, andartifact_manifest.json - Confirm
pool_size,symbols,symbol_map,version, andsource_projectare present and aligned
Symptoms:
- Contract validation reports outputs are older than the allowed age window
Actions:
- Prefer rebuilding from refreshed raw data
- If you are intentionally replaying an older month, use
--allow-staleand record that the run is historical - Do not treat stale output as a healthy production release
Symptoms:
- Preflight errors for
GCP_PROJECT_ID,GCS_BUCKET, Firestore collection, or Firestore document
Actions:
- Fix the missing workflow variable first
- Re-run
scripts/publish_release.py --dry-run --mode core_major - Only retry real publish after dry-run is clean
Symptoms:
pool_sizemismatch- live pool symbols not found in ranking
- live pool symbols are not a subset of latest universe
Actions:
- Stop the release
- Review the latest build inputs and
config/default.yaml - Rebuild and validate before any downstream sync
Use rollback only when the newest publish is clearly bad or malformed.
- Identify the last known good version from:
- Firestore document history
- GCS
crypto-live-pool-pipelines/releases/<version>/ - the last good
data/output/release_manifest.json
- Restore the five canonical artifacts from that version into
data/output/:
latest_universe.jsonlatest_ranking.csvlive_pool.jsonlive_pool_legacy.jsonartifact_manifest.json
- Validate the restored payload locally:
.venv/bin/python scripts/validate_release_contract.py --mode core_major --expected-pool-size 5 --require-artifact-manifest- Regenerate the manifest and verify publish preflight:
.venv/bin/python scripts/publish_release.py --dry-run --mode core_major --allow-stale- Re-publish the restored version to GCS / Firestore through the controlled release path.
Rollback note:
--allow-staleis expected during rollback because the restored version is historical.- Record the rollback version and reason in the operator log or release notes.
- Confirm
release_status_summary.jsonreportsstatus=okfor the published month. - Confirm
data/output/monthly_report_bundle/job_summary.mdmatches the released month and includes the expected bundle file list. - Confirm the Actions run uploaded a
monthly-report-<as_of_date>artifact for download. - Confirm Firestore
strategy/CRYPTO_LIVE_POOL_ROTATION_LIVE_POOLcontains the expectedversion,mode,symbols, andsource_project. - Confirm GCS current pointers and versioned objects exist for the same version.
- Confirm downstream consumers are reading the new version without falling back to degraded sources.
Each API must return strict JSON with verdict (approve or flag), severity
(none, data_integrity, risk_limit, missing_stale_inputs), and an evidence-based
English summary. Malformed, missing, partial, or truncated responses never pass.
Model-generated mentions are neutralized. Two approvals archive the verdict JSON,
apply auto-verified, and close the existing monthly-review issue. This closes the
review record; it does not approve a release or override deterministic gates.
Any flag submits at most one deeper Dot task with the frozen materials, via the
current workflow's existing AIGateway grant. Existing AI_SERVICE_URL,
AI_SERVICE_AUDIENCE, AI_SERVICE_PROFILE, and AI_SERVICE_MODEL variables select
that route. No cross-repository credential or grant is borrowed. Submission intent
is saved in bot-authored issue comments before POST; reruns only GET the original
task. An ambiguous POST without a task ID stays blocked. Dot's strict confirmation
is posted back; only confirmation of a real problem mentions the owner. Dismissal
archives the verdict and closes the review issue. API budget caps remain unchanged;
Dot uses only existing subscription task admission and limits, with no paid fallback.
Severe consensus requires both reviewers to flag the same severe category. Only an existing actuator bound to this cycle may pause rebalancing, holding positions and creating no orders. This pipeline has no such bound actuator: the loop reports the gap and notifies the owner, without building or changing trading logic. No finding or AI response can edit code, configuration, settings, orders or servers.
Monthly Review Dead-man runs independently after Monthly Publish and daily. It
counts failed, skipped, cancelled, timed-out and missing review jobs, and missing
natural monthly cycles after November 2026. REVIEW_DEADMAN_THRESHOLD defaults to
3 (range 1–24); success resets the streak. Alerts are bot-authored, deduplicated
GitHub issues mentioning REVIEW_OWNER_LOGIN (default Pigbibi). A monitor API
failure fails the monitor visibly rather than claiming health. Verdict artifacts
are retained for 90 days; durable issue records are retained without expiry.
Current operational gaps: both API secret names must already be available to this
repository; the deployed grant template does not establish monthly-publisher Dot
admission. Without a route/grant, flags remain escalation_unavailable and count
toward the dead-man threshold. This change creates neither secrets nor grants and
does not run production publication or a live model acceptance test.