Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions backend/core/ouroboros/governance/candidate_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,22 @@
return False


def _dw_autarky_enabled() -> bool:
"""Slice 225 Phase 2 master. Default-TRUE — when the Claude fallback breaker
is OPEN/HALF_OPEN (terminal_quota / out-of-credits / transport), STANDARD and
COMPLEX ops keep the DW primary on the full op budget instead of severing it
at the 30s/75s reflex cap into a dead lane (the live GOAL-001::file-00
generation_failed wedge). Sibling to the P2.1 IMMEDIATE-route gate above, for
the STANDARD/COMPLEX primary-budget path. Operator force-off with =0. NEVER
raises — fail-closed to legacy cascade."""
try:
return os.environ.get(
"JARVIS_DW_AUTARKY_ENABLED", "true",
).strip().lower() in ("1", "true", "yes", "on")
except Exception: # noqa: BLE001
return False


def immediate_reroute_to_dw(
*,
dw_is_primary: bool,
Expand Down Expand Up @@ -4945,9 +4961,36 @@
_force_batch = _slice36_should_force_batch(context)
except Exception: # noqa: BLE001 — defensive, legacy budget
_force_batch = False
# Slice 225 Phase 2 — Sovereign DW Autarky. Read the Claude fallback
# breaker (read-only, no probe side effect — same _claude_breaker_open
# predicate the Slice 127 P2.1 IMMEDIATE reroute uses). When the
# fallback lane is OPEN/HALF_OPEN (incl. terminal_quota / out-of-
# credits), there's no live lane to sever DW into — give DW the full
# runway instead of the 30s/75s reflex cap. Gated default-TRUE;
# OFF (or breaker CLOSED) is the byte-identical legacy cascade.
_fallback_dead = False
if _dw_autarky_enabled():
try:
from backend.core.ouroboros.governance.doubleword_provider import (
_claude_breaker_open as _autarky_breaker_open,
)
_fallback_dead = _autarky_breaker_open()
except Exception: # noqa: BLE001 — fail-closed to legacy cascade
_fallback_dead = False
primary_budget = self._compute_primary_budget(
remaining, model_id=model_id, force_batch=_force_batch,
fallback_dead=_fallback_dead,
)
if _fallback_dead and primary_budget > _PRIMARY_MAX_TIMEOUT_S:
logger.warning(
"[CandidateGenerator] ⚡ DW AUTARKY ENGAGED: Claude fallback "
"breaker OPEN — granting DW the full %.1fs budget (vs %.1fs "
"reflex cap), no dead-lane handoff. route=%s op=%s model=%s",
primary_budget, _PRIMARY_MAX_TIMEOUT_S,
getattr(context, "provider_route", "?"),
getattr(context, "op_id", "?")[:16],
model_id or "(unspecified)",

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (secret)
as clear text.
This expression logs
sensitive data (secret)
as clear text.
)
# Slice 34 Phase 2 — dispatch profiler (default OFF; zero
# overhead when disabled). Records the sem-wait + budget
# stages into the per-op summary; STAGE_PROVIDER_GENERATE
Expand Down Expand Up @@ -6486,6 +6529,7 @@
*,
model_id: str = "",
force_batch: bool = False,
fallback_dead: bool = False,
) -> float:
"""Deterministic Tier 1 primary budget with fallback reserve + Tier 3 cap.

Expand Down Expand Up @@ -6541,6 +6585,24 @@
batch_cap = _envf_or_default("JARVIS_DW_BATCH_TIMEOUT_S", 300.0)
return max(min(total_s, batch_cap), 0.0)

# Slice 225 Phase 2 — Sovereign DW Autarky. When the Claude fallback
# lane is unreliable (breaker OPEN/HALF_OPEN — incl. the terminal_quota
# / out-of-credits economic refusal), there is NO live fallback to hand
# off to. Severing DW at the 30s/75s reflex cap only accelerates
# exhaustion into a dead lane — the live-soak GOAL-001::file-00 wedge:
# DW cut at 30s -> Claude 400 "credit balance too low" -> EXHAUSTION,
# generation_failed, no patch ever produced. Give DW the full remaining
# runway up to a cost-safety ceiling instead (default 180s = the COMPLEX
# generation window). Mirrors the force_batch precedent directly above
# ("Claude disabled -> no fallback to reserve -> full runway"). The
# caller stamps fallback_dead from the read-only _claude_breaker_open
# predicate; default False is byte-identical to the legacy cascade.
if fallback_dead:
autarky_cap = _envf_or_default(
"JARVIS_DW_AUTARKY_MAX_BUDGET_S", 180.0,
)
return max(min(total_s, autarky_cap), 0.0)

fb_reserve = min(_FALLBACK_MIN_RESERVE_S, total_s * 0.35)

# Slice 28 Phase 2 — adaptive Tier 3 cap for heavy models
Expand Down
46 changes: 40 additions & 6 deletions backend/core/ouroboros/governance/doubleword_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -2754,12 +2754,46 @@ async def _generate_realtime(
# (the simple-background half of the v40b deadlock would otherwise
# remain: loop runs, tools suppressed). Env-gated + BACKGROUND-only
# -> byte-identical legacy when Claude is enabled / flag off.
if background_is_terminal_worker(str(_route)):
_will_skip_tools = (_complexity == "trivial")
else:
_will_skip_tools = (
_complexity in ("trivial", "simple")
or should_skip_venom_for_route(str(_route))
# Slice 226 — Iron Gate / provider capability alignment. The base
# tool-skip decision (BG-terminal-worker vs complexity/route skip) is
# now computed by the shared exploration_engine predicate so the
# capability plane (tools available) can never contradict the security
# plane (exploration floor). When the Iron Gate will demand exploration
# for a ``simple`` op on a venom-eligible route, the loop stays ON —
# closing the live GOAL-001::file-00 catch-22 (simple -> tools skipped
# -> exploration_insufficient -> guaranteed rejection). trivial stays
# exempt; BACKGROUND/SPECULATIVE keep their preload-credit skip.
from backend.core.ouroboros.governance.exploration_engine import (
compute_tool_loop_suppressed as _s226_compute_skip,
exploration_gate_demands_tools as _s226_gate_demands,
)
_s226_is_bg_tw = background_is_terminal_worker(str(_route))
_s226_route_skip = should_skip_venom_for_route(str(_route))
_base_skip = _s226_compute_skip(
complexity=str(_complexity),
route=str(_route),
is_bg_terminal_worker=_s226_is_bg_tw,
has_repair_context=False,
)
_will_skip_tools = _base_skip
# Slice 226 observability (operator pref: escalate capability anomalies
# LOUD, never silent re-route). When the alignment override re-opened
# the loop for a complexity that the cost heuristic would have stripped
# (simple, venom-eligible route, not BG-terminal-worker), flash it.
if (
not _base_skip
and not _s226_is_bg_tw
and not _s226_route_skip
and str(_complexity).strip().lower() == "simple"
and _s226_gate_demands(str(_complexity))
):
logger.warning(
"[DoublewordProvider] ⚡ CAPABILITY ALIGNMENT: Iron Gate floor "
"demands exploration for a 'simple' op — re-opened the Venom "
"tool loop (read_file/search_code) the cost heuristic would "
"have withheld. route=%s op=%s",
_route,
(getattr(context, "op_id", "?") or "?")[:16],
)
# ──────────────────────────────────────────────────────────────
# Slice 9 — L2 single-shot fast path (DW mirror)
Expand Down
108 changes: 108 additions & 0 deletions backend/core/ouroboros/governance/exploration_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,114 @@ def _read_int_env(name: str, default: int) -> int:
return int(default)


# ---------------------------------------------------------------------------
# Slice 226 — Iron Gate / provider capability alignment
# ---------------------------------------------------------------------------
#
# The exploration gate (orchestrator.py) enforces a per-complexity floor of
# >=1 exploration call ("read the target file") for every NON-trivial op when
# JARVIS_EXPLORATION_GATE is on. Independently, the DW/Prime providers skip the
# Venom tool loop for ``complexity in {trivial, simple}`` as a cost optimization
# — denying the model the read_file/search_code channels it needs to satisfy
# that floor. A ``simple`` op on a venom-eligible route (the live
# GOAL-001::file-00) is thus an unwinnable catch-22: no tools, then rejected for
# not using them (``exploration_insufficient: 0/1``). The intended escape hatch
# (preloaded-prompt credit) silently fails when the target file is too large to
# inline (semantic_index.py = 3246 lines).
#
# These two predicates are the single source of truth both providers consult so
# the capability plane (tools available) and the security plane (exploration
# required) can never contradict.

_ENV_GATE_ALIGNMENT = "JARVIS_GATE_ALIGNMENT_ENABLED"


def gate_alignment_enabled() -> bool:
"""Slice 226 master. Default-TRUE; OFF restores the byte-identical legacy
complexity-based tool-skip (simple -> skip). NEVER raises."""
try:
return os.environ.get(_ENV_GATE_ALIGNMENT, "true").strip().lower() in (
"1", "true", "yes", "on",
)
except Exception: # noqa: BLE001
return False


def exploration_gate_demands_tools(
complexity: str, *, gate_enabled: object = None,
) -> bool:
"""True iff the Iron Gate exploration floor will demand >=1 exploration
call for an op of this complexity — so a provider MUST keep the Venom tool
loop available rather than skipping it on a complexity heuristic.

