Feat/shepherd supervision - #196
Merged
Merged
Conversation
Integrates shepherd-kernel-go's effect bus, scope manager, and supervisor primitives into yaah. pipeline/trace.go: - ShepherdTraceMiddleware now holds bus and scope manager - Bus() and ScopeManager() accessors for tool integration pipeline/config.go: - shepherd_trace builder creates EffectBus and ScopeManager - Bus attached to store via WithBus for real-time events - ShepherdBusBuffer config field (default 64) tools/supervisor.go (new): - SupervisorTool with actions: list_scopes, fork, merge, discard, inject, halt - Opens trace store directly, creates scope manager per call - Registered when shepherd_trace_dir is configured cmd/yaah/wiring.go: - Register SupervisorTool when trace dir is set The supervisor tool lets the orchestrator: - List all scopes and their state - Fork a sub-agent's execution branch - Merge successful branches back - Discard failed branches - Inject guidance into a running scope - Halt a stuck sub-agent
These operations require sandbox isolation to be meaningful. Without it, fork/merge/discard are just trace bookkeeping — they don't isolate or roll back filesystem changes. The underlying code in shepherd-kernel-go still supports them for when sandboxed execution is added. Exposed actions: list_scopes, inject, halt, status
- Add tools.SharedScopeManager package-level variable - Set it from the shepherd_trace pipeline builder - SupervisorTool uses SharedScopeManager instead of opening its own store - Runner creates scopes for sub-agents via SharedScopeManager This fixes: - SQLITE_BUSY from separate store connections - Empty scope list from fresh ScopeManager each call - Sub-agents now get scopes automatically on creation
…args Two bugs causing TUI error popups: 1. trace_owner_id is required: PostTool/StartTurn/EndTurn/FailTurn now bail early when sessionID is empty, instead of passing empty strings to the trace store. 2. json.RawMessage panic: tool args are now validated with json.Valid() before wrapping in json.RawMessage. Invalid args (empty string, malformed JSON) are stored as a JSON-encoded string instead of causing a MarshalJSON panic.
Trace recording is best-effort. Failures (SQLITE_BUSY, schema errors) should not surface as raw stderr in the TUI. The noop fallback already handles graceful degradation — debug logging is sufficient for diagnosis.
Introduce session-wide shepherd infrastructure and a new supervised task tool with checkpoint/rollback/retry. Trace store, effect bus, and scope manager are now initialized once during wiring instead of per-loop, preventing SQLITE_BUSY contention from concurrent writers. Changes: - Add InitShepherdInfrastructure in internal/agent/pipeline/scope_init.go to centralize store and scope manager creation. - Register SupervisedTaskTool in cmd/yaah/wiring.go alongside the existing SupervisorTool. - Add a curated sub-agent middleware pipeline for sub-agent loops, excluding orchestrator-only middleware (steer, approval, etc.). - Add IsSubAgent flag to LoopConfig to select the pipeline builder. - Refactor ShepherdTraceMiddleware to use tools.SharedTraceStore and track store ownership so sub-agent loops don't close the shared store. - Replace SubAgentConfig.TraceDir/TraceSessionID with SessionID. - Add SupervisedMaxRetries and SupervisedRepoPath config options. - Bump github.com/buchenberg/shepherd-kernel-go to v0.2.0.
Introduce a blocking sub-agent tool that guarantees workspace safety: before each attempt a git checkpoint is taken, on failure the workspace is rolled back and the sub-agent retried with failure-derived guidance. This addresses the prior gap where spawn_subagent changes persisted even when a sub-agent failed, leaving the workspace in a broken state. Changes: - Add SupervisedTaskTool in internal/tools/supervised_task.go with checkpoint/rollback/retry semantics, timeout and iteration caps, and blocking execution that prevents concurrent filesystem writes. - Add orchestrator guidance (internal/prompts/subagent_tools.md) that explains when to prefer supervised_task over spawn_subagent; injected into the main prompt only when tracing (and thus the tool) is enabled. - Add supervised_task tool description doc for the model prompt. - Restrict the sub-agent middleware pipeline to tool_concurrency and shepherd_trace, excluding orchestrator-only middleware (steer, approval, compaction, etc.). - Expand config parity and pipeline tests; add buildpipeline and supervised_task tests covering success, retry, rollback, and prompt reuse. - Expand ~ in SupervisedRepoPath during config load. - Bump github.com/buchenberg/shepherd-kernel-go to v0.2.1.
… groundwork
Lay the foundation for per-turn checkpoint/restore in sub-agent loops (.agents/plans/per-turn-checkpoint-restore) and make supervised_task return a uniform JSON envelope for every outcome.
Changes: - Return a single always-JSON envelope {status, attempts, result?, error?, partial?} from supervised_task; success is now status=completed with the output in result, so callers can tell a clean run from a failed-and-rolled-back one without inspecting the worktree. Track the last non-empty partial across attempts. - Add agent.TurnCheckpointer (opaque []byte snapshots) and the ShepherdTurnCheckpointer adapter over the shared ScopeManager, with git-repo tests covering workspace revert, snapshot round-trip, and the single-use restore contract. - Plumb TurnCheckpointer/TurnCheckpointEnabled/TurnCheckpointMax through SubAgentConfig into LoopConfig; the loop integration (checkpoint before turn, restore on failure) is not wired yet. - Update the supervised_task tool description for the envelope.
Sub-agent loops can now snapshot the workspace and conversation before each model turn and rewind a failed turn instead of failing the whole attempt. Gated behind turn_checkpoint (default off) pending benchmarks. Changes: - Loop.Run takes a git checkpoint (serialized messages as snapshot) before each model turn; on a hard tool-phase error or iteration exhaustion it restores the last checkpoint, appends supervisor guidance, and retries, bounded by MaxTurnRestores (default 3). TurnCheckpointMax caps live checkpoints; unconsumed checkpoints are pruned at run end. - Runner wires ShepherdTurnCheckpointer on the sub-agent's own scope when turn_checkpoint is enabled, keeping turn checkpoints separate from supervised_task's attempt-level scope. - jobs.TurnRestoreStats flows restore counts from the loop through the context into the supervised_task envelope (new optional restores/restored_from fields). - Config knobs: turn_checkpoint, turn_checkpoint_max, max_turn_restores. - Tests: 6 loop-level tests (fake checkpointer/provider), snapshot round-trip, jobs ctx stats tests, tool envelope test, and a full-stack integration test (supervised_task -> runner -> real loop -> real git repo) verifying a corrupting turn write is rewound while earlier progress survives. - Docs: per-turn appendix in docs/supervised-task-plan.md, updated tool description, plan status -> in_progress.
…oints) Replace the global turn_checkpoint toggle with per-role shepherding under agents.subagent.roles.<name>, and land the phase-9 checkpoint-cost benchmarks that justify keeping per-turn checkpointing off by default. Config model: - RoleConfig gains supervised (default false) and turn_checkpoints (default false). Routing is exclusive: supervised roles dispatch only via supervised_task (attempt checkpointing always on); plain roles only via spawn_subagent (no checkpoints). - Remove the global turn_checkpoint bool. Numeric knobs (supervised_max_retries, turn_checkpoint_max, max_turn_restores) and supervised_repo_path stay global. Implementation: - wiring.go adds splitRolesBySupervised, filtering each tool's static role list and live RoleResolver so schemas and role validation enforce the split. - runner gates the turn checkpointer on the role's TurnCheckpoints flag and extracts RoleDescriptionsFor for both tools. Benchmarks (Intel Ultra 7 265H, Windows, -benchtime=10x): checkpoint ~241-385ms/op, restore ~447ms-1.5s/op, dominated by spawning three git subprocesses per checkpoint. Decision: keep per-turn checkpointing off by default (per-role opt-in only). Tests: config parsing of the new flags, routing partition (exclusive buckets), per-role gate on/off via integration tests, plus the existing full-stack integration test updated to the per-role model.
supervised_task gains review:true: run ONE work unit, return a review envelope (session_id, bounded diff, report, allowed verdicts) instead of auto-retrying. The supervisor tool drives the verdict cycle: - continue: accept the unit, run the next one seeded with the prior conversation (jobs.SubAgentParams.SeedMessages -> LoopConfig. InitialMessages), guidance as the new user message - rollback: restore the unit-start git checkpoint (files AND conversation), rerun with the orchestrator's more specific prompt - fork/choose: rewind to the unit-start checkpoint, run two prompt variants from the same tree, apply the winner's tree + conversation - review_diff / accept / abort round out the lifecycle One open session at a time; cancelled units stay resumable; review mode never auto-retries. Requires shepherd-kernel-go v0.3.1 (TreeState capture/apply + DiffSince, non-consuming) which replaces raw git calls in yaah.
Picks up the non-mutating checkpoint fix (unstage after stash create) and drops the temporary local replace directive.
…ard rails - Route supervised roles out of spawn_subagent only after shepherd infra initializes successfully, so a role is never unreachable when tracing is unset or init fails; gate the prompt guidance on the same state. - Hold the session mutex across the sub-agent runner call so concurrent verdict actions serialize instead of rewinding a live workspace. - Reject a fork variant whose tree snapshot failed to capture, instead of calling ApplyTree(nil). - Seed InitialMessages on any empty history, not just nil. - Restrict shepherd trace dir/store to the session owner (0700/0600). - Return the os.Getwd error instead of discarding it. - Document review_diff in the verdict lists.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (46)
📝 WalkthroughWalkthroughThe PR adds supervised sub-agent execution with shared Shepherd tracing, per-role routing, Git-backed attempt and turn checkpoints, automatic restore/retry behavior, conversation capture, and interactive review sessions with rollback and fork selection. ChangesSupervised sub-agent execution
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant SupervisorTool
participant SupervisedTaskTool
participant SubAgentRunner
participant AgentLoop
participant Shepherd
SupervisorTool->>SupervisedTaskTool: submit supervised task or review action
SupervisedTaskTool->>Shepherd: create attempt checkpoint
SupervisedTaskTool->>SubAgentRunner: execute role with prompt
SubAgentRunner->>AgentLoop: run sub-agent loop
AgentLoop->>Shepherd: checkpoint and restore turns when enabled
AgentLoop-->>SubAgentRunner: conversation and restore diagnostics
SubAgentRunner-->>SupervisedTaskTool: task result
SupervisedTaskTool-->>SupervisorTool: structured review envelope
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
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.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation