Skip to content

Sovereign Evidence Rail + L3 Memory Governor - #69514

Open
drussell23 wants to merge 1 commit into
mainfrom
feat/sovereign-evidence-rail
Open

Sovereign Evidence Rail + L3 Memory Governor#69514
drussell23 wants to merge 1 commit into
mainfrom
feat/sovereign-evidence-rail

Conversation

@drussell23

@drussell23 drussell23 commented Jun 15, 2026

Copy link
Copy Markdown
Owner

What

Evidence-driven graduation of the REVIEW/PLAN shadow subagents to authoritative status, plus a worktree-RAM-budget governor for the L3 parallel scheduler. Replaces "shadow forever" with a durable ledger that auto-graduates after a 50-op aligned soak, with a graceful-degradation circuit breaker.

Units

  • Unit D — L3 Memory Governor (autonomy/l3_memory_governor.py + subagent_scheduler.py): caps concurrent worktrees = floor(avail_mb / JARVIS_L3_WORKTREE_RAM_BUDGET_MB), reusing MemoryPressureGate (no duplicate probe), strictest-wins with the existing Slice 5 Arc B fan-out gate.
  • Unit B — Evaluator (shadow_evaluator.py): pure, never-raises. REVIEW = binary block-vs-allow agreement; PLAN = refinement (DAG covers 100% of legacy tasks ∧ acyclic ∧ disjoint owned-paths). Malformed → blocks graduation.
  • Unit A — Telemetry store (shadow_telemetry_store.py): async SQLite .jarvis/shadow_telemetry.db, bounded to_thread writer (never blocks loop / never raises), two-phase upsert keyed (op_id,agent), rolling FIFO cap.
  • Unit C — Gate + breaker (shadow_graduation_gate.py): event-driven 50-soak → flips JARVIS_{PLAN,REVIEW}_SUBAGENT_AUTHORITATIVE via the existing credential-safe persist_flag_to_env. PlanBreaker trips to legacy on cyclical/empty DAG or CRITICAL memory pressure (pre-emptive); emits AGENT_DEGRADATION SSE.

Live FSM wiring

Producers in orchestrator._run_{plan,review}_shadow; authoritative REVIEW tier-raise (strictest-wins into the GATE-local risk_tier); store constructed/owned in GovernedLoopService._build_components/stop.

Safety

OFF-is-inert: with JARVIS_SHADOW_TELEMETRY_STORE_ENABLED=false, the store is never built → orchestrator._shadow_store stays None → every producer/gate/authoritative path is skipped → FSM byte-identical. All new flags default to today's behavior; graduation only fires after a real 50-op soak.

