Add Leo production receipt template
Some checks are pending
CI / lint-and-test (push) Waiting to run
Some checks are pending
CI / lint-and-test (push) Waiting to run
This commit is contained in:
parent
57bd705079
commit
17d0f1f71a
6 changed files with 463 additions and 1 deletions
|
|
@ -78,6 +78,8 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
||||||
- Working Leo authorized apply operator runbook JSON: `docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.json`
|
- Working Leo authorized apply operator runbook JSON: `docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.json`
|
||||||
- Working Leo live production preflight baseline, read-only: `docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md`
|
- Working Leo live production preflight baseline, read-only: `docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md`
|
||||||
- Working Leo live production preflight baseline JSON: `docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.json`
|
- Working Leo live production preflight baseline JSON: `docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.json`
|
||||||
|
- Working Leo production apply receipt template, not executed: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-template-current.md`
|
||||||
|
- Working Leo production apply receipt template JSON: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-template-current.json`
|
||||||
- Working Leo production apply receipt validation, currently missing receipt: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.md`
|
- Working Leo production apply receipt validation, currently missing receipt: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.md`
|
||||||
- Working Leo production apply receipt validation JSON: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.json`
|
- Working Leo production apply receipt validation JSON: `docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.json`
|
||||||
- Working Leo cleanup readback: `docs/reports/leo-working-state-20260709/working-leo-cleanup-readback-current.md`
|
- Working Leo cleanup readback: `docs/reports/leo-working-state-20260709/working-leo-cleanup-readback-current.md`
|
||||||
|
|
@ -127,6 +129,7 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
||||||
- The authorized-apply readiness verifier now passes: packet files exist and hash, apply/rollback order matches the manifest, expected counts match, clone apply/rollback markers are ordered, clone cleanup is proven, service stayed stable, and `production_apply_executed=false`.
|
- The authorized-apply readiness verifier now passes: packet files exist and hash, apply/rollback order matches the manifest, expected counts match, clone apply/rollback markers are ordered, clone cleanup is proven, service stayed stable, and `production_apply_executed=false`.
|
||||||
- The authorized apply operator runbook is generated and ready-not-executed: it gives preflight/apply/postflight/rollback command templates in manifest order, requires `TELEO_DATABASE_URL`, and now also includes a post-apply regression command bundle plus required production-apply receipt fields and an offline receipt validator. It still does not authorize or execute production SQL.
|
- The authorized apply operator runbook is generated and ready-not-executed: it gives preflight/apply/postflight/rollback command templates in manifest order, requires `TELEO_DATABASE_URL`, and now also includes a post-apply regression command bundle plus required production-apply receipt fields and an offline receipt validator. It still does not authorize or execute production SQL.
|
||||||
- The live production preflight baseline now passes through the read-only collector: `5/5` preflight files executed on the VPS with `begin transaction read only`, `mutates_production_db=false`, `applies_production_packet=false`, and `production_apply_executed=false`. Current production still has generated base rows `0/0/0/0`, Helmer rows `0/0/0/0/0`, no generated governance/concept tables, and dependent Rio/cross-surface/governance base rows absent before any apply, as expected.
|
- The live production preflight baseline now passes through the read-only collector: `5/5` preflight files executed on the VPS with `begin transaction read only`, `mutates_production_db=false`, `applies_production_packet=false`, and `production_apply_executed=false`. Current production still has generated base rows `0/0/0/0`, Helmer rows `0/0/0/0/0`, no generated governance/concept tables, and dependent Rio/cross-surface/governance base rows absent before any apply, as expected.
|
||||||
|
- The production apply receipt template is generated but intentionally invalid as a final receipt: `production_apply_executed=false`, `valid_production_receipt=false`, and it names the fields that must only be filled after authorized apply execution (`explicit_authorization_record`, `operator_identity`, `apply_output_paths`, `postflight_output_paths`, `actual_after_apply_counts`, `telegram_or_handler_regression_paths`, `service_readback`, `cleanup_readback`).
|
||||||
- The production-apply receipt validator currently reports `missing_receipt`, which is correct because no production apply has been authorized or executed.
|
- The production-apply receipt validator currently reports `missing_receipt`, which is correct because no production apply has been authorized or executed.
|
||||||
- DB-first identity rendering is now documented from the July 9 PDFs plus VPS readback: canonical identity rows feed rendered `SOUL.md`, direct SOUL edits are not canonical DB updates, and no active renderer/timer/hook is proven in the current VPS readback.
|
- DB-first identity rendering is now documented from the July 9 PDFs plus VPS readback: canonical identity rows feed rendered `SOUL.md`, direct SOUL edits are not canonical DB updates, and no active renderer/timer/hook is proven in the current VPS readback.
|
||||||
- The decision-matrix approval schema is still a target design on the current VPS: `kb_stage.matrix_voters`, `kb_stage.proposal_votes`, and `kb_stage.proposal_decisions` were not present in live schema readback.
|
- The decision-matrix approval schema is still a target design on the current VPS: `kb_stage.matrix_voters`, `kb_stage.proposal_votes`, and `kb_stage.proposal_decisions` were not present in live schema readback.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Working Leo Current State - 2026-07-09
|
# Working Leo Current State - 2026-07-09
|
||||||
|
|
||||||
Generated UTC: `2026-07-10T01:42:00Z`
|
Generated UTC: `2026-07-10T01:46:00Z`
|
||||||
|
|
||||||
## Current Working Definition
|
## Current Working Definition
|
||||||
|
|
||||||
|
|
@ -149,6 +149,12 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
||||||
- Helmer proposal `a64df080` remains `approved`, required existing claims are present, and generated rows remain `0/0/0/0/0`
|
- Helmer proposal `a64df080` remains `approved`, required existing claims are present, and generated rows remain `0/0/0/0/0`
|
||||||
- cross-surface/Rio/governance preflights show the expected before-apply baseline: dependent generated base rows are still absent and governance/concept tables are still absent
|
- cross-surface/Rio/governance preflights show the expected before-apply baseline: dependent generated base rows are still absent and governance/concept tables are still absent
|
||||||
- this is read-only production preflight evidence, not production apply authorization or proof of canonical mutation
|
- this is read-only production preflight evidence, not production apply authorization or proof of canonical mutation
|
||||||
|
- Production apply receipt template is now retained:
|
||||||
|
- `production_apply_executed=false`
|
||||||
|
- `valid_production_receipt=false`
|
||||||
|
- pre-filled/baseline fields are current git SHA, preflight output paths, expected counts, current direct-claim score path, rollback packet paths, and known residual risks
|
||||||
|
- after-apply fields still required are explicit authorization record, operator identity, apply outputs, postflight outputs, actual counts, post-apply regression paths, service readback, and cleanup readback
|
||||||
|
- this is a template, not a receipt and not a substitute for `working-leo-production-apply-receipt-current.json`
|
||||||
- VPS/Hermes/DB identity and document-linking map is now documented:
|
- VPS/Hermes/DB identity and document-linking map is now documented:
|
||||||
- the supplied July 9 master/build and database-reference PDFs confirm the intended architecture is DB-first identity: canonical Postgres identity graph rows render to `SOUL.md`, and evidence depth remains on demand through `teleo-kb`
|
- the supplied July 9 master/build and database-reference PDFs confirm the intended architecture is DB-first identity: canonical Postgres identity graph rows render to `SOUL.md`, and evidence depth remains on demand through `teleo-kb`
|
||||||
- direct `SOUL.md` edits are profile/runtime artifact edits, not canonical DB updates; they can drift or be overwritten unless represented in canonical rows first
|
- direct `SOUL.md` edits are profile/runtime artifact edits, not canonical DB updates; they can drift or be overwritten unless represented in canonical rows first
|
||||||
|
|
@ -195,6 +201,7 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
||||||
- Authorized-apply readiness verifier: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md`
|
- Authorized-apply readiness verifier: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md`
|
||||||
- Authorized apply operator runbook: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.md`
|
- Authorized apply operator runbook: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.md`
|
||||||
- Live production preflight baseline: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md`
|
- Live production preflight baseline: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md`
|
||||||
|
- Production apply receipt template: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-template-current.md`
|
||||||
- Production apply receipt validation: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.md`
|
- Production apply receipt validation: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-apply-receipt-validation-current.md`
|
||||||
- Cleanup readback: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-cleanup-readback-current.md`
|
- Cleanup readback: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-cleanup-readback-current.md`
|
||||||
- VPS/Hermes/DB mapping: `outputs/vps-hermes-db-mapping-20260709.md`
|
- VPS/Hermes/DB mapping: `outputs/vps-hermes-db-mapping-20260709.md`
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
{
|
||||||
|
"claim_ceiling": "This is a receipt template only. It proves the operator knows which evidence must be captured, but it does not authorize production apply and does not prove canonical rows were changed.",
|
||||||
|
"field_status": {
|
||||||
|
"actual_after_apply_counts": "must_fill_after_postflight_execution",
|
||||||
|
"apply_output_paths": "must_fill_after_apply_execution",
|
||||||
|
"cleanup_readback": "must_fill_after_post_apply_cleanup_readback",
|
||||||
|
"direct_claim_score_path": "baseline_available_but_must_rerun_after_apply",
|
||||||
|
"expected_after_apply_counts": "pre_filled_from_authorized_runbook",
|
||||||
|
"explicit_authorization_record": "must_fill_after_explicit_authorization",
|
||||||
|
"git_commit_sha": "pre_filled_current_head_verify_at_apply_time",
|
||||||
|
"known_residual_risks": "pre_filled_review_after_apply",
|
||||||
|
"operator_identity": "must_fill_after_explicit_authorization",
|
||||||
|
"postflight_output_paths": "must_fill_after_postflight_execution",
|
||||||
|
"preflight_output_paths": "baseline_available_rerun_immediately_before_apply",
|
||||||
|
"rollback_packet_paths": "pre_filled_from_authorized_runbook",
|
||||||
|
"service_readback": "must_fill_after_post_apply_service_readback",
|
||||||
|
"telegram_or_handler_regression_paths": "must_fill_after_post_apply_regression_rerun"
|
||||||
|
},
|
||||||
|
"generated_at_utc": "2026-07-10T01:46:12.932110+00:00",
|
||||||
|
"mode": "receipt_template_not_executed",
|
||||||
|
"must_fill_after_authorized_apply": [
|
||||||
|
"explicit_authorization_record",
|
||||||
|
"operator_identity",
|
||||||
|
"apply_output_paths",
|
||||||
|
"postflight_output_paths",
|
||||||
|
"actual_after_apply_counts",
|
||||||
|
"telegram_or_handler_regression_paths",
|
||||||
|
"service_readback",
|
||||||
|
"cleanup_readback"
|
||||||
|
],
|
||||||
|
"postflight_sql_paths_to_run_after_apply": [
|
||||||
|
"docs/reports/leo-working-state-20260709/production-postflight.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/cross-surface-postflight.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/rio-strategy-postflight.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/governance-concept-postflight.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/helmer-7powers-production-postflight.sql"
|
||||||
|
],
|
||||||
|
"preflight_artifacts": [
|
||||||
|
{
|
||||||
|
"bytes": 12496,
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bytes": 10047,
|
||||||
|
"exists": true,
|
||||||
|
"path": "docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"production_apply_executed": false,
|
||||||
|
"ready_or_baseline_fields": [
|
||||||
|
"git_commit_sha",
|
||||||
|
"preflight_output_paths",
|
||||||
|
"expected_after_apply_counts",
|
||||||
|
"direct_claim_score_path",
|
||||||
|
"rollback_packet_paths",
|
||||||
|
"known_residual_risks"
|
||||||
|
],
|
||||||
|
"receipt_template": {
|
||||||
|
"actual_after_apply_counts": {},
|
||||||
|
"apply_output_paths": [],
|
||||||
|
"cleanup_readback": {},
|
||||||
|
"direct_claim_score_path": "docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-score-current.md",
|
||||||
|
"expected_after_apply_counts": {
|
||||||
|
"claim_concept_map_links": 1,
|
||||||
|
"claim_edges": 18,
|
||||||
|
"claim_evidence": 34,
|
||||||
|
"claim_governance_gate_links": 2,
|
||||||
|
"claims": 12,
|
||||||
|
"concept_maps": 1,
|
||||||
|
"cross_surface_anchor_updates": 1,
|
||||||
|
"helmer_ledger_rows_marked_applied": 1,
|
||||||
|
"reasoning_tools": 1,
|
||||||
|
"rio_strategy_anchors": 5,
|
||||||
|
"rio_strategy_nodes": 2,
|
||||||
|
"sources": 28
|
||||||
|
},
|
||||||
|
"explicit_authorization_record": {
|
||||||
|
"authorized": false,
|
||||||
|
"fill_after_authorization": true,
|
||||||
|
"required_scope": "integrated Working Leo packet set in runbook dependency order"
|
||||||
|
},
|
||||||
|
"git_commit_sha": "57bd705079b2cb5f8cdc7a0a734083cf888177ff",
|
||||||
|
"known_residual_risks": [
|
||||||
|
"GCP parity remains separate until access is restored and read-only parity proof is captured.",
|
||||||
|
"Any Telegram-visible post-apply proof must be separately authorized at action time."
|
||||||
|
],
|
||||||
|
"operator_identity": "",
|
||||||
|
"postflight_output_paths": [],
|
||||||
|
"preflight_output_paths": [
|
||||||
|
"docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.json",
|
||||||
|
"docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md"
|
||||||
|
],
|
||||||
|
"rollback_packet_paths": [
|
||||||
|
"docs/reports/leo-working-state-20260709/helmer-7powers-production-delete-rollback.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/governance-concept-delete-rollback.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/rio-strategy-delete-rollback.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/cross-surface-delete-rollback.sql",
|
||||||
|
"docs/reports/leo-working-state-20260709/production-delete-rollback.sql"
|
||||||
|
],
|
||||||
|
"service_readback": {},
|
||||||
|
"telegram_or_handler_regression_paths": []
|
||||||
|
},
|
||||||
|
"receipt_validation_status_before_apply": "missing_receipt",
|
||||||
|
"runbook_path": "docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.json",
|
||||||
|
"valid_production_receipt": false
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
# Working Leo Production Apply Receipt Template
|
||||||
|
|
||||||
|
Generated UTC: `2026-07-10T01:46:12.932110+00:00`
|
||||||
|
Mode: `receipt_template_not_executed`
|
||||||
|
Production apply executed: `False`
|
||||||
|
Valid production receipt: `False`
|
||||||
|
Receipt validation status before apply: `missing_receipt`
|
||||||
|
|
||||||
|
## Field Status
|
||||||
|
|
||||||
|
- `explicit_authorization_record`: `must_fill_after_explicit_authorization`
|
||||||
|
- `operator_identity`: `must_fill_after_explicit_authorization`
|
||||||
|
- `git_commit_sha`: `pre_filled_current_head_verify_at_apply_time`
|
||||||
|
- `preflight_output_paths`: `baseline_available_rerun_immediately_before_apply`
|
||||||
|
- `apply_output_paths`: `must_fill_after_apply_execution`
|
||||||
|
- `postflight_output_paths`: `must_fill_after_postflight_execution`
|
||||||
|
- `expected_after_apply_counts`: `pre_filled_from_authorized_runbook`
|
||||||
|
- `actual_after_apply_counts`: `must_fill_after_postflight_execution`
|
||||||
|
- `telegram_or_handler_regression_paths`: `must_fill_after_post_apply_regression_rerun`
|
||||||
|
- `direct_claim_score_path`: `baseline_available_but_must_rerun_after_apply`
|
||||||
|
- `service_readback`: `must_fill_after_post_apply_service_readback`
|
||||||
|
- `cleanup_readback`: `must_fill_after_post_apply_cleanup_readback`
|
||||||
|
- `rollback_packet_paths`: `pre_filled_from_authorized_runbook`
|
||||||
|
- `known_residual_risks`: `pre_filled_review_after_apply`
|
||||||
|
|
||||||
|
## Ready Or Baseline Fields
|
||||||
|
|
||||||
|
- `git_commit_sha`
|
||||||
|
- `preflight_output_paths`
|
||||||
|
- `expected_after_apply_counts`
|
||||||
|
- `direct_claim_score_path`
|
||||||
|
- `rollback_packet_paths`
|
||||||
|
- `known_residual_risks`
|
||||||
|
|
||||||
|
## Must Fill After Authorized Apply
|
||||||
|
|
||||||
|
- `explicit_authorization_record`
|
||||||
|
- `operator_identity`
|
||||||
|
- `apply_output_paths`
|
||||||
|
- `postflight_output_paths`
|
||||||
|
- `actual_after_apply_counts`
|
||||||
|
- `telegram_or_handler_regression_paths`
|
||||||
|
- `service_readback`
|
||||||
|
- `cleanup_readback`
|
||||||
|
|
||||||
|
## Postflight SQL Paths
|
||||||
|
|
||||||
|
- `docs/reports/leo-working-state-20260709/production-postflight.sql`
|
||||||
|
- `docs/reports/leo-working-state-20260709/cross-surface-postflight.sql`
|
||||||
|
- `docs/reports/leo-working-state-20260709/rio-strategy-postflight.sql`
|
||||||
|
- `docs/reports/leo-working-state-20260709/governance-concept-postflight.sql`
|
||||||
|
- `docs/reports/leo-working-state-20260709/helmer-7powers-production-postflight.sql`
|
||||||
|
|
||||||
|
## Claim Ceiling
|
||||||
|
|
||||||
|
This is a receipt template only. It proves the operator knows which evidence must be captured, but it does not authorize production apply and does not prove canonical rows were changed.
|
||||||
223
scripts/build_working_leo_production_receipt_template.py
Normal file
223
scripts/build_working_leo_production_receipt_template.py
Normal file
|
|
@ -0,0 +1,223 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Build a non-executed Working Leo production-apply receipt template.
|
||||||
|
|
||||||
|
The real production apply receipt must be written only after explicit
|
||||||
|
authorization and actual apply/postflight/regression execution. This script
|
||||||
|
prepares the operator-facing template before that boundary: it identifies which
|
||||||
|
receipt fields are already backed by retained artifacts and which fields must be
|
||||||
|
filled after the authorized apply window.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
REPORT_DIR = Path("docs/reports/leo-working-state-20260709")
|
||||||
|
DEFAULT_RUNBOOK = REPORT_DIR / "working-leo-authorized-apply-runbook-current.json"
|
||||||
|
DEFAULT_PREFLIGHT_JSON = REPORT_DIR / "working-leo-production-preflight-current.json"
|
||||||
|
DEFAULT_PREFLIGHT_MD = REPORT_DIR / "working-leo-production-preflight-current.md"
|
||||||
|
DEFAULT_VALIDATION = REPORT_DIR / "working-leo-production-apply-receipt-validation-current.json"
|
||||||
|
DEFAULT_OUT = REPORT_DIR / "working-leo-production-apply-receipt-template-current.json"
|
||||||
|
DEFAULT_MARKDOWN_OUT = REPORT_DIR / "working-leo-production-apply-receipt-template-current.md"
|
||||||
|
|
||||||
|
|
||||||
|
def _load_json(path: Path) -> dict[str, Any]:
|
||||||
|
return json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
|
||||||
|
|
||||||
|
def _path_status(path: Path) -> dict[str, Any]:
|
||||||
|
exists = path.exists()
|
||||||
|
return {"path": str(path), "exists": exists, "bytes": path.stat().st_size if exists else 0}
|
||||||
|
|
||||||
|
|
||||||
|
def current_git_sha(repo_root: Path = Path(".")) -> str:
|
||||||
|
proc = subprocess.run(
|
||||||
|
["git", "rev-parse", "HEAD"],
|
||||||
|
cwd=repo_root,
|
||||||
|
text=True,
|
||||||
|
capture_output=True,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
return proc.stdout.strip() if proc.returncode == 0 else ""
|
||||||
|
|
||||||
|
|
||||||
|
def _regression_artifacts(runbook: dict[str, Any]) -> dict[str, str]:
|
||||||
|
result: dict[str, str] = {}
|
||||||
|
for command in runbook.get("post_apply_regression_commands", []):
|
||||||
|
artifact = str(command.get("expected_artifact") or "")
|
||||||
|
if artifact and artifact != "terminal pytest output":
|
||||||
|
result[str(command.get("id"))] = artifact
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _rollback_paths(runbook: dict[str, Any]) -> list[str]:
|
||||||
|
return [str(entry["path"]) for entry in runbook["phases"]["rollback_order"]]
|
||||||
|
|
||||||
|
|
||||||
|
def _postflight_paths(runbook: dict[str, Any]) -> list[str]:
|
||||||
|
return [str(entry["path"]) for entry in runbook["phases"]["postflight_order"]]
|
||||||
|
|
||||||
|
|
||||||
|
def build_template(
|
||||||
|
*,
|
||||||
|
runbook_path: Path = DEFAULT_RUNBOOK,
|
||||||
|
preflight_json_path: Path = DEFAULT_PREFLIGHT_JSON,
|
||||||
|
preflight_markdown_path: Path = DEFAULT_PREFLIGHT_MD,
|
||||||
|
validation_path: Path = DEFAULT_VALIDATION,
|
||||||
|
git_sha: str | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
runbook = _load_json(runbook_path)
|
||||||
|
preflight = _load_json(preflight_json_path) if preflight_json_path.exists() else {}
|
||||||
|
validation = _load_json(validation_path) if validation_path.exists() else {}
|
||||||
|
regressions = _regression_artifacts(runbook)
|
||||||
|
sha = git_sha if git_sha is not None else current_git_sha()
|
||||||
|
|
||||||
|
receipt_template = {
|
||||||
|
"explicit_authorization_record": {
|
||||||
|
"authorized": False,
|
||||||
|
"fill_after_authorization": True,
|
||||||
|
"required_scope": "integrated Working Leo packet set in runbook dependency order",
|
||||||
|
},
|
||||||
|
"operator_identity": "",
|
||||||
|
"git_commit_sha": sha,
|
||||||
|
"preflight_output_paths": [str(preflight_json_path), str(preflight_markdown_path)],
|
||||||
|
"apply_output_paths": [],
|
||||||
|
"postflight_output_paths": [],
|
||||||
|
"expected_after_apply_counts": runbook["expected_after_apply_counts"],
|
||||||
|
"actual_after_apply_counts": {},
|
||||||
|
"telegram_or_handler_regression_paths": [],
|
||||||
|
"direct_claim_score_path": regressions.get("direct_claim_strict_score", ""),
|
||||||
|
"service_readback": {},
|
||||||
|
"cleanup_readback": {},
|
||||||
|
"rollback_packet_paths": _rollback_paths(runbook),
|
||||||
|
"known_residual_risks": [
|
||||||
|
"GCP parity remains separate until access is restored and read-only parity proof is captured.",
|
||||||
|
"Any Telegram-visible post-apply proof must be separately authorized at action time.",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
field_status = {
|
||||||
|
"explicit_authorization_record": "must_fill_after_explicit_authorization",
|
||||||
|
"operator_identity": "must_fill_after_explicit_authorization",
|
||||||
|
"git_commit_sha": "pre_filled_current_head_verify_at_apply_time",
|
||||||
|
"preflight_output_paths": (
|
||||||
|
"baseline_available_rerun_immediately_before_apply"
|
||||||
|
if preflight.get("status") == "pass"
|
||||||
|
else "missing_or_failed_preflight_baseline"
|
||||||
|
),
|
||||||
|
"apply_output_paths": "must_fill_after_apply_execution",
|
||||||
|
"postflight_output_paths": "must_fill_after_postflight_execution",
|
||||||
|
"expected_after_apply_counts": "pre_filled_from_authorized_runbook",
|
||||||
|
"actual_after_apply_counts": "must_fill_after_postflight_execution",
|
||||||
|
"telegram_or_handler_regression_paths": "must_fill_after_post_apply_regression_rerun",
|
||||||
|
"direct_claim_score_path": "baseline_available_but_must_rerun_after_apply",
|
||||||
|
"service_readback": "must_fill_after_post_apply_service_readback",
|
||||||
|
"cleanup_readback": "must_fill_after_post_apply_cleanup_readback",
|
||||||
|
"rollback_packet_paths": "pre_filled_from_authorized_runbook",
|
||||||
|
"known_residual_risks": "pre_filled_review_after_apply",
|
||||||
|
}
|
||||||
|
|
||||||
|
ready_now = [
|
||||||
|
field
|
||||||
|
for field, status in field_status.items()
|
||||||
|
if status.startswith("pre_filled") or status.startswith("baseline_available")
|
||||||
|
]
|
||||||
|
must_fill = [field for field, status in field_status.items() if status.startswith("must_fill")]
|
||||||
|
|
||||||
|
return {
|
||||||
|
"generated_at_utc": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"mode": "receipt_template_not_executed",
|
||||||
|
"production_apply_executed": False,
|
||||||
|
"valid_production_receipt": False,
|
||||||
|
"runbook_path": str(runbook_path),
|
||||||
|
"preflight_artifacts": [_path_status(preflight_json_path), _path_status(preflight_markdown_path)],
|
||||||
|
"receipt_validation_status_before_apply": validation.get("status", "missing_validation_artifact"),
|
||||||
|
"receipt_template": receipt_template,
|
||||||
|
"field_status": field_status,
|
||||||
|
"ready_or_baseline_fields": ready_now,
|
||||||
|
"must_fill_after_authorized_apply": must_fill,
|
||||||
|
"postflight_sql_paths_to_run_after_apply": _postflight_paths(runbook),
|
||||||
|
"claim_ceiling": (
|
||||||
|
"This is a receipt template only. It proves the operator knows which evidence must be captured, but it "
|
||||||
|
"does not authorize production apply and does not prove canonical rows were changed."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def write_json(path: Path, data: dict[str, Any]) -> None:
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def write_markdown(path: Path, data: dict[str, Any]) -> None:
|
||||||
|
lines = [
|
||||||
|
"# Working Leo Production Apply Receipt Template",
|
||||||
|
"",
|
||||||
|
f"Generated UTC: `{data['generated_at_utc']}`",
|
||||||
|
f"Mode: `{data['mode']}`",
|
||||||
|
f"Production apply executed: `{data['production_apply_executed']}`",
|
||||||
|
f"Valid production receipt: `{data['valid_production_receipt']}`",
|
||||||
|
f"Receipt validation status before apply: `{data['receipt_validation_status_before_apply']}`",
|
||||||
|
"",
|
||||||
|
"## Field Status",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
for field, status in data["field_status"].items():
|
||||||
|
lines.append(f"- `{field}`: `{status}`")
|
||||||
|
lines.extend(["", "## Ready Or Baseline Fields", ""])
|
||||||
|
lines.extend(f"- `{field}`" for field in data["ready_or_baseline_fields"])
|
||||||
|
lines.extend(["", "## Must Fill After Authorized Apply", ""])
|
||||||
|
lines.extend(f"- `{field}`" for field in data["must_fill_after_authorized_apply"])
|
||||||
|
lines.extend(["", "## Postflight SQL Paths", ""])
|
||||||
|
lines.extend(f"- `{path}`" for path in data["postflight_sql_paths_to_run_after_apply"])
|
||||||
|
lines.extend(["", "## Claim Ceiling", "", data["claim_ceiling"], ""])
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text("\n".join(lines), encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument("--runbook", type=Path, default=DEFAULT_RUNBOOK)
|
||||||
|
parser.add_argument("--preflight-json", type=Path, default=DEFAULT_PREFLIGHT_JSON)
|
||||||
|
parser.add_argument("--preflight-markdown", type=Path, default=DEFAULT_PREFLIGHT_MD)
|
||||||
|
parser.add_argument("--validation", type=Path, default=DEFAULT_VALIDATION)
|
||||||
|
parser.add_argument("--out", type=Path, default=DEFAULT_OUT)
|
||||||
|
parser.add_argument("--markdown-out", type=Path, default=DEFAULT_MARKDOWN_OUT)
|
||||||
|
parser.add_argument("--git-sha", default=None)
|
||||||
|
return parser.parse_args(argv)
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: list[str] | None = None) -> int:
|
||||||
|
args = parse_args(argv)
|
||||||
|
data = build_template(
|
||||||
|
runbook_path=args.runbook,
|
||||||
|
preflight_json_path=args.preflight_json,
|
||||||
|
preflight_markdown_path=args.preflight_markdown,
|
||||||
|
validation_path=args.validation,
|
||||||
|
git_sha=args.git_sha,
|
||||||
|
)
|
||||||
|
write_json(args.out, data)
|
||||||
|
write_markdown(args.markdown_out, data)
|
||||||
|
print(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"out": str(args.out),
|
||||||
|
"markdown_out": str(args.markdown_out),
|
||||||
|
"production_apply_executed": data["production_apply_executed"],
|
||||||
|
"valid_production_receipt": data["valid_production_receipt"],
|
||||||
|
"must_fill_after_authorized_apply": data["must_fill_after_authorized_apply"],
|
||||||
|
},
|
||||||
|
indent=2,
|
||||||
|
sort_keys=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
66
tests/test_build_working_leo_production_receipt_template.py
Normal file
66
tests/test_build_working_leo_production_receipt_template.py
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
"""Tests for scripts/build_working_leo_production_receipt_template.py."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||||
|
|
||||||
|
import build_working_leo_authorized_apply_runbook as runbook_builder # noqa: E402
|
||||||
|
import build_working_leo_production_receipt_template as template # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
|
def test_template_contains_required_receipt_fields_without_claiming_execution():
|
||||||
|
runbook = runbook_builder.build_runbook()
|
||||||
|
result = template.build_template(git_sha="57bd705")
|
||||||
|
receipt = result["receipt_template"]
|
||||||
|
|
||||||
|
assert result["mode"] == "receipt_template_not_executed"
|
||||||
|
assert result["production_apply_executed"] is False
|
||||||
|
assert result["valid_production_receipt"] is False
|
||||||
|
assert set(runbook["production_apply_receipt_required_fields"]).issubset(receipt.keys())
|
||||||
|
assert receipt["explicit_authorization_record"]["authorized"] is False
|
||||||
|
assert receipt["git_commit_sha"] == "57bd705"
|
||||||
|
assert receipt["expected_after_apply_counts"] == runbook["expected_after_apply_counts"]
|
||||||
|
assert receipt["actual_after_apply_counts"] == {}
|
||||||
|
assert receipt["apply_output_paths"] == []
|
||||||
|
assert receipt["postflight_output_paths"] == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_template_marks_after_apply_fields_as_not_ready():
|
||||||
|
result = template.build_template(git_sha="57bd705")
|
||||||
|
|
||||||
|
assert "apply_output_paths" in result["must_fill_after_authorized_apply"]
|
||||||
|
assert "postflight_output_paths" in result["must_fill_after_authorized_apply"]
|
||||||
|
assert "actual_after_apply_counts" in result["must_fill_after_authorized_apply"]
|
||||||
|
assert "service_readback" in result["must_fill_after_authorized_apply"]
|
||||||
|
assert "cleanup_readback" in result["must_fill_after_authorized_apply"]
|
||||||
|
assert "expected_after_apply_counts" in result["ready_or_baseline_fields"]
|
||||||
|
assert "rollback_packet_paths" in result["ready_or_baseline_fields"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_template_uses_live_preflight_baseline_as_baseline_not_apply_proof():
|
||||||
|
result = template.build_template(git_sha="57bd705")
|
||||||
|
|
||||||
|
assert result["field_status"]["preflight_output_paths"] == "baseline_available_rerun_immediately_before_apply"
|
||||||
|
assert result["receipt_template"]["preflight_output_paths"] == [
|
||||||
|
"docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.json",
|
||||||
|
"docs/reports/leo-working-state-20260709/working-leo-production-preflight-current.md",
|
||||||
|
]
|
||||||
|
assert "does not authorize production apply" in result["claim_ceiling"]
|
||||||
|
assert "does not prove canonical rows were changed" in result["claim_ceiling"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_markdown_preserves_non_executed_boundary(tmp_path: Path):
|
||||||
|
result = template.build_template(git_sha="57bd705")
|
||||||
|
out = tmp_path / "template.md"
|
||||||
|
|
||||||
|
template.write_markdown(out, result)
|
||||||
|
|
||||||
|
text = out.read_text()
|
||||||
|
assert "Production apply executed: `False`" in text
|
||||||
|
assert "Valid production receipt: `False`" in text
|
||||||
|
assert "`apply_output_paths`: `must_fill_after_apply_execution`" in text
|
||||||
|
assert "Claim Ceiling" in text
|
||||||
Loading…
Reference in a new issue