Mirrors the orchestrator's gate-enable condition: ``JARVIS_EXPLORATION_GATE``
on AND complexity != 'trivial' (trivial is exempt; simple+ carry the >=1
"read the target file" floor). ``gate_enabled`` may be passed explicitly to
avoid the env read (testing / callers that already resolved it). NEVER
raises — fail-closed to False (legacy, no tools forced)."""
try:
if gate_enabled is None:
gate_enabled = (
os.environ.get("JARVIS_EXPLORATION_GATE", "true")
.strip().lower() == "true"
)
if not gate_enabled:
return False
return str(complexity or "").strip().lower() not in ("trivial", "")
except Exception: # noqa: BLE001
return False


def compute_tool_loop_suppressed(
*,
complexity: str,
route: str,
is_bg_terminal_worker: bool,
has_repair_context: bool,
gate_enabled: object = None,
) -> bool:
"""Unified Venom-tool-loop suppression decision (Slice 226).

Faithfully mirrors the historical DW-provider logic
(doubleword_provider ``_generate_realtime``):

* BG terminal-worker (Claude disabled): skip only ``trivial``.
* Otherwise: skip ``trivial``/``simple`` OR a venom-skip route
(BACKGROUND/SPECULATIVE — these pass the gate via preloaded-prompt
credit, not tools).
* L2 repair single-shot fast path (Slice 9): always skip.

