Verify Working Leo apply readiness gate
Some checks are pending
CI / lint-and-test (push) Waiting to run
Some checks are pending
CI / lint-and-test (push) Waiting to run
- Add retained-artifact verifier for integrated apply packet readiness - Record ready=true while preserving production_apply_executed=false - Cover success and authorization-boundary failure paths with focused tests Files: - docs/reports/leo-working-state-20260709/current-truth-index.md - docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.json - docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md - docs/reports/leo-working-state-20260709/working-leo-current-state-20260709.md - docs/reports/leo-working-state-20260709/working-leo-execution-plan-current.md - scripts/verify_working_leo_apply_readiness.py - tests/test_verify_working_leo_apply_readiness.py
This commit is contained in:
parent
2a15bdef06
commit
fd7ab67b44
7 changed files with 600 additions and 1 deletions
|
|
@ -64,6 +64,8 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
|||
- Working Leo integrated packet JSON: `docs/reports/leo-working-state-20260709/working-leo-integrated-packet.json`
|
||||
- Working Leo integrated clone rehearsal report: `docs/reports/leo-working-state-20260709/working-leo-integrated-packet-current.md`
|
||||
- Working Leo integrated clone rehearsal log: `docs/reports/leo-working-state-20260709/working-leo-integrated-clone-rehearsal-current.log`
|
||||
- Working Leo authorized-apply readiness verifier: `docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md`
|
||||
- Working Leo authorized-apply readiness verifier JSON: `docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.json`
|
||||
- Helmer live rollback log: `docs/reports/leo-working-state-20260709/helmer-7powers-live-preflight-rollback-current.log`
|
||||
- Helmer clone commit/delete rollback log: `docs/reports/leo-working-state-20260709/helmer-7powers-clone-commit-delete-rollback-current.log`
|
||||
- Helmer ledger clone commit/delete rollback log: `docs/reports/leo-working-state-20260709/helmer-7powers-ledger-clone-commit-delete-rollback-current.log`
|
||||
|
|
@ -102,6 +104,7 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
|||
- The Rio strategy-context companion write for mapped rich proposal `14fa5ecc` is clone-proven and reversible: after the mapped base packet exists, it creates `2` Rio strategy nodes and `5` strategy anchors in a disposable clone; production stayed unchanged.
|
||||
- The governance/concept-map schema companion write is clone-proven and reversible: after the mapped base packet exists, it creates minimal concept-map and claim-to-governance link tables, then inserts `1` concept map, `1` concept link, and `2` governance links in a disposable clone; production stayed unchanged.
|
||||
- The full integrated packet set is now clone-proven in production dependency order: mapped base, cross-surface anchor, Rio strategy context, governance/concept schema, and Helmer 7 Powers applied together in `teleo_integrated_rehearsal_20260710`, then rolled back in reverse order; production stayed unchanged and the disposable clone/temp files were removed.
|
||||
- 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`.
|
||||
- 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.
|
||||
- Pending/approved document proposals are real `kb_stage.kb_proposals` rows with `source_ref`s, but inspected `source_ref`s did not directly match `public.sources`; they still need review/apply mapping into canonical sources/evidence/edges.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,200 @@
|
|||
{
|
||||
"checks": {
|
||||
"all_packet_files_ok": true,
|
||||
"apply_order_matches_manifest": true,
|
||||
"clone_apply_markers_ordered": true,
|
||||
"clone_cleanup_db_dropped": true,
|
||||
"clone_report_says_production_not_modified": true,
|
||||
"clone_rollback_markers_ordered": true,
|
||||
"expected_counts_match": true,
|
||||
"manifest_status_not_executed": true,
|
||||
"rollback_order_matches_manifest": true,
|
||||
"service_stable_after_rehearsal": true
|
||||
},
|
||||
"claim_ceiling": "Ready means the retained packet set is complete, ordered, clone-proven, and cleanly rolled back. It does not authorize or prove production DB mutation.",
|
||||
"clone_log": {
|
||||
"exists": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/working-leo-integrated-clone-rehearsal-current.log",
|
||||
"sha256": "d1cb1fe6aa47e37e7da363f9674e168f861bed57539833684c794848fed12e8c"
|
||||
},
|
||||
"clone_report": {
|
||||
"exists": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/working-leo-integrated-packet-current.md",
|
||||
"sha256": "cd4a51da1be711424cd49dc77bdb646ffda21a1e8a914ffeba353e9f1062d033"
|
||||
},
|
||||
"file_checks": [
|
||||
{
|
||||
"bytes": 38892,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/production-apply-authorized-commit.sql",
|
||||
"sha256": "d7c9d06e77571b9751a94fdf49715c9997421f071dc840e65247ea1a0d5c8088",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 5803,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/production-delete-rollback.sql",
|
||||
"sha256": "297bd9e8b5246e6d9cb4883b15ad9e11e745b220508305f223985be38506bc36",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 7119,
|
||||
"exists": true,
|
||||
"json_valid": true,
|
||||
"kind": "json",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/production-apply-packet.json",
|
||||
"sha256": "c78107cf0ccf48487f2c80f01623376416e22d2e333262813135b0585fa9336d"
|
||||
},
|
||||
{
|
||||
"bytes": 1366,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/cross-surface-apply-authorized-commit.sql",
|
||||
"sha256": "381c6dcf178a419cb588d3e57bb63a1f794a03e9d5ff4a9ff3c2d9735a1bdf3f",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 823,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/cross-surface-delete-rollback.sql",
|
||||
"sha256": "41d10138e6d668426f8601ea5f528d70335ed4d30aae23830a55c0f068f046a8",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 2365,
|
||||
"exists": true,
|
||||
"json_valid": true,
|
||||
"kind": "json",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/cross-surface-packet.json",
|
||||
"sha256": "7fec3252a833f0e5f4eec8bd60bc2224332500175dfe8e55df5cfa29a747b9bd"
|
||||
},
|
||||
{
|
||||
"bytes": 6579,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/rio-strategy-apply-authorized-commit.sql",
|
||||
"sha256": "0a219df35db7ea3379c8b232449b5a6b8bd3a0164dd26ee393e55fa997b31463",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 1185,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/rio-strategy-delete-rollback.sql",
|
||||
"sha256": "f7c6896018ac785fe8214bb4dfbdbf936cb3f91d92dcf877aee80b682dae2d93",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 7031,
|
||||
"exists": true,
|
||||
"json_valid": true,
|
||||
"kind": "json",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/rio-strategy-packet.json",
|
||||
"sha256": "71bb6a81a631e36d28131b35af9a759f7dd6054729a50c37e92cd8b703f8fa1b"
|
||||
},
|
||||
{
|
||||
"bytes": 6822,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/governance-concept-apply-authorized-commit.sql",
|
||||
"sha256": "63b1ea56180ddd2308d4a4ca0e2d229ba3fe6cce494d5339339a6f62f1962bba",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 1160,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/governance-concept-delete-rollback.sql",
|
||||
"sha256": "786e107134a7c502130af9d92f19109184ac936399ac90d62b3b8c07f3e90f65",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 4044,
|
||||
"exists": true,
|
||||
"json_valid": true,
|
||||
"kind": "json",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/governance-concept-packet.json",
|
||||
"sha256": "081b2bb346349978f13797330966ca4d2d24b0817c66c29dff1064521a5b8924"
|
||||
},
|
||||
{
|
||||
"bytes": 42770,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/helmer-7powers-production-apply-authorized-commit.sql",
|
||||
"sha256": "9264baa4249432dcdc96510e67cc694bb5f2b2e485b63a3bfee959d31a89104d",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 5702,
|
||||
"ends_commit": true,
|
||||
"exists": true,
|
||||
"kind": "sql",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/helmer-7powers-production-delete-rollback.sql",
|
||||
"sha256": "77579ea3efbb3f3a06666f645a2bc662a501c8a3e92d9b389fca044dfef06a2d",
|
||||
"starts_transaction": true
|
||||
},
|
||||
{
|
||||
"bytes": 1322,
|
||||
"exists": true,
|
||||
"json_valid": true,
|
||||
"kind": "json",
|
||||
"non_empty": true,
|
||||
"ok": true,
|
||||
"path": "docs/reports/leo-working-state-20260709/helmer-7powers-production-apply-packet.json",
|
||||
"sha256": "0a7e419f98711ab11eb7b6e839008d7105e178ec40e864fb37f714bd4bf133e5"
|
||||
}
|
||||
],
|
||||
"generated_at_utc": "2026-07-09T22:57:32.369798+00:00",
|
||||
"missing_apply_markers": [],
|
||||
"missing_rollback_markers": [],
|
||||
"mode": "retained_artifact_readiness_verify",
|
||||
"not_done": [
|
||||
"Production apply still requires explicit operator authorization.",
|
||||
"Live Telegram regression must be rerun after any production apply.",
|
||||
"GCP parity remains separate from this VPS packet-readiness gate."
|
||||
],
|
||||
"production_apply_authorization_present": false,
|
||||
"production_apply_executed": false,
|
||||
"ready_for_authorized_production_apply_packet": true,
|
||||
"report_dir": "docs/reports/leo-working-state-20260709"
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
# Working Leo Apply Readiness
|
||||
|
||||
Generated UTC: `2026-07-09T22:57:32.369798+00:00`
|
||||
Mode: `retained_artifact_readiness_verify`
|
||||
Ready for separately authorized production apply packet: `True`
|
||||
Production apply executed: `False`
|
||||
Production apply authorization present: `False`
|
||||
|
||||
## Checks
|
||||
|
||||
- `manifest_status_not_executed`: `True`
|
||||
- `apply_order_matches_manifest`: `True`
|
||||
- `rollback_order_matches_manifest`: `True`
|
||||
- `expected_counts_match`: `True`
|
||||
- `all_packet_files_ok`: `True`
|
||||
- `clone_apply_markers_ordered`: `True`
|
||||
- `clone_rollback_markers_ordered`: `True`
|
||||
- `clone_cleanup_db_dropped`: `True`
|
||||
- `service_stable_after_rehearsal`: `True`
|
||||
- `clone_report_says_production_not_modified`: `True`
|
||||
|
||||
## Packet Files
|
||||
|
||||
- `production-apply-authorized-commit.sql`: `ok=True`, `bytes=38892`, `sha256=d7c9d06e77571b9751a94fdf49715c9997421f071dc840e65247ea1a0d5c8088`
|
||||
- `production-delete-rollback.sql`: `ok=True`, `bytes=5803`, `sha256=297bd9e8b5246e6d9cb4883b15ad9e11e745b220508305f223985be38506bc36`
|
||||
- `production-apply-packet.json`: `ok=True`, `bytes=7119`, `sha256=c78107cf0ccf48487f2c80f01623376416e22d2e333262813135b0585fa9336d`
|
||||
- `cross-surface-apply-authorized-commit.sql`: `ok=True`, `bytes=1366`, `sha256=381c6dcf178a419cb588d3e57bb63a1f794a03e9d5ff4a9ff3c2d9735a1bdf3f`
|
||||
- `cross-surface-delete-rollback.sql`: `ok=True`, `bytes=823`, `sha256=41d10138e6d668426f8601ea5f528d70335ed4d30aae23830a55c0f068f046a8`
|
||||
- `cross-surface-packet.json`: `ok=True`, `bytes=2365`, `sha256=7fec3252a833f0e5f4eec8bd60bc2224332500175dfe8e55df5cfa29a747b9bd`
|
||||
- `rio-strategy-apply-authorized-commit.sql`: `ok=True`, `bytes=6579`, `sha256=0a219df35db7ea3379c8b232449b5a6b8bd3a0164dd26ee393e55fa997b31463`
|
||||
- `rio-strategy-delete-rollback.sql`: `ok=True`, `bytes=1185`, `sha256=f7c6896018ac785fe8214bb4dfbdbf936cb3f91d92dcf877aee80b682dae2d93`
|
||||
- `rio-strategy-packet.json`: `ok=True`, `bytes=7031`, `sha256=71bb6a81a631e36d28131b35af9a759f7dd6054729a50c37e92cd8b703f8fa1b`
|
||||
- `governance-concept-apply-authorized-commit.sql`: `ok=True`, `bytes=6822`, `sha256=63b1ea56180ddd2308d4a4ca0e2d229ba3fe6cce494d5339339a6f62f1962bba`
|
||||
- `governance-concept-delete-rollback.sql`: `ok=True`, `bytes=1160`, `sha256=786e107134a7c502130af9d92f19109184ac936399ac90d62b3b8c07f3e90f65`
|
||||
- `governance-concept-packet.json`: `ok=True`, `bytes=4044`, `sha256=081b2bb346349978f13797330966ca4d2d24b0817c66c29dff1064521a5b8924`
|
||||
- `helmer-7powers-production-apply-authorized-commit.sql`: `ok=True`, `bytes=42770`, `sha256=9264baa4249432dcdc96510e67cc694bb5f2b2e485b63a3bfee959d31a89104d`
|
||||
- `helmer-7powers-production-delete-rollback.sql`: `ok=True`, `bytes=5702`, `sha256=77579ea3efbb3f3a06666f645a2bc662a501c8a3e92d9b389fca044dfef06a2d`
|
||||
- `helmer-7powers-production-apply-packet.json`: `ok=True`, `bytes=1322`, `sha256=0a7e419f98711ab11eb7b6e839008d7105e178ec40e864fb37f714bd4bf133e5`
|
||||
|
||||
## Evidence
|
||||
|
||||
- Clone log: `docs/reports/leo-working-state-20260709/working-leo-integrated-clone-rehearsal-current.log`
|
||||
- Clone report: `docs/reports/leo-working-state-20260709/working-leo-integrated-packet-current.md`
|
||||
|
||||
## Claim Ceiling
|
||||
|
||||
Ready means the retained packet set is complete, ordered, clone-proven, and cleanly rolled back. It does not authorize or prove production DB mutation.
|
||||
|
||||
## Not Done
|
||||
|
||||
- Production apply still requires explicit operator authorization.
|
||||
- Live Telegram regression must be rerun after any production apply.
|
||||
- GCP parity remains separate from this VPS packet-readiness gate.
|
||||
|
|
@ -110,6 +110,11 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
|||
- clone apply footprint matched the integrated manifest: `12` claims, `28` sources, `18` claim edges, `34` claim evidence rows, `1` reasoning tool, `2` Rio strategy nodes, `5` Rio strategy anchors, `1` concept map, `1` concept link, `2` governance links, one Helmer ledger row marked `applied`, and one cross-surface anchor update
|
||||
- reverse rollback restored generated base rows to `0/0/0/0`, Helmer rows to `0/0/0/0/0`, Helmer ledger to `approved`, cross-surface anchor to old claim `d0000000-0000-0000-0000-000000000005` at weight `0.7`, Rio rows to `0/0`, and generated governance/concept schema to absent
|
||||
- production readback after the clone proof stayed unchanged: generated base rows `0/0/0/0`, Helmer rows `0/0/0/0/0`, Helmer ledger `approved`, generated governance/concept schema absent, service active with `MainPID=3252143`, `NRestarts=0`
|
||||
- Authorized-apply readiness verifier now passes:
|
||||
- `ready_for_authorized_production_apply_packet=true`
|
||||
- `production_apply_executed=false`
|
||||
- `production_apply_authorization_present=false`
|
||||
- verifier checks packet file hashes, manifest apply/rollback order, expected counts, retained clone apply/rollback markers, clone cleanup, and service stability
|
||||
- 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
|
||||
|
|
@ -148,6 +153,7 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
|||
- Governance/concept-map clone proof log: `outputs/rich-proposal-creation-plan-20260709/governance-concept-20260710/governance-concept-clone-rehearsal-current.log`
|
||||
- Integrated packet manifest: `outputs/rich-proposal-creation-plan-20260709/integrated-20260710/working-leo-integrated-packet.json`
|
||||
- Integrated clone proof log: `outputs/rich-proposal-creation-plan-20260709/integrated-20260710/working-leo-integrated-clone-rehearsal-current.log`
|
||||
- Authorized-apply readiness verifier: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md`
|
||||
- VPS/Hermes/DB mapping: `outputs/vps-hermes-db-mapping-20260709.md`
|
||||
- Identity render / decision matrix / document artifact image: `outputs/leo-db-state-22-identity-render-matrix-artifacts.svg`
|
||||
- Execution plan: `outputs/working-leo-execution-plan-20260709/working-leo-execution-plan-current.md`
|
||||
|
|
|
|||
|
|
@ -86,12 +86,13 @@ Claim ceiling: VPS Telegram memory/KB audit, full live-safe open-ended Telegram
|
|||
|
||||
## WL-EXEC-06B - Integrated production-order packet rehearsal
|
||||
- Status: `done_integrated_clone_ready_not_executed`
|
||||
- Result: Applied the full prepared packet set in one disposable clone in dependency order: mapped base, cross-surface anchor, Rio strategy context, governance/concept schema, and Helmer 7 Powers. Expected integrated footprint was `12` claims, `28` sources, `18` claim edges, `34` claim evidence rows, `1` reasoning tool, `2` Rio strategy nodes, `5` Rio strategy anchors, `1` concept map, `1` concept link, `2` governance links, one Helmer ledger row marked applied, and one cross-surface anchor update. Reverse rollback restored all generated rows/schema to zero/absent, restored the cross-surface anchor to the old claim, restored the Helmer ledger to `approved`, dropped the disposable DB, removed temp files, and left production unchanged.
|
||||
- Result: Applied the full prepared packet set in one disposable clone in dependency order: mapped base, cross-surface anchor, Rio strategy context, governance/concept schema, and Helmer 7 Powers. Expected integrated footprint was `12` claims, `28` sources, `18` claim edges, `34` claim evidence rows, `1` reasoning tool, `2` Rio strategy nodes, `5` Rio strategy anchors, `1` concept map, `1` concept link, `2` governance links, one Helmer ledger row marked applied, and one cross-surface anchor update. Reverse rollback restored all generated rows/schema to zero/absent, restored the cross-surface anchor to the old claim, restored the Helmer ledger to `approved`, dropped the disposable DB, removed temp files, and left production unchanged. The apply-readiness verifier now passes over the retained manifest/files/logs with `ready_for_authorized_production_apply_packet=true`, `production_apply_executed=false`, and `production_apply_authorization_present=false`.
|
||||
- Next action: If production apply is explicitly authorized, use the integrated manifest order and immediately rerun live Telegram regression canaries after production postflight.
|
||||
- Not done condition: Production canonical rows/schema remain unapplied until explicit production apply authorization.
|
||||
- Evidence:
|
||||
- `/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/outputs/rich-proposal-creation-plan-20260709/integrated-20260710/working-leo-integrated-packet.md`
|
||||
- `/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/outputs/rich-proposal-creation-plan-20260709/integrated-20260710/working-leo-integrated-clone-rehearsal-current.log`
|
||||
- `/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-apply-readiness-current.md`
|
||||
|
||||
## WL-EXEC-07 - Leo-in-the-loop staging from Telegram
|
||||
- Status: `done_for_guarded_kb_stage_canary`
|
||||
|
|
|
|||
268
scripts/verify_working_leo_apply_readiness.py
Normal file
268
scripts/verify_working_leo_apply_readiness.py
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Verify the Working Leo integrated apply packet is ready but not executed.
|
||||
|
||||
This is a read-only retained-artifact verifier. It does not connect to
|
||||
production and does not execute SQL. The purpose is to make the final
|
||||
production-apply boundary explicit: all packet files, manifest ordering, clone
|
||||
proof markers, cleanup markers, and "not production-applied" claim ceilings must
|
||||
line up before an operator treats the packet set as ready for separately
|
||||
authorized execution.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import working_leo_integrated_packet as integrated_packet
|
||||
|
||||
REPO_REPORT_DIR = Path("docs/reports/leo-working-state-20260709")
|
||||
EXPECTED_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,
|
||||
}
|
||||
CLONE_LOG = "working-leo-integrated-clone-rehearsal-current.log"
|
||||
CLONE_REPORT = "working-leo-integrated-packet-current.md"
|
||||
|
||||
|
||||
def _sha256(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def _ordered_markers_present(text: str, markers: list[str]) -> tuple[bool, list[str]]:
|
||||
missing: list[str] = []
|
||||
cursor = 0
|
||||
for marker in markers:
|
||||
index = text.find(marker, cursor)
|
||||
if index < 0:
|
||||
missing.append(marker)
|
||||
else:
|
||||
cursor = index + len(marker)
|
||||
return not missing, missing
|
||||
|
||||
|
||||
def _read_manifest(report_dir: Path) -> dict[str, Any]:
|
||||
path = report_dir / "working-leo-integrated-packet.json"
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(path)
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def _file_check(path: Path, *, kind: str) -> dict[str, Any]:
|
||||
exists = path.exists()
|
||||
result: dict[str, Any] = {
|
||||
"path": str(path),
|
||||
"exists": exists,
|
||||
"kind": kind,
|
||||
"ok": False,
|
||||
}
|
||||
if not exists:
|
||||
result["error"] = "missing"
|
||||
return result
|
||||
|
||||
data = path.read_bytes()
|
||||
result.update(
|
||||
{
|
||||
"bytes": len(data),
|
||||
"sha256": hashlib.sha256(data).hexdigest(),
|
||||
"non_empty": len(data) > 0,
|
||||
}
|
||||
)
|
||||
if kind == "json":
|
||||
try:
|
||||
json.loads(data.decode("utf-8"))
|
||||
result["json_valid"] = True
|
||||
except json.JSONDecodeError as exc:
|
||||
result["json_valid"] = False
|
||||
result["error"] = str(exc)
|
||||
result["ok"] = bool(result["non_empty"] and result.get("json_valid"))
|
||||
return result
|
||||
|
||||
text = data.decode("utf-8")
|
||||
result.update(
|
||||
{
|
||||
"starts_transaction": bool(re.search(r"(^|\n)\s*(\\set\s+ON_ERROR_STOP\s+on\s*)?begin;", text, re.I)),
|
||||
"ends_commit": bool(re.search(r"commit;\s*$", text, re.I)),
|
||||
}
|
||||
)
|
||||
result["ok"] = bool(result["non_empty"] and result["starts_transaction"] and result["ends_commit"])
|
||||
return result
|
||||
|
||||
|
||||
def build_readiness(report_dir: Path = REPO_REPORT_DIR) -> dict[str, Any]:
|
||||
manifest = _read_manifest(report_dir)
|
||||
expected_apply_order = [packet["id"] for packet in integrated_packet.PACKETS]
|
||||
expected_rollback_order = list(reversed(expected_apply_order))
|
||||
clone_log_path = report_dir / CLONE_LOG
|
||||
clone_report_path = report_dir / CLONE_REPORT
|
||||
clone_log = clone_log_path.read_text(encoding="utf-8") if clone_log_path.exists() else ""
|
||||
clone_report = clone_report_path.read_text(encoding="utf-8") if clone_report_path.exists() else ""
|
||||
|
||||
file_checks: list[dict[str, Any]] = []
|
||||
for packet in manifest.get("packets", []):
|
||||
file_checks.append(_file_check(report_dir / packet["apply_sql"], kind="sql"))
|
||||
file_checks.append(_file_check(report_dir / packet["rollback_sql"], kind="sql"))
|
||||
file_checks.append(_file_check(report_dir / packet["packet_json"], kind="json"))
|
||||
|
||||
apply_markers = [
|
||||
f"=== clone apply {index} {packet_id} ==="
|
||||
for index, packet_id in enumerate(expected_apply_order, start=1)
|
||||
]
|
||||
rollback_markers = [
|
||||
f"=== clone rollback {index} {packet_id} ==="
|
||||
for index, packet_id in enumerate(expected_rollback_order, start=1)
|
||||
]
|
||||
apply_markers_ok, missing_apply_markers = _ordered_markers_present(clone_log, apply_markers)
|
||||
rollback_markers_ok, missing_rollback_markers = _ordered_markers_present(clone_log, rollback_markers)
|
||||
cleanup_db_dropped = bool(re.search(r"disposable_db_exists\s*-+\s*\n\s*0\s*\n", clone_log))
|
||||
service_stable = all(marker in clone_log for marker in ["MainPID=3252143", "NRestarts=0", "ActiveState=active"])
|
||||
report_says_not_modified = all(
|
||||
phrase in clone_report
|
||||
for phrase in [
|
||||
"Production was not modified.",
|
||||
"no production apply SQL was executed",
|
||||
"Production apply still requires explicit authorization",
|
||||
]
|
||||
)
|
||||
|
||||
checks = {
|
||||
"manifest_status_not_executed": manifest.get("production_apply_status") == "not_executed",
|
||||
"apply_order_matches_manifest": manifest.get("apply_order") == expected_apply_order,
|
||||
"rollback_order_matches_manifest": manifest.get("rollback_order") == expected_rollback_order,
|
||||
"expected_counts_match": manifest.get("expected_after_apply_counts") == EXPECTED_COUNTS,
|
||||
"all_packet_files_ok": all(item["ok"] for item in file_checks),
|
||||
"clone_apply_markers_ordered": apply_markers_ok,
|
||||
"clone_rollback_markers_ordered": rollback_markers_ok,
|
||||
"clone_cleanup_db_dropped": cleanup_db_dropped,
|
||||
"service_stable_after_rehearsal": service_stable,
|
||||
"clone_report_says_production_not_modified": report_says_not_modified,
|
||||
}
|
||||
ready = all(checks.values())
|
||||
return {
|
||||
"generated_at_utc": datetime.now(timezone.utc).isoformat(),
|
||||
"mode": "retained_artifact_readiness_verify",
|
||||
"report_dir": str(report_dir),
|
||||
"ready_for_authorized_production_apply_packet": ready,
|
||||
"production_apply_executed": False,
|
||||
"production_apply_authorization_present": False,
|
||||
"claim_ceiling": (
|
||||
"Ready means the retained packet set is complete, ordered, clone-proven, and cleanly rolled back. "
|
||||
"It does not authorize or prove production DB mutation."
|
||||
),
|
||||
"checks": checks,
|
||||
"missing_apply_markers": missing_apply_markers,
|
||||
"missing_rollback_markers": missing_rollback_markers,
|
||||
"file_checks": file_checks,
|
||||
"clone_log": {
|
||||
"path": str(clone_log_path),
|
||||
"exists": clone_log_path.exists(),
|
||||
"sha256": _sha256(clone_log_path) if clone_log_path.exists() else None,
|
||||
},
|
||||
"clone_report": {
|
||||
"path": str(clone_report_path),
|
||||
"exists": clone_report_path.exists(),
|
||||
"sha256": _sha256(clone_report_path) if clone_report_path.exists() else None,
|
||||
},
|
||||
"not_done": [
|
||||
"Production apply still requires explicit operator authorization.",
|
||||
"Live Telegram regression must be rerun after any production apply.",
|
||||
"GCP parity remains separate from this VPS packet-readiness gate.",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def write_markdown_report(path: Path, readiness: dict[str, Any]) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
lines = [
|
||||
"# Working Leo Apply Readiness",
|
||||
"",
|
||||
f"Generated UTC: `{readiness['generated_at_utc']}`",
|
||||
f"Mode: `{readiness['mode']}`",
|
||||
f"Ready for separately authorized production apply packet: `{readiness['ready_for_authorized_production_apply_packet']}`",
|
||||
f"Production apply executed: `{readiness['production_apply_executed']}`",
|
||||
f"Production apply authorization present: `{readiness['production_apply_authorization_present']}`",
|
||||
"",
|
||||
"## Checks",
|
||||
"",
|
||||
]
|
||||
lines.extend(f"- `{key}`: `{value}`" for key, value in readiness["checks"].items())
|
||||
lines.extend(["", "## Packet Files", ""])
|
||||
for item in readiness["file_checks"]:
|
||||
lines.append(
|
||||
f"- `{Path(item['path']).name}`: `ok={item['ok']}`, `bytes={item.get('bytes')}`, "
|
||||
f"`sha256={item.get('sha256')}`"
|
||||
)
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
"## Evidence",
|
||||
"",
|
||||
f"- Clone log: `{readiness['clone_log']['path']}`",
|
||||
f"- Clone report: `{readiness['clone_report']['path']}`",
|
||||
"",
|
||||
"## Claim Ceiling",
|
||||
"",
|
||||
readiness["claim_ceiling"],
|
||||
"",
|
||||
"## Not Done",
|
||||
"",
|
||||
]
|
||||
)
|
||||
lines.extend(f"- {item}" for item in readiness["not_done"])
|
||||
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--report-dir", type=Path, default=REPO_REPORT_DIR)
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
type=Path,
|
||||
default=REPO_REPORT_DIR / "working-leo-apply-readiness-current.json",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--markdown-out",
|
||||
type=Path,
|
||||
default=REPO_REPORT_DIR / "working-leo-apply-readiness-current.md",
|
||||
)
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
args = parse_args(argv)
|
||||
readiness = build_readiness(args.report_dir)
|
||||
args.out.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.out.write_text(json.dumps(readiness, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
||||
write_markdown_report(args.markdown_out, readiness)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"out": str(args.out),
|
||||
"markdown_out": str(args.markdown_out),
|
||||
"ready": readiness["ready_for_authorized_production_apply_packet"],
|
||||
"production_apply_executed": readiness["production_apply_executed"],
|
||||
},
|
||||
indent=2,
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0 if readiness["ready_for_authorized_production_apply_packet"] else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
68
tests/test_verify_working_leo_apply_readiness.py
Normal file
68
tests/test_verify_working_leo_apply_readiness.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
"""Tests for scripts/verify_working_leo_apply_readiness.py."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(REPO_ROOT / "scripts"))
|
||||
|
||||
import verify_working_leo_apply_readiness as readiness # noqa: E402
|
||||
|
||||
|
||||
def _copy_readiness_fixture(tmp_path: Path) -> Path:
|
||||
source_dir = REPO_ROOT / readiness.REPO_REPORT_DIR
|
||||
fixture_dir = tmp_path / "reports"
|
||||
fixture_dir.mkdir()
|
||||
manifest = json.loads((source_dir / "working-leo-integrated-packet.json").read_text())
|
||||
files = {
|
||||
"working-leo-integrated-packet.json",
|
||||
readiness.CLONE_LOG,
|
||||
readiness.CLONE_REPORT,
|
||||
}
|
||||
for packet in manifest["packets"]:
|
||||
files.add(packet["apply_sql"])
|
||||
files.add(packet["rollback_sql"])
|
||||
files.add(packet["packet_json"])
|
||||
for filename in files:
|
||||
shutil.copy2(source_dir / filename, fixture_dir / filename)
|
||||
return fixture_dir
|
||||
|
||||
|
||||
def test_readiness_passes_current_retained_artifacts():
|
||||
result = readiness.build_readiness()
|
||||
assert result["ready_for_authorized_production_apply_packet"] is True
|
||||
assert result["production_apply_executed"] is False
|
||||
assert result["production_apply_authorization_present"] is False
|
||||
assert all(result["checks"].values())
|
||||
assert result["missing_apply_markers"] == []
|
||||
assert result["missing_rollback_markers"] == []
|
||||
|
||||
|
||||
def test_readiness_fails_if_manifest_says_executed(tmp_path: Path):
|
||||
fixture_dir = _copy_readiness_fixture(tmp_path)
|
||||
manifest_path = fixture_dir / "working-leo-integrated-packet.json"
|
||||
manifest = json.loads(manifest_path.read_text())
|
||||
manifest["production_apply_status"] = "executed"
|
||||
manifest_path.write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
|
||||
|
||||
result = readiness.build_readiness(fixture_dir)
|
||||
|
||||
assert result["ready_for_authorized_production_apply_packet"] is False
|
||||
assert result["checks"]["manifest_status_not_executed"] is False
|
||||
assert result["checks"]["all_packet_files_ok"] is True
|
||||
|
||||
|
||||
def test_markdown_report_keeps_authorization_boundary(tmp_path: Path):
|
||||
result = readiness.build_readiness()
|
||||
out = tmp_path / "readiness.md"
|
||||
|
||||
readiness.write_markdown_report(out, result)
|
||||
|
||||
text = out.read_text()
|
||||
assert "Ready for separately authorized production apply packet: `True`" in text
|
||||
assert "Production apply executed: `False`" in text
|
||||
assert "It does not authorize or prove production DB mutation." in text
|
||||
Loading…
Reference in a new issue