diff --git a/lib/ops-setup.sh b/lib/ops-setup.sh index 8933343..db6e674 100644 --- a/lib/ops-setup.sh +++ b/lib/ops-setup.sh @@ -205,6 +205,16 @@ OPSEOF seeded=true fi + # Copy vault policy.toml template if not already present + if [ ! -f "${ops_root}/vault/policy.toml" ]; then + local policy_src="${FACTORY_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/vault/policy.toml" + if [ -f "$policy_src" ]; then + cp "$policy_src" "${ops_root}/vault/policy.toml" + echo " + Copied vault/policy.toml template" + seeded=true + fi + fi + # Create stub files if they don't exist [ -f "${ops_root}/portfolio.md" ] || { echo "# Portfolio" > "${ops_root}/portfolio.md"; seeded=true; } [ -f "${ops_root}/prerequisites.md" ] || { echo "# Prerequisite Tree" > "${ops_root}/prerequisites.md"; seeded=true; } diff --git a/vault/classify.sh b/vault/classify.sh new file mode 100755 index 0000000..f91ab25 --- /dev/null +++ b/vault/classify.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# classify.sh — Blast-radius classification engine +# +# Reads the ops-repo policy.toml and prints the tier for a given formula. +# An optional blast_radius override (from the action TOML) takes precedence. +# +# Usage: classify.sh [blast_radius_override] +# Output: prints "low", "medium", or "high" to stdout; exits 0 +# +# Source lib/env.sh directly (not vault-env.sh) to avoid circular dependency: +# vault-env.sh calls classify.sh, so classify.sh must not source vault-env.sh. +# The only variable needed here is OPS_REPO_ROOT, which comes from lib/env.sh. +# shellcheck source=../lib/env.sh +set -euo pipefail + +source "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/lib/env.sh" + +formula="${1:-}" +override="${2:-}" + +if [ -z "$formula" ]; then + echo "Usage: classify.sh [blast_radius_override]" >&2 + exit 1 +fi + +# If the action TOML provides a blast_radius override, use it directly +if [[ "$override" =~ ^(low|medium|high)$ ]]; then + echo "$override" + exit 0 +fi + +# Read tier from ops-repo policy.toml +policy_file="${OPS_REPO_ROOT}/vault/policy.toml" + +if [ -f "$policy_file" ]; then + # Parse: look for `formula_name = "tier"` under [tiers] + # Escape regex metacharacters in formula name for safe grep + escaped_formula=$(printf '%s' "$formula" | sed 's/[].[*^$\\]/\\&/g') + # grep may find no match (exit 1); guard with || true to avoid pipefail abort + tier=$(sed -n '/^\[tiers\]/,/^\[/{/^\[tiers\]/d;/^\[/d;p}' "$policy_file" \ + | { grep -E "^${escaped_formula}[[:space:]]*=" || true; } \ + | sed -E 's/^[^=]+=[[:space:]]*"([^"]+)".*/\1/' \ + | head -n1) + + if [[ "$tier" =~ ^(low|medium|high)$ ]]; then + echo "$tier" + exit 0 + fi +fi + +# Default-deny: unknown formulas are high +echo "high" +exit 0 diff --git a/vault/policy.toml b/vault/policy.toml new file mode 100644 index 0000000..5ba2667 --- /dev/null +++ b/vault/policy.toml @@ -0,0 +1,30 @@ +# vault/policy.toml — Blast-radius tier classification for formulas +# +# Each formula maps to a tier: "low", "medium", or "high". +# Unknown formulas default to "high" (default-deny). +# +# This file is a template. `disinto init` copies it to +# $OPS_REPO_ROOT/vault/policy.toml where operators can override tiers +# per-deployment without a disinto PR. + +[tiers] +# Read-only / internal bookkeeping — no external side-effects +groom-backlog = "low" +triage = "low" +reproduce = "low" +review-pr = "low" + +# Create issues, PRs, or internal plans — visible but reversible +dev = "medium" +run-planner = "medium" +run-gardener = "medium" +run-predictor = "medium" +run-supervisor = "medium" +run-architect = "medium" +upgrade-dependency = "medium" + +# External-facing or irreversible operations +run-publish-site = "high" +run-rent-a-human = "high" +add-rpc-method = "high" +release = "high" diff --git a/vault/vault-env.sh b/vault/vault-env.sh index 8e7f7c6..8ceddc3 100644 --- a/vault/vault-env.sh +++ b/vault/vault-env.sh @@ -11,6 +11,14 @@ FORGE_TOKEN="${FORGE_VAULT_TOKEN:-${FORGE_TOKEN}}" # Vault redesign in progress (PR-based approval workflow) # This file is kept for shared env setup; scripts being replaced by #73 +# Blast-radius classification — set VAULT_TIER if a formula is known +# Callers may set VAULT_ACTION_FORMULA before sourcing, or pass it later. +if [ -n "${VAULT_ACTION_FORMULA:-}" ]; then + VAULT_TIER=$("$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/classify.sh" \ + "$VAULT_ACTION_FORMULA" "${VAULT_BLAST_RADIUS_OVERRIDE:-}") + export VAULT_TIER +fi + # ============================================================================= # VAULT ACTION VALIDATION # =============================================================================