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 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 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 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`
|
||||
|
|
@ -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 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 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.
|
||||
- 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.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Working Leo Current State - 2026-07-09
|
||||
|
||||
Generated UTC: `2026-07-10T01:42:00Z`
|
||||
Generated UTC: `2026-07-10T01:46:00Z`
|
||||
|
||||
## 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`
|
||||
- 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
|
||||
- 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:
|
||||
- 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
|
||||
|
|
@ -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 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`
|
||||
- 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`
|
||||
- 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`
|
||||
|
|
|
|||
|
|
@ -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