Sub-Agent Family Tracking
When you spawn sub-agents, you create a family tree: you are the parent, your spawned
agents are children, and your children's spawned agents are grandchildren. If you do not
track this tree explicitly, three failure modes are common:
- Lost child — you spawn an agent, lose track of its
task_id, and never read its
result.
- Sibling duplication — two children of yours do the same work, wasting tokens.
- Lingering child — you move on to the next sub-task, leaving an old child running
in the background, burning context budget.
This Skill codifies a family-tracking file so these failures are visible, not hidden.
When to use
Activate when any of these is true:
- You are about to call
task and the result of that call is "fire and wait," not "do it
inline." (Inline calls don't need a tree.)
- You have already spawned one or more sub-agents in this session.
- The task description suggests a tree: "X has sub-tasks", "for each of A/B/C, ...",
"the migration has 5 stages, each stage can be parallelised."
- A user asks "what's your sub-agent doing right now?" and you don't have an immediate
answer.
When NOT to use
- The sub-task is so cheap you would just inline it. (No sub-agent → no tree.)
- The harness already exposes a live dashboard of running sub-agents. (Use that instead.)
- You are the child, not the parent. Children don't track siblings; they only see their
own parent.
Process
Pick a single, predictable path. Default (illustrative; actual
on-disk path is host-internal):
<host-agents-root>/<thread-id>/subagents.md. The mcode 0.2.4 public
surface does not document a family-file path. The Skills below use
<host-agents-root> as a conceptual placeholder; the host determines
the actual root. Different from the goal file (which is "what we
are doing") and the world-state file (which is "where we are"); this is "who is
working for us."
Initialise the file on the first spawn in this exact shape:
# Sub-agent family — <short task name>
**Parent (you)**: <thread-id>
**Last updated**: <ISO timestamp>
## Children
| id | spawned_at | brief | status | result_summary |
|----|------------|-------|--------|----------------|
| <task_id> | <ISO> | <one-line brief> | open | (pending) |
On every spawn, add a row with status: open and a one-line brief.
On every sub-agent completion, update the row:
status: closed (or closed-failed if it didn't meet its pass condition)
result_summary: <one line>
If a sub-agent spawns its own children, append a sub-section for that child:
| <task_id> | <ISO> | <one-line brief> | open | (pending) |
## Children of <task_id>
| grandchild-id | spawned_at | brief | status | result_summary |
|---------------|------------|-------|--------|----------------|
At every context-pressure-compact, the compact summary must reference the family
file by path, not duplicate it. The file is the ground truth.
At the end of a fan-out aggregation (see parallel-fanout), include a one-line
"all children closed" check. If any are still open, surface that to the user — the
aggregation is not safe to declare done while children are running.
Output contract
The user sees:
- The family file's contents (full) at the start of any multi-agent task.
- A one-line status update per spawn / completion (e.g. "spawned task-7a3f for OIDC review,"
"task-7a3f closed with PASS").
- A "all children closed" check at the end of any fan-out.
Example
The path to the family file in the example below is illustrative; the
actual on-disk path is host-internal. The thread-7c2b value is a
placeholder for the calling session's thread id (on mcode 0.2.4 the
relevant lifecycle identifier for a sub-agent is the task_id
returned by task(...)). The file shape is what the calling agent
maintains in its own bookkeeping.
# Sub-agent family — Auth refactor (OIDC alongside SAML)
**Parent (you)**: thread-7c2b *(placeholder for the calling session's thread id)*
**Last updated**: 2026-08-23T23:55:00Z
## Children
| id | spawned_at | brief | status | result_summary |
|----|------------|-------|--------|----------------|
| task-3f1a | 23:40:00Z | Audit /repo/server/Cargo.toml for CVEs | closed | No critical CVEs; 2 moderate, listed in SECURITY-REPORT.md |
| task-4d2b | 23:40:00Z | Audit /repo/web/package.json for CVEs | closed | 1 critical CVE (CVE-2024-xxxx); surfaced immediately, did not wait for others |
| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | open | (pending) |
After task-5e3c finishes:
| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | closed | 47 deps; 1 AGPL, 4 Apache-2.0, rest MIT — full table in SECURITY-REPORT.md |
If task-5e3c spawned a grandchild (e.g. for cross-checking an ambiguous license):
| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | closed | 47 deps; 1 AGPL, 4 Apache-2.0, rest MIT |
## Children of task-5e3c
| task-5e3c-1 | 23:42:00Z | Cross-check `foo-1.0.0` license classification | closed | Confirmed AGPL-3.0 via SPDX registry |
Common pitfalls
- Do not skip the file "because it's only one sub-agent." You will spawn another
before you know it, and then you will not know which results came from which.
- Do not put full sub-agent output in the table. The table is the index. The full
output lives in the sub-agent's own response (or a file it wrote). The table points to it.
- Do not let the file grow unbounded. A 500-line family file is no longer a tracking
file. If it grows past ~80 lines, summarise closed children into a "Completed
(summary)" section.
- Do not confuse "open" with "running". A sub-agent can be
open and waiting on user
input, or open and silently failed. "Closed" means the result was received and
processed, not that the work succeeded.
- Do not declare fan-out done while children are still open. A
parallel-fanout aggregation
must wait for all children to close. The check is mechanical, not visual.
- Do not let a child spawn grand-children without recording it. If you do not capture
the grandchild relationship, you cannot tell which child is responsible for which
grandchild's result.
Verification checklist
1---2name: subagent-family-tracking3description: Track parent/child thread tree of spawned sub-agents with Open/Closed status. USE WHEN: spawned one or more sub-agents, task description suggests a tree (sub-tasks, "for each of A/B/C", "5 stages"), user asks "what's your sub-agent doing right now" / "子 agent 都在干嘛", sub-agent may fan out, want to know "还在跑吗" / "还有几个没关", before declaring fan-out done (all children closed check). TRIGGER PHRASES: "子 agent 都在干嘛", "sub-agent", "子任务", "family tree", "who is running", "还在跑吗", "还有几个没关", "what's your sub-agent doing", "subagent family", "subagent tree", "all children closed". SKIP WHEN: sub-task is so cheap you'd just inline it, harness already exposes live sub-agent dashboard, you are the child not the parent.4license: Apache-2.05---67# Sub-Agent Family Tracking89When you spawn sub-agents, you create a **family tree**: you are the parent, your spawned10agents are children, and your children's spawned agents are grandchildren. If you do not11track this tree explicitly, three failure modes are common:12131. **Lost child** — you spawn an agent, lose track of its `task_id`, and never read its14 result.152. **Sibling duplication** — two children of yours do the same work, wasting tokens.163. **Lingering child** — you move on to the next sub-task, leaving an old child running17 in the background, burning context budget.1819This Skill codifies a **family-tracking file** so these failures are visible, not hidden.2021## When to use2223Activate when **any** of these is true:2425- You are about to call `task` and the result of that call is "fire and wait," not "do it26 inline." (Inline calls don't need a tree.)27- You have already spawned one or more sub-agents in this session.28- The task description suggests a tree: "X has sub-tasks", "for each of A/B/C, ...",29 "the migration has 5 stages, each stage can be parallelised."30- A user asks "what's your sub-agent doing right now?" and you don't have an immediate31 answer.3233## When NOT to use3435- The sub-task is so cheap you would just inline it. (No sub-agent → no tree.)36- The harness already exposes a live dashboard of running sub-agents. (Use that instead.)37- You are the *child*, not the parent. Children don't track siblings; they only see their38 own parent.3940## Process41421. **Pick a single, predictable path.** **Default (illustrative; actual43 on-disk path is host-internal):**44 `<host-agents-root>/<thread-id>/subagents.md`. The mcode 0.2.4 public45 surface does not document a family-file path. The Skills below use46 `<host-agents-root>` as a conceptual placeholder; the host determines47 the actual root. Different from the goal file (which is "what we48 are doing") and the world-state file (which is "where we are"); this is "who is49 working for us."502. **Initialise the file on the first spawn** in this exact shape:5152 ```markdown53 # Sub-agent family — <short task name>5455 **Parent (you)**: <thread-id>56 **Last updated**: <ISO timestamp>5758 ## Children5960 | id | spawned_at | brief | status | result_summary |61 |----|------------|-------|--------|----------------|62 | <task_id> | <ISO> | <one-line brief> | open | (pending) |63 ```64653. **On every spawn**, add a row with `status: open` and a one-line brief.664. **On every sub-agent completion**, update the row:67 - `status: closed` (or `closed-failed` if it didn't meet its pass condition)68 - `result_summary: <one line>`695. **If a sub-agent spawns its own children**, append a sub-section for that child:7071 ```markdown72 | <task_id> | <ISO> | <one-line brief> | open | (pending) |73 ## Children of <task_id>74 | grandchild-id | spawned_at | brief | status | result_summary |75 |---------------|------------|-------|--------|----------------|76 ```77786. **At every `context-pressure-compact`**, the compact summary must reference the family79 file by path, not duplicate it. The file is the ground truth.807. **At the end of a fan-out aggregation** (see `parallel-fanout`), include a one-line81 "all children closed" check. If any are still `open`, surface that to the user — the82 aggregation is not safe to declare done while children are running.8384## Output contract8586The user sees:8788- The family file's contents (full) at the start of any multi-agent task.89- A one-line status update per spawn / completion (e.g. "spawned task-7a3f for OIDC review,"90 "task-7a3f closed with PASS").91- A "all children closed" check at the end of any fan-out.9293## Example9495> The path to the family file in the example below is illustrative; the96> actual on-disk path is host-internal. The `thread-7c2b` value is a97> placeholder for the calling session's thread id (on mcode 0.2.4 the98> relevant lifecycle identifier for a sub-agent is the `task_id`99> returned by `task(...)`). The file shape is what the calling agent100> maintains in its own bookkeeping.101102```markdown103# Sub-agent family — Auth refactor (OIDC alongside SAML)104105**Parent (you)**: thread-7c2b *(placeholder for the calling session's thread id)*106**Last updated**: 2026-08-23T23:55:00Z107108## Children109110| id | spawned_at | brief | status | result_summary |111|----|------------|-------|--------|----------------|112| task-3f1a | 23:40:00Z | Audit /repo/server/Cargo.toml for CVEs | closed | No critical CVEs; 2 moderate, listed in SECURITY-REPORT.md |113| task-4d2b | 23:40:00Z | Audit /repo/web/package.json for CVEs | closed | 1 critical CVE (CVE-2024-xxxx); surfaced immediately, did not wait for others |114| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | open | (pending) |115```116117After task-5e3c finishes:118119```markdown120| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | closed | 47 deps; 1 AGPL, 4 Apache-2.0, rest MIT — full table in SECURITY-REPORT.md |121```122123If task-5e3c spawned a grandchild (e.g. for cross-checking an ambiguous license):124125```markdown126| task-5e3c | 23:40:00Z | List licenses of /repo/server and /repo/web direct deps | closed | 47 deps; 1 AGPL, 4 Apache-2.0, rest MIT |127 ## Children of task-5e3c128 | task-5e3c-1 | 23:42:00Z | Cross-check `foo-1.0.0` license classification | closed | Confirmed AGPL-3.0 via SPDX registry |129```130131## Common pitfalls132133- **Do not skip the file "because it's only one sub-agent."** You will spawn another134 before you know it, and then you will not know which results came from which.135- **Do not put full sub-agent output in the table.** The table is the index. The full136 output lives in the sub-agent's own response (or a file it wrote). The table points to it.137- **Do not let the file grow unbounded.** A 500-line family file is no longer a tracking138 file. If it grows past ~80 lines, summarise closed children into a "Completed139 (summary)" section.140- **Do not confuse "open" with "running".** A sub-agent can be `open` and waiting on user141 input, or `open` and silently failed. "Closed" means the result was received and142 processed, not that the work succeeded.143- **Do not declare fan-out done while children are still open.** A `parallel-fanout` aggregation144 must wait for *all* children to close. The check is mechanical, not visual.145- **Do not let a child spawn grand-children without recording it.** If you do not capture146 the grandchild relationship, you cannot tell which child is responsible for which147 grandchild's result.148149## Verification checklist150151- [ ] Is the family file at a single, predictable path?152- [ ] Is it initialised with the full table shape on the first spawn?153- [ ] Does every spawn add a row with `status: open`?154- [ ] Does every completion update the row to `status: closed`?155- [ ] Are grand-children recorded in a sub-section under their parent?156- [ ] Is the file < ~80 lines? (Summarise old entries if not.)157- [ ] At every `context-pressure-compact`, is the file referenced by path (not158 duplicated)?159- [ ] At the end of any fan-out, is the "all children closed" check explicit?