Add CTO Core route admission guard

This commit is contained in:
Svrnty
2026-06-02 07:11:41 -04:00
parent 205ce424e9
commit d69b6b9ad8
11 changed files with 568 additions and 2 deletions
+167
View File
@@ -88,6 +88,10 @@ REQUIRED_FILES = [
".sot/03-PROTOCOLS/CTO-CORE-PROMOTION-DECISION-PACKET-ISSUES.md",
".sot/03-PROTOCOLS/CTO-CORE-PROMOTION-DECISION-RECORD.md",
".sot/03-PROTOCOLS/CTO-CORE-PROMOTION-DECISION-PACKET-CLOSEOUT.md",
".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-PRD.md",
".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-ISSUES.md",
".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD.md",
".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-CLOSEOUT.md",
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-PRD.md",
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-ISSUES.md",
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-APPROVAL-PACKET.md",
@@ -1545,6 +1549,113 @@ REQUIRED_CORE_PROMOTION_DECISION_PACKET_CLOSEOUT_PHRASES = [
"No Core Sequence Protocol route has selected CTO promotion as current work.",
]
REQUIRED_CORE_ROUTE_ADMISSION_GUARD_PRD_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"Core Route Admission Guard",
"CTO-WORK-089",
"CTO-WORK-090",
"CTO-WORK-091",
"CTO-WORK-092",
"core_route_admission_status: not_admitted",
"guard_status: blocked",
"blocked_reason: active_or_conflicting_core_work_present",
"do_not_touch_other_agent_work: true",
"ready_for_core_route_review: true",
"recommended_next_decision: open_governed_core_prd_route",
"idle_governed_core_route_required: true",
"no_active_conflicting_core_worktree_required: true",
"S135 conflict avoidance",
"Core Sequence Protocol route",
"Core validator coverage",
"No Core mutation occurs.",
"No Core reservation",
"No Core promotion occurs.",
"Do not mutate `../core/`.",
"runtime_default_activation: false",
"core_promotion_status: not-promoted",
"Do not activate Case as default backend.",
"No Core aggregate validation is required because this slice does not edit Core.",
]
REQUIRED_CORE_ROUTE_ADMISSION_GUARD_ISSUE_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"Core Route Admission Guard",
"CTO-WORK-089",
"CTO-WORK-090",
"CTO-WORK-091",
"CTO-WORK-092",
"core_route_admission_status: not_admitted",
"guard_status: blocked",
"blocked_reason: active_or_conflicting_core_work_present",
"do_not_touch_other_agent_work: true",
"ready_for_core_route_review: true",
"recommended_next_decision: open_governed_core_prd_route",
"candidate-only recommendation until guard passes",
"idle governed Core route required",
"no active conflicting Core worktree required",
"S135 conflict avoidance",
"Runtime default activation remains false.",
"Do not activate Case as default backend.",
"python3 tools/validate_cto_child.py",
]
REQUIRED_CORE_ROUTE_ADMISSION_GUARD_RECORD_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"Core Route Admission Guard",
"CTO-WORK-089",
"CTO-WORK-090",
"core_route_admission_status: not_admitted",
"guard_status: blocked",
"blocked_reason: active_or_conflicting_core_work_present",
"do_not_touch_other_agent_work: true",
"ready_for_core_route_review: true",
"recommended_next_decision: open_governed_core_prd_route",
"next_allowed_action: wait_or_open_later_core_route_when_idle",
"idle_governed_core_route_required: true",
"no_active_conflicting_core_worktree_required: true",
"runtime_default_activation: false",
"core_promotion_status: not-promoted",
"No Core mutation occurs.",
"No Core reservation occurs.",
"No Core promotion occurs.",
"Do not mutate `../core/`.",
"Runtime default activation remains false.",
"Do not activate Case as default backend.",
"This guard does not authorize another Case run.",
"S135 conflict avoidance check for `CORE-WORK-172` and `core/worktrees/core-keyvault-authmd-promotion-135`.",
"Ownership uncertainty blocks action.",
]
REQUIRED_CORE_ROUTE_ADMISSION_GUARD_CLOSEOUT_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"Core Route Admission Guard",
"CTO-WORK-089",
"CTO-WORK-090",
"CTO-WORK-091",
"CTO-WORK-092",
"core_route_admission_status: not_admitted",
"guard_status: blocked",
"blocked_reason: active_or_conflicting_core_work_present",
"do_not_touch_other_agent_work: true",
"ready_for_core_route_review: true",
"recommended_next_decision: open_governed_core_prd_route",
"next_allowed_action: wait_or_open_later_core_route_when_idle",
"idle_governed_core_route_required: true",
"no_active_conflicting_core_worktree_required: true",
"runtime_default_activation: false",
"core_promotion_status: not-promoted",
"No Core mutation occurs.",
"No Core reservation occurs.",
"No Core promotion occurs.",
"Do not mutate `../core/`.",
"Runtime default activation remains false.",
"Do not activate Case as default backend.",
"This closeout does not authorize another Case run.",
"S135 conflict avoidance remains required when `CORE-WORK-172` or `core/worktrees/core-keyvault-authmd-promotion-135` is active.",
"Do not touch other agent work.",
"candidate-only until the guard passes",
]
def workboard_status(text: str, issue_id: str) -> str | None:
pattern = rf"- id: {re.escape(issue_id)}\n(?: .+\n)*? status: ([^\n]+)"
@@ -2133,6 +2244,46 @@ def main() -> int:
if phrase not in text:
errors.append(f"missing_core_promotion_decision_packet_closeout_phrase:{phrase}")
core_route_admission_guard_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-PRD.md"
if core_route_admission_guard_prd.is_file():
text = core_route_admission_guard_prd.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("core_route_admission_guard_prd_missing_not_promoted_frontmatter")
for phrase in REQUIRED_CORE_ROUTE_ADMISSION_GUARD_PRD_PHRASES:
checked.append(f"core_route_admission_guard_prd_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_core_route_admission_guard_prd_phrase:{phrase}")
core_route_admission_guard_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-ISSUES.md"
if core_route_admission_guard_issues.is_file():
text = core_route_admission_guard_issues.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("core_route_admission_guard_issues_missing_not_promoted_frontmatter")
for phrase in REQUIRED_CORE_ROUTE_ADMISSION_GUARD_ISSUE_PHRASES:
checked.append(f"core_route_admission_guard_issue_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_core_route_admission_guard_issue_phrase:{phrase}")
core_route_admission_guard = ROOT / ".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD.md"
if core_route_admission_guard.is_file():
text = core_route_admission_guard.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("core_route_admission_guard_missing_not_promoted_frontmatter")
for phrase in REQUIRED_CORE_ROUTE_ADMISSION_GUARD_RECORD_PHRASES:
checked.append(f"core_route_admission_guard_record_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_core_route_admission_guard_record_phrase:{phrase}")
core_route_admission_guard_closeout = ROOT / ".sot/03-PROTOCOLS/CTO-CORE-ROUTE-ADMISSION-GUARD-CLOSEOUT.md"
if core_route_admission_guard_closeout.is_file():
text = core_route_admission_guard_closeout.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("core_route_admission_guard_closeout_missing_not_promoted_frontmatter")
for phrase in REQUIRED_CORE_ROUTE_ADMISSION_GUARD_CLOSEOUT_PHRASES:
checked.append(f"core_route_admission_guard_closeout_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_core_route_admission_guard_closeout_phrase:{phrase}")
prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-CANDIDATE-BACKEND-PRD.md"
if prd.is_file():
text = prd.read_text(encoding="utf-8")
@@ -2670,6 +2821,10 @@ def main() -> int:
checked.append(f"workboard_id:{issue_id}")
if issue_id not in text:
errors.append(f"missing_workboard_id:{issue_id}")
for issue_id in ["CTO-WORK-089", "CTO-WORK-090", "CTO-WORK-091", "CTO-WORK-092"]:
checked.append(f"workboard_id:{issue_id}")
if issue_id not in text:
errors.append(f"missing_workboard_id:{issue_id}")
expected_statuses = {
"CTO-WORK-001": "validated",
"CTO-WORK-002": "validated",
@@ -2756,6 +2911,10 @@ def main() -> int:
"CTO-WORK-086": "validated",
"CTO-WORK-087": "validated",
"CTO-WORK-088": "validated",
"CTO-WORK-089": "validated",
"CTO-WORK-090": "validated",
"CTO-WORK-091": "validated",
"CTO-WORK-092": "validated",
}
for issue_id, expected in expected_statuses.items():
checked.append(f"workboard_status:{issue_id}:{expected}")
@@ -2842,6 +3001,14 @@ def main() -> int:
errors.append("workboard_missing_core_promotion_decision_record_source")
if "CTO-CORE-PROMOTION-DECISION-PACKET-CLOSEOUT.md" not in text:
errors.append("workboard_missing_core_promotion_decision_packet_closeout_source")
if "CTO-CORE-ROUTE-ADMISSION-GUARD-PRD.md" not in text:
errors.append("workboard_missing_core_route_admission_guard_prd_source")
if "CTO-CORE-ROUTE-ADMISSION-GUARD-ISSUES.md" not in text:
errors.append("workboard_missing_core_route_admission_guard_issues_source")
if "CTO-CORE-ROUTE-ADMISSION-GUARD.md" not in text:
errors.append("workboard_missing_core_route_admission_guard_source")
if "CTO-CORE-ROUTE-ADMISSION-GUARD-CLOSEOUT.md" not in text:
errors.append("workboard_missing_core_route_admission_guard_closeout_source")
payload = {
"ok": not errors,