2026-03-16 22:35:13 +01:00
|
|
|
#!/usr/bin/env bash
|
2026-03-21 18:49:31 +00:00
|
|
|
# vault-fire.sh — Execute an approved vault item by ID
|
2026-03-16 22:35:13 +01:00
|
|
|
#
|
2026-03-21 18:49:31 +00:00
|
|
|
# Handles two pipelines:
|
|
|
|
|
# A. Action gating (*.json): pending/ → approved/ → fired/
|
2026-03-29 12:43:18 +00:00
|
|
|
# Execution delegated to ephemeral runner container via disinto run.
|
|
|
|
|
# The runner gets vault secrets (.env.vault.enc); this script does NOT.
|
2026-03-21 18:49:31 +00:00
|
|
|
# B. Procurement (*.md): approved/ → fired/ (writes RESOURCES.md entry)
|
2026-03-16 22:35:13 +01:00
|
|
|
#
|
2026-03-21 18:49:31 +00:00
|
|
|
# If item is in pending/, moves to approved/ first.
|
|
|
|
|
# If item is already in approved/, fires directly (crash recovery).
|
|
|
|
|
#
|
|
|
|
|
# Usage: bash vault-fire.sh <item-id>
|
2026-03-16 22:35:13 +01:00
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
2026-03-26 16:20:40 +00:00
|
|
|
source "${SCRIPT_DIR}/vault-env.sh"
|
2026-03-16 22:35:13 +01:00
|
|
|
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
OPS_VAULT_DIR="${OPS_REPO_ROOT}/vault"
|
2026-03-27 14:29:22 +00:00
|
|
|
LOCKS_DIR="${DISINTO_LOG_DIR}/vault/.locks"
|
|
|
|
|
LOGFILE="${DISINTO_LOG_DIR}/vault/vault.log"
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
RESOURCES_FILE="${OPS_REPO_ROOT}/RESOURCES.md"
|
2026-03-16 22:35:13 +01:00
|
|
|
|
|
|
|
|
log() {
|
|
|
|
|
printf '[%s] vault-fire: %s\n' "$(date -u '+%Y-%m-%d %H:%M:%S UTC')" "$*" >> "$LOGFILE"
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-21 18:49:31 +00:00
|
|
|
ACTION_ID="${1:?Usage: vault-fire.sh <item-id>}"
|
2026-03-16 22:35:13 +01:00
|
|
|
|
2026-03-21 18:49:31 +00:00
|
|
|
# =============================================================================
|
|
|
|
|
# Detect pipeline: procurement (.md) or action gating (.json)
|
|
|
|
|
# =============================================================================
|
|
|
|
|
IS_PROCUREMENT=false
|
2026-03-16 22:35:13 +01:00
|
|
|
ACTION_FILE=""
|
2026-03-21 18:49:31 +00:00
|
|
|
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
if [ -f "${OPS_VAULT_DIR}/approved/${ACTION_ID}.md" ]; then
|
2026-03-21 18:49:31 +00:00
|
|
|
IS_PROCUREMENT=true
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
ACTION_FILE="${OPS_VAULT_DIR}/approved/${ACTION_ID}.md"
|
|
|
|
|
elif [ -f "${OPS_VAULT_DIR}/pending/${ACTION_ID}.md" ]; then
|
2026-03-21 18:49:31 +00:00
|
|
|
IS_PROCUREMENT=true
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
mv "${OPS_VAULT_DIR}/pending/${ACTION_ID}.md" "${OPS_VAULT_DIR}/approved/${ACTION_ID}.md"
|
|
|
|
|
ACTION_FILE="${OPS_VAULT_DIR}/approved/${ACTION_ID}.md"
|
2026-03-21 18:49:31 +00:00
|
|
|
log "$ACTION_ID: pending → approved (procurement)"
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
elif [ -f "${OPS_VAULT_DIR}/approved/${ACTION_ID}.json" ]; then
|
|
|
|
|
ACTION_FILE="${OPS_VAULT_DIR}/approved/${ACTION_ID}.json"
|
|
|
|
|
elif [ -f "${OPS_VAULT_DIR}/pending/${ACTION_ID}.json" ]; then
|
|
|
|
|
mv "${OPS_VAULT_DIR}/pending/${ACTION_ID}.json" "${OPS_VAULT_DIR}/approved/${ACTION_ID}.json"
|
|
|
|
|
ACTION_FILE="${OPS_VAULT_DIR}/approved/${ACTION_ID}.json"
|
2026-03-16 22:35:13 +01:00
|
|
|
TMP=$(mktemp)
|
|
|
|
|
jq '.status = "approved"' "$ACTION_FILE" > "$TMP" && mv "$TMP" "$ACTION_FILE"
|
|
|
|
|
log "$ACTION_ID: pending → approved"
|
|
|
|
|
else
|
2026-03-21 18:49:31 +00:00
|
|
|
log "ERROR: item $ACTION_ID not found in pending/ or approved/"
|
2026-03-16 22:35:13 +01:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Acquire lock
|
|
|
|
|
mkdir -p "$LOCKS_DIR"
|
|
|
|
|
LOCKFILE="${LOCKS_DIR}/${ACTION_ID}.lock"
|
|
|
|
|
if [ -f "$LOCKFILE" ]; then
|
|
|
|
|
LOCK_PID=$(cat "$LOCKFILE" 2>/dev/null || true)
|
|
|
|
|
if [ -n "$LOCK_PID" ] && kill -0 "$LOCK_PID" 2>/dev/null; then
|
|
|
|
|
log "$ACTION_ID: already being fired by PID $LOCK_PID"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
echo $$ > "$LOCKFILE"
|
|
|
|
|
trap 'rm -f "$LOCKFILE"' EXIT
|
|
|
|
|
|
2026-03-21 18:49:31 +00:00
|
|
|
# =============================================================================
|
|
|
|
|
# Pipeline A: Procurement — extract RESOURCES.md entry and append
|
|
|
|
|
# =============================================================================
|
|
|
|
|
if [ "$IS_PROCUREMENT" = true ]; then
|
|
|
|
|
log "$ACTION_ID: firing procurement request"
|
|
|
|
|
|
|
|
|
|
# Extract the proposed RESOURCES.md entry from the markdown file.
|
2026-03-21 19:22:02 +00:00
|
|
|
# Everything after the "## Proposed RESOURCES.md Entry" heading to EOF.
|
|
|
|
|
# Uses awk because the entry itself contains ## headings (## <resource-id>).
|
2026-03-21 18:49:31 +00:00
|
|
|
ENTRY=""
|
2026-03-21 19:22:02 +00:00
|
|
|
ENTRY=$(awk '/^## Proposed RESOURCES\.md Entry/{found=1; next} found{print}' "$ACTION_FILE" 2>/dev/null || true)
|
2026-03-21 18:49:31 +00:00
|
|
|
|
|
|
|
|
# Strip leading/trailing blank lines and markdown code fences
|
|
|
|
|
ENTRY=$(echo "$ENTRY" | sed '/^```/d' | sed -e '/./,$!d' -e :a -e '/^\n*$/{$d;N;ba;}')
|
|
|
|
|
|
|
|
|
|
if [ -z "$ENTRY" ]; then
|
|
|
|
|
log "ERROR: $ACTION_ID has no '## Proposed RESOURCES.md Entry' section"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Append entry to RESOURCES.md
|
|
|
|
|
printf '\n%s\n' "$ENTRY" >> "$RESOURCES_FILE"
|
|
|
|
|
log "$ACTION_ID: wrote RESOURCES.md entry"
|
|
|
|
|
|
|
|
|
|
# Move to fired/
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
mv "$ACTION_FILE" "${OPS_VAULT_DIR}/fired/${ACTION_ID}.md"
|
2026-03-21 18:49:31 +00:00
|
|
|
rm -f "${LOCKS_DIR}/${ACTION_ID}.notified"
|
|
|
|
|
log "$ACTION_ID: approved → fired (procurement)"
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# =============================================================================
|
2026-03-29 12:43:18 +00:00
|
|
|
# Pipeline B: Action gating — delegate to ephemeral runner container
|
2026-03-21 18:49:31 +00:00
|
|
|
# =============================================================================
|
2026-03-16 22:35:13 +01:00
|
|
|
ACTION_TYPE=$(jq -r '.type // ""' < "$ACTION_FILE")
|
|
|
|
|
ACTION_SOURCE=$(jq -r '.source // ""' < "$ACTION_FILE")
|
|
|
|
|
|
|
|
|
|
if [ -z "$ACTION_TYPE" ]; then
|
|
|
|
|
log "ERROR: $ACTION_ID has no type field"
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2026-03-29 12:43:18 +00:00
|
|
|
log "$ACTION_ID: firing type=$ACTION_TYPE source=$ACTION_SOURCE via runner"
|
2026-03-16 22:35:13 +01:00
|
|
|
|
|
|
|
|
FIRE_EXIT=0
|
|
|
|
|
|
2026-03-29 12:43:18 +00:00
|
|
|
# Delegate execution to the ephemeral runner container.
|
|
|
|
|
# The runner gets vault secrets (.env.vault.enc) injected at runtime;
|
2026-03-26 16:41:27 +00:00
|
|
|
# this host process never sees those secrets.
|
|
|
|
|
if [ -f "${FACTORY_ROOT}/.env.vault.enc" ] && [ -f "${FACTORY_ROOT}/docker-compose.yml" ]; then
|
2026-03-29 12:43:18 +00:00
|
|
|
bash "${FACTORY_ROOT}/bin/disinto" run "$ACTION_ID" >> "$LOGFILE" 2>&1 || FIRE_EXIT=$?
|
2026-03-26 16:41:27 +00:00
|
|
|
else
|
|
|
|
|
# Fallback for bare-metal or pre-migration setups: run action handler directly
|
|
|
|
|
log "$ACTION_ID: no .env.vault.enc or docker-compose.yml — running action directly"
|
2026-03-29 12:43:18 +00:00
|
|
|
bash "${SCRIPT_DIR}/run-action.sh" "$ACTION_ID" >> "$LOGFILE" 2>&1 || FIRE_EXIT=$?
|
2026-03-26 16:41:27 +00:00
|
|
|
fi
|
2026-03-16 22:35:13 +01:00
|
|
|
|
|
|
|
|
# =============================================================================
|
|
|
|
|
# Move to fired/ or leave in approved/ on failure
|
|
|
|
|
# =============================================================================
|
|
|
|
|
if [ "$FIRE_EXIT" -eq 0 ]; then
|
|
|
|
|
# Update with fired timestamp and move to fired/
|
|
|
|
|
TMP=$(mktemp)
|
|
|
|
|
jq --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '.status = "fired" | .fired_at = $ts' "$ACTION_FILE" > "$TMP" \
|
fix: {project}-ops repo — separate operations from code (#757) (#767)
Fixes #757
## Changes
Separate operations from code into {project}-ops repo pattern. Added OPS_REPO_ROOT infrastructure (env.sh, load-project.sh, formula-session.sh with ensure_ops_repo helper). Updated all 8 agent scripts and 7 formulas to read/write vault items, journals, evidence, prerequisites, RESOURCES.md, and knowledge from the ops repo. Added setup_ops_repo() to disinto init for automatic ops repo creation and seeding. Removed migrated data from code repo (vault data dirs, planner journal/memory/prerequisites, supervisor journal/best-practices, evidence, RESOURCES.md). Updated all documentation. 55 files changed, ShellCheck clean, all 38 phase tests pass.
Co-authored-by: openhands <openhands@all-hands.dev>
Reviewed-on: https://codeberg.org/johba/disinto/pulls/767
Reviewed-by: Disinto_bot <disinto_bot@noreply.codeberg.org>
2026-03-26 19:55:12 +01:00
|
|
|
&& mv "$TMP" "${OPS_VAULT_DIR}/fired/${ACTION_ID}.json"
|
2026-03-16 22:35:13 +01:00
|
|
|
rm -f "$ACTION_FILE"
|
|
|
|
|
log "$ACTION_ID: approved → fired"
|
|
|
|
|
else
|
|
|
|
|
log "ERROR: $ACTION_ID fire failed (exit $FIRE_EXIT) — stays in approved/ for retry"
|
|
|
|
|
exit "$FIRE_EXIT"
|
|
|
|
|
fi
|