diff --git a/lib/substantive_fixer.py b/lib/substantive_fixer.py index c7537b0..907f6f2 100644 --- a/lib/substantive_fixer.py +++ b/lib/substantive_fixer.py @@ -647,10 +647,25 @@ async def verdict_deadlock_reaper_cycle(conn) -> int: return 0 # Two stuck-verdict shapes: leo:rc+domain:approve, leo:skipped+domain:rc. - # Branch allowlist scopes the reaper to disposable pipeline-managed branches. - # extract/, reweave/, fix/ are content the pipeline created and can recreate; - # agent branches (theseus/, vida/, epimetheus/, etc.) are WIP feature work - # and must not be reaped — owners review their own PRs on their own cadence. + # + # Branch allowlist invariant: the reaper closes ONLY disposable, pipeline- + # generated branches — content the pipeline (or a daily cron) created and + # can recreate. Three classes qualify: + # + # extract/* — per-source extraction PRs, regenerated next ingest cycle + # reweave/* — nightly graph-edge maintenance, regenerated next reweave + # fix/* — pipeline-internal fix branches + # */research-2* — daily {agent}/research-{YYYY-MM-DD} sessions; the date + # suffix scopes this to cron-generated outputs only and + # excludes hand-named research branches like + # rio/research-batch-agents-memory-harnesses, which are + # feature work owned by the agent. + # + # WIP agent feature branches (theseus/feature-foo, epimetheus/some-fix, + # rio/research-thesis-name) are NEVER reaped — owners review their own PRs + # on their own cadence. The */research-2* pattern threads the needle: it + # picks up daily synthesis output that the agent will regenerate tomorrow + # while leaving manually-named research work alone. rows = conn.execute( """SELECT number, branch, eval_issues, leo_verdict, domain_verdict, last_attempt, fix_attempts @@ -659,7 +674,10 @@ async def verdict_deadlock_reaper_cycle(conn) -> int: AND tier0_pass = 1 AND last_attempt IS NOT NULL AND last_attempt < datetime('now', ? || ' hours') - AND (branch LIKE 'extract/%' OR branch LIKE 'reweave/%' OR branch LIKE 'fix/%') + AND (branch LIKE 'extract/%' + OR branch LIKE 'reweave/%' + OR branch LIKE 'fix/%' + OR branch LIKE '%/research-2%') AND ( (leo_verdict = 'request_changes' AND domain_verdict = 'approve') OR (leo_verdict = 'skipped' AND domain_verdict = 'request_changes')