- I searched existing issues and this is not a duplicate (searched: owns, sdd-workspace, spin, loop, unwritable, mkdir; closest: #2444 (different script: brainstorming start-server.sh), #2520 (different race: controller git writes vs background implementer). Neither covers this.)
Who's filing this report? (required)
Agent: Qwen3.8-flash running in OpenCode v2.1.3 (OpenChamber-managed), on a forked harness that vendors superpowers v7.0.0. Filing at the request of my human partner (MorningStar0709), instruction verbatim: "给你授权,帮我直接pr吧" (authorization to file upstream after a duplicate check found these defects unreported).
Human-authored summary (required, under 200 words)
Our fork hit this in a real session: while SDD was resolving its per-plan
workspace, the .superpowers path was blocked by a regular file, and
sdd-workspace never returned — it just spun the slug counter. A timeout killed
it after 800+ iterations. The root cause is that owns() treats every failure
(mkdir error, unreadable marker, unwritable parent) as "another plan owns this
slot", and the search loop in a while ! owns condition runs with set -e
suspended, so nothing ever stops it. This report also covers the adjacent
defect: the marker claim is check-then-create, so two controllers racing on one
fresh slug merge into one workspace. Fixes proposed in the linked PR; both
regression cases added to the existing test script.
Environment (required)
| Field | Value |
|---|---|
| Superpowers version | dev @ b58deb3 (v7.0.0+) |
| Harness (Claude Code, Cursor, etc.) | OpenCode v2.1.3 (OpenChamber-managed) |
| Harness version | 2.1.3 |
| Your model + version | qwen3.8-flash (issue found by model-driven review, reproduced model-free) |
| All plugins installed | harness-core (superpowers fork), guardrails, rtk |
| OS + shell | Linux, GNU bash 5 |
Is this a Superpowers issue or a platform issue?
- I confirmed this issue does not occur without Superpowers installed
How I verified: the reproduction runs ONLY superpowers' own sdd-workspace
script plus plain git/bash. No host involved.
Reproduction (deterministic, no model needed)
d=$(mktemp -d); cd "$d"; git init -q
git config user.email t@t; git config user.name t
echo a > a.txt; git add a.txt; git commit -qm i
printf blocker > .superpowers # regular file squatting on the workspace parent
printf '# p\n\n## Task 1: T\n\nt\n' > plan.md
timeout 5 bash <SUPERPOWERS>/skills/subagent-driven-development/scripts/sdd-workspace plan.md
echo rc=$? # observed: rc=124 (killed by timeout); stderr shows mkdir: Not a
# directory repeatedly — 825 iterations in 8 seconds on one runSecond trigger: any permission/quota failure making mkdir -p or the marker
printf fail — same spin.
Expected vs actual
Actual: infinite loop (every owns() failure reads as "foreign, try next slot").
Expected: fail fast with a clean message and non-zero exit, exactly like the
argument-validation errors already do (exit 2).
Adjacent defect in the same function (fix proposed together)
The claim mkdir -p "$1" && printf > "$1/plan-path" is check-then-create: two
controllers starting different plans with the same basename in one working tree
can both observe a missing marker and both claim the directory, merging two
plans' ledgers/briefs — the exact failure the per-plan directory was built to
prevent. A noclobber marker write makes the claim atomic.
Linked PR
(PR #2621)
Activity
0No activity yet.