Problem
After #461 / PR #462, the runtime now emits a coherent pending policy-review promotion:
status=ready_for_policy_review
decision_record=pending_operator_review_packet
accepted_record=null
governance_packet.review_packet_status=pending_operator_review
readiness_checks.missing_inputs=[]
readiness_checks.provenance_complete=true
readiness_blocker.state=ready_for_policy_review
source_commit=2998ffa5047db482c39fae91b84d6799735a3761
Live proof from /api/promotions.items[0] after eeepc deploy/collect:
{
"identity_key": "promotion-26cbaba1d30b",
"status": "ready_for_policy_review",
"decision_record": "pending_operator_review_packet",
"accepted_record": null,
"readiness_checks": {
"artifact_present": true,
"evidence_refs_present": true,
"provenance_complete": true,
"missing_inputs": []
},
"readiness_blocker": {
"state": "ready_for_policy_review",
"recommended_next_action": "ready_for_policy_review"
},
"recommended_next_action": "ready_for_policy_review",
"governance_packet.review_packet_status": "pending_operator_review",
"governance_packet.decision": "ready_for_policy_review",
"source_commit": "2998ffa5047db482c39fae91b84d6799735a3761"
}
But Mission Control still reports:
/api/mission-control.headline = Blocked: accepted_record
/api/system.autonomy_verdict.reasons = [promotion_lifecycle_blocked]
This is a dashboard/Mission-Control classification bug: accepted_record=null is expected before acceptance when the promotion is pending policy review. It must not be treated as a blocker in the ready_for_policy_review / pending_operator_review_packet state.
Contract interpretation
A promotion with:
review_status/status=ready_for_policy_review
decision_record=pending_operator_review_packet
accepted_record=null
governance_packet.review_packet_status=pending_operator_review
is not accepted yet, but it is also not blocked. It is awaiting policy/operator review.
Blocked states should be reserved for actual gate failures such as:
not_ready_for_policy_review
blocked_not_ready
- missing readiness inputs
- missing source provenance
- missing artifact/evidence
Likely files/functions
ops/dashboard/src/nanobot_ops_dashboard/app.py
_promotion_replay_readiness_from_promotions()
_autonomy_verdict()
_mission_control_summary()
- tests likely in:
ops/dashboard/tests/test_dashboard_truth_audit_gaps.py
ops/dashboard/tests/test_app.py
ops/dashboard/tests/test_promotions_truth.py
Acceptance criteria
- Add regression coverage for a latest promotion with:
status=ready_for_policy_review
decision_record=pending_operator_review_packet
accepted_record=null
governance_packet.review_packet_status=pending_operator_review
/api/mission-control must not show Blocked: accepted_record for that state.
/api/system.autonomy_verdict.reasons must not include promotion_lifecycle_blocked solely because accepted_record is null in that state.
/api/promotions must still show the candidate as pending review, not accepted.
- Genuine
not_ready_for_policy_review / blocked_not_ready candidates must still be classified as blocked.
- Deploy to live dashboard and prove Mission Control no longer blocks on
accepted_record for the latest ready candidate, or expose the next real blocker.
Problem
After #461 / PR #462, the runtime now emits a coherent pending policy-review promotion:
status=ready_for_policy_reviewdecision_record=pending_operator_review_packetaccepted_record=nullgovernance_packet.review_packet_status=pending_operator_reviewreadiness_checks.missing_inputs=[]readiness_checks.provenance_complete=truereadiness_blocker.state=ready_for_policy_reviewsource_commit=2998ffa5047db482c39fae91b84d6799735a3761Live proof from
/api/promotions.items[0]after eeepc deploy/collect:{ "identity_key": "promotion-26cbaba1d30b", "status": "ready_for_policy_review", "decision_record": "pending_operator_review_packet", "accepted_record": null, "readiness_checks": { "artifact_present": true, "evidence_refs_present": true, "provenance_complete": true, "missing_inputs": [] }, "readiness_blocker": { "state": "ready_for_policy_review", "recommended_next_action": "ready_for_policy_review" }, "recommended_next_action": "ready_for_policy_review", "governance_packet.review_packet_status": "pending_operator_review", "governance_packet.decision": "ready_for_policy_review", "source_commit": "2998ffa5047db482c39fae91b84d6799735a3761" }But Mission Control still reports:
/api/mission-control.headline = Blocked: accepted_record/api/system.autonomy_verdict.reasons = [promotion_lifecycle_blocked]This is a dashboard/Mission-Control classification bug:
accepted_record=nullis expected before acceptance when the promotion is pending policy review. It must not be treated as a blocker in theready_for_policy_review/pending_operator_review_packetstate.Contract interpretation
A promotion with:
review_status/status=ready_for_policy_reviewdecision_record=pending_operator_review_packetaccepted_record=nullgovernance_packet.review_packet_status=pending_operator_reviewis not accepted yet, but it is also not blocked. It is awaiting policy/operator review.
Blocked states should be reserved for actual gate failures such as:
not_ready_for_policy_reviewblocked_not_readyLikely files/functions
ops/dashboard/src/nanobot_ops_dashboard/app.py_promotion_replay_readiness_from_promotions()_autonomy_verdict()_mission_control_summary()ops/dashboard/tests/test_dashboard_truth_audit_gaps.pyops/dashboard/tests/test_app.pyops/dashboard/tests/test_promotions_truth.pyAcceptance criteria
status=ready_for_policy_reviewdecision_record=pending_operator_review_packetaccepted_record=nullgovernance_packet.review_packet_status=pending_operator_review/api/mission-controlmust not showBlocked: accepted_recordfor that state./api/system.autonomy_verdict.reasonsmust not includepromotion_lifecycle_blockedsolely becauseaccepted_recordis null in that state./api/promotionsmust still show the candidate as pending review, not accepted.not_ready_for_policy_review/blocked_not_readycandidates must still be classified as blocked.accepted_recordfor the latest ready candidate, or expose the next real blocker.