fix(lifecycle): research_required nonterminal disposition + recall A/B honesty + hook hardening
Pre-PL1 closure (handoff 2026-09-10): 1. research_required: new nonterminal task status (records enum, state machine edges created/running -> research_required -> running/ completed/failed/cancelled/superseded). The operator's RESEARCHED_CHANGE disposition now transitions to research_required instead of failed — research routing is not failure. Live canary: status=research_required, outcome_ref=research_dispatch, route_ref set. 2. Experience consumer skips research-dispatch tasks — no false failure-learning evidence in PL0 (verified: 0 FAILURE records for research tasks). 3. recall_uplift A/B documented honestly in the module: latency 521-1213ms → 14-18ms; terms bounded (893-1665 → 16-21); recall ROW COUNTS identical per query but 1/8-7/7 of recalled IDs differ (expansion terms differ → different lexical candidates). Marked PROVISIONAL — quality not proven equivalent; harness original retained for rollback. 4. Hook hardening: durable fire-trace (/tmp/rune-bridge-fire.log, one line per actual injection with token count) + harness-internal-step guard (checkpoint-writer/compaction steps no longer receive capsules). 5. QX7 canary fully purged: entries, contentless-FTS ghosts, both stores; retrieval-level verification shows zero hits. 1227 tests pass; ratchet 353/80; henxels clean.
This commit is contained in:
1 parent
3dfb4ee9e6
commit
bf5eb53d1e
8 files changed
+120
-32
No files matched your search
@@ -158,6 +158,11 @@ def record_operator_outcomes(task_state_path: str | None = None, ledger_path: st
|
||||
status = t.get("status", "")
|
||||
if status not in ("completed", "failed"):
|
||||
continue
|
||||
# research_required tasks: routing disposition, NOT failure evidence
|
||||
# (handoff §2/§C). The dispatch lives in route.jsonl; recording it
|
||||
# as FAILURE would poison PL0 with false failure-learning pressure.
|
||||
if t.get("outcome_ref") == "research_dispatch" or t.get("result") == "RESEARCH_REQUIRED":
|
||||
continue
|
||||
task_id = t.get("task_id", "")
|
||||
if not task_id or task_id in seen_tasks:
|
||||
continue
|
||||
|
||||
Reference in new issue
Block a user