yoi/.yoi/tickets/00001KT1P0V1R/thread.md

13 KiB

Created

Created by tickets.sh create.


Decision

Clarification

The requested command is not a TUI attach/switch affordance. It should make another existing Pod known to the currently attached Pod so that the current Pod's ListPods tool can see it.

The implementation should therefore focus on Pod-authoritative visibility metadata and ListPods semantics, with the TUI : command only acting as the human-facing control path that registers that relationship.


Decision

Clarification

The requested command is not a TUI attach/switch affordance. It should initiate a Pod-authoritative peer handshake between the currently attached Pod and another existing Pod.

The intended result is broader than one-sided ListPods visibility: after a successful handshake, both Pods should be mutually visible as peers and should be able to exchange messages through an explicit peer-safe tool/method. The relationship must stay distinct from spawned-child delegation: no delegated filesystem scope, no parent/child ownership, no child completion notifications, and no child output cursor authority.

The TUI : command is the human-facing control path for initiating the handshake; the durable relationship and messaging authorization belong in Pod metadata/runtime semantics, not in TUI-local state.


Plan

Delegation intent: peer Pod handshake and messaging

Intent:

  • Investigate the existing Pod visibility/messaging implementation, then implement a TUI-initiated peer Pod handshake and peer messaging path if no design blockers are found.

Requirements:

  • Start with investigation. Map current authority boundaries for ListPods, RestorePod, SendToPod, Pod metadata, spawned-child registry, protocol methods, and TUI : command handling.
  • If there are design blockers or ambiguous authority decisions, write findings to the ticket artifacts and stop for parent decision.
  • If there are no blockers, proceed with implementation in the worktree.
  • Add a TUI : command that initiates peer handshake from the currently attached Pod to a target Pod by name.
  • Make the peer relationship Pod-authoritative, durable where appropriate, and reciprocal by default.
  • Ensure both Pods see each other in ListPods as peer/known, not spawned child.
  • Add or safely broaden messaging semantics so a Pod can message a visible peer without granting spawned-child powers.
  • Record delivered peer messages through an explainable durable path; do not silently mutate hidden context.
  • Preserve explicit boundaries: no delegated filesystem scope, parent/child ownership, completion notification authority, or child output cursor authority for peer Pods.
  • Add focused tests for protocol/runtime behavior, metadata persistence/restore, reciprocal ListPods, peer message authorization/delivery, and TUI command parsing/help where feasible.
  • Update docs/help text for the new command and peer semantics.

Invariants:

  • Do not treat peer Pods as spawned children.
  • Do not reintroduce hidden context injection; model-affecting delivered messages must go through the normal committed history/event path.
  • Do not add broad relationship graph semantics beyond the minimal peer relation.
  • Do not edit the parent workspace; work only in the delegated worktree.
  • Do not read ignored secret-like file contents.
  • Do not close the ticket, merge the branch, delete worktrees, or push.

Non-goals:

  • Arbitrary autonomous Pod-to-Pod background chatter.
  • Replacing the multi-Pod dashboard or Pod picker.
  • Delegated scope sharing between peers.
  • E2E test framework design for real spawned processes.

Escalate if:

  • Reciprocal handshake cannot be made atomic enough to avoid misleading partial state.
  • Peer messaging requires changing history semantics in a way that could violate context/history invariants.
  • Existing protocol or metadata schemas need a broad migration.
  • The TUI command cannot safely deliver the runtime method while preserving current Pod authority.
  • SendToPod broadening would confuse spawned-child and peer semantics.

Validation:

  • Before implementation: write a short investigation summary in the implementation report or a separate artifact.
  • Focused tests for touched crates.
  • ./tickets.sh doctor and git diff --check.
  • nix build .#yoi if feasible; record if skipped and why.
  • Commit the implementation in the worktree when reviewable.

Implementation report

Implementation report: peer Pod handshake command

Date: 2026-06-02

Investigation

The current boundaries are documented in artifacts/investigation-summary.md. No escalation blocker was found. The main concern identified was avoiding reuse of spawned-child state (SpawnedPodRegistry, delegated scope, output cursors, and child completion semantics) for peer communication; the implementation therefore adds separate peer metadata and a separate peer send tool.

Implemented behavior

  • Added reciprocal peer metadata to PodMetadata as peers, separate from spawned_children and reclaimed_children.
  • Added protocol Method::RegisterPeer { name } and Event::PeerRegistered { result }.
  • Added controller handling for RegisterPeer, idle/paused only, validating an existing target Pod and rejecting self-handshakes.
  • Added PodDiscovery::register_peer that persists both metadata directions and rolls back the first side on ordinary second-side write failure.
  • Extended ListPods visibility to include VisibilityReason::Peer; a successful handshake makes both Pods see each other as peer through Pod metadata.
  • Added SendToPeerPod as a distinct LLM tool. It only sends to visible live peer Pods, delivers Method::Notify with a source label, and does not use child delegation, output cursors, parent ownership, or child completion notifications.
  • Added TUI command :peer <pod-name> for idle attached Pods. Success is reported through a transient actionbar notice when the controller returns PeerRegistered.
  • Documented peer semantics in docs/design/pod-session-state.md and added prompt guidance that peer Pods are not spawned children.

Tests and validation run

  • cargo test -p protocol -p pod-store -p pod -p tui --lib
  • ./tickets.sh doctor
  • git diff --check
  • nix build .#yoi