Verification

  • 45 rail + governor unit/integration tests pass (incl. end-to-end: 50 aligned → graduate, 1 divergence → block).
  • 49 SSE broker tests pass against main's broker (keep-both validated).
  • Orchestrator / GLS edits verified by ast.parse + scope-confirmation (these files can't be imported in the dev sandbox — split-brain guard); guarded so OFF-inert is bulletproof.

Notes for reviewers

  • Rebased onto main (Slice 255). The only conflict was a mechanical EVENT_TYPE_* collision with the loop's orthogonal Slice 252 Shadow-Telemetry — resolved keep-both. Spec §14 documents that the loop's resilience "Shadow Mode" and this subagent "Shadow Rail" are unrelated systems.
  • Deferred (follow-up slice): endorsed-DAG-drives-execution. Today a graduated PLAN's DAG is observer-only (stashed on ctx, not best_candidate); the breaker/telemetry run but the DAG does not yet steer the L3 scheduler.
  • semantic_guard_hard is conservatively False at the REVIEW hook (guardian signal out of scope there) — flagged in-code for a follow-up.

🤖 Generated with Claude Code


Summary by cubic

Graduates the REVIEW and PLAN shadow subagents based on evidence and adds an L3 memory governor that keeps worktree parallelism within live RAM limits. This makes promotion safe and prevents RAM thrash on busy hosts.

  • New Features

    • Evidence Rail: async SQLite store with two-phase upsert and a deterministic evaluator; auto-graduates after 50 aligned ops and flips JARVIS_{PLAN,REVIEW}_SUBAGENT_AUTHORITATIVE.
    • Circuit breaker: degrades to legacy on malformed plans or critical memory pressure and emits AGENT_DEGRADATION SSE.
    • Orchestrator wiring: producers added for shadow REVIEW/PLAN; rail is inert when JARVIS_SHADOW_TELEMETRY_STORE_ENABLED=false.
    • L3 memory governor: reuses the MemoryPressureGate probe to cap concurrent worktrees by floor(avail_mb / JARVIS_L3_WORKTREE_RAM_BUDGET_MB); strictest-wins with the existing fan-out gate.
  • Migration

    • No action needed; defaults preserve current behavior.
    • To adopt gradually: enable the store with JARVIS_SHADOW_TELEMETRY_STORE_ENABLED=true (optional JARVIS_SHADOW_GRADUATION_THRESHOLD, default 50).
    • Tune memory limits via JARVIS_L3_MEMORY_GOVERNOR_ENABLED and JARVIS_L3_WORKTREE_RAM_BUDGET_MB.

Written for commit a580562. Summary will update on new commits.

Review in cubic

Evidence-driven graduation of the REVIEW/PLAN shadow subagents to
authoritative status, plus a worktree-RAM-budget governor for L3.

Unit D — L3 Memory Governor (l3_memory_governor.py + subagent_scheduler.py):
  reuses MemoryPressureGate; caps concurrent worktrees by live RAM,
  strictest-wins with the existing fan-out gate. Off-is-inert.
Unit B — Evaluator (shadow_evaluator.py): pure REVIEW binary agreement +
  PLAN refinement (coverage ∧ acyclic ∧ disjoint); malformed→block.
Unit A — Telemetry store (shadow_telemetry_store.py): async SQLite,
  to_thread non-blocking writer, two-phase upsert, rolling FIFO cap.
Unit C — Gate + breaker (shadow_graduation_gate.py): event-driven 50-soak
  → flips _AUTHORITATIVE via existing persist_flag_to_env; PlanBreaker
  (CRITICAL-pressure pre-empt → legacy); AGENT_DEGRADATION SSE.
Live wiring: producers in orchestrator _run_{plan,review}_shadow,
  authoritative REVIEW tier-raise, GLS construct/teardown. OFF-inert:
  store disabled → orchestrator _shadow_store None → FSM byte-identical.

Rebased onto main (Slice 255); keep-both resolution of the EVENT_TYPE_*
collision with the loop's orthogonal Slice 252 Shadow-Telemetry (spec §14
documents the two unrelated "shadows"). Endorsed-DAG-drives-execution is
deferred (observer-only today). 45 rail/governor tests + 49 SSE green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

[integrity-verified: daaafc3768bc]
@github-actions

Copy link
Copy Markdown

💡 PR Description Suggestions

Consider improving your PR description:
- Add a summary section
  • Add a testing section

  • Link related issues

    Template:

    ## Summary
    Brief description of changes
    
    ## Changes Made
    - Change 1
    - Change 2
    
    ## Test Plan
    How to verify these changes
    
    ## Related Issues
    Closes #123
    

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

📊 PR Size Analysis

Size: XL
Files Changed: 18
Lines Added: +4292
Lines Deleted: -11
Total Changes: 4303

⚠️ This PR is very large. Consider breaking it into smaller PRs for easier review.

Review Checklist

  • All tests passing
  • Code follows project style guidelines
  • Documentation updated if needed
  • No sensitive data exposed
  • Breaking changes documented

@github-actions

Copy link
Copy Markdown

💡 PR Description Suggestions

Consider improving your PR description:
- Add a testing section
  • Link related issues

    Template:

    ## Summary
    Brief description of changes
    
    ## Changes Made
    - Change 1
    - Change 2
    
    ## Test Plan
    How to verify these changes
    
    ## Related Issues
    Closes #123
    

@github-actions

Copy link
Copy Markdown

🤖 CI/CD Pipeline Results

Status: success
Branch: 69514/merge
Commit: 8f7e88f8015ef180d99744fd405ff36081111c14

Pipeline Stages

  • Code Quality: ❌
  • Build & Test: ❌
  • Architecture: ❌
  • Security Scan: ❌

View full workflow run

self._pressure_fn = pressure_fn or _default_pressure_fn

def should_use_legacy(self, *, dag) -> BreakerDecision:
level = "ok"
assert gov is None
# Composition guard: None -> no truncation.
if gov is not None and gov.n_allowed < len(selected):
selected = selected[:gov.n_allowed]
Comment on lines +1607 to +1609
async def _run_review_shadow(
self, ctx: Any, best_candidate: Any,
) -> "Optional[RiskTier]":
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants