Add Leo production apply authorization verifier
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
427a9f1a1e
commit
db0c5382c2
7 changed files with 325 additions and 3 deletions
|
|
@ -80,6 +80,8 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
|||
- Working Leo authorized apply session plan JSON: `docs/reports/leo-working-state-20260709/working-leo-authorized-apply-session-plan-current.json`
|
||||
- Working Leo production apply authorization packet, not executed: `docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-packet-current.md`
|
||||
- Working Leo production apply authorization packet JSON: `docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-packet-current.json`
|
||||
- Working Leo production apply authorization verification, currently refused/missing text: `docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-verification-current.md`
|
||||
- Working Leo production apply authorization verification JSON: `docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-verification-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`
|
||||
|
|
@ -134,6 +136,7 @@ Use this file before making status claims. Prefer fresh VPS/GCP readbacks when c
|
|||
- 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 session plan is generated and ready-not-executed: it maps concrete output log paths for pre-apply validation, preflight, apply, postflight, post-apply regression, service readback, cleanup readback, receipt validation, and rollback. Apply and rollback steps require explicit authorization; non-apply steps are marked non-mutating.
|
||||
- The production apply authorization packet is generated and ready-to-request, not authorized/executed: all evidence gates pass, it names the exact integrated packet order and the operator authorization template, requires a fresh deployed-SHA readback at apply time, and keeps `production_apply_executed=false` plus `production_apply_authorization_present=false`.
|
||||
- The production apply authorization verifier currently refuses the apply window: deployed SHA shape is valid and the auth packet is ready/not-executed/not-authorized, but `authorization_text_present=false`, `operator_identity_present=false`, `authorization_text_matches_expected=false`, `safe_to_enter_apply_window=false`, and `production_apply_executed=false`.
|
||||
- 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.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Working Leo Current State - 2026-07-09
|
||||
|
||||
Generated UTC: `2026-07-10T02:02:21Z`
|
||||
Generated UTC: `2026-07-10T02:08:33Z`
|
||||
|
||||
## Current Working Definition
|
||||
|
||||
|
|
@ -155,6 +155,13 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
|||
- `production_apply_authorization_present=false`
|
||||
- evidence gates pass for runbook readiness, gated session plan, read-only production preflight, direct-claim score, receipt template, and missing-receipt validator status
|
||||
- the operator authorization template is retained, but it must use a fresh deployed-SHA readback at apply time, and the packet itself does not authorize or execute SQL
|
||||
- Production apply authorization verification is now retained:
|
||||
- `mode=authorization_verification_only`
|
||||
- `status=missing_authorization_text`
|
||||
- `safe_to_enter_apply_window=false`
|
||||
- `production_apply_executed=false`
|
||||
- `production_apply_authorization_present=false`
|
||||
- the verifier constructs the exact expected authorization text for deployed SHA `427a9f1a1e114814c750bb3e9e99e3456a6c1539`, but refuses because authorization text and operator identity are absent
|
||||
- Live production preflight baseline is now retained:
|
||||
- the collector ran on the VPS with `--transport local-docker`, `execute_requested=true`, `mutates_production_db=false`, `applies_production_packet=false`, `production_apply_executed=false`, and `readonly_transaction_wrapper=true`
|
||||
- `5/5` preflight SQL files returned `ok=True`
|
||||
|
|
@ -215,6 +222,7 @@ A working Leo, for Cory/m3taversal's current expectation, is a Telegram-facing a
|
|||
- Authorized apply operator runbook: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-authorized-apply-runbook-current.md`
|
||||
- Authorized apply session plan: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-authorized-apply-session-plan-current.md`
|
||||
- Production apply authorization packet: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-packet-current.md`
|
||||
- Production apply authorization verification: `work/teleo-infra-main/docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-verification-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`
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Working Leo Execution Plan - 2026-07-09
|
||||
|
||||
Claim ceiling: VPS Telegram memory/KB audit, full live-safe open-ended Telegram suite, full mixed-evidence Cory-style outcome/direct-claim sandbox benchmark, live VPS GatewayRunner no-context direct-claim suite, Telegram-to-`kb_stage` proposal staging, and strict existing-ID apply are working. The live VPS handler suite for exact `DC-01` through `DC-06` prompts strict-scores `6/6` after the authorized-session-plan deploy and scorer refresh, with no Telegram post, no live profile write, no production DB apply, unchanged DB counts, temp profile cleanup, and unchanged gateway service state during the harness. The full prepared DB packet set is integrated-clone-proven in dependency order: mapped rich base, cross-surface anchor, Rio strategy context, governance/concept schema, and Helmer 7 Powers. A read-only live production preflight baseline now passes `5/5`, an authorized apply operator runbook is generated, an authorized apply session plan maps every apply-window output path with authorization gates, and a production apply authorization packet is ready-to-request, but none of those packets are production-applied or authorized. GCP parity remains pending.
|
||||
Claim ceiling: VPS Telegram memory/KB audit, full live-safe open-ended Telegram suite, full mixed-evidence Cory-style outcome/direct-claim sandbox benchmark, live VPS GatewayRunner no-context direct-claim suite, Telegram-to-`kb_stage` proposal staging, and strict existing-ID apply are working. The live VPS handler suite for exact `DC-01` through `DC-06` prompts strict-scores `6/6` after the authorized-session-plan deploy and scorer refresh, with no Telegram post, no live profile write, no production DB apply, unchanged DB counts, temp profile cleanup, and unchanged gateway service state during the harness. The full prepared DB packet set is integrated-clone-proven in dependency order: mapped rich base, cross-surface anchor, Rio strategy context, governance/concept schema, and Helmer 7 Powers. A read-only live production preflight baseline now passes `5/5`, an authorized apply operator runbook is generated, an authorized apply session plan maps every apply-window output path with authorization gates, a production apply authorization packet is ready-to-request, and the authorization verifier refuses the current apply window because no exact authorization text/operator identity is present. None of those packets are production-applied or authorized. GCP parity remains pending.
|
||||
|
||||
## WL-EXEC-01 - VPS Telegram-visible memory + KB audit
|
||||
- Status: `done`
|
||||
|
|
@ -96,7 +96,7 @@ 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. 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`. The authorized apply runbook now emits preflight/apply/postflight/rollback command templates in manifest order, a read-only pre-apply production baseline collector, a post-apply regression command bundle, a required production-apply receipt schema, and an offline receipt validator with `status=ready_not_executed`. The authorized apply session plan maps concrete output paths for pre-apply validation, preflight, apply, postflight, post-apply regression, service readback, cleanup readback, receipt validation, and rollback; apply and rollback steps require explicit authorization, non-apply steps are non-mutating, and `production_apply_executed=false`. The production apply authorization packet now passes all evidence gates and retains the operator authorization template plus fresh deployed-SHA requirement while keeping `production_apply_executed=false` and `production_apply_authorization_present=false`. The live production preflight baseline ran through `begin transaction read only` and passed `5/5` with no production apply 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. 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`. The authorized apply runbook now emits preflight/apply/postflight/rollback command templates in manifest order, a read-only pre-apply production baseline collector, a post-apply regression command bundle, a required production-apply receipt schema, and an offline receipt validator with `status=ready_not_executed`. The authorized apply session plan maps concrete output paths for pre-apply validation, preflight, apply, postflight, post-apply regression, service readback, cleanup readback, receipt validation, and rollback; apply and rollback steps require explicit authorization, non-apply steps are non-mutating, and `production_apply_executed=false`. The production apply authorization packet now passes all evidence gates and retains the operator authorization template plus fresh deployed-SHA requirement while keeping `production_apply_executed=false` and `production_apply_authorization_present=false`. The authorization verifier constructs the exact expected text for deployed SHA `427a9f1a1e114814c750bb3e9e99e3456a6c1539` but refuses the apply window with `safe_to_enter_apply_window=false` because authorization text and operator identity are absent. The live production preflight baseline ran through `begin transaction read only` and passed `5/5` with no production apply executed.
|
||||
- Next action: If production apply is explicitly authorized, use the generated runbook order, run every postflight SQL file, run the post-apply regression bundle, retain the production receipt, and then rerun any user-visible Telegram canary needed for the demo/meeting tier.
|
||||
- Not done condition: Production canonical rows/schema remain unapplied until explicit production apply authorization.
|
||||
- Evidence:
|
||||
|
|
@ -106,6 +106,7 @@ Claim ceiling: VPS Telegram memory/KB audit, full live-safe open-ended Telegram
|
|||
- `/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-authorized-apply-runbook-current.md`
|
||||
- `/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-authorized-apply-session-plan-current.md`
|
||||
- `/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-production-apply-authorization-packet-current.md`
|
||||
- `/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-production-apply-authorization-verification-current.md`
|
||||
- `/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-production-preflight-current.md`
|
||||
- `/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-production-apply-receipt-validation-current.md`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"auth_packet_path": "docs/reports/leo-working-state-20260709/working-leo-production-apply-authorization-packet-current.json",
|
||||
"checks": {
|
||||
"auth_packet_not_authorized": true,
|
||||
"auth_packet_not_executed": true,
|
||||
"auth_packet_ready": true,
|
||||
"authorization_text_matches_expected": false,
|
||||
"authorization_text_present": false,
|
||||
"deployed_sha_shape": true,
|
||||
"operator_identity_present": false,
|
||||
"telegram_visible_post_not_authorized": true
|
||||
},
|
||||
"claim_ceiling": "This verifier only checks whether an authorization string is valid for the current deployed SHA. It does not run SQL, does not mutate production, and does not prove canonical rows were changed.",
|
||||
"deployed_sha": "427a9f1a1e114814c750bb3e9e99e3456a6c1539",
|
||||
"expected_authorization_text": "I authorize production DB apply for the integrated Working Leo packet set on VPS using deployed commit 427a9f1a1e114814c750bb3e9e99e3456a6c1539 in this order: mapped-rich-base, cross-surface-anchor, rio-strategy-context, governance-concept-schema, helmer-7powers. Run preflight immediately before each phase, run the authorized apply SQL, run every postflight, run the non-posting direct-claim regression and scorer, capture service and cleanup readbacks, validate the production receipt, and do not post Telegram-visible messages unless separately authorized.",
|
||||
"generated_at_utc": "2026-07-10T02:08:21.123976+00:00",
|
||||
"mode": "authorization_verification_only",
|
||||
"next_action_if_verified": [
|
||||
"Re-run production preflight immediately before each packet phase.",
|
||||
"Run apply and postflight SQL in the retained manifest order.",
|
||||
"Capture apply/postflight/regression/service/cleanup logs in the session-plan paths.",
|
||||
"Write and validate the production receipt before claiming canonical rows changed."
|
||||
],
|
||||
"operator_identity": "",
|
||||
"production_apply_authorization_present": false,
|
||||
"production_apply_executed": false,
|
||||
"provided_authorization_text_hashable_length": 0,
|
||||
"safe_to_enter_apply_window": false,
|
||||
"status": "missing_authorization_text"
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# Working Leo Production Apply Authorization Verification
|
||||
|
||||
Generated UTC: `2026-07-10T02:08:21.123976+00:00`
|
||||
Mode: `authorization_verification_only`
|
||||
Status: `missing_authorization_text`
|
||||
Safe to enter apply window: `False`
|
||||
Production apply executed: `False`
|
||||
Production apply authorization present: `False`
|
||||
Deployed SHA: `427a9f1a1e114814c750bb3e9e99e3456a6c1539`
|
||||
Operator identity: ``
|
||||
|
||||
## Checks
|
||||
|
||||
- `auth_packet_not_authorized`: `True`
|
||||
- `auth_packet_not_executed`: `True`
|
||||
- `auth_packet_ready`: `True`
|
||||
- `authorization_text_matches_expected`: `False`
|
||||
- `authorization_text_present`: `False`
|
||||
- `deployed_sha_shape`: `True`
|
||||
- `operator_identity_present`: `False`
|
||||
- `telegram_visible_post_not_authorized`: `True`
|
||||
|
||||
## Expected Authorization Text
|
||||
|
||||
I authorize production DB apply for the integrated Working Leo packet set on VPS using deployed commit 427a9f1a1e114814c750bb3e9e99e3456a6c1539 in this order: mapped-rich-base, cross-surface-anchor, rio-strategy-context, governance-concept-schema, helmer-7powers. Run preflight immediately before each phase, run the authorized apply SQL, run every postflight, run the non-posting direct-claim regression and scorer, capture service and cleanup readbacks, validate the production receipt, and do not post Telegram-visible messages unless separately authorized.
|
||||
|
||||
## Next Action If Verified
|
||||
|
||||
- Re-run production preflight immediately before each packet phase.
|
||||
- Run apply and postflight SQL in the retained manifest order.
|
||||
- Capture apply/postflight/regression/service/cleanup logs in the session-plan paths.
|
||||
- Write and validate the production receipt before claiming canonical rows changed.
|
||||
|
||||
## Claim Ceiling
|
||||
|
||||
This verifier only checks whether an authorization string is valid for the current deployed SHA. It does not run SQL, does not mutate production, and does not prove canonical rows were changed.
|
||||
170
scripts/verify_working_leo_production_apply_authorization.py
Normal file
170
scripts/verify_working_leo_production_apply_authorization.py
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Verify Working Leo production-apply authorization text.
|
||||
|
||||
This verifier checks that an operator authorization sentence exactly matches
|
||||
the retained authorization template after substituting the fresh deployed SHA.
|
||||
It is intentionally non-mutating: it never opens a database connection, never
|
||||
runs SQL, and never marks production apply as executed.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
REPORT_DIR = Path("docs/reports/leo-working-state-20260709")
|
||||
DEFAULT_AUTH_PACKET = REPORT_DIR / "working-leo-production-apply-authorization-packet-current.json"
|
||||
DEFAULT_OUT = REPORT_DIR / "working-leo-production-apply-authorization-verification-current.json"
|
||||
DEFAULT_MARKDOWN_OUT = REPORT_DIR / "working-leo-production-apply-authorization-verification-current.md"
|
||||
|
||||
SHA_RE = re.compile(r"[0-9a-f]{7,40}")
|
||||
|
||||
|
||||
def _load_json(path: Path) -> dict[str, Any]:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def expected_authorization_text(auth_packet: dict[str, Any], deployed_sha: str) -> str:
|
||||
template = str(auth_packet["explicit_operator_authorization_text_template"])
|
||||
return template.replace("<DEPLOYED_SHA_READBACK>", deployed_sha)
|
||||
|
||||
|
||||
def _normalize_text(value: str) -> str:
|
||||
return " ".join(value.strip().split())
|
||||
|
||||
|
||||
def verify_authorization(
|
||||
*,
|
||||
deployed_sha: str,
|
||||
authorization_text: str = "",
|
||||
operator_identity: str = "",
|
||||
auth_packet_path: Path = DEFAULT_AUTH_PACKET,
|
||||
) -> dict[str, Any]:
|
||||
auth_packet = _load_json(auth_packet_path)
|
||||
expected_text = expected_authorization_text(auth_packet, deployed_sha) if deployed_sha else ""
|
||||
checks = {
|
||||
"auth_packet_ready": auth_packet.get("ready_to_request_authorization") is True,
|
||||
"auth_packet_not_authorized": auth_packet.get("production_apply_authorization_present") is False,
|
||||
"auth_packet_not_executed": auth_packet.get("production_apply_executed") is False,
|
||||
"deployed_sha_shape": bool(SHA_RE.fullmatch(deployed_sha)),
|
||||
"operator_identity_present": bool(operator_identity.strip()),
|
||||
"authorization_text_present": bool(authorization_text.strip()),
|
||||
"authorization_text_matches_expected": bool(expected_text)
|
||||
and _normalize_text(authorization_text) == _normalize_text(expected_text),
|
||||
"telegram_visible_post_not_authorized": auth_packet.get("authorization_scope", {}).get(
|
||||
"telegram_visible_post_authorized"
|
||||
)
|
||||
is False,
|
||||
}
|
||||
safe_to_enter_apply_window = all(checks.values())
|
||||
if safe_to_enter_apply_window:
|
||||
status = "authorization_verified_not_executed"
|
||||
elif not checks["authorization_text_present"]:
|
||||
status = "missing_authorization_text"
|
||||
elif not checks["authorization_text_matches_expected"]:
|
||||
status = "authorization_text_mismatch"
|
||||
else:
|
||||
status = "authorization_not_ready"
|
||||
return {
|
||||
"generated_at_utc": datetime.now(timezone.utc).isoformat(),
|
||||
"mode": "authorization_verification_only",
|
||||
"status": status,
|
||||
"safe_to_enter_apply_window": safe_to_enter_apply_window,
|
||||
"production_apply_executed": False,
|
||||
"production_apply_authorization_present": safe_to_enter_apply_window,
|
||||
"auth_packet_path": str(auth_packet_path),
|
||||
"deployed_sha": deployed_sha,
|
||||
"operator_identity": operator_identity,
|
||||
"checks": checks,
|
||||
"expected_authorization_text": expected_text,
|
||||
"provided_authorization_text_hashable_length": len(_normalize_text(authorization_text)),
|
||||
"next_action_if_verified": [
|
||||
"Re-run production preflight immediately before each packet phase.",
|
||||
"Run apply and postflight SQL in the retained manifest order.",
|
||||
"Capture apply/postflight/regression/service/cleanup logs in the session-plan paths.",
|
||||
"Write and validate the production receipt before claiming canonical rows changed.",
|
||||
],
|
||||
"claim_ceiling": (
|
||||
"This verifier only checks whether an authorization string is valid for the current deployed SHA. It does "
|
||||
"not run SQL, does not mutate production, 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 Authorization Verification",
|
||||
"",
|
||||
f"Generated UTC: `{data['generated_at_utc']}`",
|
||||
f"Mode: `{data['mode']}`",
|
||||
f"Status: `{data['status']}`",
|
||||
f"Safe to enter apply window: `{data['safe_to_enter_apply_window']}`",
|
||||
f"Production apply executed: `{data['production_apply_executed']}`",
|
||||
f"Production apply authorization present: `{data['production_apply_authorization_present']}`",
|
||||
f"Deployed SHA: `{data['deployed_sha']}`",
|
||||
f"Operator identity: `{data['operator_identity']}`",
|
||||
"",
|
||||
"## Checks",
|
||||
"",
|
||||
]
|
||||
for key, value in sorted(data["checks"].items()):
|
||||
lines.append(f"- `{key}`: `{value}`")
|
||||
lines.extend(["", "## Expected Authorization Text", "", data["expected_authorization_text"] or "(missing)", ""])
|
||||
lines.extend(["## Next Action If Verified", ""])
|
||||
lines.extend(f"- {item}" for item in data["next_action_if_verified"])
|
||||
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("--auth-packet", type=Path, default=DEFAULT_AUTH_PACKET)
|
||||
parser.add_argument("--deployed-sha", default="")
|
||||
parser.add_argument("--authorization-text", default="")
|
||||
parser.add_argument("--authorization-text-file", type=Path)
|
||||
parser.add_argument("--operator-identity", default="")
|
||||
parser.add_argument("--out", type=Path, default=DEFAULT_OUT)
|
||||
parser.add_argument("--markdown-out", type=Path, default=DEFAULT_MARKDOWN_OUT)
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
args = parse_args(argv)
|
||||
authorization_text = args.authorization_text
|
||||
if args.authorization_text_file is not None:
|
||||
authorization_text = args.authorization_text_file.read_text(encoding="utf-8")
|
||||
data = verify_authorization(
|
||||
deployed_sha=args.deployed_sha,
|
||||
authorization_text=authorization_text,
|
||||
operator_identity=args.operator_identity,
|
||||
auth_packet_path=args.auth_packet,
|
||||
)
|
||||
write_json(args.out, data)
|
||||
write_markdown(args.markdown_out, data)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"out": str(args.out),
|
||||
"markdown_out": str(args.markdown_out),
|
||||
"safe_to_enter_apply_window": data["safe_to_enter_apply_window"],
|
||||
"status": data["status"],
|
||||
},
|
||||
indent=2,
|
||||
sort_keys=True,
|
||||
)
|
||||
)
|
||||
return 0 if data["safe_to_enter_apply_window"] else 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
"""Tests for scripts/verify_working_leo_production_apply_authorization.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 verify_working_leo_production_apply_authorization as verifier # noqa: E402
|
||||
|
||||
|
||||
def test_missing_authorization_text_refuses_apply_window():
|
||||
result = verifier.verify_authorization(
|
||||
deployed_sha="427a9f1a1e114814c750bb3e9e99e3456a6c1539",
|
||||
operator_identity="operator@example.com",
|
||||
)
|
||||
|
||||
assert result["status"] == "missing_authorization_text"
|
||||
assert result["safe_to_enter_apply_window"] is False
|
||||
assert result["production_apply_executed"] is False
|
||||
assert result["production_apply_authorization_present"] is False
|
||||
assert result["checks"]["auth_packet_ready"] is True
|
||||
assert result["checks"]["authorization_text_matches_expected"] is False
|
||||
assert "does not run SQL" in result["claim_ceiling"]
|
||||
|
||||
|
||||
def test_exact_authorization_text_verifies_without_execution():
|
||||
deployed_sha = "427a9f1a1e114814c750bb3e9e99e3456a6c1539"
|
||||
auth_packet = verifier._load_json(verifier.DEFAULT_AUTH_PACKET)
|
||||
text = verifier.expected_authorization_text(auth_packet, deployed_sha)
|
||||
|
||||
result = verifier.verify_authorization(
|
||||
deployed_sha=deployed_sha,
|
||||
authorization_text=text,
|
||||
operator_identity="operator@example.com",
|
||||
)
|
||||
|
||||
assert result["status"] == "authorization_verified_not_executed"
|
||||
assert result["safe_to_enter_apply_window"] is True
|
||||
assert result["production_apply_executed"] is False
|
||||
assert result["production_apply_authorization_present"] is True
|
||||
assert all(result["checks"].values())
|
||||
assert result["expected_authorization_text"] == text
|
||||
|
||||
|
||||
def test_wrong_deployed_sha_or_text_refuses_apply_window():
|
||||
deployed_sha = "427a9f1a1e114814c750bb3e9e99e3456a6c1539"
|
||||
auth_packet = verifier._load_json(verifier.DEFAULT_AUTH_PACKET)
|
||||
text = verifier.expected_authorization_text(auth_packet, deployed_sha)
|
||||
|
||||
result = verifier.verify_authorization(
|
||||
deployed_sha="45bec0ed84846ae92a53993e5337313014538206",
|
||||
authorization_text=text,
|
||||
operator_identity="operator@example.com",
|
||||
)
|
||||
|
||||
assert result["status"] == "authorization_text_mismatch"
|
||||
assert result["safe_to_enter_apply_window"] is False
|
||||
assert result["checks"]["authorization_text_matches_expected"] is False
|
||||
|
||||
|
||||
def test_markdown_shows_claim_ceiling(tmp_path: Path):
|
||||
result = verifier.verify_authorization(deployed_sha="427a9f1a1e114814c750bb3e9e99e3456a6c1539")
|
||||
out = tmp_path / "auth.md"
|
||||
|
||||
verifier.write_markdown(out, result)
|
||||
|
||||
text = out.read_text(encoding="utf-8")
|
||||
assert "Working Leo Production Apply Authorization Verification" in text
|
||||
assert "Safe to enter apply window: `False`" in text
|
||||
assert "Production apply executed: `False`" in text
|
||||
assert "Claim Ceiling" in text
|
||||
Loading…
Reference in a new issue