Notes

The two-file reciprocal metadata update is not crash-transactional because the existing Pod metadata store has no multi-record transaction boundary. The implementation avoids successful replies with one-sided state for normal validation/write failures by rolling back the first write if the reciprocal write fails.


Implementation report

Implementation report: peer Pod handshake command

Date: 2026-06-02

Investigation

The current boundaries are documented in artifacts/investigation-summary.md. No escalation blocker was found. The main concern identified was avoiding reuse of spawned-child state (SpawnedPodRegistry, delegated scope, output cursors, and child completion semantics) for peer communication; the implementation therefore adds separate peer metadata and a separate peer send tool.

Implemented behavior

  • Added reciprocal peer metadata to PodMetadata as peers, separate from spawned_children and reclaimed_children.
  • Added protocol Method::RegisterPeer { name } and Event::PeerRegistered { result }.
  • Added controller handling for RegisterPeer, idle/paused only, validating an existing target Pod and rejecting self-handshakes.
  • Added PodDiscovery::register_peer that persists both metadata directions and restores the exact prior source-side peer state on ordinary second-side write failure.
  • Extended ListPods visibility to include VisibilityReason::Peer; a successful handshake makes both Pods see each other as peer through Pod metadata.
  • Added SendToPeerPod as a distinct LLM tool. It only sends to visible live peer Pods, delivers Method::Notify with a source label, and does not use child delegation, output cursors, parent ownership, or child completion notifications.
  • Added TUI command :peer <pod-name> for idle attached Pods. Success is reported through a transient actionbar notice when the controller returns PeerRegistered.
  • Documented peer semantics in docs/design/pod-session-state.md and added prompt guidance that peer Pods are not spawned children.

Reviewer blocker fixes

  • SendToPeerPod now reuses the existing one-shot Pod socket client path (connect_and_send), which drains connect-time Alert / Snapshot traffic before writing Notify and returns an error if method delivery fails.
  • Added a regression test where the target socket emits an alert and snapshot before reading the peer Notify, proving the peer send drains the prelude and still delivers the message.
  • Registration failure rollback now restores the exact prior source peer list instead of unconditionally removing source -> target; a target-side injected failure test verifies a pre-existing source relation is preserved.
  • Wording now describes :peer as metadata-level reciprocal registration rather than live target-controller consent, and documents that SendToPeerPod fails for non-live peers instead of auto-restoring them.

Tests and validation run

  • cargo test -p protocol -p pod-store -p pod -p tui --lib
  • ./tickets.sh doctor
  • git diff --check
  • nix build .#yoi

Notes

The two-file reciprocal metadata update is not crash-transactional because the existing Pod metadata store has no multi-record transaction boundary. The implementation avoids successful replies with one-sided state for normal validation/write failures by restoring the exact prior source-side peer list if the reciprocal write fails.


Review: approve

Review: peer Pod handshake command

Reviewer Pods:

  • Initial review: peer-pod-handshake-reviewer-20260602
  • Re-review: peer-pod-handshake-rereviewer-20260602

Result

Approved after fixes. No remaining blockers.

Initial blocker findings

The first reviewer found two blockers:

  1. SendToPeerPod wrote Method::Notify directly to the target socket without draining connect-time Alert / Snapshot traffic, so a real Pod socket could fail to process the notify while the sender reported success.
  2. Reciprocal registration rollback could delete a pre-existing source -> target peer relation when the reciprocal target -> source write failed.

Fix verification

Coder added commit 057c2ef fix: harden peer pod registration.

The re-review confirmed:

  • SendToPeerPod now uses the existing connect_and_send one-shot client path, which drains connect-time Alert / Snapshot traffic before writing Method::Notify and reports delivery failures.
  • A regression test covers a target socket that emits an alert/snapshot before reading the peer notify.
  • register_peer now snapshots the source Pod's existing peer list and restores that exact list if the target-side write fails.
  • A regression test covers an injected target-side failure where the source already had the peer relation and verifies it is preserved.

Validation evidence

Coder reported:

  • cargo test -p pod discovery --lib
  • cargo test -p tui command --lib
  • cargo test -p protocol -p pod-store -p pod -p tui --lib
  • ./tickets.sh doctor
  • git diff --check
  • nix build .#yoi

Reviewer re-ran:

  • cargo test -p pod --lib peer
  • cargo test -p pod --lib connect_and_send

Parent/orchestrator reran after merge:

  • cargo test -p pod discovery --lib
  • cargo test -p tui command --lib
  • cargo test -p protocol -p pod-store -p pod -p tui --lib
  • ./tickets.sh doctor
  • git diff --check
  • nix build .#yoi
  • ./result/bin/yoi pod --help

Residual risk

Peer registration updates two metadata files and is not crash-transactional because the current Pod metadata store has no multi-record transaction boundary. Normal write failures are handled by restoring the exact prior source peer list.

The implemented peer relationship is metadata-level reciprocal registration, not live target-process consent. This is documented and remains separate from spawned-child delegation, delegated scope, output cursors, parent ownership, and child completion notifications.


Closed

Implemented TUI-initiated peer Pod handshake and peer messaging. Peers are persisted separately from spawned children, appear in ListPods as peers, and can receive peer messages through a distinct tool/method. Reviewer blockers were fixed; focused tests and nix build passed.