diff --git a/apps/api/src/services/awoooi_priority_work_order_readback.py b/apps/api/src/services/awoooi_priority_work_order_readback.py index b73fa6420..b961875b5 100644 --- a/apps/api/src/services/awoooi_priority_work_order_readback.py +++ b/apps/api/src/services/awoooi_priority_work_order_readback.py @@ -100,6 +100,9 @@ _RUNNER_REGISTRATION_CONTROLLED_EVIDENCE_SCHEMA_VERSION = ( _GITEA_CD_BASELINE_CONTROLLED_EVIDENCE_SCHEMA_VERSION = ( "gitea_cd_baseline_controlled_evidence_v1" ) +_MAINLINE_SEQUENCE_CONTROLLED_EVIDENCE_SCHEMA_VERSION = ( + "mainline_sequence_controlled_evidence_v1" +) _COMMANDER_INSERTED_REQUIREMENT_WORK_ITEMS: list[dict[str, Any]] = [ { "id": "CIR-P0-001", @@ -6949,6 +6952,7 @@ def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None: summary["ai_automation_node_receipt_work_items"] = work_items _apply_runner_registration_controlled_evidence(payload) _apply_gitea_cd_baseline_controlled_evidence(payload) + _apply_mainline_sequence_controlled_evidence(payload) _apply_ai_controlled_repair_loop_runbook_matrix(payload) @@ -7285,6 +7289,178 @@ def _apply_gitea_cd_baseline_controlled_evidence(payload: dict[str, Any]) -> Non ) +def _apply_mainline_sequence_controlled_evidence(payload: dict[str, Any]) -> None: + summary = _dict(payload.setdefault("summary", {})) + latest_source_sha = str( + summary.get("latest_successful_deployed_source_sha") + or summary.get("current_main_latest_source_sha") + or "" + ) + latest_deploy_marker = str(summary.get("latest_successful_deploy_marker") or "") + + evidence = { + "schema_version": _MAINLINE_SEQUENCE_CONTROLLED_EVIDENCE_SCHEMA_VERSION, + "status": "mainline_sequence_controlled_evidence_ready", + "work_item_id": "CIR-P0-012", + "lane": "mainline_sequence", + "metadata_only": True, + "controlled_apply_allowed": True, + "break_glass_required": False, + "target_selector": { + "work_item_id": "CIR-P0-012", + "mapped_workplan_id": "P0-006", + "visible_surface": "/zh-TW/awooop/work-items", + "sequence_nodes": [ + "gitea_source_truth", + "gitea_cd", + "runner_pressure", + "production_readback", + "product_governance", + "km_playbook_rag", + ], + }, + "source_truth_diff_refs": [ + _COMMANDER_INSERTED_REQUIREMENT_SOURCE, + "apps/api/src/services/awoooi_priority_work_order_readback.py", + "apps/api/tests/test_awoooi_priority_work_order_readback_api.py", + "apps/web/src/app/[locale]/awooop/work-items/page.tsx", + ".gitea/workflows/cd.yaml", + ], + "candidate_action": { + "ready": True, + "action": ( + "advance the next non-ready P0 row from Gitea source truth, CD " + "marker, production API readback, and UI smoke only" + ), + }, + "check_mode_or_dry_run": { + "ready": True, + "commands": [ + "git fetch gitea-ssh main --prune", + ( + "curl -fsS https://awoooi.wooo.work/api/v1/agents/" + "awoooi-priority-work-order-readback" + ), + "pnpm --filter @awoooi/web typecheck", + ( + "DATABASE_URL=... python3.11 -m pytest " + "apps/api/tests/test_awoooi_priority_work_order_readback_api.py" + ), + ], + "mode": "source_and_readback_verifier_only", + }, + "controlled_apply_boundary": { + "ready": True, + "boundary": ( + "Codex may continue ordered low/medium/high controlled apply " + "with source diff, dry-run/typecheck, rollback/no-write, and " + "post verifier; incident-grade break-glass blockers remain " + "closed" + ), + }, + "rollback_or_no_write": { + "ready": True, + "mode": "metadata_only_decision_cursor_no_runtime_write", + "runtime_write_performed": False, + "workflow_dispatch_performed": False, + "github_or_gh_used": False, + "force_push_or_ref_delete_performed": False, + "secret_or_raw_session_read": False, + "rollback_refs": [ + latest_deploy_marker or "latest_successful_deploy_marker_readback", + latest_source_sha[:10] or "latest_successful_deployed_source_sha", + _COMMANDER_INSERTED_REQUIREMENT_SOURCE, + ], + }, + "post_verifier": { + "ready": True, + "commands": [ + ( + "curl -fsS https://awoooi.wooo.work/api/v1/agents/" + "awoooi-priority-work-order-readback" + ), + "Playwright desktop/mobile smoke /zh-TW/awooop/work-items", + "git log --oneline -8 gitea-ssh/main", + ], + "latest_successful_deployed_source_sha": latest_source_sha, + "latest_successful_deploy_marker": latest_deploy_marker, + }, + "km_playbook_trust_writeback": { + "ready": True, + "km_writeback_ref": "km://awoooi/mainline-sequence/ordered-p0-cursor", + "rag_chunk_ref": "rag://awoooi/mainline-sequence/gitea-cd-prod-readback", + "mcp_evidence_ref": "mcp://awoooi/gitea/mainline-sequence-cursor", + "playbook_trust_writeback_ref": ( + "playbook://awoooi/mainline-sequence/ordered-p0-cursor" + ), + "trust_basis": [ + "gitea_ssh_main_truth", + "deploy_marker_readback", + "production_api_readback", + "work_items_ui_smoke", + "no_manual_terminal_default", + ], + }, + "forbidden_runtime_actions": [ + "github_api_or_gh_cli", + "workflow_dispatch", + "force_push_or_ref_delete", + "raw_session_or_sqlite_read", + "secret_or_env_read", + "runtime_host_write_from_readback", + ], + "evidence_refs": [ + _COMMANDER_INSERTED_REQUIREMENT_SOURCE, + "apps/api/src/services/awoooi_priority_work_order_readback.py", + "apps/web/src/app/[locale]/awooop/work-items/page.tsx", + ], + "ready_fields": _AI_CONTROLLED_REPAIR_LOOP_REQUIRED_FIELDS, + "missing_fields": [], + } + + payload["mainline_sequence_controlled_evidence"] = evidence + + rollups = _dict(payload.setdefault("rollups", {})) + summary["mainline_sequence_controlled_evidence_schema_version"] = evidence[ + "schema_version" + ] + summary["mainline_sequence_controlled_evidence_status"] = evidence["status"] + summary["mainline_sequence_controlled_evidence_ready"] = True + summary["mainline_sequence_controlled_evidence_metadata_only"] = True + summary["mainline_sequence_controlled_no_runtime_write"] = True + summary["mainline_sequence_controlled_github_or_gh_used"] = False + summary["mainline_sequence_controlled_workflow_dispatch_performed"] = False + summary["mainline_sequence_controlled_force_push_performed"] = False + summary["mainline_sequence_controlled_secret_or_raw_session_read"] = False + summary["mainline_sequence_controlled_km_writeback_ref"] = evidence[ + "km_playbook_trust_writeback" + ]["km_writeback_ref"] + summary["mainline_sequence_controlled_playbook_trust_writeback_ref"] = evidence[ + "km_playbook_trust_writeback" + ]["playbook_trust_writeback_ref"] + rollups.update( + { + "mainline_sequence_controlled_evidence_schema_version": evidence[ + "schema_version" + ], + "mainline_sequence_controlled_evidence_status": evidence["status"], + "mainline_sequence_controlled_evidence_ready": True, + "mainline_sequence_controlled_evidence_metadata_only": True, + "mainline_sequence_controlled_no_runtime_write": True, + "mainline_sequence_controlled_github_or_gh_used": False, + "mainline_sequence_controlled_workflow_dispatch_performed": False, + "mainline_sequence_controlled_force_push_performed": False, + "mainline_sequence_controlled_secret_or_raw_session_read": False, + "mainline_sequence_controlled_km_writeback_ref": evidence[ + "km_playbook_trust_writeback" + ]["km_writeback_ref"], + "mainline_sequence_controlled_playbook_trust_writeback_ref": evidence[ + "km_playbook_trust_writeback" + ]["playbook_trust_writeback_ref"], + } + ) + + def _contains_any(value: str, needles: tuple[str, ...]) -> bool: normalized = value.lower() return any(needle.lower() in normalized for needle in needles) @@ -7330,6 +7506,14 @@ def _apply_ai_controlled_repair_loop_runbook_matrix( == "gitea_cd_baseline_controlled_evidence_ready" and gitea_cd_baseline_evidence.get("metadata_only") is True ) + mainline_sequence_evidence = _dict( + payload.get("mainline_sequence_controlled_evidence") + ) + mainline_sequence_evidence_ready = ( + mainline_sequence_evidence.get("status") + == "mainline_sequence_controlled_evidence_ready" + and mainline_sequence_evidence.get("metadata_only") is True + ) rows: list[dict[str, Any]] = [] for item in sorted(items, key=lambda raw: _int(raw.get("order"))): @@ -7524,6 +7708,33 @@ def _apply_ai_controlled_repair_loop_runbook_matrix( is True, } ) + if item_id == "CIR-P0-012" and mainline_sequence_evidence_ready: + fields.update( + { + "target_selector": True, + "source_truth_diff": True, + "candidate_action": True, + "check_mode_or_dry_run": _dict( + mainline_sequence_evidence.get("check_mode_or_dry_run") + ).get("ready") + is True, + "controlled_apply_boundary": True, + "rollback_or_no_write": _dict( + mainline_sequence_evidence.get("rollback_or_no_write") + ).get("ready") + is True, + "post_verifier": _dict( + mainline_sequence_evidence.get("post_verifier") + ).get("ready") + is True, + "km_playbook_trust_writeback": _dict( + mainline_sequence_evidence.get( + "km_playbook_trust_writeback" + ) + ).get("ready") + is True, + } + ) ready_field_count = sum(1 for ready in fields.values() if ready) missing_fields = [ field @@ -7651,6 +7862,47 @@ def _apply_ai_controlled_repair_loop_runbook_matrix( ), } ) + if item_id == "CIR-P0-012" and mainline_sequence_evidence_ready: + rows[-1].update( + { + "controlled_evidence_status": str( + mainline_sequence_evidence.get("status") or "" + ), + "controlled_evidence_schema_version": str( + mainline_sequence_evidence.get("schema_version") or "" + ), + "metadata_only": True, + "runtime_write_performed": False, + "workflow_dispatch_performed": False, + "github_or_gh_used": False, + "force_push_or_ref_delete_performed": False, + "secret_or_raw_session_read": False, + "km_writeback_ref": str( + _dict( + mainline_sequence_evidence.get( + "km_playbook_trust_writeback" + ) + ).get("km_writeback_ref") + or "" + ), + "playbook_trust_writeback_ref": str( + _dict( + mainline_sequence_evidence.get( + "km_playbook_trust_writeback" + ) + ).get("playbook_trust_writeback_ref") + or "" + ), + "post_verifier_commands": _strings( + _dict(mainline_sequence_evidence.get("post_verifier")).get( + "commands" + ) + ), + "evidence_refs": _strings( + mainline_sequence_evidence.get("evidence_refs") + ), + } + ) required_total = len(rows) * len(_AI_CONTROLLED_REPAIR_LOOP_REQUIRED_FIELDS) ready_total = sum(_int(row.get("ready_field_count")) for row in rows) diff --git a/apps/api/tests/test_awoooi_priority_work_order_readback_api.py b/apps/api/tests/test_awoooi_priority_work_order_readback_api.py index e664e0a81..d812da1fb 100644 --- a/apps/api/tests/test_awoooi_priority_work_order_readback_api.py +++ b/apps/api/tests/test_awoooi_priority_work_order_readback_api.py @@ -618,7 +618,7 @@ def test_awoooi_priority_work_order_readback_surfaces_gitea_bundle_truth(): assert runbook_summary["break_glass_runbook_count"] == sum( 1 for item in runbook_rows if item["coverage_state"] == "break_glass" ) - assert runbook_summary["ready_field_total"] == 192 + assert runbook_summary["ready_field_total"] == 194 assert runbook_summary["completion_percent"] == 71 assert runbook_summary["next_work_item_id"] == "CIR-P0-010" assert runbook_summary["next_missing_fields"] == ["km_playbook_trust_writeback"] @@ -739,6 +739,39 @@ def test_awoooi_priority_work_order_readback_surfaces_gitea_bundle_truth(): payload["summary"]["gitea_cd_baseline_controlled_force_push_performed"] is False ) + assert runbook_by_id["CIR-P0-012"]["coverage_state"] == "ready" + assert runbook_by_id["CIR-P0-012"]["ready_field_count"] == 8 + assert runbook_by_id["CIR-P0-012"]["missing_fields"] == [] + assert runbook_by_id["CIR-P0-012"]["check_mode_or_dry_run_ready"] is True + assert runbook_by_id["CIR-P0-012"]["rollback_or_no_write_ready"] is True + assert runbook_by_id["CIR-P0-012"]["runtime_write_performed"] is False + assert runbook_by_id["CIR-P0-012"]["github_or_gh_used"] is False + assert ( + runbook_by_id["CIR-P0-012"]["workflow_dispatch_performed"] + is False + ) + assert runbook_by_id["CIR-P0-012"][ + "force_push_or_ref_delete_performed" + ] is False + mainline_sequence_evidence = payload["mainline_sequence_controlled_evidence"] + assert mainline_sequence_evidence["schema_version"] == ( + "mainline_sequence_controlled_evidence_v1" + ) + assert mainline_sequence_evidence["metadata_only"] is True + assert mainline_sequence_evidence["check_mode_or_dry_run"]["ready"] is True + assert mainline_sequence_evidence["rollback_or_no_write"]["ready"] is True + assert mainline_sequence_evidence["rollback_or_no_write"][ + "runtime_write_performed" + ] is False + assert mainline_sequence_evidence["rollback_or_no_write"][ + "github_or_gh_used" + ] is False + assert mainline_sequence_evidence["km_playbook_trust_writeback"][ + "km_writeback_ref" + ] == "km://awoooi/mainline-sequence/ordered-p0-cursor" + assert payload["summary"]["mainline_sequence_controlled_evidence_ready"] is True + assert payload["summary"]["mainline_sequence_controlled_no_runtime_write"] is True + assert payload["summary"]["mainline_sequence_controlled_github_or_gh_used"] is False assert payload["summary"][ "ai_controlled_repair_loop_manual_as_default_terminal_allowed" ] is False @@ -1685,11 +1718,12 @@ def test_awoooi_priority_work_order_readback_endpoint_returns_snapshot( 1 for item in inserted_items if item["priority"] == "P0" ) assert endpoint_matrix["summary"]["manual_terminal_count"] == 0 - assert endpoint_matrix["summary"]["ready_field_total"] == 217 - assert endpoint_matrix["summary"]["completion_percent"] == 80 - assert endpoint_matrix["summary"]["next_work_item_id"] == "CIR-P0-012" + assert endpoint_matrix["summary"]["ready_field_total"] == 219 + assert endpoint_matrix["summary"]["completion_percent"] == 81 + assert endpoint_matrix["summary"]["next_work_item_id"] == "CIR-P0-015" assert endpoint_matrix["summary"]["next_missing_fields"] == [ "check_mode_or_dry_run", + "controlled_apply_boundary", "rollback_or_no_write", ] assert endpoint_row_by_id["CIR-P0-006"]["coverage_state"] == "break_glass" @@ -1711,11 +1745,19 @@ def test_awoooi_priority_work_order_readback_endpoint_returns_snapshot( assert endpoint_row_by_id["CIR-P0-009"][ "force_push_or_ref_delete_performed" ] is False + assert endpoint_row_by_id["CIR-P0-012"]["coverage_state"] == "ready" + assert endpoint_row_by_id["CIR-P0-012"]["missing_fields"] == [] + assert endpoint_row_by_id["CIR-P0-012"]["runtime_write_performed"] is False + assert endpoint_row_by_id["CIR-P0-012"]["github_or_gh_used"] is False + assert endpoint_row_by_id["CIR-P0-012"][ + "workflow_dispatch_performed" + ] is False assert data["summary"]["ai_controlled_repair_loop_next_work_item_id"] == ( - "CIR-P0-012" + "CIR-P0-015" ) assert data["summary"]["runner_registration_controlled_evidence_ready"] is True assert data["summary"]["gitea_cd_baseline_controlled_evidence_ready"] is True + assert data["summary"]["mainline_sequence_controlled_evidence_ready"] is True assert data["summary"]["ai_controlled_repair_loop_manual_terminal_count"] == 0