fix: bug: dispatcher runner invokes formulas as bash scripts but formulas are TOML (#516)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e70da015db
commit
77de5ef4c5
7 changed files with 327 additions and 38 deletions
|
|
@ -408,17 +408,10 @@ launch_runner() {
|
|||
local secrets_array
|
||||
secrets_array="${VAULT_ACTION_SECRETS:-}"
|
||||
|
||||
# Build command array (safe from shell injection)
|
||||
local -a cmd=(docker run --rm
|
||||
--name "vault-runner-${action_id}"
|
||||
--network disinto_disinto-net
|
||||
-e "FORGE_URL=${FORGE_URL}"
|
||||
-e "FORGE_TOKEN=${FORGE_TOKEN}"
|
||||
-e "FORGE_REPO=${FORGE_REPO}"
|
||||
-e "FORGE_OPS_REPO=${FORGE_OPS_REPO}"
|
||||
-e "PRIMARY_BRANCH=${PRIMARY_BRANCH}"
|
||||
-e DISINTO_CONTAINER=1
|
||||
)
|
||||
# Build docker compose run command (delegates to compose runner service)
|
||||
# The runner service definition handles image, network, volumes, and base env.
|
||||
# The dispatcher only adds declared secrets and the ops repo mount.
|
||||
local -a cmd=(docker compose run --rm)
|
||||
|
||||
# Add environment variables for secrets (if any declared)
|
||||
if [ -n "$secrets_array" ]; then
|
||||
|
|
@ -438,27 +431,13 @@ launch_runner() {
|
|||
log "Action ${action_id} has no secrets declared — runner will execute without extra env vars"
|
||||
fi
|
||||
|
||||
# Add formula and action id as arguments (safe from shell injection)
|
||||
local formula="${VAULT_ACTION_FORMULA:-}"
|
||||
cmd+=(disinto-agents:latest bash -c
|
||||
"cd /home/agent/disinto && bash formulas/${formula}.sh ${action_id}")
|
||||
# Mount the ops repo so the runner entrypoint can read the action TOML
|
||||
cmd+=(-v "${OPS_REPO_ROOT}:/home/agent/ops:ro")
|
||||
|
||||
# Log command skeleton (hide all -e flags for security)
|
||||
local -a log_cmd=()
|
||||
local skip_next=0
|
||||
for arg in "${cmd[@]}"; do
|
||||
if [[ $skip_next -eq 1 ]]; then
|
||||
skip_next=0
|
||||
continue
|
||||
fi
|
||||
if [[ "$arg" == "-e" ]]; then
|
||||
log_cmd+=("$arg" "<redacted>")
|
||||
skip_next=1
|
||||
else
|
||||
log_cmd+=("$arg")
|
||||
fi
|
||||
done
|
||||
log "Running: ${log_cmd[*]}"
|
||||
# Service name and action-id argument
|
||||
cmd+=(runner "$action_id")
|
||||
|
||||
log "Running: docker compose run --rm runner ${action_id} (secrets: ${secrets_array:-none})"
|
||||
|
||||
# Create temp file for logs
|
||||
local log_file
|
||||
|
|
|
|||
103
docker/runner/entrypoint-runner.sh
Normal file
103
docker/runner/entrypoint-runner.sh
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/env bash
|
||||
# entrypoint-runner.sh — Vault runner entrypoint
|
||||
#
|
||||
# Receives an action-id, reads the vault action TOML to get the formula name,
|
||||
# then dispatches to the appropriate executor:
|
||||
# - formulas/<name>.sh → bash (mechanical operations like release)
|
||||
# - formulas/<name>.toml → claude -p (reasoning tasks like triage, architect)
|
||||
#
|
||||
# Usage: entrypoint-runner.sh <action-id>
|
||||
#
|
||||
# Expects:
|
||||
# OPS_REPO_ROOT — path to the ops repo (mounted by compose)
|
||||
# FACTORY_ROOT — path to disinto code (default: /home/agent/disinto)
|
||||
#
|
||||
# Part of #516.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
FACTORY_ROOT="${FACTORY_ROOT:-/home/agent/disinto}"
|
||||
OPS_REPO_ROOT="${OPS_REPO_ROOT:-/home/agent/ops}"
|
||||
|
||||
log() {
|
||||
printf '[%s] runner: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*"
|
||||
}
|
||||
|
||||
# ── Argument parsing ─────────────────────────────────────────────────────
|
||||
|
||||
action_id="${1:-}"
|
||||
if [ -z "$action_id" ]; then
|
||||
log "ERROR: action-id argument required"
|
||||
echo "Usage: entrypoint-runner.sh <action-id>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Read vault action TOML ───────────────────────────────────────────────
|
||||
|
||||
action_toml="${OPS_REPO_ROOT}/vault/actions/${action_id}.toml"
|
||||
if [ ! -f "$action_toml" ]; then
|
||||
log "ERROR: vault action TOML not found: ${action_toml}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract formula name from TOML
|
||||
formula=$(grep -E '^formula\s*=' "$action_toml" \
|
||||
| sed -E 's/^formula\s*=\s*"(.*)"/\1/' | tr -d '\r')
|
||||
|
||||
if [ -z "$formula" ]; then
|
||||
log "ERROR: no 'formula' field found in ${action_toml}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract context for logging
|
||||
context=$(grep -E '^context\s*=' "$action_toml" \
|
||||
| sed -E 's/^context\s*=\s*"(.*)"/\1/' | tr -d '\r')
|
||||
|
||||
log "Action: ${action_id}, formula: ${formula}, context: ${context:-<none>}"
|
||||
|
||||
# ── Dispatch: .sh (mechanical) vs .toml (Claude reasoning) ──────────────
|
||||
|
||||
formula_sh="${FACTORY_ROOT}/formulas/${formula}.sh"
|
||||
formula_toml="${FACTORY_ROOT}/formulas/${formula}.toml"
|
||||
|
||||
if [ -f "$formula_sh" ]; then
|
||||
# Mechanical operation — run directly
|
||||
log "Dispatching to shell script: ${formula_sh}"
|
||||
exec bash "$formula_sh" "$action_id"
|
||||
|
||||
elif [ -f "$formula_toml" ]; then
|
||||
# Reasoning task — launch Claude with the formula as prompt
|
||||
log "Dispatching to Claude with formula: ${formula_toml}"
|
||||
|
||||
formula_content=$(cat "$formula_toml")
|
||||
action_context=$(cat "$action_toml")
|
||||
|
||||
prompt="You are a vault runner executing a formula-based operational task.
|
||||
|
||||
## Vault action
|
||||
\`\`\`toml
|
||||
${action_context}
|
||||
\`\`\`
|
||||
|
||||
## Formula
|
||||
\`\`\`toml
|
||||
${formula_content}
|
||||
\`\`\`
|
||||
|
||||
## Instructions
|
||||
Execute the steps defined in the formula above. The vault action context provides
|
||||
the specific parameters for this run. Execute each step in order, verifying
|
||||
success before proceeding to the next.
|
||||
|
||||
FACTORY_ROOT=${FACTORY_ROOT}
|
||||
OPS_REPO_ROOT=${OPS_REPO_ROOT}
|
||||
"
|
||||
|
||||
exec claude -p "$prompt" \
|
||||
--dangerously-skip-permissions \
|
||||
${CLAUDE_MODEL:+--model "$CLAUDE_MODEL"}
|
||||
|
||||
else
|
||||
log "ERROR: no formula found for '${formula}' — checked ${formula_sh} and ${formula_toml}"
|
||||
exit 1
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue