escalation_state

async escalation_state.get_escalation_state(redis, channel_id, user_id)

Load the escalation state for (channel, user); blank IDLE when none.

Return type:

dict[str, Any]

Parameters:
async escalation_state.save_escalation_state(redis, channel_id, user_id, state)

Persist the state JSON plus the individual observability keys.

Return type:

None

Parameters:
async escalation_state.deactivate(redis, channel_id, user_id, reason='manual')

Rule 7 — full de-escalation back to IDLE.

Return type:

None

Parameters:
escalation_state.classify_trigger(friction_buckets, star_steered=False)

Classify friction buckets into one of the 5 trigger categories.

Category 5 (Star being steered) auto-wins; then distress (fast lane), sexual spiral, cognitive rigidity, and finally general hostility. Returns 0 when nothing matched.

Return type:

int

Parameters:
escalation_state.should_escalate(state, quality)

Decide whether Parallax understanding has failed → Needle Judo.

Only meaningful after ≥1 parallax run (Rule 1: parallax-first).

Co-Regulation gates:

  • Cat 1: omega variance ≥ 0.3 OR failsafes OR same pattern 2+ times

  • Cat 2: omega variance ≥ 0.15 (distressed users route faster)

  • Cat 3: 2+ sexual-spiral hits (craving→heat→feral loop confirmed)

  • Cat 4: same lattice quadrant across 3+ parallax runs

Solo Mode (Cat 5): AUTOMATIC — any confirmed drift escalates.

Return type:

bool

Parameters:
async escalation_state.record_parallax_run(redis, channel_id, user_id, omega_variance, failsafes, star_drift=0.0)

Rule 1 bookkeeping — a parallax analysis just ran for this episode.

Return type:

None

Parameters:
async escalation_state.activate_needle_judo(redis, channel_id, user_id, mode='co_reg')

Rule 3 — flip the state machine into needle judo.

Return type:

dict[str, Any]

Parameters:
async escalation_state.record_needle_turn(redis, channel_id, user_id, hop_advanced)

Rule 4 — progress tracking. Hop advancement resets the stall clock.

Return type:

dict[str, Any]

Parameters:
escalation_state.check_reeval_due(state)

Rule 6 — parallax re-evaluation every 3 needle-judo turns.

A due re-eval is CONSUMED by record_parallax_run() (it stamps last_reeval_turns), so the same turn count can’t re-trigger it.

Return type:

bool

Parameters:

state (dict[str, Any])

async escalation_state.detect_star_drift(redis, channel_id, recent_analyses)

Compute Star’s axiom drift from the rolling analysis history.

Uses omega-variance convergence as the drift proxy: when the manifold variance collapses across consecutive analyses WHILE steering pressure is present, Star’s position is converging toward the user’s. Positive return = drift toward the user; 0.0 = stable.

The result is cached at sg:escalation:star_drift:{channel_id}.

Return type:

float

Parameters:
escalation_state.get_solo_mode_header(state, drift=0.0)

Minimal header token for the active judo mode. # ⚧️

Exactly one bare token, nothing more — SOLO when Star is self-correcting, JUDO when co-regulating the user. It rides in her normal response header; no drift values, no reasons, no bloat.

Return type:

str

Parameters:
escalation_state.quadrant_of(node_meta)

Map lattice (x, y) coordinates to a quadrant label.

Lattice geometry: low y = hot (top), high y = cold; low x = yield (left), high x = wield (right).

Return type:

str

Parameters:

node_meta (dict[str, Any] | None)

async escalation_state.evaluate_escalation(redis, channel_id, user_id, text, friction_buckets, quality, star_steered=False, star_drift=0.0, located_node='', located_quadrant='')

Run the full 7-rule ladder for one inbound message.

Called by mandatory_tool_rules conditions. Updates persisted state and returns a directive dictionary with force, state, and reason keys. The force value is parallax, needle, or none.

Rules applied: 0 classify → 1 parallax-first → 2 understanding gate → 3 activation → 4 progress tracking → 6 re-eval cadence → 7 de-escalation.

Return type:

dict[str, Any]

Parameters: