Terminal-exhaustion three-cause classifier
Goal
Add the discriminator the system lacks today: a three-cause terminal-exhaustion classifier. gap_test is purely structural (no metric reachability); this section adds the reachability + corpus-stability + remaining-work-disposition signals that separate decomposition_exhausted (do more work) from mis_fit (re-scope) and dependency_blocked (wait/relocate).
Implementation sketch
New module scripts/plan_orchestrator/terminal_exhaustion.py (script-first §4). classify_terminal_exhaustion(plan_dir) consumes ledger_evolution_runtime.state.{assemble_corpus,corpus_digest,read_no_op_record} + mission_reground.gap_test (untouched) + the remaining work_item dispositions. Verdict enum + evidence dict. Exception-safe: errors -> mis_fit (conservative existing route).
Spec references
scripts/plan_orchestrator/mission_reground.py:gap_test (structural-only, untouched); scripts/ledger_evolution_runtime/state.py:{assemble_corpus,corpus_digest,read_no_op_record}; learning-ledger.md §13 (anchor-liveness signals); script-first.md §4 (runtime layout).
Work Items
-
Define the terminal-exhaustion verdict enum
{mis_fit, decomposition_exhausted, dependency_blocked}+ an evidence dict (the gate_metric reachability reading, the corpus_digest-stability flag, the gap_test structural verdict, the remaining-work disposition tally) in a newscripts/plan_orchestrator/terminal_exhaustion.pymodule (script-first: logic in the runtime, never skill prose). -
Implement
classify_terminal_exhaustion(plan_dir) -> dictALONGSIDEmission_reground.gap_test(gap_test is structural-only and stays untouched). Reachability = residual movement towardgate_metric.directionacross recent ledger cycles AND no whole-class wall; corpus stability vialedger_evolution_runtime.state.read_no_op_record==corpus_digest(assemble_corpus(plan_dir)). -
Implement the dependency-blocked discriminator: remaining work_items classified INERT/BLOCKED against another domain (the aims-burden #275 shape) resolve to
dependency_blocked, NOTdecomposition_exhausted. Exception-safe: any IO/parse error returnsmis_fit(the conservative existing route), never raises into serve emission. -
Author pytest matrix in
scripts/plan_orchestrator/tests/covering all three verdicts on fixtures (reachable+stable -> decomposition_exhausted; unreachable -> mis_fit; INERT-remaining -> dependency_blocked) + the error-path fallback. Tests precede the implementation per TDD.
Fresh intel (regenerated)
{ “schema_version”: 1, “target”: { “kind”: “plan-section”, “ref”: “grind-exhaustion-forward-escalation/s-06c459a0” }, “generated_at”: “2026-06-19T16:39:27.235079+00:00”, “graph_state”: { “head_sha”: “a1b25f7a”, “last_code_import_at”: “2026-06-19T16:39:12.852Z”, “embedding_stale”: false, “insights_stale”: false, “cpg_stale”: false }, “surfaces”: {}, “summary”: “intel-package[plan-section:grind-exhaustion-forward-escalation/s-06c459a0] agent-authored dossier”, “degraded”: false, “dossier”: { “objective_symbols”: [], “tiers”: {}, “agent_authored”: true, “difficulty”: { “class”: “routine”, “research_online”: false, “research_mode”: “auto”, “signals”: [], “plan_dir”: “/home/eric/projects/ori_lang/plans/grind-exhaustion-forward-escalation” } } }
(full dossier: terminal-exhaustion-classifier—s-06c459a0.intel.json)