Repository navigation
fix(dispatch): carry inter-agent chain depth through loops, schedule triggers, session turns and events (#2973) - #3120
Merged
Conversation
…triggers, session turns and events (#2973) Follow-up to #2806. Loop starts, manual schedule triggers, chat-session turns and agent event emits by an agent principal now inherit the caller's chain depth and are refused past inter_agent_max_chain_depth with the named 403 inter_agent_depth_exceeded, instead of starting a fresh depth-0 root. - Loops: depth stored on agent_loops.chain_depth (SQLite migration + Alembic 0084) and stamped on every iteration row. - Schedule trigger: depth forwarded to the scheduler; retries keep it. - Session turns: depth passed through run_resumable_turn to execute_task. - Events: depth signed into the EVT-001 loopback JWT (chain_depth claim), minted whether or not the source is vouched; task-completion events carry the finished row's depth + 1 (the max when the row is unreadable); _chain_caller falls back to vouched_source_agent. - Per source->subscriber hourly event-dispatch budget in trigger_subscription (ops setting event_dispatch_max_fires_per_hour, default 120, one alert per window, fail-open on Redis errors). - App-level handler maps InterAgentDepthExceeded to the #2806 403 body. - MCP run_agent_loop, trigger_agent_schedule and emit_event render the refusal as a non-retryable result. Mutation-checked: reverting each fix turns its test red in tests/unit/test_2973_depth_new_roots.py, test_2973_event_dispatch_budget.py and src/mcp-server/src/tools/depth-refusal.test.ts. Webhook tokens, agent-created cron schedules and self-reminders remain roots; tracked in #3116. Fixes #2973 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
obasilakis
force-pushed
the
feature/2973-chain-depth-laundering
branch
from
September 30, 2026 13:25
3d4278c to
6b02181
Compare
…ons, budget alert write (#2973) Review follow-ups on #3120: the cold retry in run_resumable_turn keeps chain_depth (mutation-checked), a missing session answers 404 before the depth 403, and the budget alert writes a high-priority notification on the subscriber. Doc counts updated for the four covered paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 tasks done
Contributor
|
merge-train: this PR is on today's train with #3122, #3119 and #3085. The one Tier 1 blocker was the Two gaps to consider. Neither blocks this train. Each was found by a mutation that stayed green:
Also worth a decision, from This PR goes in ahead of #3085, and #3085 will re-parent onto your |
This was referenced Sep 30, 2026
vybe
pushed a commit
that referenced
this pull request
Sep 30, 2026
…5_ent720_email_identity (#3085) #3120 landed 0084_agent_loops_chain_depth off the same parent as this PR's 0084_ent720_email_identity. Disjoint tables, so the revision is re-parented: 0085_ent720_email_identity <- 0084_agent_loops_chain_depth. SQLite list keeps both entries, dev's first — the same resolution train #3126 was gated on. Co-Authored-By: Claude Opus 5.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.
Summary
inter_agent_max_chain_depthcould reset its depth to 0 by starting a loop, manually triggering a schedule, driving a chat-session turn, or emitting an event its subscription answers. All four now inherit the caller's depth and are refused at the max with the same named 403inter_agent_depth_exceeded.chain_depthclaim in the EVT-001 loopback JWT, so an emit on another agent's behalf and systemagent.task.*completions (finished row's depth + 1) carry it too._chain_callerfalls back tovouched_source_agent.event_dispatch_max_fires_per_hour, default 120, one high-priority notification per window, fail-open on Redis errors.Changes
routers/{loops,schedules,sessions,event_subscriptions}.py— callenforce_inter_agent_depth; refusal propagates to the new app-level handler (error_handlers.inter_agent_depth_exceeded, registered inmain.py).services/loop_service.py,db/loops.py+agent_loops.chain_depth(SQLite migrationloop_chain_depth, Alembic0084,schema.py,tables.py).src/scheduler/*—ExecutionOrigin.chain_depth(validated 1–1000), stamped on insert, kept on retry.services/event_dispatch_service.py— loopback claim, terminal-event depth, dispatch budget;dependencies.py/models.User.loopback_chain_depth;services/dispatch_admission_service.py— claim read before the root early-return.services/task_execution_service.execute_task(chain_depth=).services/monitoring_alerts.py— budget alert;config.py/settings_service.py— new ops setting.client.ts::depthRefusalFromError;run_agent_loop,trigger_agent_schedule,emit_eventreturn the refusal as a non-retryable result.requirements/core-agent.md§9.1.1,requirements/mcp.md,architecture/{execution,database,api-endpoints}.md, feature flows, IA-04 gaps, learnings fragment, CSO diff report.Test Plan
cd tests && pytest unit/test_2973_depth_new_roots.py unit/test_2973_event_dispatch_budget.py -v— every path driven through its real route with a minted agent bearer and a non-default max (34 + 10 pass)src/mcp-server/src/tools/depth-refusal.test.tsnode --test600/600;tsc --noEmitcleancheck_alembic_heads.pysingle head;check_alembic_parity.pyPASSDeferred: webhook tokens, agent-created cron schedules and self-reminders still start a depth-0 root — #3116 (needs a design call on whether a stored trigger carries its creator's depth forever).
Fixes #2973
🤖 Generated with Claude Code