feat(automation): Arc D phase 3b — content-gen + orchestrator + triage CLI#46
Merged
Conversation
…ibrary) Wire the gated executor (3a) to the recovery content primitives and drive the load -> filter-approved -> plan -> execute -> mark-executed -> save loop. - build_context_pr_plan: ExecutionPlan whose apply_change regenerates the managed context block via recovery's _build_context_sections + render/upsert_managed_context_block (byte-identical to the direct-apply path). - build_catalog_seeds_for: reuses _suggested_catalog_seed, keyed by catalog key. - execute_approved_proposals: routes only APPROVED proposals by action_type; real apply transitions to EXECUTED + persists; skips context-PR with empty repo_full_name (no fabricated slug); resolves by slug then display_name. 13 tests, FakeRunner-injected (no real git/network).
Wire the bounded-automation lifecycle into the triage/report CLI: --propose-automation, --list-proposals, --approve-proposal <id>, --reject-proposal <id>, --execute-proposals [--apply] (dry-run unless --apply). - _add_automation_proposal_flags shared helper on both report subparser + legacy parser; mode inference + legacy-argv rewrite updated to route the flags. - _run_automation_proposals_mode handler; execute short-circuits before building the (expensive) portfolio snapshot when nothing is approved. - Output uses 'status: id' form (no [brackets]) so Rich markup never eats it. 5 CLI integration tests (drive main() through list/approve/reject); report flag-count guardrail raised 35->41 for the 6 new flags.
- execute_approved_proposals: isolate each proposal's execution (extract _dispatch_proposal); an AutomationExecutionError or catalog OSError now becomes a 'failed' result for that proposal instead of aborting the whole batch and silently dropping the rest. New test pins the guarantee. - Extract write_managed_context_block in portfolio_context_recovery and reuse it from both apply_context_recovery_plan and the context-PR plan, so the two render paths share one source of truth (kills the byte-identical-by-hope dup). - Derive the save condition from results instead of a parallel applied_any flag.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Arc D phase 3b — the last rung of Safe Automation
Wires the gated executor (3a, #45) to the recovery content primitives and exposes the full lifecycle on the CLI. Built library-first, CLI last, so nothing dangerous landed half-wired.
Library:
src/automation_workflow.pybuild_context_pr_plan— anExecutionPlanwhoseapply_changerefreshes the managed context block via the sharedwrite_managed_context_block(extracted inportfolio_context_recovery, so the auto-PR content is byte-identical to the direct-apply recovery path — enforced by reuse, not a comment).build_catalog_seeds_for— reuses_suggested_catalog_seed, keyed by catalog repo key.execute_approved_proposals—load → filter-approved → plan → execute → mark-executed → save. Routes byaction_type; only a real apply transitions to EXECUTED + persists. Each proposal's execution is isolated: a safety-rail violation or catalog I/O error becomes afailedresult, never aborting the batch.repo_full_nameis skipped (no fabricated head/base ref); resolution is by GitHub slug then display name (mirrors risk keying for spaced names).CLI:
src/cli.py--propose-automation,--list-proposals,--approve-proposal <id>,--reject-proposal <id>,--execute-proposals [--apply](dry-run unless--apply). Execute short-circuits before building the expensive portfolio snapshot when nothing is approved.Safety
authority_capunchanged; the operator approval workflow remains the gate.Tests / verification
FakeRunner-injected (no real git/network). Full suite 2413 passed, 2 skipped,ruffclean./code-reviewrun; fixes applied (per-proposal exception isolation, shared managed-block helper, derived save condition). Deferred findings documented in commit/PR thread (default-branch=main is a documented param; branch-orphan + empty execution_ref live in the untouched 3a executor).Known limitation:
default_branchdefaults tomain(canonical + portfolio convention); per-repo default-branch detection is a follow-up.