feat(awooop): expose repair candidate automation closure
Some checks failed
Code Review / ai-code-review (push) Successful in 22s
CD Pipeline / tests (push) Successful in 2m4s
CD Pipeline / build-and-deploy (push) Successful in 7m32s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 22s
CD Pipeline / tests (push) Successful in 2m4s
CD Pipeline / build-and-deploy (push) Successful in 7m32s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -841,6 +841,98 @@ class RepairCandidateService:
|
||||
"assign_km_and_playbook_trust_writeback_owner",
|
||||
"rerun_repair_candidate_gate_after_owner_release",
|
||||
],
|
||||
"controlled_automation_closure": {
|
||||
"schema_version": "repair_candidate_controlled_automation_closure_v1",
|
||||
"status": "owner_review_ready_no_write_rehearsal",
|
||||
"runtime_write_gate": "closed_until_owner_release",
|
||||
"no_write_rehearsal": {
|
||||
"rehearsal_id": (
|
||||
f"repair-rehearsal:{project_id}:{incident_id}:{lane}"
|
||||
if incident_id
|
||||
else f"repair-rehearsal:{project_id}:unbound:{lane}"
|
||||
),
|
||||
"status": "ready_for_owner_review",
|
||||
"route_id": route or "--",
|
||||
"input_refs": {
|
||||
"source_work_item_id": work_item_id or None,
|
||||
"evidence_refs": list(evidence_refs),
|
||||
"coverage_key": coverage_gap.get("coverage_key"),
|
||||
},
|
||||
"planned_steps": [
|
||||
"render_repair_command_without_execution",
|
||||
"render_rollback_command_without_execution",
|
||||
"check_route_allowlist_and_target_selector",
|
||||
"produce_verifier_rehearsal_plan",
|
||||
],
|
||||
"writes_runtime_state": False,
|
||||
"executes_command": False,
|
||||
},
|
||||
"verifier_writeback_plan": {
|
||||
"verifier_id": (
|
||||
f"verifier-plan:{project_id}:{incident_id}:{lane}"
|
||||
if incident_id
|
||||
else f"verifier-plan:{project_id}:unbound:{lane}"
|
||||
),
|
||||
"status": "planned_not_executed",
|
||||
"checks": list(verifier_plan),
|
||||
"result_states": ["healthy", "degraded", "failed", "rollback_required"],
|
||||
"writes_after_execution": [
|
||||
"incident_timeline",
|
||||
"auto_repair_execution_result",
|
||||
"km_draft",
|
||||
"playbook_trust_event",
|
||||
],
|
||||
"writes_runtime_state": False,
|
||||
},
|
||||
"automation_asset_ledger": [
|
||||
{
|
||||
"asset_type": "KM",
|
||||
"asset_id": (
|
||||
f"km-draft:{project_id}:{incident_id}:{lane}"
|
||||
if incident_id
|
||||
else f"km-draft:{project_id}:unbound:{lane}"
|
||||
),
|
||||
"owner": "Hermes",
|
||||
"status": "draft_required_after_verifier",
|
||||
"next_action": "prepare_km_draft_from_incident_evidence",
|
||||
},
|
||||
{
|
||||
"asset_type": "PlayBook",
|
||||
"asset_id": (
|
||||
f"playbook-draft:{project_id}:{incident_id}:{lane}"
|
||||
if incident_id
|
||||
else f"playbook-draft:{project_id}:unbound:{lane}"
|
||||
),
|
||||
"owner": "OpenClaw",
|
||||
"status": "owner_review_ready",
|
||||
"next_action": "review_service_specific_repair_steps",
|
||||
},
|
||||
{
|
||||
"asset_type": "ScriptOrAnsible",
|
||||
"asset_id": route or "--",
|
||||
"owner": "Executor lane",
|
||||
"status": "route_allowlist_review_required",
|
||||
"next_action": "confirm_check_mode_and_blast_radius",
|
||||
},
|
||||
{
|
||||
"asset_type": "Verifier",
|
||||
"asset_id": (
|
||||
f"verifier-plan:{project_id}:{incident_id}:{lane}"
|
||||
if incident_id
|
||||
else f"verifier-plan:{project_id}:unbound:{lane}"
|
||||
),
|
||||
"owner": "PostExecutionVerifier",
|
||||
"status": "planned_not_executed",
|
||||
"next_action": "owner_review_post_apply_verifier",
|
||||
},
|
||||
],
|
||||
"operator_next_actions": [
|
||||
"review_no_write_rehearsal_inputs",
|
||||
"approve_or_reject_owner_release",
|
||||
"fill_blast_radius_maintenance_window_and_rollback_owner",
|
||||
"promote_to_controlled_apply_only_after_all_gates_pass",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
def _promotion_contract_field(
|
||||
|
||||
@@ -359,6 +359,20 @@ async def test_candidate_blocked_observe_only_prompts_repair_playbook_draft() ->
|
||||
assert "maintenance_window" in promotion_contract["blocked_fields"]
|
||||
assert promotion_contract["runtime_execution_authorized"] is False
|
||||
assert promotion_contract["runtime_write_allowed"] is False
|
||||
closure = promotion_contract["controlled_automation_closure"]
|
||||
assert closure["schema_version"] == "repair_candidate_controlled_automation_closure_v1"
|
||||
assert closure["status"] == "owner_review_ready_no_write_rehearsal"
|
||||
assert closure["runtime_write_gate"] == "closed_until_owner_release"
|
||||
assert closure["no_write_rehearsal"]["status"] == "ready_for_owner_review"
|
||||
assert closure["no_write_rehearsal"]["executes_command"] is False
|
||||
assert closure["verifier_writeback_plan"]["status"] == "planned_not_executed"
|
||||
assert "incident_timeline" in closure["verifier_writeback_plan"]["writes_after_execution"]
|
||||
assert [item["asset_type"] for item in closure["automation_asset_ledger"]] == [
|
||||
"KM",
|
||||
"PlayBook",
|
||||
"ScriptOrAnsible",
|
||||
"Verifier",
|
||||
]
|
||||
assert result.metadata["repair_candidate_promotion_contract"] == promotion_contract
|
||||
assert "promotion=6/11" in result.metadata["repair_candidate_promotion_summary"]
|
||||
assert "runtime=false" in result.metadata["repair_candidate_promotion_summary"]
|
||||
|
||||
Reference in New Issue
Block a user