From 217efe3f0a33c85d023840660835572775196b15 Mon Sep 17 00:00:00 2001 From: Svrnty Date: Sun, 31 May 2026 19:00:20 -0400 Subject: [PATCH] Add CTO Case Stage 1 gated engine PRD --- README.md | 4 +- WORKBOARD.yaml | 10 ++ .../CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md | 79 ++++++++++++++++ .../CTO-CASE-STAGE1-GATED-ENGINE-PRD.md | 92 +++++++++++++++++++ tools/validate_cto_child.py | 57 ++++++++++++ 5 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md create mode 100644 sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md diff --git a/README.md b/README.md index 9824288..9dcd7f6 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ This workspace is registered as a child-local planning workspace. Registration d | |-- CTO-CASE-SOURCE-ADMISSION-RECORD.md | |-- CTO-CASE-ADAPTER-CONTRACT.md | |-- CTO-CASE-FAILURE-FIXTURE-MATRIX.md -| `-- CTO-CASE-STAGED-PROOF-GATES.md +| |-- CTO-CASE-STAGED-PROOF-GATES.md +| |-- CTO-CASE-STAGE1-GATED-ENGINE-PRD.md +| `-- CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md `-- tools/ `-- validate_cto_child.py ``` diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 6e5b3c3..1c35f72 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -39,3 +39,13 @@ items: status: validated source: sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md owner: jp + - id: CTO-WORK-009 + title: Stage 1 Gated Case Engine PRD + status: candidate + source: sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md + owner: jp + - id: CTO-WORK-010 + title: Stage 1 Harness Implementation Route + status: candidate + source: sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md + owner: jp diff --git a/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md b/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md new file mode 100644 index 0000000..158dd06 --- /dev/null +++ b/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md @@ -0,0 +1,79 @@ +--- +name: cto-case-stage1-gated-engine-issues +tier: local +status: draft +owner: jp +source: sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md +created: 2026-05-31 +last_reviewed: 2026-05-31 +lifecycle_classification: planning +core_promotion_status: not-promoted +description: Child-local issue sequence for Stage 1 gated Case engine proof. +--- + +# CTO Case Stage 1 Gated Engine Issues + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Issue Sequence + +### CTO-WORK-009 - Stage 1 Gated Case Engine PRD + +Type: AFK + +Blocked by: CTO-WORK-008 + +User stories covered: CTO Case Candidate Backend PRD stories 4, 5, 7, 9, 11. + +What to build: Define the Stage 1 gated Case engine proof as a child-local PRD and issue sequence before implementation starts. + +Acceptance criteria: + +- [ ] PRD states Stage 1 allowed mutation scope is `none`. +- [ ] PRD states Case is not executed. +- [ ] PRD requires blocked default-deny behavior. +- [ ] PRD requires evidence artifacts and no source mutation proof. +- [ ] PRD names `backend.gate.blocked` and `CTO_HARNESS_ALLOW_CASE=1`. +- [ ] Local CTO validator checks the PRD and issue artifact. + +Allowed files: CTO child workspace planning docs and local validator only. + +Validator: `python3 tools/validate_cto_child.py` + +Done evidence: PRD, issue artifact, validator JSON, clean worktree, commit. + +### CTO-WORK-010 - Stage 1 Harness Implementation Route + +Type: AFK + +Blocked by: CTO-WORK-009 + +User stories covered: CTO Case Candidate Backend PRD stories 4, 5, 7, 9, 11. + +What to build: In `/home/svrnty/workspaces/hermes/cto/harness`, implement a no-op gated `case` backend that proves default-deny behavior, evidence emission, and no source mutation. + +Acceptance criteria: + +- [ ] `case` backend is registered but disabled by default. +- [ ] `harness.yaml` uses `gated_by_env: CTO_HARNESS_ALLOW_CASE`. +- [ ] Usage text, argument validation, `harness.yaml`, and engine dispatch all recognize `case`. +- [ ] `--engine case` is rejected unless `CTO_HARNESS_ALLOW_CASE=1`. +- [ ] Missing gate produces blocked status. +- [ ] Missing gate emits `backend.gate.blocked` with `backend`, `gate`, `reason`, `mutation_mode`, and `case_executed: false`. +- [ ] Required Stage 1 artifacts are produced, including `report.md` and `backend/case-gate.log`. +- [ ] Fake remains default validation lane. +- [ ] No Case process runs. +- [ ] `report.json` records `source_admission_status: not_admitted` and `case_process_started: false`. +- [ ] No files under harness source checkout, target repo, Case source, vendor source, or Cortex Core are changed during execution. +- [ ] Gate runs before case workspace copy, `git init`, runner invocation, target repository inspection, or Case process start. +- [ ] Focused validator runs command-level checks for default fake, blocked `--engine case` without env, and enabled no-op Stage 1 behavior. + +Allowed files: `harness.yaml`, `harness/evals/run-case.sh`, focused Stage 1 validator, docs, and tests under the routed Hermes CTO harness. WebUI, Core, Case source, vendor source, and target repositories are forbidden. + +Validator: focused Stage 1 harness validator, plus local harness validation. + +Done evidence: Stage 1 report JSON, normalized events, artifact digests, no-mutation proof, clean worktree, commit. + +## Granularity Check + +This is intentionally two slices: one governed planning route, one future executable harness implementation. Combining them would skip the PRD-to-issue control loop. diff --git a/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md b/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md new file mode 100644 index 0000000..ecdc5da --- /dev/null +++ b/sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md @@ -0,0 +1,92 @@ +--- +name: cto-case-stage1-gated-engine-prd +tier: local +status: draft +owner: jp +source: sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md +created: 2026-05-31 +last_reviewed: 2026-05-31 +lifecycle_classification: planning +core_promotion_status: not-promoted +description: Child-local PRD for Stage 1 gated Case engine proof with no mutation and no Case execution. +--- + +# CTO Case Stage 1 Gated Engine PRD + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Problem Statement + +The CTO planning path now defines the Case candidate backend, evidence interface, source admission record, adapter contract, failure matrix, and staged proof gates. The next risk is jumping from planning into executable Case integration too broadly. Stage 1 must prove only the smallest safe executable behavior: the harness can recognize a gated `case` backend, reject it by default, and produce evidence for that rejection without mutating source or running Case. + +## Solution + +Define a no-mutation Stage 1 implementation slice for the Hermes CTO harness route. The slice creates a no-op gated `case` backend path that proves default-deny behavior and evidence emission. It does not run Case, does not inspect target repositories, does not patch files, and does not broaden Hermes WebUI behavior. + +## Scope + +- Register `case` as a gated backend in the future harness implementation. +- Require `CTO_HARNESS_ALLOW_CASE=1` before `--engine case` can proceed past the Stage 1 gate. +- Produce a blocked report when the gate is missing. +- Produce normalized events and artifacts for the blocked preflight. +- Prove no source mutation. +- Keep fake as the default validation lane. +- Route future implementation through `/home/svrnty/workspaces/hermes/cto/harness` after reading that workspace guidance and validators. + +## Non-Goals + +- Do not run Case. +- Do not create real PRs. +- Do not mutate a Target Repository. +- Do not add WebUI Product behavior. +- Do not resolve the Case license blocker. +- Do not implement artificial fixture execution. +- Do not promote any artifact into Core. +- Do not vendor Case source. + +## Acceptance Criteria + +- Stage 1 keeps allowed mutation scope as `none`. +- `case` is disabled by default. +- Missing gate produces blocked status, not warning. +- Harness evidence includes `report.json`, `report.md`, `events.normalized.jsonl`, `trace.jsonl`, no-op `patch.diff`, no-op `test.log`, and `backend/case-gate.log`. +- Report records `backend: case`, `status: blocked`, `backend_exit_code`, `blockers`, artifact paths, digests, freshness proof, `source_admission_status: not_admitted`, and `case_process_started: false`. +- Normalized events include `run.started`, `task.contract.created`, `backend.gate.blocked`, and `run.completed`. +- `backend.gate.blocked` includes `backend`, `gate`, `reason`, `mutation_mode`, and `case_executed: false`. +- Stage 1 blocked preflight may omit patch, diff, and verification events only when `report.json` records explicit `not_applicable` reasons. +- Stage 1 gate runs before case workspace copy, `git init`, runner invocation, target repository inspection, or Case process start. +- No files under harness source checkout, target repo, Case source, vendor source, or Cortex Core are changed by the Stage 1 run. Only runtime artifact directory writes are allowed. +- Implementation-time edits may touch only the routed harness files named by the implementation issue. +- Validator proves `--engine case` is rejected unless `CTO_HARNESS_ALLOW_CASE=1`. +- Validator proves fake remains the default validation lane. +- Validator proves `case` is selected through the same engine dispatch path as `fake`, `codex`, and `pi`; no separate command, script path, or special-case bypass. +- Implementation remains outside Cortex OS Core and does not claim Runtime or product readiness. + +## Validation + +- Focused Stage 1 validator must check gated `case` registration, default-deny behavior, required artifact set, normalized events, no source mutation, fake default retention, and blocked status. +- Focused Stage 1 validator must run command-level checks: default harness without engine still selects `fake`; `--engine case` without env emits blocked evidence; `CTO_HARNESS_ALLOW_CASE=1 --engine case` still does not run Case in Stage 1. +- Focused Stage 1 validator must inspect `harness.yaml`, CLI usage text, argument validation, and engine dispatch. +- Existing child-local CTO validator must require this PRD and issue artifact before later Stage 1 implementation is considered governed. +- Post-implementation validation must run the focused Stage 1 validator before any broader harness validation. + +## Risks + +- A no-op adapter can be mistaken for Case execution. +- A gate can become warning-only instead of blocking. +- Evidence can become path-only without digest or freshness proof. +- Harness code can accidentally make `case` available by default. +- Stage 1 success can be misused to justify artificial fixture or real-repo work. + +## Dependencies + +- Validated Harness Evidence Interface Contract. +- Validated Case Adapter Contract. +- Validated Case Failure Fixture Matrix. +- Validated Staged Proof Gate Records. +- Future implementation route in the harness workspace. +- Focused Stage 1 validator spec or stub before implementation edits. + +## Success Definition + +Stage 1 is successful when the future harness can prove `case` is recognized as a backend, denied by default, evidence-producing, and non-mutating. Stage 1 does not make Case executable and does not resolve Case source admission. diff --git a/tools/validate_cto_child.py b/tools/validate_cto_child.py index f37cac9..3d0ba11 100644 --- a/tools/validate_cto_child.py +++ b/tools/validate_cto_child.py @@ -23,6 +23,8 @@ REQUIRED_FILES = [ "sot/03-PROTOCOLS/CTO-CASE-ADAPTER-CONTRACT.md", "sot/03-PROTOCOLS/CTO-CASE-FAILURE-FIXTURE-MATRIX.md", "sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md", + "sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md", + "sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md", ] REQUIRED_BRIEF_PHRASES = [ @@ -182,6 +184,31 @@ REQUIRED_STAGED_PROOF_PHRASES = [ "must not skip to real-repo execution", ] +REQUIRED_STAGE1_PRD_PHRASES = [ + "Local planning SOT only. Not a Core Protocol. Not active Core authority.", + "Stage 1 must prove only the smallest safe executable behavior", + "no-op gated `case` backend path", + "It does not run Case", + "Stage 1 keeps allowed mutation scope as `none`.", + "`case` is disabled by default.", + "Missing gate produces blocked status, not warning.", + "CTO_HARNESS_ALLOW_CASE=1", + "backend.gate.blocked", + "case_process_started: false", + "source_admission_status: not_admitted", + "backend/case-gate.log", + "Stage 1 gate runs before case workspace copy", + "No files under harness source checkout, target repo, Case source, vendor source, or Cortex Core are changed by the Stage 1 run.", + "fake remains the default validation lane", + "/home/svrnty/workspaces/hermes/cto/harness", + "Stage 1 does not make Case executable", +] + +REQUIRED_STAGE1_ISSUE_IDS = [ + "CTO-WORK-009", + "CTO-WORK-010", +] + def main() -> int: checked: list[str] = [] @@ -279,6 +306,28 @@ def main() -> int: if phrase not in text: errors.append(f"missing_staged_proof_phrase:{phrase}") + stage1_prd = ROOT / "sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-PRD.md" + if stage1_prd.is_file(): + text = stage1_prd.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("stage1_prd_missing_not_promoted_frontmatter") + for phrase in REQUIRED_STAGE1_PRD_PHRASES: + checked.append(f"stage1_prd_phrase:{phrase}") + if phrase not in text: + errors.append(f"missing_stage1_prd_phrase:{phrase}") + + stage1_issues = ROOT / "sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md" + if stage1_issues.is_file(): + text = stage1_issues.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("stage1_issues_missing_not_promoted_frontmatter") + if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text: + errors.append("stage1_issues_missing_local_planning_notice") + for issue_id in REQUIRED_STAGE1_ISSUE_IDS: + checked.append(f"stage1_issue_id:{issue_id}") + if issue_id not in text: + errors.append(f"missing_stage1_issue_id:{issue_id}") + board = ROOT / "WORKBOARD.yaml" if board.is_file(): text = board.read_text(encoding="utf-8") @@ -286,6 +335,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 REQUIRED_STAGE1_ISSUE_IDS: + checked.append(f"workboard_id:{issue_id}") + if issue_id not in text: + errors.append(f"missing_workboard_id:{issue_id}") if "CTO-HARNESS-EVIDENCE-INTERFACE-CONTRACT.md" not in text: errors.append("workboard_missing_evidence_interface_contract_source") if "CTO-WORK-004" in text and "status: validated" not in text: @@ -298,6 +351,10 @@ def main() -> int: errors.append("workboard_missing_failure_matrix_source") if "CTO-CASE-STAGED-PROOF-GATES.md" not in text: errors.append("workboard_missing_staged_proof_gates_source") + if "CTO-CASE-STAGE1-GATED-ENGINE-PRD.md" not in text: + errors.append("workboard_missing_stage1_prd_source") + if "CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md" not in text: + errors.append("workboard_missing_stage1_issues_source") payload = { "ok": not errors,