Composes reconciliation as the 4th tick layer at its own cadence.
tools/controller/master/loop.py:
- MasterConfig gains reconciliation_interval_s (default 300s per
plan v9).
- MasterTickReport gains reconciliation: ReconciliationReport | None.
- master_main_loop gains reconciliation_args parameter — tuple of
(owner, repo, get_pr_state_cb, get_issue_state_cb). When provided,
runs run_reconciliation_tick every reconciliation_interval_s.
When None, reconciliation is disabled (useful for tests + one-shot
modes).
- Reconciliation exception is caught + logged; master keeps running.
- Iteration log line now includes reconciled=N.
tools/controller/master/__main__.py:
- Passes reconciliation_args from ForgejoCallbacks (built earlier
in the entry point) so the production master automatically runs
reconciliation against the configured (owner, repo).
3 new tests in test_master_loop.py:
- reconciliation_fires_when_configured: workflow with externally-
merged state → reconciliation transitions to MERGED.
- reconciliation_skipped_when_args_none: workflows untouched +
no reconciliation reports.
- reconciliation_exception_doesnt_break_loop: per-row fetch failures
don't crash the master.
Total: 433 controller tests; full auto_agents suite 2795 pass.