feat(automation): bounded-automation candidate layer (Arc D phase 1)#43
Conversation
…rc D phase 1) Add src/portfolio_automation.py: a strictly read-only trust-bar predicate (evaluate_automation_eligibility) and candidate selector (select_automation_candidates). A repo clears the bar only when the portfolio decision_quality_status is 'trusted' AND the repo has high path confidence, an active/candidate registry status, and non-trivial context quality. Blockers accumulate so the operator sees every reason a repo is held back. Surface the eligible cohort as an automation_candidates section in the weekly command-center digest + markdown. No proposals are created and nothing is applied; proposal creation (phase 2) and gated execution (phase 3) build on this signal layer. The report-only guardrail is unchanged. 24 new tests. Full suite 2341 passed, ruff clean.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ecc499ee86
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # creation, execution re-checks) reuse the exact same gate. | ||
| TRUSTED_DECISION_QUALITY = "trusted" | ||
| ELIGIBLE_PATH_CONFIDENCE = frozenset({"high"}) | ||
| ELIGIBLE_REGISTRY_STATUS = frozenset({"active", "candidate"}) |
There was a problem hiding this comment.
Use the schema's recent registry status
For snapshots produced by this repo, derived.registry_status is validated against {"active", "recent", "parked", "archived"} in src/portfolio_truth_types.py and _registry_status_for() returns the activity status except mapping stale to parked, so no valid portfolio-truth project can have "candidate". As written, a recent repo that otherwise clears decision quality, high path confidence, and usable context is always blocked as registry-status-not-eligible, so the digest silently omits eligible recent projects.
Useful? React with 👍 / 👎.
|
|
||
| ``decision_quality_status`` is the portfolio-level value (the same for every | ||
| repo in a run); the remaining checks are per-repo. Blockers accumulate so | ||
| the operator sees every reason a repo is held back, not just the first. | ||
| """ |
There was a problem hiding this comment.
Keep candidates behind the existing opt-in
This marks a repo eligible using only derived path/context/status fields, but the existing automation trust bar in src/auto_apply.py requires declared.automation_eligible and baseline risk before any repo can receive automated writes. Because catalog entries default automation_eligible to false, a trusted run with an active, high-confidence, standard-context repo that has not opted in (or has elevated risk) will still be listed under “Automation Candidates,” giving the operator a candidate that later automation phases must reject.
Useful? React with 👍 / 👎.
Arc D — Phase 1 of 3: advisory candidate layer (read-only)
First rung of the Arc D safe-automation ladder. Strictly advisory — opens no PRs, applies nothing.
What
src/portfolio_automation.py:evaluate_automation_eligibility(project, *, decision_quality_status)→AutomationEligibility(eligible, blockers). Blockers accumulate so the operator sees every reason a repo is held back.select_automation_candidates(truth, *, decision_quality_status)→ sorted, capped list ofAutomationCandidate.decision_quality_status == "trusted"AND repopath_confidence == "high"ANDregistry_status ∈ {active, candidate}ANDcontext_quality ∈ {minimum-viable, standard, full}.automation_candidatessection into the weekly command-center digest + markdown.Safety
decision_qualitygate means: when calibration is noisy/mixed/insufficient, zero repos are eligible.decision_quality_statusis sourced once (normalized toinsufficient-data) so the displayed status and the gate can never diverge (/code-reviewfinding, applied).Tests / gates
tests/test_portfolio_automation.py): every blocker, accumulation, selection/sort/cap, missing-identity safety, digest integration (trusted → surfaced, not-trusted → empty).ruff check .clean./code-reviewrun, findings applied.Next: phase 2 (durable proposal queue + real approval gate), phase 3 (gated executor + auto-PR with dry-run/never-main/skip-dirty rails).