diff --git a/.sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-EVIDENCE.md b/.sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-EVIDENCE.md new file mode 100644 index 0000000..797321c --- /dev/null +++ b/.sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-EVIDENCE.md @@ -0,0 +1,56 @@ +--- +name: CTO Hermes Approval State Evidence +status: validated +lifecycle_classification: sot +owner: jp +created: 2026-06-01 +last_reviewed: 2026-06-01 +core_promotion_status: not-promoted +--- + +# CTO Hermes Approval State Evidence + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Scope + +This evidence closes `CTO-WORK-063`. + +The implementation adds read-only JP approval state and next-action visibility to the Hermes WebUI CTO control panel. It does not add executable approval buttons, mutate target repositories, activate Case as default backend, or change Cortex authority. + +## Implementation Evidence + +- Hermes plugin commit: `154d835 Add CTO approval state surface` +- API field: `approval_required` +- API field: `approval_granted` +- API field: `execution_allowed` +- API field: allowed next actions +- API field: blocked next actions +- UI surface: `static/cto_control_panel.js` +- Route surface: `routes/cto_control_summary.py` + +## Validation Evidence + +- Focused validation: `python3 -m pytest tests/unit/test_cto_control_summary.py tests/unit/test_cto_control_panel_static.py -q` +- Focused result: `5 passed` +- Aggregate validation before commit: `python3 scripts/ast-connection-map.py --check` +- Aggregate result before commit: `CONNECTION-MAP.md is fresh` +- Aggregate validation before commit: `python3 -m pytest tests/ -q` +- Aggregate result before commit: `103 passed, 4 skipped` +- Aggregate validation after merge: `python3 scripts/ast-connection-map.py --check` +- Aggregate result after merge: `CONNECTION-MAP.md is fresh` +- Aggregate validation after merge: `python3 -m pytest tests/ -q` +- Aggregate result after merge: `107 passed` + +## Governance Evidence + +- Harness-backed summary data remains the source of truth. +- Case runtime default active: false +- target repository mutation: false +- upstream `hermes-webui` edited: false +- upstream `hermes-agent` edited: false +- Hermes visualizes control state; CTO and Harness remain the gates. + +## Result + +`CTO-WORK-063` is validated because Hermes now exposes JP approval posture and next-action visibility without gaining execution authority. diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 8769b67..56c1a7f 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -313,6 +313,6 @@ items: owner: "" - id: CTO-WORK-063 title: Hermes WebUI JP Approval State Surface - status: candidate + status: validated source: .sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-ISSUES.md owner: "" diff --git a/tools/validate_cto_child.py b/tools/validate_cto_child.py index cb7cefa..92851bb 100644 --- a/tools/validate_cto_child.py +++ b/tools/validate_cto_child.py @@ -56,6 +56,7 @@ REQUIRED_FILES = [ ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-EVIDENCE.md", ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-PRD.md", ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-ISSUES.md", + ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-EVIDENCE.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", @@ -222,6 +223,24 @@ REQUIRED_HERMES_APPROVAL_STATE_PHRASES = [ "Hermes visualizes control state; CTO and Harness remain the gates.", ] +REQUIRED_HERMES_APPROVAL_STATE_EVIDENCE_PHRASES = [ + "Local planning SOT only. Not a Core Protocol. Not active Core authority.", + "CTO-WORK-063", + "154d835 Add CTO approval state surface", + "approval_required", + "approval_granted", + "execution_allowed", + "allowed next actions", + "blocked next actions", + "5 passed", + "107 passed", + "CONNECTION-MAP.md is fresh", + "Case runtime default active: false", + "target repository mutation: false", + "upstream `hermes-webui` edited: false", + "upstream `hermes-agent` edited: false", +] + REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_EVIDENCE_PHRASES = [ "Local planning SOT only. Not a Core Protocol. Not active Core authority.", "CTO-WORK-057", @@ -1295,6 +1314,16 @@ def main() -> int: if phrase not in text: errors.append(f"missing_hermes_approval_state_issue_phrase:{phrase}") + hermes_approval_state_evidence = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-EVIDENCE.md" + if hermes_approval_state_evidence.is_file(): + text = hermes_approval_state_evidence.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("hermes_approval_state_evidence_missing_not_promoted_frontmatter") + for phrase in REQUIRED_HERMES_APPROVAL_STATE_EVIDENCE_PHRASES: + checked.append(f"hermes_approval_state_evidence_phrase:{phrase}") + if phrase not in text: + errors.append(f"missing_hermes_approval_state_evidence_phrase:{phrase}") + hermes_real_refresh_control_replay_evidence = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-EVIDENCE.md" if hermes_real_refresh_control_replay_evidence.is_file(): text = hermes_real_refresh_control_replay_evidence.read_text(encoding="utf-8") @@ -1908,7 +1937,7 @@ def main() -> int: "CTO-WORK-060": "validated", "CTO-WORK-061": "validated", "CTO-WORK-062": "validated", - "CTO-WORK-063": "candidate", + "CTO-WORK-063": "validated", } for issue_id, expected in expected_statuses.items(): checked.append(f"workboard_status:{issue_id}:{expected}")