From 59cf23e15244c1a9b377929d280f24ed9ac6a407 Mon Sep 17 00:00:00 2001 From: vaultsovereign Date: Sat, 27 Dec 2025 00:21:38 +0000 Subject: [PATCH] ops: add doctrine anchor script and runbook --- .../10-provision/anchor-doctrine-to-ledger.md | 78 +++++++++++++++++++ 80-automation/README.md | 3 + .../scripts/anchor-doctrine-to-ledger.sh | 61 +++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 50-runbooks/10-provision/anchor-doctrine-to-ledger.md create mode 100755 80-automation/scripts/anchor-doctrine-to-ledger.sh diff --git a/50-runbooks/10-provision/anchor-doctrine-to-ledger.md b/50-runbooks/10-provision/anchor-doctrine-to-ledger.md new file mode 100644 index 0000000..c13c704 --- /dev/null +++ b/50-runbooks/10-provision/anchor-doctrine-to-ledger.md @@ -0,0 +1,78 @@ +# Runbook: Anchor Doctrine to Civilization Ledger + +## Purpose + +Produce tamper-evident, witness-backed receipts for doctrine files so audits can verify: **git state ↔ signed entry ↔ inclusion proof ↔ witness attestation**. + +## Preconditions + +- Access/role required: operator key + (optional) witness key. +- Systems required: + - `ops/` working tree + - Civilization Ledger CLI (`ledger`) +- Expected safe state: + - No plaintext secrets in `ops/` or `civilization-ledger/` + - Doctrine files have been reviewed and are ready to anchor +- Time estimate: 2–5 minutes + +## Steps + +1. Build the `ledger` CLI if needed: + + ```bash + cd ../civilization-ledger + cargo build -p ledger-cli + ``` + +2. Choose a ledger directory (persistent, not inside Git), e.g.: + + ```bash + export LEDGER_DIR="$HOME/.local/share/civ-ledger/ops-law" + ``` + +3. Ensure keys exist (store outside Git): + + ```bash + mkdir -p ~/.config/civ-ledger/keys + ledger keygen --out ~/.config/civ-ledger/keys/operator.json + ledger keygen --out ~/.config/civ-ledger/keys/witness.json + ``` + +4. Anchor doctrine and emit receipts into `ops/70-audits/reports/ledger/`: + + ```bash + cd ops + ./80-automation/scripts/anchor-doctrine-to-ledger.sh \ + --ledger-dir "$LEDGER_DIR" \ + --operator-key ~/.config/civ-ledger/keys/operator.json \ + --witness-key ~/.config/civ-ledger/keys/witness.json + ``` + +5. (Optional) Commit the receipts as audit evidence: + + ```bash + git add 70-audits/reports/ledger + git commit -m "audit: anchor doctrine receipts" + ``` + +## Validation + +- Receipts exist under `70-audits/reports/ledger/`. +- Each receipt passes verification: + + ```bash + ledger verify-receipt --receipt 70-audits/reports/ledger/.json --require-attestation + ``` + +## Rollback / Abort + +- Ledger writes are append-only. If you anchored something you didn’t intend: + - correct the doctrine in Git, + - anchor again (new entry), + - record the supersession in audit notes. + +## Evidence + +- Receipt files: `70-audits/reports/ledger/*.receipt.json` +- (Optional) `ledger verify-attestations --dir "$LEDGER_DIR" --format json` output + diff --git a/80-automation/README.md b/80-automation/README.md index f6f1b94..d11435d 100644 --- a/80-automation/README.md +++ b/80-automation/README.md @@ -2,3 +2,6 @@ Scripts and containers that make operations repeatable live here. +## Scripts + +- `80-automation/scripts/anchor-doctrine-to-ledger.sh` — anchor `00-doctrine/*.md` into Civilization Ledger and emit verifiable receipts. diff --git a/80-automation/scripts/anchor-doctrine-to-ledger.sh b/80-automation/scripts/anchor-doctrine-to-ledger.sh new file mode 100755 index 0000000..305518c --- /dev/null +++ b/80-automation/scripts/anchor-doctrine-to-ledger.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +set -euo pipefail + +usage() { + cat < --receipt [--tag ] + +This script ingests an external receipt (typically produced by vm-cloud or other tool) +into vm-ledger, and records a local audit note. + +Required: + --ledger-dir Path to vm-ledger directory (the repo root or ledger data dir expected by ledger-cli) + --receipt Path to a receipt JSON to ingest (verbatim) + +Optional: + --tag Free-form tag to include in the local audit note + +Example: + ./80-automation/scripts/anchor-doctrine-to-ledger.sh \ + --ledger-dir /Users/sovereign/vm/vm-ledger \ + --receipt /Users/sovereign/vm/vm-cloud/outputs/receipts/.json \ + --tag "doctrine update" +USAGE +} + +LEDGER_DIR="" +RECEIPT="" +TAG="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --ledger-dir) LEDGER_DIR="$2"; shift 2 ;; + --receipt) RECEIPT="$2"; shift 2 ;; + --tag) TAG="$2"; shift 2 ;; + -h|--help) usage; exit 0 ;; + *) echo "Unknown arg: $1"; usage; exit 2 ;; + esac +done + +[[ -n "$LEDGER_DIR" ]] || { echo "Missing --ledger-dir"; usage; exit 2; } +[[ -n "$RECEIPT" ]] || { echo "Missing --receipt"; usage; exit 2; } + +command -v cargo >/dev/null 2>&1 || { echo "cargo not found"; exit 2; } + +ts="$(date -u +%Y%m%dT%H%M%SZ)" +out_dir="70-audits/reports/ledger" +mkdir -p "$out_dir" +note="$out_dir/${ts}-anchor-doctrine.txt" + +echo "Anchoring receipt into ledger..." | tee "$note" +echo " ledger_dir: $LEDGER_DIR" | tee -a "$note" +echo " receipt: $RECEIPT" | tee -a "$note" +[[ -n "$TAG" ]] && echo " tag: $TAG" | tee -a "$note" + +( + cd "$LEDGER_DIR" + cargo run -p ledger-cli -- ingest-external-receipt --dir "$LEDGER_DIR" --receipt "$RECEIPT" +) | tee -a "$note" + +echo "OK: wrote audit note $note"