Repository navigation
feat(claude): session lineage (kind badge + spawned-by nesting) - #2
Merged
Merged
Conversation
Propose showing where a spawned (kind:bg) Claude Code session came from: add SessionInfo.Kind + ParentPID (both already observable on disk), and a UI that badges kind and prints "▸ spawned by <parent>" under the parent. Honest naming (not "subagent"): an in-process Task subagent has no sessions/<pid>.json of its own — it exists only as isSidechain:true lines inside its parent's transcript — so it can never surface as a card. Stated structurally (aitop's cards come exclusively from sessions/<pid>.json, none ever a sidechain), with no fragile transcript count. Co-Authored-By: Claude <noreply@anthropic.com>
Surface where a spawned Claude Code session came from, using signals already
on disk. Adds two honest SessionInfo fields:
- Kind ("bg" | "interactive"): verbatim from the session file's `kind` key,
previously read-and-discarded. Empty for adapters with no equivalent.
- ParentPID: the on-board session that spawned this one, resolved by a bounded
gopsutil PPID walk (maxParentWalkHops=40) to the first ancestor that is
itself a tracked session; 0 = a root / no visible parent. Never fabricated.
UI: a [bg]/[interactive] badge, a "▸ spawned by <parent>" line (only when the
parent is actually a card on the board, else an honest fallback), and children
indented under their parent in list view — at unchanged card height. --demo
gains a real root + two children so the lineage renders.
No new file I/O (kind parses an already-read field; the walk uses the same
gopsutil category as the existing daemon scan), no new dependency, no new
credential surface. In-process Task subagents (sidechains) still never surface
as cards — they have no sessions/<pid>.json of their own — documented as a
structural known gap in the adapter's ADAPTER.md.
Implements RFC 0003. Faked-Reader + faked-ppidOf tests cover kind parse,
kind-absent, walk-through-untracked-ancestor, orphan→0, self-reference, and
the hop cap. go build / go vet / go test -race all green.
Co-Authored-By: Claude <noreply@anthropic.com>
…ture
First worked record of /aitop-enhance driving a full feature end to end
through the specialized agents (audit → scout → engineer/test → re-audit →
docs). Captures the moment the honesty gate caught a fabricated statistic the
author had written into the RFC prose ("0/204 transcripts"), and how the fix
was to state the guarantee structurally instead of with a fragile count.
Links the case study from agentic-orchestration.md.
Co-Authored-By: Claude <noreply@anthropic.com>
grippado
marked this pull request as ready for review
July 10, 2026 01:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Surface where a spawned Claude Code session came from. When one session launches
others as real background processes (worktree mutirões, detached
claude -pruns), they used to land as unrelated cards. This adds honest lineage:
SessionInfo.Kind(bg/interactive): verbatim from thekindkey alreadypresent in
~/.claude/sessions/<pid>.json, previously read and discarded.SessionInfo.ParentPID: the on-board session that spawned this one, resolved bya bounded gopsutil PPID walk (cap 40 hops) to the first ancestor that is itself
a tracked session. A root or orphan stays
0. Never fabricated.[bg]/[interactive]badge, aspawned by <parent>line (only when theparent is actually a card on the board, otherwise an honest fallback), and
children indented under their parent in list view, at unchanged card height.
--demogains a real root plus two children so the lineage renders.Implements RFC 0003.
Why it stays honest
kindparses an already read field; the PPID walk uses thesame gopsutil category as the existing daemon scan. No new dependency, no new
credential surface.
no
sessions/<pid>.jsonof their own. Documented as a structural known gap inthe adapter's
ADAPTER.md, stated without any fragile transcript count.How it was built
Driven through the repo's own
/aitop-enhanceflow, with the specialized agentsin hand off: audit gate, pattern scout, adapter engineer, test engineer, UI
integrator, blocking re audit, docs scribe. The run is recorded as
Case study 0001, including the moment
the honesty gate caught a fabricated statistic written into the RFC prose itself,
and the fix that stated the guarantee structurally instead.
Tests and verification
Faked Reader plus faked ppid hook cover: kind parse, kind absent to empty, walk
through untracked ancestor to the tracked parent, orphan to
0, self referenceguard, and the hop cap (cycle run in a goroutine so a non terminating walk would
hang rather than pass).
go build,go vet, andCGO_ENABLED=1 go test -race ./...all green.
--json --democonfirms the fields serialize.Follow up (out of scope here)
The plain
--oncetext snapshot does not yet showkind/parent_pid(only theJSON snapshot and the TUI cards do). A short
/aitop-enhancecan close that paritylater.
🤖 Generated with Claude Code