Repository navigation
docs: record per-subagent Viche identity research (viche-7yi) - #87
Open
ihorkatkov wants to merge 1 commit into
Open
ihorkatkov wants to merge 1 commit into
ihorkatkov wants to merge 1 commit into
Conversation
Investigated whether Claude Code subagents can be first-class Viche participants with their own agent IDs. Decision: DEFERRED, not rejected. Measured: a spawned subagent returns the parent session's agent ID and acts on the network as the host. Identity is a module-level singleton per MCP process (channel/claude-code-plugin-viche/service.ts:68), minted fresh per registration, stored nowhere durable. The server already supports N self-expiring identities per host. The blockers are the plugin singleton, the absence of a caller discriminator in MCP, and pipe-scoped inbound channel delivery -- the last being a Claude Code limit, not a Viche one. Achievable today: own identity + own outbox, inbox relayed through the orchestrator. Also flags 2026-03-24-agent-lifecycle.md as partially superseded: self-expiry now exists (agent_server.ex polling_timeout_ms / grace_period_ms) and agent IDs are UUIDs, not 8-char hex. Bumps credo 1.7.17 -> 1.7.19 in mix.lock (within the existing ~> 1.7 pin) to unblock the pre-commit hook: 1.7.17 crashed with a FunctionClauseError in Credo.Code.Token.position/1 on Phoenix ~p verified-route sigils. Verified pre-existing on clean main. Credo now reports no issues across 106 files. decimal and jason moved patch-level as transitive updates. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
Records the outcome of investigating whether Claude Code subagents can be first-class Viche participants with their own agent IDs. Decision: DEFERRED, not rejected. No implementation here — this is research capture plus one tooling unblock.
Findings
Measured live: a spawned Claude Code subagent calls
viche_whoamiand gets back the parent session's agent ID. Subagents inherit the viche MCP tools and act on the network as the host, indistinguishably.Identity is a module-level singleton per MCP process —
channel/claude-code-plugin-viche/service.ts:68, set once on join (:261-266), read context-free by every tool (:360,tools.ts:517-525). It is minted fresh per registration (lib/viche/agents.ex:872) and stored nowhere durable, so it is per-process, not per-host.Three blockers, ascending difficulty
CallToolRequestcarries no subagent/session id and no tool schema acceptsname/as/from, so even with N connections the server cannot tell which subagent is calling. Needs an explicit identity tool-arg, or one MCP server instance per subagent.new_messagebecomes onenotifications/claude/channel(service.ts:233-257) delivered to whoever owns the stdio pipe. One inbox, one session. This is a Claude Code limitation, not a Viche one. Solving 1+2 buys per-subagent sending but not receiving.Server side is mostly ready
No rate limit or per-caller registration cap on the registration path (
lib/viche_web/controllers/registry_controller.ex:16-102→lib/viche/agents.ex:186-193); auth is optional and never halts (lib/viche_web/plugs/api_auth.ex:33-53). Identities self-expire viapolling_timeout_msandgrace_period_msinlib/viche/agent_server.ex, withrestart: :temporary— so ephemeral subagent identities would not leak.Absent: no
parent_id/spawner linkage (lib/viche/agent.ex:11-23,lib/viche/agents/agent_record.ex:18-44), no generic metadata field, no bulk registration.registriesis a flat list — namespace, not hierarchy. A subagent fleet would appear as N unrelated peers.parent_idor metadataAchievable shape today: own identity + own outbox, inbox relayed through the orchestrator.
Changes
thoughts/research/2026-03-24-agent-lifecycle.md— flagged partially superseded. Two claims were stale: "no cleanup or deregistration logic exists" (self-expiry now exists) and 8-char hex agent ids (they are UUIDs). The lifecycle structure it documents was re-verified and still holds..beads/issues.jsonl— beadviche-7yiwith the full findings, blockers, and scope-if-picked-up.mix.lock— credo1.7.17→1.7.19, within the existing~> 1.7pin.Why the credo bump is in this PR
The pre-commit hook was already broken on
mainbefore this branch: credo 1.7.17 crashes withFunctionClauseErrorinCredo.Code.Token.position/1on Phoenix~pverified-route sigils. I verified this on a clean tree with my changes stashed. 1.7.19 fixes the parser — credo now reports no issues across 106 source files.decimalandjasonmoved patch-level as transitive updates. Nomix.exschange was needed.Happy to split this into its own PR if you'd rather keep the docs commit pure.
Verification
mix precommitpasses end to end (compile, deps check, format, credo, tests, dialyzer) — hook exit 0.mix credo --strict→ "found no issues", 69 checks on 106 files.Follow-up not in this PR
Two things surfaced from a live end-to-end channel test with another session while writing this, both worth their own beads:
<channel source="plugin:viche:viche">, but the shipped MCP instruction text (server.ts:19-32) tells agents to expect<channel source="viche">. Any agent matching the documented form literally will miss every message. Suggested fix is to correct the docs to the real shape, with a match rule that survives a marketplace rename.type=pingis not a cheap probe. It shares the delivery path withtask— the type only selects a display prefix and rides inparams.meta.type. A ping interrupts the recipient identically to a task, which the field name actively implies otherwise. A genuine no-op probe would have to be answered server-side from connection state.🤖 Generated with Claude Code