Plan Hermes approval state

This commit is contained in:
Svrnty 2026-06-01 07:40:37 -04:00
parent e732e1f373
commit 405ea616a5
4 changed files with 162 additions and 0 deletions

View File

@ -0,0 +1,53 @@
---
name: CTO Hermes Approval State Issues
status: candidate
lifecycle_classification: sot
owner: jp
created: 2026-06-01
last_reviewed: 2026-06-01
core_promotion_status: not-promoted
---
# CTO Hermes Approval State Issues
Local planning SOT only. Not a Core Protocol. Not active Core authority.
## CTO-WORK-062: Hermes WebUI JP Approval State PRD
Status: validated.
Acceptance criteria:
- PRD defines JP approval state scope.
- PRD keeps the surface read-only.
- PRD forbids executable approval buttons.
- PRD keeps Harness-backed summary data as source of truth.
- PRD states Hermes visualizes control state; CTO and Harness remain the gates.
## CTO-WORK-063: Hermes WebUI JP Approval State Surface
Status: candidate.
Implementation route:
- Add read-only approval posture to `/api/cto/control-summary`.
- Add `approval_required`, `approval_granted`, and `execution_allowed`.
- Add allowed next actions.
- Add blocked next actions.
- Render JP approval state in `cto_control_panel.js`.
- Add focused plugin tests.
- Record evidence after implementation.
Acceptance criteria:
- CTO control summary includes JP approval state.
- CTO control summary includes allowed next actions.
- CTO control summary includes blocked next actions.
- `approval_required` defaults to true.
- `approval_granted` defaults to false.
- `execution_allowed` defaults to false.
- Do not add executable approval buttons.
- Do not activate Case as default backend.
- Do not mutate target repositories.
- Harness-backed summary data remains the source of truth.
- Hermes visualizes control state; CTO and Harness remain the gates.

View File

@ -0,0 +1,60 @@
---
name: CTO Hermes Approval State PRD
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 PRD
Local planning SOT only. Not a Core Protocol. Not active Core authority.
## Problem
The CTO panel shows Harness proof state, but it does not yet expose JP approval state or allowed next actions. That leaves Hermes as evidence display only. The endgoal requires Hermes to provide visualization, approval, control, and replay while CTO and Harness keep execution gated.
## Scope
Add read-only approval posture to the CTO control summary and panel:
- `approval_required`
- `approval_granted`
- `execution_allowed`
- approval reason
- allowed next actions
- blocked next actions
This slice must show what can happen next, not perform the action.
## Non-goals
- Do not add executable approval buttons.
- Do not activate Case as default backend.
- Do not mutate target repositories.
- Do not edit upstream `hermes-webui`.
- Do not edit upstream `hermes-agent`.
- Do not change Cortex Core authority.
## Acceptance Criteria
- CTO control summary includes read-only approval posture.
- CTO control summary includes allowed next actions and blocked next actions.
- Approval state defaults to `approval_required: true`, `approval_granted: false`, and `execution_allowed: false`.
- Hermes panel renders JP approval state.
- Hermes panel renders allowed next actions.
- Harness-backed summary data remains the source of truth.
- Hermes visualizes control state; CTO and Harness remain the gates.
## Validation
- Focused plugin tests prove approval posture is present, safe, and rendered by static JS.
- Plugin aggregate tests pass before commit and after merge.
- CTO child validator records the planning and evidence state.
- S69 prose validator passes before final report.
## Success Definition
Hermes can show JP approval state and allowed next actions for the CTO flow without becoming an authority layer or allowing execution from the WebUI.

View File

@ -306,3 +306,13 @@ items:
status: validated
source: .sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-ISSUES.md
owner: ""
- id: CTO-WORK-062
title: Hermes WebUI JP Approval State PRD
status: validated
source: .sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-PRD.md
owner: ""
- id: CTO-WORK-063
title: Hermes WebUI JP Approval State Surface
status: candidate
source: .sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-ISSUES.md
owner: ""

View File

@ -54,6 +54,8 @@ REQUIRED_FILES = [
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-PRD.md",
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-ISSUES.md",
".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-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",
@ -205,6 +207,21 @@ REQUIRED_HERMES_WEBUI_LIVE_SMOKE_EVIDENCE_PHRASES = [
"upstream `hermes-agent` edited: false",
]
REQUIRED_HERMES_APPROVAL_STATE_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"JP approval state",
"read-only approval posture",
"allowed next actions",
"approval_required",
"approval_granted",
"execution_allowed",
"Do not add executable approval buttons.",
"Do not activate Case as default backend.",
"Do not mutate target repositories.",
"Harness-backed summary data remains the source of truth.",
"Hermes visualizes control state; CTO and Harness remain the gates.",
]
REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_EVIDENCE_PHRASES = [
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
"CTO-WORK-057",
@ -1258,6 +1275,26 @@ def main() -> int:
if phrase not in text:
errors.append(f"missing_hermes_webui_live_smoke_evidence_phrase:{phrase}")
hermes_approval_state_prd = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-PRD.md"
if hermes_approval_state_prd.is_file():
text = hermes_approval_state_prd.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("hermes_approval_state_prd_missing_not_promoted_frontmatter")
for phrase in REQUIRED_HERMES_APPROVAL_STATE_PHRASES:
checked.append(f"hermes_approval_state_prd_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_hermes_approval_state_prd_phrase:{phrase}")
hermes_approval_state_issues = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-APPROVAL-STATE-ISSUES.md"
if hermes_approval_state_issues.is_file():
text = hermes_approval_state_issues.read_text(encoding="utf-8")
if "core_promotion_status: not-promoted" not in text:
errors.append("hermes_approval_state_issues_missing_not_promoted_frontmatter")
for phrase in ["CTO-WORK-062", "CTO-WORK-063", *REQUIRED_HERMES_APPROVAL_STATE_PHRASES]:
checked.append(f"hermes_approval_state_issue_phrase:{phrase}")
if phrase not in text:
errors.append(f"missing_hermes_approval_state_issue_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")
@ -1870,6 +1907,8 @@ def main() -> int:
"CTO-WORK-059": "validated",
"CTO-WORK-060": "validated",
"CTO-WORK-061": "validated",
"CTO-WORK-062": "validated",
"CTO-WORK-063": "candidate",
}
for issue_id, expected in expected_statuses.items():
checked.append(f"workboard_status:{issue_id}:{expected}")