Skip to content

archon-adversarial-dev: init-workspace 'sed -i' fails on macOS BSD sed #1103

@scriptmunkee

Description

@scriptmunkee

Summary

The init-workspace bash node in the bundled archon-adversarial-dev.yaml workflow uses GNU sed -i "..." syntax, which is incompatible with macOS BSD sed. The node "succeeds" (exits 0 because of how the heredoc is structured) but writes a state.json containing the literal string SPRINT_COUNT_PLACEHOLDER instead of the resolved sprint count, and emits this stderr:

sed: 1: "/Users/<user>/.archon/workspaces/<…>/state.json": command c expects \ followed by text

Logged as:

{"level":40,"module":"workflow.dag-executor","nodeId":"init-workspace",
 "stderr":"sed: 1: \"/Users/...\": command c expects \\ followed by text",
 "msg":"bash_node_stderr"}

The workflow continued running because downstream prompts re-derive the sprint count from spec.md rather than relying on state.json.totalSprints, but the state.json file (which the workflow conceptually owns as the state-machine source of truth) is corrupt for the rest of the run.

Root cause

.archon/workflows/defaults/archon-adversarial-dev.yaml line 104:

sed -i "s/SPRINT_COUNT_PLACEHOLDER/\$SPRINT_COUNT/" "\$ARTIFACTS/state.json"

GNU sed treats -i as "edit in place, no backup". BSD sed (macOS) treats the next argument as the backup-extension, so the actual sed program becomes "\$ARTIFACTS/state.json" and the file path is interpreted as the next sed command — hence the command c expects \\ followed by text error.

Suggested fix

The cleanest fix is to skip sed entirely. The heredoc currently uses <<'STATEEOF' (single-quoted, no expansion) just so the placeholder can be substituted afterward. Switching to an unquoted heredoc lets bash do the substitution natively:

-      # Write initial state machine file
-      cat > "\$ARTIFACTS/state.json" << 'STATEEOF'
-      {
-        "phase": "negotiating",
-        "sprint": 1,
-        "totalSprints": SPRINT_COUNT_PLACEHOLDER,
-        "retry": 0,
-        "maxRetries": 3,
-        "passThreshold": 7,
-        "completedSprints": [],
-        "status": "running"
-      }
-      STATEEOF
-      sed -i "s/SPRINT_COUNT_PLACEHOLDER/\$SPRINT_COUNT/" "\$ARTIFACTS/state.json"
+      # Write initial state machine file
+      cat > "\$ARTIFACTS/state.json" << STATEEOF
+      {
+        "phase": "negotiating",
+        "sprint": 1,
+        "totalSprints": \$SPRINT_COUNT,
+        "retry": 0,
+        "maxRetries": 3,
+        "passThreshold": 7,
+        "completedSprints": [],
+        "status": "running"
+      }
+      STATEEOF

This:

  • removes the BSD/GNU sed portability problem
  • removes one subprocess
  • removes the placeholder/replacement indirection (which is what made the bug latent — the workflow happened to keep working with a corrupted state file)

If a sed call is preferred for any reason, the portable form is perl -i -pe '...' (always available on both macOS and Linux), or write to a tmp file and mv it back.

Worth grepping .archon/workflows/defaults/ for other sed -i "..." file invocations that may have the same bug — at minimum they'd want the same heredoc-substitution refactor.

Environment

  • Archon dev branch (commit 536584db)
  • macOS 15.x (Darwin 25.3.0), arm64
  • BSD sed (macOS default)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priority - Backlog, when time permitsarea: workflowsWorkflow enginebugSomething is brokeneffort/lowSingle file or function, one responsibility, isolated change

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions