#!/usr/bin/env bash
# twin-pickup-continuation — substrate-routable continuation pickup primitive.
#
# A worker arriving on ANY habitat (Mac, Homebase, DGX, GCP, Cloudflare,
# GitHub Actions, etc.) with substrate access can run this script and
# receive the active convergence queue, the persistent invariants, the
# current authority, and the next bounded item filtered for this habitat.
#
# Per arq://doc/operator_directive/substrate-routable-execution-territory-2026-05-18
# the load-bearing invariant is: receiving "continue" on a fresh worker
# must yield the next correct action without local session memory.
#
# This script IS the substrate-only pickup primitive that closes that
# invariant for shell-based workers. Frontend operators read the
# ConvergenceQueuePanel on /system/substrate-health; this script gives
# the same view to CLI workers on every habitat.
#
# Usage:
#   scripts/twin-pickup-continuation                  # current habitat
#   scripts/twin-pickup-continuation Homebase         # filter to Homebase
#   scripts/twin-pickup-continuation --json           # raw JSON output
#
# Requirements:
#   - twin CLI (any --use-keychain-capable identity)
#   - jq

set -euo pipefail

# Latest convergence queue body. Bumped to v2 on 2026-05-18 to
# substrate-readable but is superseded; per
# arq://act/substrate_truth_reconciliation/addressing-service-body-payload-append-only-via-full-flag-2026-05-18
# the addressing service serves body payloads append-only via ?full=1,
# so each revision lands at a new versioned address.
QUEUE_BODY="${TWIN_CONVERGENCE_QUEUE:-arq://body/convergence_queue/v2}"
ROUTING_DOC="arq://doc/protocol/worker-territory-routing-v1-seed"
APPROVAL_ACT="arq://act/operator_approval_granted/substrate-authority-blanket-approval-pre-uat-2026-05-18"
DIRECTIVE_DOC="arq://doc/operator_directive/substrate-routable-execution-territory-2026-05-18"

HABITAT=""
FORMAT="human"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --json)
      FORMAT="json"
      shift
      ;;
    --help|-h)
      sed -n '2,28p' "$0"
      exit 0
      ;;
    *)
      HABITAT="$1"
      shift
      ;;
  esac
done

if ! command -v twin >/dev/null 2>&1; then
  echo "error: twin CLI not on PATH — install ara-protocol/twin and retry" >&2
  exit 2
fi

if ! command -v jq >/dev/null 2>&1; then
  echo "error: jq not on PATH" >&2
  exit 2
fi

fetch_payload() {
  local addr="$1"
  twin --use-keychain address fetch "$addr" --json 2>/dev/null \
    | jq -r '.payload_preview // empty'
}

QUEUE_JSON="$(twin --use-keychain address fetch "$QUEUE_BODY" --json 2>/dev/null || true)"
if [[ -z "$QUEUE_JSON" ]]; then
  echo "error: failed to fetch $QUEUE_BODY — substrate unreachable from this habitat" >&2
  exit 3
fi

# payload_preview is the first ~800 chars of the JSON payload — for our
# convergence queue we need the full payload, so fetch via address with
# ?full=1 if available; otherwise fall back to fetching the doc/body
# cache. The Rust twin CLI always returns payload_preview truncated for
# bodies larger than ~800 bytes, so we read from ~/.arqera cache if the
# preview is truncated.
PREVIEW="$(echo "$QUEUE_JSON" | jq -r '.payload_preview // empty')"
PAYLOAD_SIZE="$(echo "$QUEUE_JSON" | jq -r '.payload_size // 0')"

