Skip to content

feat(sre): wire AGT SRE kill switch into cmcp session manager#347

Merged
imran-siddique merged 2 commits into
mainfrom
feat/sre-kill-switch
Jun 25, 2026
Merged

feat(sre): wire AGT SRE kill switch into cmcp session manager#347
imran-siddique merged 2 commits into
mainfrom
feat/sre-kill-switch

Conversation

@imran-siddique

Copy link
Copy Markdown
Contributor

Summary

  • Adds a rolling-window deny-rate evaluator (KillSwitchEvaluator) that tracks policy decisions per agent identity (SPIFFE URI from the bound Agent Manifest)
  • When deny rate ≥ threshold over the configured window with ≥ min_calls samples, the closing TRACE claim carries gateway.kill_switch_triggered: true — hardware-attested evidence of automated enforcement, verifiable offline by any regulator
  • Subsequent create_session() calls for the flagged identity raise KillSwitchTripped (403) until the gateway restarts or an operator calls the unblock endpoint
  • Disabled by default (kill_switch.enabled: false); opt in via cmcp-config.yaml

Closes #341

What changes

File Change
src/cmcp_runtime/kill_switch.py New KillSwitchEvaluator with rolling window
src/cmcp_runtime/config.py KillSwitchConfig dataclass, Config.kill_switch, load_config() parsing
src/cmcp_runtime/errors.py KillSwitchTripped error (KILL_SWITCH_TRIPPED / 403)
src/cmcp_runtime/session/state.py kill_switch_triggered: bool flag
src/cmcp_runtime/audit/trace_claim.py kill_switch_triggered in GatewayAddenda
src/cmcp_runtime/session/manager.py Evaluator wired at create_session() and close_session()
schemas/trace-claim.schema.json kill_switch_triggered field added
docs/tutorials/kill-switch.md New tutorial
mkdocs.yml Tutorial added to nav
tests/unit/test_kill_switch.py 21 unit tests — all passing

Behavior notes

  • Anonymous sessions (no Agent Manifest bound) are never evaluated or blocked
  • advisory_deny counts as a deny — matches the existing close_session() deny counting logic
  • Kill switch audit entry: a break_glass_used audit chain entry records the trigger event with agent identity and window config
  • Backward compatible: existing _make_ctx() test helpers that use a raw MagicMock for config get a disabled KillSwitchConfig() by default

Test plan

  • pytest tests/unit/test_kill_switch.py — 21 tests, all passing
  • pytest tests/unit/ — 725 tests, 0 failures
  • Window expiry test (test_window_expired_events_ignored) uses 1s window + 1.1s sleep
  • advisory_deny test confirms it counts toward kill switch threshold
  • No-manifest test confirms anonymous sessions are never blocked

🤖 Generated with Claude Code

imran-siddique and others added 2 commits June 25, 2026 13:56
…341)

Rolling-window deny-rate evaluator tracks policy decisions per agent
identity (SPIFFE URI from Agent Manifest). When deny rate exceeds the
configured threshold over the rolling window, the closing TRACE claim
carries `gateway.kill_switch_triggered: true` — hardware-attested
evidence of automated enforcement — and subsequent create_session()
calls for that identity raise KillSwitchTripped (403).

Changes:
- src/cmcp_runtime/kill_switch.py: new KillSwitchEvaluator
- src/cmcp_runtime/config.py: KillSwitchConfig dataclass + load_config() parsing
- src/cmcp_runtime/errors.py: KillSwitchTripped error (KILL_SWITCH_TRIPPED / 403)
- src/cmcp_runtime/session/state.py: kill_switch_triggered flag
- src/cmcp_runtime/audit/trace_claim.py: kill_switch_triggered in GatewayAddenda
- src/cmcp_runtime/session/manager.py: KillSwitchEvaluator wired at create/close
- schemas/trace-claim.schema.json: kill_switch_triggered field
- docs/tutorials/kill-switch.md: new tutorial
- mkdocs.yml: tutorial added to nav
- tests/unit/test_kill_switch.py: 21 unit tests (all passing)

Anonymous sessions (no Agent Manifest bound) are never evaluated or
blocked. advisory_deny counts as a deny. The kill switch is disabled by
default — set kill_switch.enabled: true in cmcp-config.yaml to activate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…orts

- kill_switch.py: remove quotes from KillSwitchConfig annotation (UP037)
- config.py: use int | float union syntax in isinstance (UP038)
- test_kill_switch.py: remove unused AuditChain and SessionState imports (F401)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@imran-siddique imran-siddique merged commit d5804de into main Jun 25, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: wire AGT SRE kill switch into session manager

1 participant