[Feature]: Multi-agent isolation protocol — process-level feature context without shared-state races
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 55/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- shell
- 領域
- documentation, tooling
調査の方向性
common.sh の get_feature_paths から始め、次に specify skill のテンプレートと既存のドキュメント構成を確認します。docs/multi-agent.md にマルチエージェントプロトコルを定義し、テンプレートのガイダンスを更新して、SPECIFY_NO_PERSIST のオプション動作を評価します。文書化されたワークフローとテンプレートが直接の feature.json 書き込みを回避し、明記された後方互換性のケースを維持できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Problem Statement
When multiple AI agents run Spec Kit pipelines concurrently within the same repository checkout (e.g., Antigravity subagents, Claude Code sub-agents, or parallel Cursor Composer tabs), they share a single .specify/feature.json file as their feature context pointer. This creates a write-write race condition:
Timeline:
t0 Agent-A: SPECIFY_FEATURE_DIRECTORY="specs/003-auth" → setup-plan.sh
→ get_feature_paths() persists "specs/003-auth" to feature.json ✓
t1 Agent-B: SPECIFY_FEATURE_DIRECTORY="specs/004-perf" → setup-tasks.sh
→ get_feature_paths() persists "specs/004-perf" to feature.json ← overwrites A's value
t2 Agent-A: (new process, no env var) → check-prerequisites.sh
→ reads feature.json → resolves "specs/004-perf" ← WRONG FEATURE
The root issue: get_feature_paths() in common.sh (L191-192) always persists SPECIFY_FEATURE_DIRECTORY back to feature.json unless the caller explicitly passes --no-persist. Since most scripts (setup-plan.sh, setup-tasks.sh) call get_feature_paths without --no-persist, every agent invocation silently overwrites the shared singleton.
Impact
- Silent cross-contamination: Agent B's plan/tasks get written into Agent A's feature directory (or vice versa) without any error signal.
- Non-reproducible failures: The behavior depends on timing — sometimes it works, sometimes it doesn't, making debugging extremely difficult.
- Blocks multi-agent orchestration: Features like
/speckit-implement-waves(#3507), which propose running phases in parallel subagents, cannot work safely without solving this shared-state problem first.
Real-world reproduction
We encountered this in TTZip (a macOS archive utility, 525+ tests, 28 design patterns) while running Antigravity subagents to parallelize a sorting-bugfix TDD suite alongside a 7z compression optimization. Both agents used SPECIFY_FEATURE_DIRECTORY correctly in their own processes, but the persist-on-read side effect in get_feature_paths caused each agent to clobber the other's feature.json entry on every script call.
Root Cause Analysis
The feature resolution chain in common.sh get_feature_paths() (L163-231) has a correct read priority:
1. SPECIFY_FEATURE_DIRECTORY env var (explicit override)
2. .specify/feature.json (persisted fallback)
3. Error (no context)
But it has an unconditional write side effect on the env-var branch (L191-192):
if [[ "$no_persist" != true ]]; then
_persist_feature_json "$repo_root" "$SPECIFY_FEATURE_DIRECTORY"
fi
The --no-persist guard (added in #3025) is a function-level parameter, not an environment-level control. Scripts that are "just resolving paths" but don't know they should pass --no-persist (like setup-plan.sh, setup-tasks.sh) trigger the persist unconditionally.
What already works
Credit to the maintainers — the infrastructure for multi-agent isolation is already in place:
| Mechanism | Status | Issue |
|---|---|---|
SPECIFY_FEATURE_DIRECTORY env var priority |
✅ Working | — |
--no-persist read-only resolution |
✅ Working | #3025 |
CURRENT_BRANCH fallback from feature dir basename |
✅ Working | #3026 |
SPECIFY_INIT_DIR for monorepo project scoping |
✅ Working | — |
| Parser fallback chain (jq → python3 → grep/sed) | ✅ Working | #3304 |
What's missing is the guidance layer: documentation, agent skill instructions, and an environment-level no-persist toggle.
Proposed Solution
1. Official multi-agent documentation (docs/multi-agent.md)
A new document covering:
- The race condition scenario (as above)
- The Multi-Agent Isolation Protocol: always inject
SPECIFY_FEATURE_DIRECTORYper-process, never rely onfeature.jsonfor read - Integration-specific examples (Antigravity subagents, Claude Code sub-agents, Cursor multi-tab, CI matrix)
- FAQ: "Do I need git worktrees?" → No, env-var isolation is sufficient for same-checkout concurrency
2. Update agent skill templates to stop instructing direct feature.json writes
Currently, the specify command template (the upstream equivalent of speckit-specify/SKILL.md) instructs agents to:
Persist the resolved path to
.specify/feature.json:{"feature_directory": "<resolved feature dir>"}
This instruction should be replaced with:
Pass the resolved feature directory to downstream commands via
SPECIFY_FEATURE_DIRECTORYenvironment variable prefix. Example:SPECIFY_FEATURE_DIRECTORY="specs/003-auth" .specify/scripts/bash/setup-plan.sh --json
The feature.json persistence should remain as an automatic side effect of get_feature_paths() for single-agent backward compatibility, but agents should not be told to write it directly (which bypasses the script's own idempotency guards in _persist_feature_json).
3. (Optional) SPECIFY_NO_PERSIST environment variable
Add an environment-level equivalent of the --no-persist function parameter:
# In get_feature_paths(), after the --no-persist argument check (L167-171):
if [[ "${SPECIFY_NO_PERSIST:-}" == "1" || "${SPECIFY_NO_PERSIST:-}" == "true" ]]; then
no_persist=true
fi
This allows CI pipelines and agent orchestrators to set SPECIFY_NO_PERSIST=1 globally, ensuring that no script invocation can accidentally write feature.json — even scripts that don't pass --no-persist internally.
Backward Compatibility
This proposal is fully backward compatible:
| Scenario | Before | After |
|---|---|---|
| Single agent, no env var | Reads feature.json |
Identical behavior |
| Single agent, with env var | Reads env var, persists to feature.json |
Identical behavior |
| Multi-agent, each sets env var | Race on feature.json (bug) |
Each agent's reads are short-circuited by env var; persistence is harmless |
Multi-agent + SPECIFY_NO_PERSIST=1 |
N/A | No feature.json writes at all |
specify integration upgrade |
Overwrites managed files | docs/multi-agent.md is not in manifest; protocol rules live in user-space |
No existing scripts, templates, or workflows change behavior. The persist side effect is still there (it's a "last writer wins" overwrite that's harmless when every reader uses env vars). SPECIFY_NO_PERSIST is strictly additive.
Reference Implementation
We've been running this protocol in production at TTZip with Antigravity (Google DeepMind's agentic coding tool) subagents. Our implementation consists of:
- Project-level rule file (
.agents/rules/speckit-multiagent.md): Instructs all agents to injectSPECIFY_FEATURE_DIRECTORYper-process and never read/writefeature.jsondirectly. - Global user rule: Gates (hard state machine gating) that prevent any agent from writing production code before spec/plan/tasks artifacts exist under the declared feature directory.
- Concurrent verification: Validated that two agents operating on
specs/003-sorting-fix/andspecs/006-7z-conquest/simultaneously produce zero cross-contamination.
The protocol adds zero overhead to single-agent workflows and requires no upstream code changes to function — it's purely a documentation and guidance contribution. The optional SPECIFY_NO_PERSIST env var is a small, additive improvement to common.sh.
Related Issues
- #3507 —
/speckit-implement-waves: Needs this isolation protocol as a prerequisite for safe parallel phase execution - #1476 — Git worktree isolation: Our approach is complementary (env-var isolation within a single checkout vs. filesystem isolation across worktrees)
- #3025 —
--no-persistfor read-only resolution: Foundation we build on - #3026 —
CURRENT_BRANCHfallback: Foundation we build on - #752 — Claude Code subagent feature execution: Would benefit from this protocol
Component
Core scripts (common.sh), Documentation, Agent skill templates
- 主要言語
- Python
- スター
- 138k
- フォーク
- 12.4k
- 平均マージ
- 3日 6時間
- マージ済み PR(30日)
- 136
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
github/spec-kit のほかの issue
-
triage-can-wait
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
enhancement needs-triage triage-can-wait
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
-
bundle-submission needs-info triage-can-wait validation-failed
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
author-awaiting enhancement needs-triage preset-submission triage-can-wait validation-failed
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
-
author-awaiting enhancement extension-submission needs-triage triage-can-wait validation-failed
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
github/spec-kit の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
use-agent-os/agent-os#3314 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
BasedHardware/omi#15662 · コメント 1 件 ·
-
documentation help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
AiursoftWeb/AnduinOS-2#19 ·