| 1 | set -uo pipefail |
| 2 | PM="/shared/projects/zion-pm" |
| 3 | OUT="$PM/state/outbox.json" |
| 4 | |
| 5 | mapfile -t APPROVED < <(jq -r '.history[] | select(.decision=="approved" and (.executed|not)) | .id' "$OUT" 2>/dev/null) |
| 6 | [ "${#APPROVED[@]}" -eq 0 ] && { echo "[pm] nothing approved to flush"; exit 0; } |
| 7 | |
| 8 | for OID in "${APPROVED[@]}"; do |
| 9 | KIND=$(jq -r --arg id "$OID" '.history[] | select(.id==$id) | .kind' "$OUT") |
| 10 | HAND="$PM/hands/execute-$KIND.sh" |
| 11 | if [ -x "$HAND" ] || [ -f "$HAND" ]; then |
| 12 | echo "[pm] executing $OID via $HAND" |
| 13 | PM_APPROVED=1 bash "$HAND" "$OID" "$OUT" && STATUS="executed" || STATUS="failed" |
| 14 | else |
| 15 | echo "[pm] no hand for kind='$KIND' (item $OID). Wire hands/execute-$KIND.sh. Left for manual." |
| 16 | STATUS="needs_hand" |
| 17 | fi |
| 18 | python3 - "$OUT" "$OID" "$STATUS" <<'PY' |
| 19 | import json,sys,time |
| 20 | path,oid,status=sys.argv[1:4] |
| 21 | o=json.load(open(path)) |
| 22 | for h in o["history"]: |
| 23 | if h["id"]==oid: |
| 24 | h["executed"]=True; h["exec_status"]=status; h["executed_at"]=time.strftime("%Y-%m-%dT%H:%M:%S") |
| 25 | json.dump(o,open(path,"w"),indent=2) |
| 26 | PY |
| 27 | done |