#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source_container="${SOURCE_CONTAINER:-teleo-pg}" source_db="${SOURCE_DB:-teleo}" service="${LEO_SERVICE:-leoclean-gateway.service}" image="${POSTGRES_CANARY_IMAGE:-postgres:16}" source_tier="${SOURCE_TIER:-live-readonly}" normalization_json="" output="${repo_root}/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json" lifecycle_receipt_output="" rollback_sql_output="" while [[ $# -gt 0 ]]; do case "$1" in --normalization-json) normalization_json="$2" shift 2 ;; --output) output="$2" shift 2 ;; --lifecycle-receipt-output) lifecycle_receipt_output="$2" shift 2 ;; --rollback-sql-output) rollback_sql_output="$2" shift 2 ;; --source-container) source_container="$2" shift 2 ;; --source-db) source_db="$2" shift 2 ;; --service) service="$2" shift 2 ;; --source-tier) source_tier="$2" shift 2 ;; *) echo "unknown argument: $1" >&2 exit 2 ;; esac done if [[ "$source_tier" != "isolated-local" && "$source_tier" != "live-readonly" ]]; then echo "--source-tier must be isolated-local or live-readonly" >&2 exit 2 fi source_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$source_container")" source_canary_label="$( docker inspect -f '{{index .Config.Labels "livingip.canary"}}' "$source_container" )" if [[ "$source_tier" == "isolated-local" ]]; then if [[ "$source_network_mode" != "none" || "$source_canary_label" != "working-leo-approved-source" ]]; then echo "isolated-local source must be networkless and labeled livingip.canary=working-leo-approved-source" >&2 exit 2 fi fi container="working-leo-approve-claim-$RANDOM-$$" workdir="/tmp/${container}" apply_password="isolated-apply-${RANDOM}-${RANDOM}" review_password="isolated-review-${RANDOM}-${RANDOM}" cleanup() { docker rm -f "$container" >/dev/null 2>&1 || true rm -rf "$workdir" } trap cleanup EXIT source_counts() { docker exec "$source_container" psql -U postgres -d "$source_db" -Atq \ -v ON_ERROR_STOP=1 -c "begin transaction read only; select jsonb_build_object( 'public.claims',(select count(*) from public.claims), 'public.sources',(select count(*) from public.sources), 'public.claim_evidence',(select count(*) from public.claim_evidence), 'public.claim_edges',(select count(*) from public.claim_edges), 'public.reasoning_tools',(select count(*) from public.reasoning_tools), 'kb_stage.kb_proposals',(select count(*) from kb_stage.kb_proposals) )::text; rollback;" } service_state() { if ! command -v systemctl >/dev/null 2>&1; then printf 'Available=false\nReason=systemctl_unavailable\n' return 0 fi local output if output="$(systemctl show "$service" --no-pager \ -p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp 2>&1)"; then printf 'Available=true\n%s\n' "$output" else printf 'Available=false\nReason=service_readback_failed\n' fi } mkdir -p "$workdir" "$(dirname "$output")" if [[ -n "$lifecycle_receipt_output" ]]; then mkdir -p "$(dirname "$lifecycle_receipt_output")" fi if [[ -n "$rollback_sql_output" ]]; then mkdir -p "$(dirname "$rollback_sql_output")" fi source_counts_before="$(source_counts)" service_before="$(service_state)" docker run -d --name "$container" \ --network none \ --label livingip.canary=proposal-apply-lifecycle \ --label "livingip.canary.instance=${container}" \ --tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m \ -e POSTGRES_PASSWORD="isolated-postgres-${RANDOM}-${RANDOM}" \ -e POSTGRES_DB=teleo \ "$image" >/dev/null ready_streak=0 for _ in $(seq 1 80); do if docker exec "$container" pg_isready -U postgres -d teleo >/dev/null 2>&1; then ready_streak=$((ready_streak + 1)) if [[ "$ready_streak" -ge 2 ]]; then break fi else ready_streak=0 fi sleep 0.25 done if [[ "$ready_streak" -lt 2 ]]; then echo "disposable Postgres did not become stably ready" >&2 exit 1 fi container_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$container")" container_mounts_json="$(docker inspect -f '{{json .Mounts}}' "$container")" container_canary_label="$( docker inspect -f '{{index .Config.Labels "livingip.canary"}}' "$container" )" container_instance_label="$( docker inspect -f '{{index .Config.Labels "livingip.canary.instance"}}' "$container" )" docker exec "$source_container" pg_dump -U postgres -d "$source_db" \ --schema-only --no-owner --no-privileges >"$workdir/schema.sql" docker exec "$source_container" pg_dump -U postgres -d "$source_db" \ --data-only --no-owner --no-privileges \ --table=public.agents --table=public.claims >"$workdir/reference-data.sql" docker cp "$workdir/schema.sql" "$container:/tmp/schema.sql" docker cp "$workdir/reference-data.sql" "$container:/tmp/reference-data.sql" docker exec -i "$container" psql -U postgres -d postgres -v ON_ERROR_STOP=1 -q <"$workdir/kb-apply.env" <"$workdir/kb-review.env" <"$workdir/stdout.json" 2>"$workdir/stderr.log" canary_rc=$? set -e set +e docker rm -f "$container" >/dev/null 2>&1 outer_container_remove_rc=$? rm -rf "$workdir" outer_workdir_remove_rc=$? container_name_readback="$( docker container ls -a --filter "name=^/${container}$" --format '{{.Names}}' 2>&1 )" container_name_readback_rc=$? container_label_readback="$( docker container ls -a \ --filter "label=livingip.canary=proposal-apply-lifecycle" \ --filter "label=livingip.canary.instance=${container}" \ --format '{{.Names}}' 2>&1 )" container_label_readback_rc=$? if [[ "$container_label_readback_rc" -eq 0 ]]; then container_label_orphan_count="$( awk 'NF { count += 1 } END { print count + 0 }' <<<"$container_label_readback" )" else container_label_orphan_count=-1 fi if [[ -e "$workdir" || -L "$workdir" ]]; then outer_workdir_lexists=true else outer_workdir_lexists=false fi set -e trap - EXIT source_counts_after="$(source_counts)" service_after="$(service_state)" SOURCE_COUNTS_BEFORE="$source_counts_before" \ SOURCE_COUNTS_AFTER="$source_counts_after" \ SOURCE_CONTAINER="$source_container" \ SOURCE_DB="$source_db" \ SERVICE_BEFORE="$service_before" \ SERVICE_AFTER="$service_after" \ REPO_ROOT="$repo_root" \ OUTER_CONTAINER_REMOVE_RC="$outer_container_remove_rc" \ OUTER_WORKDIR_REMOVE_RC="$outer_workdir_remove_rc" \ CONTAINER_NAME_READBACK="$container_name_readback" \ CONTAINER_NAME_READBACK_RC="$container_name_readback_rc" \ CONTAINER_LABEL_READBACK="$container_label_readback" \ CONTAINER_LABEL_READBACK_RC="$container_label_readback_rc" \ CONTAINER_LABEL_ORPHAN_COUNT="$container_label_orphan_count" \ OUTER_WORKDIR_LEXISTS="$outer_workdir_lexists" \ CANARY_RC="$canary_rc" \ SOURCE_TIER="$source_tier" \ SOURCE_NETWORK_MODE="$source_network_mode" \ SOURCE_CANARY_LABEL="$source_canary_label" \ CANARY_NETWORK_MODE="$container_network_mode" \ CANARY_MOUNTS_JSON="$container_mounts_json" \ CANARY_LABEL="$container_canary_label" \ CANARY_INSTANCE_LABEL="$container_instance_label" \ python3 "$repo_root/scripts/finalize_approve_claim_isolated_canary.py" "$output"