PLUS the Slice-226 alignment override: when the gate will demand
exploration for this complexity, the COMPLEXITY-based skip is lifted (the
ROUTE-based skip is preserved — BACKGROUND keeps its preload-credit path).
Gated by ``gate_alignment_enabled()``; OFF = byte-identical legacy.
NEVER raises — fail-closed to the legacy decision on any error."""
try:
from backend.core.ouroboros.governance.route_predicates import (
should_skip_venom_for_route,
)
c = str(complexity or "").strip().lower()
r = str(route or "").strip().lower()
if is_bg_terminal_worker:
suppressed = (c == "trivial")
else:
route_skip = should_skip_venom_for_route(r)
suppressed = (c in ("trivial", "simple")) or route_skip
if (
gate_alignment_enabled()
and suppressed
and not route_skip
and exploration_gate_demands_tools(c, gate_enabled=gate_enabled)
):
suppressed = False
if has_repair_context and not suppressed:
suppressed = True
return suppressed
except Exception: # noqa: BLE001 — fail-closed to legacy complexity skip
c = str(complexity or "").strip().lower()
return c in ("trivial", "simple")


@dataclass(frozen=True)
class ExplorationFloors:
"""Per-complexity exploration thresholds.
Expand Down
74 changes: 74 additions & 0 deletions backend/core/ouroboros/governance/orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import ast
import asyncio
import hashlib
import json
import logging
import os
import sys
Expand Down Expand Up @@ -141,6 +142,75 @@
}


_ENV_SUBGOAL_WRITEBACK = "JARVIS_SUBGOAL_COMPLETION_WRITEBACK_ENABLED"


