From 605fc136aecb88af31fd7200ba1f2fba2b9aac9b Mon Sep 17 00:00:00 2001 From: Agent Date: Wed, 8 Apr 2026 20:15:26 +0000 Subject: [PATCH] fix: dispatcher.sh: handle direct-commit low-tier vault actions (#439) --- docker/edge/dispatcher.sh | 42 +++++++++++++++++++++++++++++++++------ lib/vault.sh | 8 +++++++- vault/vault-env.sh | 2 +- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/docker/edge/dispatcher.sh b/docker/edge/dispatcher.sh index 2041eaa..f8eda5a 100755 --- a/docker/edge/dispatcher.sh +++ b/docker/edge/dispatcher.sh @@ -303,7 +303,7 @@ is_action_completed() { # Validate a vault action TOML file # Usage: validate_action -# Sets: VAULT_ACTION_ID, VAULT_ACTION_FORMULA, VAULT_ACTION_CONTEXT, VAULT_ACTION_SECRETS +# Sets: VAULT_ACTION_ID, VAULT_ACTION_FORMULA, VAULT_ACTION_CONTEXT, VAULT_ACTION_SECRETS, VAULT_DISPATCH_MODE validate_action() { local toml_file="$1" @@ -325,6 +325,26 @@ validate_action() { return 0 } +# Extract dispatch_mode from TOML file +# Usage: get_dispatch_mode +# Returns: "direct" for direct-commit, "pr" for PR-merged, or empty if not specified +get_dispatch_mode() { + local toml_file="$1" + local toml_content dispatch_mode + + toml_content=$(cat "$toml_file") + + # Extract dispatch_mode field if present + dispatch_mode=$(echo "$toml_content" | grep -E '^dispatch_mode\s*=' | sed -E 's/^dispatch_mode\s*=\s*"(.*)"/\1/' | tr -d '\r') + + if [ -n "$dispatch_mode" ]; then + echo "$dispatch_mode" + else + # Default to "pr" for backward compatibility (PR-based workflow) + echo "pr" + fi +} + # Write result file for an action # Usage: write_result write_result() { @@ -367,11 +387,21 @@ launch_runner() { return 1 fi - # Verify admin merge - if ! verify_admin_merged "$toml_file"; then - log "ERROR: Admin merge verification failed for ${action_id}" - write_result "$action_id" 1 "Admin merge verification failed: see logs above" - return 1 + # Check dispatch mode to determine if admin verification is needed + local dispatch_mode + dispatch_mode=$(get_dispatch_mode "$toml_file") + + if [ "$dispatch_mode" = "direct" ]; then + log "Action ${action_id}: tier=${VAULT_TIER:-unknown}, dispatch_mode=${dispatch_mode} — skipping admin merge verification (direct commit)" + else + # Verify admin merge for PR-based actions + log "Action ${action_id}: tier=${VAULT_TIER:-unknown}, dispatch_mode=${dispatch_mode} — verifying admin merge" + if ! verify_admin_merged "$toml_file"; then + log "ERROR: Admin merge verification failed for ${action_id}" + write_result "$action_id" 1 "Admin merge verification failed: see logs above" + return 1 + fi + log "Action ${action_id}: admin merge verified" fi # Extract secrets from validated action diff --git a/lib/vault.sh b/lib/vault.sh index 61141f7..484fd57 100644 --- a/lib/vault.sh +++ b/lib/vault.sh @@ -173,7 +173,13 @@ vault_request() { # For low-tier actions, commit directly to ops main using FORGE_ADMIN_TOKEN if [ "$vault_tier" = "low" ]; then _vault_log "low-tier — committed directly to ops main" - _vault_commit_direct "$ops_api" "$tmp_toml" "${action_id}" + # Add dispatch_mode field to indicate direct commit (no PR) + local direct_toml + direct_toml=$(mktemp /tmp/vault-direct-XXXXXX.toml) + trap 'rm -f "$tmp_toml" "$direct_toml"' RETURN + # Prepend dispatch_mode = "direct" to the TOML + printf 'dispatch_mode = "direct"\n%s\n' "$toml_content" > "$direct_toml" + _vault_commit_direct "$ops_api" "$direct_toml" "${action_id}" return 0 fi diff --git a/vault/vault-env.sh b/vault/vault-env.sh index f6f5240..5bf6e5f 100644 --- a/vault/vault-env.sh +++ b/vault/vault-env.sh @@ -73,7 +73,7 @@ validate_vault_action() { local unknown_fields unknown_fields=$(echo "$toml_content" | grep -E '^[a-zA-Z_][a-zA-Z0-9_]*\s*=' | sed -E 's/^([a-zA-Z_][a-zA-Z0-9_]*)\s*=.*/\1/' | sort -u | while read -r field; do case "$field" in - id|formula|context|secrets|model|tools|timeout_minutes) ;; + id|formula|context|secrets|model|tools|timeout_minutes|dispatch_mode) ;; *) echo "$field" ;; esac done)