# If preview is truncated, fall back to addressing-service ?full=1
if [[ "${#PREVIEW}" -lt "$PAYLOAD_SIZE" ]]; then
  ADDR_ENCODED="$(python3 -c "import urllib.parse,sys;print(urllib.parse.quote(sys.argv[1],safe=''))" "$QUEUE_BODY")"
  BASE="${TWIN_ADDRESSING_BASE:-https://addressing.arqera.io}"
  # NOTE: this is the one curl we tolerate because it's a read-only GET
  # against the canonical addressing service to retrieve a body the
  # substrate itself owns. Not a mutation; the substrate IS the source.
  FULL="$(curl --silent --fail "${BASE}/address/${ADDR_ENCODED}?full=1" 2>/dev/null || true)"
  if [[ -n "$FULL" ]]; then
    PAYLOAD="$(echo "$FULL" | jq -r '.payload // empty')"
  else
    PAYLOAD="$PREVIEW"
  fi
else
  PAYLOAD="$PREVIEW"
fi

if [[ -z "$PAYLOAD" ]]; then
  echo "error: queue payload empty — verify $QUEUE_BODY exists on substrate" >&2
  exit 4
fi

if [[ "$FORMAT" == "json" ]]; then
  echo "$PAYLOAD"
  exit 0
fi

# Human-readable output
SNAPSHOT="$(echo "$PAYLOAD" | jq -r '.snapshot_at // "unknown"')"
ACTIVE_COUNT="$(echo "$PAYLOAD" | jq -r '.active_items | length')"
DEFERRED_COUNT="$(echo "$PAYLOAD" | jq -r '.deferred_items | length')"
OPTIER_COUNT="$(echo "$PAYLOAD" | jq -r '.operator_tier_items | length')"
VERIFY_COUNT="$(echo "$PAYLOAD" | jq -r '.verify_items | length')"

cat <<EOF
=== ARQERA substrate-routable continuation pickup ===

source : $QUEUE_BODY (snapshot $SNAPSHOT)
$( [[ -n "$HABITAT" ]] && echo "habitat filter: $HABITAT" )

queue state:
  active        : $ACTIVE_COUNT
  operator-tier : $OPTIER_COUNT
  verify        : $VERIFY_COUNT
  deferred      : $DEFERRED_COUNT

EOF

echo "## Persistent invariants (carry across habitats)"
echo "$PAYLOAD" | jq -r '.continuity_invariants.law_zero // empty'
echo ""
echo "$PAYLOAD" | jq -r '.continuity_invariants.operator_constraints_persistent[]?' \
  | sed 's/^/  · /'

echo ""
echo "## Authority"
echo "  $APPROVAL_ACT"

echo ""
echo "## Pending items"

filter_items() {
  local key="$1"
  if [[ -n "$HABITAT" ]]; then
    echo "$PAYLOAD" \
      | jq -r --arg habitat "$HABITAT" \
        ".${key}[] | select((.best_habitat // \"any\") | test(\$habitat; \"i\")) | \"  · \(.id)  [\(.best_habitat // \"any\")]\n      \(.twin_recommendation // .decision // .blocking // \"see envelope\")\""
  else
    echo "$PAYLOAD" \
      | jq -r ".${key}[] | \"  · \(.id)  [\(.best_habitat // \"any\")]\n      \(.twin_recommendation // .decision // .blocking // \"see envelope\")\""
  fi
}

if [[ "$OPTIER_COUNT" -gt 0 ]]; then
  echo ""
  echo "### Operator-tier ($OPTIER_COUNT)"
  filter_items operator_tier_items
fi
if [[ "$VERIFY_COUNT" -gt 0 ]]; then
  echo ""
  echo "### Verify ($VERIFY_COUNT)"
  filter_items verify_items
fi
if [[ "$DEFERRED_COUNT" -gt 0 ]]; then
  echo ""
  echo "### Deferred ($DEFERRED_COUNT)"
  filter_items deferred_items
fi

echo ""
echo "## Next pickup hint"
echo "  - read the full operator-directive: twin --use-keychain doc fetch $DIRECTIVE_DOC"
echo "  - read worker-territory routing:    twin --use-keychain doc fetch $ROUTING_DOC"
echo "  - read full queue JSON:             $0 --json | jq"
echo ""
echo "If continuity fails (next action unclear from substrate alone),"
echo "that's a substrate-completeness gap — emit a substrate_truth_reconciliation"
echo "act so the next session closes it."