def _slice_a1_subgoal_completion_writeback(ctx: Any, state: Any) -> None:
"""§51.11.34-ROADMAP A1 — close the sub-goal completion feedback loop.

The multi_step orchestrator emits sub-goal envelopes (stamping
``sub_goal_id`` + ``parent_goal_id`` into the envelope evidence) and writes
a ``PROPOSED`` row to the canonical goal_decomposition completion ledger at
EMIT time — but historically NOTHING wrote the terminal
``COMPLETED``/``FAILED`` transition back. ``done_count`` (which counts
``completed`` rows) was therefore structurally pinned at 0: a roadmap
sub-goal could dispatch and succeed any number of times and the roadmap
would never advance.

This writeback fires from the orchestrator terminal hook — the same
fail-soft, recorder-independent seam the Slice-134 episodic synapse uses.
When the terminal op carries roadmap sub-goal provenance via
``ctx.intake_evidence_json``, the terminal state is mapped to a
CompletionStatus (``applied`` -> COMPLETED; any other terminal -> FAILED)
and appended to the completion ledger, so the multi_step orchestrator's
``done_count`` advances and the roadmap can progress.

Gated ``JARVIS_SUBGOAL_COMPLETION_WRITEBACK_ENABLED`` (default TRUE — this
closes a structural gap; OFF is byte-identical to the legacy severed loop).
NEVER raises.
"""
try:
raw = os.environ.get(_ENV_SUBGOAL_WRITEBACK, "true").strip().lower()
if raw in ("0", "false", "no", "off"):
return
# Cheap substring pre-check avoids a json.loads on the vast majority of
# ops (sensor signals) that carry no sub_goal provenance.
evidence_json = getattr(ctx, "intake_evidence_json", "") or ""
if not evidence_json or "sub_goal_id" not in evidence_json:
return
try:
evidence = json.loads(evidence_json)
except Exception: # noqa: BLE001
return
if not isinstance(evidence, dict):
return
sub_goal_id = str(evidence.get("sub_goal_id") or "").strip()
parent_goal_id = str(evidence.get("parent_goal_id") or "").strip()
if not sub_goal_id or not parent_goal_id:
return
state_value = getattr(state, "value", str(state)) or ""
from backend.core.ouroboros.governance.goal_decomposition_planner import ( # noqa: E501
CompletionStatus,
mark_sub_goal_status,
)
status = (
CompletionStatus.COMPLETED
if state_value == "applied"
else CompletionStatus.FAILED
)
mark_sub_goal_status(
sub_goal_id=sub_goal_id,
parent_goal_id=parent_goal_id,
status=status,
note=(
"terminal:" + str(state_value) + " via orchestrator op "
+ str(getattr(ctx, "op_id", ""))
)[:512],
)
except Exception: # noqa: BLE001 — writeback never perturbs the FSM
return


def _slice12q_record_terminal(
ctx: Any, state: Any, data: Dict[str, Any],
) -> None:
Expand Down Expand Up @@ -184,6 +254,10 @@ def _slice12q_record_terminal(
)
except Exception: # noqa: BLE001 — synapse never perturbs the FSM
pass
# §51.11.34-ROADMAP A1 — sub-goal completion writeback (the severed feedback
# wire). Recorder-independent + fail-soft, exactly like the episodic synapse
# above. Closes the roadmap progress loop: terminal op -> completion ledger.
_slice_a1_subgoal_completion_writeback(ctx, state)
try:
from backend.core.ouroboros.battle_test.session_recorder import (
get_active_recorder,
Expand Down
5 changes: 5 additions & 0 deletions docker-compose.dw-cortex-soak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ services:
# upstream works (reader valid -> decomposition valid, 2 sub-goals ->
# envelope into router); THIS flag is what lets sub-goals emit. ──
JARVIS_MULTI_STEP_ORCHESTRATION_ENABLED: "1"
# §51.11.34-ROADMAP A1 — sub-goal completion writeback (the severed
# feedback wire). Default-TRUE; pinned explicit here for soak auditability.
# Closes the loop multi_step EMIT (PROPOSED) -> terminal op (COMPLETED) so
# done_count advances and GOAL-001::file-00 stops being a hostage.
JARVIS_SUBGOAL_COMPLETION_WRITEBACK_ENABLED: "1"
# Fallback-sem relief (landmine A): D2/12F-B sem-exhausted fast-fail
# confirmed live; raise rescue concurrency to the cap so boot-time op
# stacks queue less (observed 135s sem_wait on concurrency=3).
Expand Down
Loading
Loading