Canonical contract for
.claude/.idd/state/chain-spawned-issues.json— the cross-skill manifest written by 4 spawning sub-skills and consumed by/idd-all-chain.
Source: add-idd-all-chain-skill Spectra change (capability idd-spawn-manifest).
<repo-root>/.claude/.idd/state/chain-spawned-issues.json
The file lives inside the target repo's git tree under the .claude/.idd/state/ namespace (per IDD v2.35.0+ namespace migration). The directory is created by /idd-all-chain Phase 0 (chain shell initialization). Sub-skills MUST NOT create the directory — if it doesn't exist, sub-skills are NOT in chain context and skip manifest writes.
{
"schema_version": 2,
"session_id": "<uuid v4>",
"root_issues": [<integer>, ...],
"traversal": "dfs" | "bfs",
"spawned": [
{
"issue_number": <integer>,
"spawned_by": "<sub-skill name>",
"spawn_step": "<step identifier>",
"spawn_kind": "<enum>",
"same_file_as_root": <boolean>,
"same_skill_as_root": <boolean>,
"root_id": <integer>,
"filed_at": "<ISO-8601 UTC>",
"title": "<string>"
}
]
}| Field | Type | Description |
|---|---|---|
schema_version |
integer | Always 2 for the v2 contract. Future schema breaking changes increment this. Sub-skills MUST refuse to write when this doesn't match the version they were built against (EXPECTED_SCHEMA_VERSION=2 in the v2 cohort). |
session_id |
UUID v4 string | Generated by chain shell at file initialization. Sub-skills MUST NOT modify this field after initialization. Used for audit / log correlation. |
root_issues |
array of integer (>0) | Non-empty array of issue numbers passed to /idd-all-chain. For N=1 single-root invocations this is a single-element array. Ordering matches the positional order of #NNN tokens at invocation. |
traversal |
string enum | One of "dfs" (default when --bfs flag absent) or "bfs" (when --bfs flag present). Determines whether new spawns are pushed to queue front (DFS) or back (BFS). |
spawned |
array | Append-only list of spawn entries. Initially empty. |
| Field | Type | Required | Description |
|---|---|---|---|
issue_number |
integer (>0) | yes | GitHub issue number of the spawned issue. |
spawned_by |
enum string | yes | One of: "idd-implement", "idd-verify", "idd-plan", "idd-diagnose". |
spawn_step |
string | yes | Human-readable step identifier matching the sub-skill's spawn step. Examples: "Step 5.7 sister bug sweep", "Phase 4 follow-up findings triage", "Step 2.5 tangential observations", "Step 3.6 sister concern surfacing". |
spawn_kind |
enum string | yes | One of: "sister-bug" / "follow-up-finding" / "tangential" / "sister-concern" / "upstream-tracking". Determines chain eligibility. |
same_file_as_root |
boolean | yes | True only if the spawn references the same source files as the specific root this spawn descends from (not any root in the chain). |
same_skill_as_root |
boolean | yes | True only if the spawn references the same skill / module as the specific root this spawn descends from. |
root_id |
integer (>0) | yes | The issue number of the root that owns this spawn's subtree. MUST be one of the values in the top-level root_issues array. For top-level root issues themselves (depth 0), root_id equals the issue's own number. New in v2 (multi-root traversal support). |
filed_at |
ISO-8601 string | yes | UTC timestamp of gh issue create completion. Format: 2026-05-08T03:14:22Z. |
title |
string | yes | Spawned issue title (raw, no formatting). |
| Kind | Sub-skill source | Chain-eligible default |
|---|---|---|
sister-bug |
idd-implement Step 5.7 |
YES (forced eligible by heuristic) |
follow-up-finding |
idd-verify Phase 4 |
depends on same_file / same_skill |
tangential |
idd-plan Step 2.5 |
depends on same_file / same_skill |
sister-concern |
idd-diagnose Step 3.6 |
depends on same_file / same_skill |
upstream-tracking |
idd-diagnose Step 3.6 (cross-cutting variant) |
NO (always cross-cutting by definition) |
chain_eligible(spawned, root) =
spawned.same_file_as_root == true
OR spawned.same_skill_as_root == true
OR spawned.spawn_kind == "sister-bug"
Spawned issues failing eligibility ARE still filed (sub-skill audit trail unchanged) but NOT added to the chain queue.
Sub-skills MUST update the manifest using the read-modify-write pattern via atomic file replacement:
- Acquire (or skip — single-process, sequential within chain context)
- Read current manifest content
- Validate
schema_versionmatches expected (v1) - Parse JSON, append entry to
spawnedarray - Write updated content to a temp file in the same directory (e.g.
chain-spawned-issues.json.tmp.<pid>) - Atomically rename the temp file over the original (
mv/os.rename)
Sub-skills MUST NOT use direct in-place writes (> redirection or simple file overwrites) that risk truncation on interrupt.
Sub-skills detect chain context with this rule:
MANIFEST="$REPO_ROOT/.claude/.idd/state/chain-spawned-issues.json"
if [ -f "$MANIFEST" ]; then
# Verify schema version (v2 cohort)
schema=$(jq -r '.schema_version // empty' "$MANIFEST")
if [ "$schema" = "2" ]; then
# Chain context active — write manifest entry alongside existing audit trail
IN_CHAIN=true
fi
fiWhen chain context is NOT detected, sub-skills behave identically to baseline (existing audit trail, no manifest interaction).
The manifest is additive — sub-skill audit trails (Sister Bugs Filed / Tangential Observations / Sister Concerns Filed / Closing Follow-ups Filed) remain unchanged. Manifest entries are a supplement for machine consumption by chain shell, not a replacement.
After a multi-root chain run with roots #28 + #44, DFS traversal, and 2 spawn events:
{
"schema_version": 2,
"session_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"root_issues": [28, 44],
"traversal": "dfs",
"spawned": [
{
"issue_number": 34,
"spawned_by": "idd-implement",
"spawn_step": "Step 5.7 sister bug sweep",
"spawn_kind": "sister-bug",
"same_file_as_root": false,
"same_skill_as_root": true,
"root_id": 28,
"filed_at": "2026-05-08T03:14:22Z",
"title": "refactor: 抽出 generic plugin-presence detector helper"
},
{
"issue_number": 41,
"spawned_by": "idd-verify",
"spawn_step": "Phase 4 follow-up findings triage",
"spawn_kind": "follow-up-finding",
"same_file_as_root": true,
"same_skill_as_root": true,
"root_id": 44,
"filed_at": "2026-05-08T04:21:08Z",
"title": "docs: explicit document plugin-presence trust model"
}
]
}Both entries are chain-eligible (#34 by same_skill_as_root=true, #41 by same_file_as_root=true). #34 belongs to the #28 subtree (root_id=28); #41 belongs to the #44 subtree (root_id=44).
For a single-root invocation (/idd-all-chain #28), the manifest looks identical except root_issues: [28] (single-element array) and every spawn entry's root_id equals 28. The traversal field is still present and recorded.
references/chain-flow.md— chain shell algorithm consumeridd-all-chain/SKILL.md— chain shell skillopenspec/specs/idd-spawn-manifest/spec.md— frozen spec contract (after archive)