Some checks are pending
CI / lint-and-test (push) Waiting to run
- Create guarded Rio strategy nodes and anchors after the mapped base packet - Prove clone apply and rollback while production rows and Leo runtime stay unchanged - Retain packet docs, state image, and focused tests for future apply review `docs/reports/leo-working-state-20260709/current-truth-index.md` `docs/reports/leo-working-state-20260709/leo-db-state-23-rio-strategy-context.svg` `docs/reports/leo-working-state-20260709/rio-strategy-apply-authorized-commit.sql` `docs/reports/leo-working-state-20260709/rio-strategy-apply-rollback-rehearsal.sql` `docs/reports/leo-working-state-20260709/rio-strategy-clone-rehearsal-current.log` `docs/reports/leo-working-state-20260709/rio-strategy-context-current.md` `docs/reports/leo-working-state-20260709/rio-strategy-delete-rollback.sql` `docs/reports/leo-working-state-20260709/rio-strategy-packet.json` `docs/reports/leo-working-state-20260709/rio-strategy-postflight.sql` `docs/reports/leo-working-state-20260709/rio-strategy-preflight.sql` `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/kb_rio_strategy_context_packet.py` `tests/test_kb_rio_strategy_context_packet.py`
532 lines
20 KiB
Python
532 lines
20 KiB
Python
#!/usr/bin/env python3
|
|
"""Generate a Rio strategy-context companion packet for mapped KB proposals.
|
|
|
|
The mapped rich proposal packet creates the canonical claim/source/evidence and
|
|
claim-edge rows. Some remaining approved fragments target Rio strategy context,
|
|
not claim graph rows. This packet handles that surface by creating two Rio
|
|
strategy nodes and exact anchors after the mapped base packet has created the
|
|
required successor claims.
|
|
|
|
Governance-gate and concept-map fragments remain explicit deferrals because the
|
|
current live schema has no safe direct edge table for those targets.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
import uuid
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
from kb_rich_proposal_creation_plan import _sql_literal # noqa: E402
|
|
|
|
PROPOSAL_ID = "14fa5ecc-ac7a-41c1-807d-a2e85b936617"
|
|
BASE_PACKET_REQUIRED_FIRST = "production-apply-packet-mapped-20260709"
|
|
|
|
RIO_AGENT_ID = "22222222-2222-2222-2222-222222222222"
|
|
BACK_SHARED_ROOT_ID = "6248818e-fe16-4d3b-8008-ef9752b80632"
|
|
|
|
CLAIM_A_ID = "004195cc-ab62-526c-90fb-51cb0f826ec0"
|
|
CLAIM_C_ID = "67003e10-e1ee-5905-8b51-1b0cb263ec11"
|
|
CLAIM_D_ID = "e6ce4e36-15d2-53bc-8b74-dda0efc095c1"
|
|
|
|
QUALITY_GATE_ID = "fa88e31b-6fca-4801-bf72-f5db81950a11"
|
|
EVIDENCE_BAR_ID = "45695897-2a9c-4279-ac25-e59f166dec6a"
|
|
|
|
ID_NAMESPACE = uuid.uuid5(uuid.NAMESPACE_URL, "teleo:working-leo:rio-strategy-context")
|
|
|
|
|
|
def stable_id(key: str) -> str:
|
|
return str(uuid.uuid5(ID_NAMESPACE, key))
|
|
|
|
|
|
CAPITAL_LAYER_NODE_ID = stable_id("strategy-node:rio-capital-deployment-layer")
|
|
INTERNET_FINANCE_PRODUCT_NODE_ID = stable_id("strategy-node:rio-internet-finance-capital-product")
|
|
|
|
CAPITAL_JUSTIFIED_BY_CLAIM_A_ANCHOR_ID = stable_id("anchor:capital-layer:justified-by:claim-a")
|
|
CAPITAL_SERVES_BACK_ANCHOR_ID = stable_id("anchor:capital-layer:serves:back-shared-root")
|
|
PRODUCT_JUSTIFIED_BY_CLAIM_C_ANCHOR_ID = stable_id("anchor:internet-finance-product:justified-by:claim-c")
|
|
PRODUCT_JUSTIFIED_BY_CLAIM_D_ANCHOR_ID = stable_id("anchor:internet-finance-product:justified-by:claim-d")
|
|
PRODUCT_SERVES_CAPITAL_LAYER_ANCHOR_ID = stable_id("anchor:internet-finance-product:serves:capital-layer")
|
|
|
|
|
|
def _uuid_values(values: list[str], *, column_name: str = "id") -> str:
|
|
rows = ",\n ".join(f"('{value}'::uuid)" for value in values)
|
|
return f"(values\n {rows}\n ) as v({column_name})"
|
|
|
|
|
|
def _jsonb(value: Any) -> str:
|
|
return _sql_literal(json.dumps(value, sort_keys=True)) + "::jsonb"
|
|
|
|
|
|
def strategy_nodes() -> list[dict[str, Any]]:
|
|
return [
|
|
{
|
|
"id": CAPITAL_LAYER_NODE_ID,
|
|
"agent_id": RIO_AGENT_ID,
|
|
"node_type": "policy",
|
|
"title": "Rio capital deployment layer",
|
|
"body": (
|
|
"Rio treats capital allocation as a civilizational steering layer: resources should back "
|
|
"builders through review-gated, market-aware mechanisms that serve Teleo's Back function."
|
|
),
|
|
"rank": 1,
|
|
"status": "active",
|
|
"horizon": "current strategy context",
|
|
"measure": (
|
|
"Capital-deployment analysis can name the claim evidence, review boundary, and Back shared "
|
|
"root it serves before recommending resource allocation."
|
|
),
|
|
"source_ref": "mapped-rich-proposal-14fa5ecc:rio-capital-deployment-layer",
|
|
"metadata": {
|
|
"base_packet_required_first": BASE_PACKET_REQUIRED_FIRST,
|
|
"proposal_id": PROPOSAL_ID,
|
|
"source_fragments": [
|
|
"capital_allocation_is_civilizational_steering supports rio:capital-deployment-layer",
|
|
"capital_allocation_is_civilizational_steering relates teleo telos / fund-build paths toward better attractors",
|
|
],
|
|
},
|
|
},
|
|
{
|
|
"id": INTERNET_FINANCE_PRODUCT_NODE_ID,
|
|
"agent_id": RIO_AGENT_ID,
|
|
"node_type": "objective",
|
|
"title": "Rio internet-finance capital product",
|
|
"body": (
|
|
"Rio may evaluate internet-finance mechanisms as capital-product candidates, but only as "
|
|
"instrumental mechanisms. The product must stay subordinate to Teleo's capital-allocation "
|
|
"telos and cannot become the telos itself."
|
|
),
|
|
"rank": 2,
|
|
"status": "active",
|
|
"horizon": "current strategy context",
|
|
"measure": (
|
|
"Any internet-finance product thesis states its structural advantages, its mechanism-not-telos "
|
|
"boundary, and how it serves the capital deployment layer."
|
|
),
|
|
"source_ref": "mapped-rich-proposal-14fa5ecc:rio-active-strategy-v1-internet-finance-capital-product",
|
|
"metadata": {
|
|
"base_packet_required_first": BASE_PACKET_REQUIRED_FIRST,
|
|
"proposal_id": PROPOSAL_ID,
|
|
"source_fragments": [
|
|
"internet_finance_structural_advantages_capital_allocation relates rio:active strategy v1 / internet-finance capital product",
|
|
"internet_finance_is_mechanism_not_telos constrains rio:active strategy v1 / internet-finance capital product",
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
|
|
def strategy_anchors() -> list[dict[str, Any]]:
|
|
return [
|
|
{
|
|
"id": CAPITAL_JUSTIFIED_BY_CLAIM_A_ANCHOR_ID,
|
|
"from_node_id": CAPITAL_LAYER_NODE_ID,
|
|
"anchor_role": "justified_by",
|
|
"claim_id": CLAIM_A_ID,
|
|
"weight": 0.85,
|
|
"note": (
|
|
"Mapped proposal 14fa5ecc: Claim A justifies the Rio capital deployment layer because "
|
|
"capital allocation steers which futures receive resources."
|
|
),
|
|
},
|
|
{
|
|
"id": CAPITAL_SERVES_BACK_ANCHOR_ID,
|
|
"from_node_id": CAPITAL_LAYER_NODE_ID,
|
|
"anchor_role": "serves",
|
|
"to_shared_root_id": BACK_SHARED_ROOT_ID,
|
|
"weight": 0.80,
|
|
"note": (
|
|
"Maps the fund-build / better-attractors fragment to the existing Back shared root instead "
|
|
"of forcing it into public.claim_edges."
|
|
),
|
|
},
|
|
{
|
|
"id": PRODUCT_JUSTIFIED_BY_CLAIM_C_ANCHOR_ID,
|
|
"from_node_id": INTERNET_FINANCE_PRODUCT_NODE_ID,
|
|
"anchor_role": "justified_by",
|
|
"claim_id": CLAIM_C_ID,
|
|
"weight": 0.70,
|
|
"note": (
|
|
"Mapped proposal 14fa5ecc: the internet-finance capital product is justified by the "
|
|
"structural-advantages claim, not by the old compressed claim."
|
|
),
|
|
},
|
|
{
|
|
"id": PRODUCT_JUSTIFIED_BY_CLAIM_D_ANCHOR_ID,
|
|
"from_node_id": INTERNET_FINANCE_PRODUCT_NODE_ID,
|
|
"anchor_role": "justified_by",
|
|
"claim_id": CLAIM_D_ID,
|
|
"weight": 0.85,
|
|
"note": (
|
|
"Represents the proposal's constrains fragment within the current anchor-role enum: "
|
|
"internet finance is a candidate mechanism, not Teleo's telos."
|
|
),
|
|
},
|
|
{
|
|
"id": PRODUCT_SERVES_CAPITAL_LAYER_ANCHOR_ID,
|
|
"from_node_id": INTERNET_FINANCE_PRODUCT_NODE_ID,
|
|
"anchor_role": "serves",
|
|
"to_node_id": CAPITAL_LAYER_NODE_ID,
|
|
"weight": 0.75,
|
|
"note": (
|
|
"The internet-finance product objective serves Rio's capital deployment layer rather than "
|
|
"standing as a standalone telos."
|
|
),
|
|
},
|
|
]
|
|
|
|
|
|
def _node_insert_values() -> str:
|
|
rows = []
|
|
for row in strategy_nodes():
|
|
rows.append(
|
|
"("
|
|
f"{_sql_literal(row['id'])}::uuid, "
|
|
f"{_sql_literal(row['agent_id'])}::uuid, "
|
|
f"{_sql_literal(row['node_type'])}, "
|
|
f"{_sql_literal(row['title'])}, "
|
|
f"{_sql_literal(row['body'])}, "
|
|
f"{row['rank']}, "
|
|
f"{_sql_literal(row['status'])}, "
|
|
f"{_sql_literal(row['horizon'])}, "
|
|
f"{_sql_literal(row['measure'])}, "
|
|
f"{_sql_literal(row['source_ref'])}, "
|
|
f"{_jsonb(row['metadata'])}"
|
|
")"
|
|
)
|
|
return ",\n ".join(rows)
|
|
|
|
|
|
def _anchor_insert_values() -> str:
|
|
rows = []
|
|
for row in strategy_anchors():
|
|
rows.append(
|
|
"("
|
|
f"{_sql_literal(row['id'])}::uuid, "
|
|
f"{_sql_literal(row['from_node_id'])}::uuid, "
|
|
f"{_sql_literal(row['anchor_role'])}, "
|
|
f"{_sql_literal(row.get('to_node_id'))}::uuid, "
|
|
f"{_sql_literal(row.get('to_shared_root_id'))}::uuid, "
|
|
f"{_sql_literal(row.get('belief_id'))}::uuid, "
|
|
f"{_sql_literal(row.get('claim_id'))}::uuid, "
|
|
f"{_sql_literal(row.get('source_id'))}::uuid, "
|
|
f"{row['weight']}, "
|
|
f"{_sql_literal(row['note'])}"
|
|
")"
|
|
)
|
|
return ",\n ".join(rows)
|
|
|
|
|
|
def build_generated_counts_sql() -> str:
|
|
node_ids = [row["id"] for row in strategy_nodes()]
|
|
anchor_ids = [row["id"] for row in strategy_anchors()]
|
|
return f"""select
|
|
(select count(*) from public.strategy_nodes where id in (select id from {_uuid_values(node_ids)})) as generated_strategy_node_rows,
|
|
(select count(*) from public.strategy_node_anchors where id in (select id from {_uuid_values(anchor_ids)})) as generated_strategy_anchor_rows;
|
|
"""
|
|
|
|
|
|
def build_preflight_sql() -> str:
|
|
required_claim_ids = [CLAIM_A_ID, CLAIM_C_ID, CLAIM_D_ID]
|
|
node_titles = ",\n ".join(_sql_literal(row["title"]) for row in strategy_nodes())
|
|
return f"""\\set ON_ERROR_STOP on
|
|
-- Rio strategy-context companion preflight. Read-only.
|
|
-- Run after the mapped rich proposal packet has been applied.
|
|
|
|
select 'rio_agent' as check_name, id::text, handle, kind
|
|
from public.agents
|
|
where id = {_sql_literal(RIO_AGENT_ID)}::uuid;
|
|
|
|
select 'required_base_claim' as check_name,
|
|
c.id::text,
|
|
c.status,
|
|
left(c.text, 220) as text
|
|
from public.claims c
|
|
where c.id in (select id from {_uuid_values(required_claim_ids)})
|
|
order by c.id;
|
|
|
|
select 'back_shared_root' as check_name,
|
|
id::text,
|
|
title,
|
|
left(body, 220) as body
|
|
from public.shared_root
|
|
where id = {_sql_literal(BACK_SHARED_ROOT_ID)}::uuid;
|
|
|
|
select 'existing_exact_rio_strategy_title' as check_name,
|
|
id::text,
|
|
agent_id::text,
|
|
title,
|
|
status
|
|
from public.strategy_nodes
|
|
where agent_id = {_sql_literal(RIO_AGENT_ID)}::uuid
|
|
and title in (
|
|
{node_titles}
|
|
)
|
|
order by title;
|
|
|
|
-- Must be 0/0 before authorized apply.
|
|
{build_generated_counts_sql()}
|
|
|
|
select 'governance_gate_known_not_written' as check_name,
|
|
id::text,
|
|
name,
|
|
left(criteria, 180) as criteria,
|
|
left(evidence_bar, 180) as evidence_bar
|
|
from public.governance_gates
|
|
where id in (select id from {_uuid_values([QUALITY_GATE_ID, EVIDENCE_BAR_ID])})
|
|
order by name;
|
|
"""
|
|
|
|
|
|
def build_apply_sql(*, commit: bool) -> str:
|
|
terminator = "commit;" if commit else "rollback;"
|
|
required_claim_ids = [CLAIM_A_ID, CLAIM_C_ID, CLAIM_D_ID]
|
|
node_ids = [row["id"] for row in strategy_nodes()]
|
|
anchor_ids = [row["id"] for row in strategy_anchors()]
|
|
node_titles = ",\n ".join(_sql_literal(row["title"]) for row in strategy_nodes())
|
|
return f"""\\set ON_ERROR_STOP on
|
|
begin;
|
|
|
|
do $$
|
|
declare
|
|
inserted_nodes int;
|
|
inserted_anchors int;
|
|
begin
|
|
if not exists (
|
|
select 1 from public.agents where id = {_sql_literal(RIO_AGENT_ID)}::uuid and handle = 'rio'
|
|
) then
|
|
raise exception 'Rio strategy packet requires rio agent % to exist', {_sql_literal(RIO_AGENT_ID)};
|
|
end if;
|
|
|
|
if (
|
|
select count(*) from public.claims where id in (select id from {_uuid_values(required_claim_ids)})
|
|
) <> {len(required_claim_ids)} then
|
|
raise exception 'Rio strategy packet requires mapped base claims A/C/D to exist before strategy context insert';
|
|
end if;
|
|
|
|
if not exists (select 1 from public.shared_root where id = {_sql_literal(BACK_SHARED_ROOT_ID)}::uuid) then
|
|
raise exception 'Rio strategy packet requires Back shared root % to exist', {_sql_literal(BACK_SHARED_ROOT_ID)};
|
|
end if;
|
|
|
|
if exists (select 1 from public.strategy_nodes where id in (select id from {_uuid_values(node_ids)})) then
|
|
raise exception 'Rio strategy packet generated strategy node id already exists';
|
|
end if;
|
|
|
|
if exists (select 1 from public.strategy_node_anchors where id in (select id from {_uuid_values(anchor_ids)})) then
|
|
raise exception 'Rio strategy packet generated strategy anchor id already exists';
|
|
end if;
|
|
|
|
if exists (
|
|
select 1
|
|
from public.strategy_nodes
|
|
where agent_id = {_sql_literal(RIO_AGENT_ID)}::uuid
|
|
and title in (
|
|
{node_titles}
|
|
)
|
|
) then
|
|
raise exception 'Rio strategy packet refuses to create duplicate exact Rio strategy title';
|
|
end if;
|
|
|
|
insert into public.strategy_nodes
|
|
(id, agent_id, node_type, title, body, rank, status, horizon, measure, source_ref, metadata)
|
|
values
|
|
{_node_insert_values()};
|
|
|
|
get diagnostics inserted_nodes = row_count;
|
|
if inserted_nodes <> {len(node_ids)} then
|
|
raise exception 'Rio strategy packet inserted % strategy node row(s), expected {len(node_ids)}', inserted_nodes;
|
|
end if;
|
|
|
|
insert into public.strategy_node_anchors
|
|
(id, from_node_id, anchor_role, to_node_id, to_shared_root_id, belief_id, claim_id, source_id, weight, note)
|
|
values
|
|
{_anchor_insert_values()};
|
|
|
|
get diagnostics inserted_anchors = row_count;
|
|
if inserted_anchors <> {len(anchor_ids)} then
|
|
raise exception 'Rio strategy packet inserted % strategy anchor row(s), expected {len(anchor_ids)}', inserted_anchors;
|
|
end if;
|
|
end $$;
|
|
|
|
{terminator}
|
|
"""
|
|
|
|
|
|
def build_postflight_sql() -> str:
|
|
node_ids = [row["id"] for row in strategy_nodes()]
|
|
anchor_ids = [row["id"] for row in strategy_anchors()]
|
|
return f"""\\set ON_ERROR_STOP on
|
|
-- Rio strategy-context companion postflight row-level readback.
|
|
|
|
{build_generated_counts_sql()}
|
|
|
|
select id::text,
|
|
agent_id::text,
|
|
node_type,
|
|
title,
|
|
rank,
|
|
status,
|
|
source_ref,
|
|
metadata::text
|
|
from public.strategy_nodes
|
|
where id in (select id from {_uuid_values(node_ids)})
|
|
order by rank, title;
|
|
|
|
select id::text,
|
|
from_node_id::text,
|
|
anchor_role,
|
|
to_node_id::text,
|
|
to_shared_root_id::text,
|
|
claim_id::text,
|
|
weight,
|
|
left(note, 260) as note
|
|
from public.strategy_node_anchors
|
|
where id in (select id from {_uuid_values(anchor_ids)})
|
|
order by from_node_id, anchor_role, id;
|
|
|
|
select id::text, status, left(text, 220) as text
|
|
from public.claims
|
|
where id in (select id from {_uuid_values([CLAIM_A_ID, CLAIM_C_ID, CLAIM_D_ID])})
|
|
order by id;
|
|
|
|
select id::text, title, left(body, 220) as body
|
|
from public.shared_root
|
|
where id = {_sql_literal(BACK_SHARED_ROOT_ID)}::uuid;
|
|
"""
|
|
|
|
|
|
def build_delete_rollback_sql() -> str:
|
|
node_ids = [row["id"] for row in strategy_nodes()]
|
|
anchor_ids = [row["id"] for row in strategy_anchors()]
|
|
return f"""\\set ON_ERROR_STOP on
|
|
-- Emergency rollback for Rio strategy-context generated rows only.
|
|
-- Run only before later production data depends on these generated rows.
|
|
begin;
|
|
|
|
do $$
|
|
declare
|
|
deleted_anchors int;
|
|
deleted_nodes int;
|
|
begin
|
|
delete from public.strategy_node_anchors
|
|
where id in (select id from {_uuid_values(anchor_ids)});
|
|
|
|
get diagnostics deleted_anchors = row_count;
|
|
if deleted_anchors <> {len(anchor_ids)} then
|
|
raise exception 'Rio strategy rollback deleted % strategy anchor row(s), expected {len(anchor_ids)}', deleted_anchors;
|
|
end if;
|
|
|
|
delete from public.strategy_nodes
|
|
where id in (select id from {_uuid_values(node_ids)});
|
|
|
|
get diagnostics deleted_nodes = row_count;
|
|
if deleted_nodes <> {len(node_ids)} then
|
|
raise exception 'Rio strategy rollback deleted % strategy node row(s), expected {len(node_ids)}', deleted_nodes;
|
|
end if;
|
|
end $$;
|
|
|
|
commit;
|
|
"""
|
|
|
|
|
|
def build_packet() -> dict[str, Any]:
|
|
return {
|
|
"packet_version": 1,
|
|
"purpose": "Companion packet for mapped rich proposal Rio strategy context.",
|
|
"production_apply_status": "not_executed",
|
|
"base_packet_required_first": BASE_PACKET_REQUIRED_FIRST,
|
|
"source_proposal_id": PROPOSAL_ID,
|
|
"generated_counts": {
|
|
"strategy_nodes": len(strategy_nodes()),
|
|
"strategy_node_anchors": len(strategy_anchors()),
|
|
},
|
|
"safe_writes": [
|
|
{
|
|
"table": "public.strategy_nodes",
|
|
"operation": "insert",
|
|
"rows": strategy_nodes(),
|
|
},
|
|
{
|
|
"table": "public.strategy_node_anchors",
|
|
"operation": "insert",
|
|
"rows": strategy_anchors(),
|
|
},
|
|
],
|
|
"required_existing_rows": {
|
|
"public.agents": [RIO_AGENT_ID],
|
|
"public.claims": [CLAIM_A_ID, CLAIM_C_ID, CLAIM_D_ID],
|
|
"public.shared_root": [BACK_SHARED_ROOT_ID],
|
|
},
|
|
"represented_fragments": [
|
|
"capital_allocation_is_civilizational_steering supports rio:capital-deployment-layer",
|
|
"capital_allocation_is_civilizational_steering relates teleo telos / fund-build paths toward better attractors",
|
|
"internet_finance_structural_advantages_capital_allocation relates rio:active strategy v1 / internet-finance capital product",
|
|
"internet_finance_is_mechanism_not_telos constrains rio:active strategy v1 / internet-finance capital product",
|
|
"internet_finance_is_mechanism_not_telos serves teleo telos through product -> capital layer -> Back shared root",
|
|
],
|
|
"known_non_writable_targets": [
|
|
{
|
|
"target": "governance_gate:quality-gate",
|
|
"existing_row_id": QUALITY_GATE_ID,
|
|
"reason": "Governance gate exists, but current schema has no claim-to-governance-gate edge/anchor table.",
|
|
},
|
|
{
|
|
"target": "governance_gate:evidence-bar",
|
|
"existing_row_id": EVIDENCE_BAR_ID,
|
|
"reason": "Governance gate exists, but current schema has no claim-to-governance-gate edge/anchor table.",
|
|
},
|
|
{
|
|
"target": "concept_map:distributed_market_intelligence",
|
|
"existing_row_id": None,
|
|
"reason": "No first-class concept-map table exists in the current live schema.",
|
|
},
|
|
],
|
|
"sql": {
|
|
"preflight": build_preflight_sql(),
|
|
"apply_rollback_rehearsal": build_apply_sql(commit=False),
|
|
"apply_commit": build_apply_sql(commit=True),
|
|
"postflight": build_postflight_sql(),
|
|
"delete_rollback": build_delete_rollback_sql(),
|
|
},
|
|
}
|
|
|
|
|
|
def write_packet_files(packet: dict[str, Any], output_dir: Path) -> None:
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
sql = packet["sql"]
|
|
(output_dir / "rio-strategy-preflight.sql").write_text(sql["preflight"], encoding="utf-8")
|
|
(output_dir / "rio-strategy-apply-rollback-rehearsal.sql").write_text(
|
|
sql["apply_rollback_rehearsal"], encoding="utf-8"
|
|
)
|
|
(output_dir / "rio-strategy-apply-authorized-commit.sql").write_text(sql["apply_commit"], encoding="utf-8")
|
|
(output_dir / "rio-strategy-postflight.sql").write_text(sql["postflight"], encoding="utf-8")
|
|
(output_dir / "rio-strategy-delete-rollback.sql").write_text(sql["delete_rollback"], encoding="utf-8")
|
|
summary = {key: value for key, value in packet.items() if key != "sql"}
|
|
(output_dir / "rio-strategy-packet.json").write_text(
|
|
json.dumps(summary, indent=2, sort_keys=True) + "\n", encoding="utf-8"
|
|
)
|
|
|
|
|
|
def parse_args(argv: list[str]) -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--output-dir", type=Path, help="directory to write packet files")
|
|
return parser.parse_args(argv)
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
args = parse_args(sys.argv[1:] if argv is None else argv)
|
|
packet = build_packet()
|
|
if args.output_dir:
|
|
write_packet_files(packet, args.output_dir)
|
|
print(json.dumps({key: value for key, value in packet.items() if key != "sql"}, indent=2, sort_keys=True))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|