From 0996df1bf95321e9770b362f65cdf144ec8ad92f Mon Sep 17 00:00:00 2001 From: Svrnty Date: Mon, 1 Jun 2026 06:10:15 -0400 Subject: [PATCH] Add Case Stage 6 candidate default planning --- ...TO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md | 88 +++++++++++++++ .../CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md | 101 ++++++++++++++++++ .../CTO-CASE-STAGED-PROOF-GATES.md | 7 ++ README.md | 2 + WORKBOARD.yaml | 10 ++ tools/validate_cto_child.py | 57 ++++++++++ 6 files changed, 265 insertions(+) create mode 100644 .sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md create mode 100644 .sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md diff --git a/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md b/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md new file mode 100644 index 0000000..da6f3bc --- /dev/null +++ b/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md @@ -0,0 +1,88 @@ +--- +name: cto-case-stage6-candidate-default-issues +tier: local +status: draft +owner: jp +source: .sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md +created: 2026-06-01 +last_reviewed: 2026-06-01 +lifecycle_classification: planning +core_promotion_status: not-promoted +description: Child-local issue sequence for Stage 6 Case candidate-default comparison proof. +--- + +# CTO Case Stage 6 Candidate Default Issues + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Issue Sequence + +### CTO-WORK-042 - Stage 6 Candidate Default PRD + +Type: AFK + +Status: validated. + +Blocked by: CTO-WORK-038 + +User stories covered: CTO Case Candidate Backend PRD stories 1, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13. + +What to build: Define the Stage 6 candidate-default comparison proof before implementation starts. + +Acceptance criteria: + +- [x] PRD states Stage 6 allowed mutation scope is `scoped real-repo use only`. +- [x] PRD requires Stage 5 validation before Stage 6. +- [x] PRD requires comparison against fake, Codex, and Pi where applicable. +- [x] PRD requires Harness Evidence Interface comparison, not raw backend logs alone. +- [x] PRD requires report shape, event validity, allowed-path compliance, failure closure, and artifact completeness comparison. +- [x] PRD requires current Case source admission. +- [x] PRD requires failure matrix coverage or explicit blocked rationale. +- [x] PRD requires operator acceptance after comparison proof. +- [x] PRD forbids treating Stage 6 as default activation, Core promotion, Runtime authorization, or permission for push, merge, deploy, close, PR open, issue close, public publication, vendor-source mutation, or unowned repository mutation. +- [x] Local CTO validator checks Stage 6 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-043 - Stage 6 Harness Candidate Default Comparison Route + +Type: HITL + +Status: candidate. + +Blocked by: CTO-WORK-042 + +User stories covered: CTO Case Candidate Backend PRD stories 1, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13. + +What to build: In `/home/svrnty/workspaces/hermes/cto/harness`, implement the Stage 6 candidate-default comparison route behind the existing Harness seam. + +Acceptance criteria: + +- [ ] `case` remains disabled by default. +- [ ] Stage 6 requires Stage 5 proof evidence before comparison. +- [ ] Candidate-default comparison runs or imports evidence for fake, Codex, and Pi where applicable. +- [ ] Missing comparison lane is recorded as explicitly blocked with rationale, not silently ignored. +- [ ] Comparison output records report shape parity. +- [ ] Comparison output records event validity parity. +- [ ] Comparison output records allowed-path compliance parity. +- [ ] Comparison output records failure closure parity. +- [ ] Comparison output records artifact completeness parity. +- [ ] Case source admission freshness is recorded. +- [ ] Failure matrix coverage is complete or explicitly blocked with rationale. +- [ ] Operator acceptance or rejection is recorded after comparison proof. +- [ ] Candidate-default status is recorded as evidence only; no runtime default, Core promotion, push, merge, deploy, close, PR open, issue close, public publication, vendor-source mutation, or unowned repository mutation occurs. +- [ ] Fake remains the default validation lane and broad health remains green after focused Stage 6 validation. + +Allowed files: Hermes CTO harness comparison validator, Harness docs, and tests. WebUI, Core, Case source, vendor source, unowned repositories, critical repositories, production repositories, and external developer repositories are forbidden. + +Validator: `python3 harness/runner/validate-case-stage6.py --harness-root harness --json`, then `harness/evals/health.sh --json`. + +Done evidence: Stage 6 comparison report, blocked-lane rationale where applicable, source freshness proof, failure matrix coverage proof, operator outcome, artifact digests, clean worktree, commit. + +## Granularity Check + +This is intentionally two slices: one planning route and one executable Harness comparison route. Stage 6 is not over-granular because it is the first point where Case can be discussed as candidate default, and it must separate evidence comparison from runtime default activation. diff --git a/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md b/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md new file mode 100644 index 0000000..961660f --- /dev/null +++ b/.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md @@ -0,0 +1,101 @@ +--- +name: cto-case-stage6-candidate-default-prd +tier: local +status: draft +owner: jp +source: .sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md +created: 2026-06-01 +last_reviewed: 2026-06-01 +lifecycle_classification: planning +core_promotion_status: not-promoted +description: Child-local PRD for Stage 6 Case candidate-default comparison proof. +--- + +# CTO Case Stage 6 Candidate Default PRD + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Problem Statement + +Stage 5 proves Case can change an explicitly owned low-risk Target Repository under Harness control. That is not enough to make Case the default backend. The remaining problem is comparison: Case can be discussed as candidate default only if it matches or beats the existing lanes on evidence completeness, failure closure, and bounded execution behavior. + +## Solution + +Define Stage 6 as a comparison and default-candidacy gate behind the existing CTO Harness seam. Stage 6 allowed mutation scope is `scoped real-repo use only`. Case remains disabled by default until comparison evidence exists against fake, Codex, and Pi where applicable. The CTO Product Surface may record candidate-default eligibility only after the Harness proves report shape, event validity, allowed-path compliance, failure closure, artifact completeness, source freshness, and operator acceptance. + +## Scope + +- Define Stage 6 entry gates, non-goals, acceptance criteria, validation, risks, dependencies, and success definition. +- Require Stage 5 validation before Stage 6. +- Require comparison fixtures for fake, Codex, and Pi where applicable. +- Require current Case source admission before any candidate-default claim. +- Require complete failure matrix coverage or explicit blocked rationale for each uncovered row. +- Require candidate-default evidence to use the Harness Evidence Interface. +- Require operator acceptance after comparison proof. +- Keep Core promotion, runtime default switching, merge, deploy, push, and close out of scope. + +## Non-Goals + +- Do not make Case the default backend. +- Do not authorize production, critical, customer, vendor, external developer, or unowned repository mutation. +- Do not promote any CTO artifact into Core. +- Do not add Hermes WebUI Runtime behavior. +- Do not remove fake, Codex, or Pi comparison lanes. +- Do not treat one passing owned-repo run as candidate-default proof. +- Do not let Case choose its own eligibility, authority, target, model, or approval. + +## User Stories + +1. As JP, I want Case compared against existing lanes before default candidacy, so that stronger coding behavior does not bypass evidence discipline. +2. As Cortex, I want candidate-default claims to remain child-local until Core promotion, so that execution backend choice cannot create authority. +3. As Hermes, I want comparison proof to be replayable through Harness artifacts, so that operator control and visualization remain grounded in evidence. +4. As CTO, I want backend eligibility separated from backend execution, so that Case cannot approve itself. +5. As CTO Harness, I want the same evidence interface across fake, Codex, Pi, and Case, so that comparison is mechanical rather than conversational. +6. As a Target Repository owner, I want allowed-path and forbidden-action proof preserved in Stage 6, so that scoped real-repo use stays bounded. +7. As a reviewer, I want failure matrix closure before default candidacy, so that known bad states fail closed. + +## Acceptance Criteria + +- [ ] Stage 6 requires Stage 5 validation evidence before candidate-default comparison. +- [ ] Stage 6 allowed mutation scope is `scoped real-repo use only`. +- [ ] Case remains disabled by default until Stage 6 evidence is recorded. +- [ ] Candidate-default proof compares Case against fake, Codex, and Pi where applicable. +- [ ] Comparison evidence uses the Harness Evidence Interface, not raw backend logs alone. +- [ ] Case matches or beats existing lanes on report shape. +- [ ] Case matches or beats existing lanes on event validity. +- [ ] Case matches or beats existing lanes on allowed-path compliance. +- [ ] Case matches or beats existing lanes on failure closure. +- [ ] Case matches or beats existing lanes on artifact completeness. +- [ ] Case source admission freshness is recorded. +- [ ] Failure matrix rows are covered or explicitly blocked with rationale. +- [ ] Operator acceptance is recorded after comparison proof. +- [ ] No push, merge, deploy, close, PR open, issue close, public publication, Core mutation, vendor-source mutation, or unowned repository mutation is authorized. +- [ ] Local CTO validator checks Stage 6 PRD and issue artifacts. + +## Validation + +Planning validator: `python3 tools/validate_cto_child.py`. + +Implementation validator planned for Hermes: `python3 harness/runner/validate-case-stage6.py --harness-root harness --json`, then `harness/evals/health.sh --json` after focused Stage 6 validation passes. + +## Risks + +- Candidate-default language may be mistaken for default backend activation. +- Comparison may be too weak if it checks only pass status and not evidence completeness. +- Codex or Pi may be unavailable in a specific environment; that must become explicit `where applicable` rationale, not silent omission. +- Failure matrix gaps may be hidden by green happy-path runs. +- Source admission may become stale after earlier Stage 5 proof. + +## Dependencies + +- Stage 5 owned noncritical repository proof is validated. +- Harness Evidence Interface contract remains active. +- Case source admission record remains current. +- Case adapter contract remains active. +- Failure fixture matrix remains active. +- Existing fake lane remains the default validation lane. +- Codex and Pi comparison lanes are used where applicable or explicitly blocked with rationale. + +## Success Definition + +Stage 6 is successful when the CTO Product Surface can record Case as a candidate-default backend only after Harness comparison evidence proves Case matches or beats fake, Codex, and Pi where applicable on report shape, event validity, allowed-path compliance, failure closure, and artifact completeness, with current source admission, failure matrix coverage, operator acceptance, and no authority drift. diff --git a/.sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md b/.sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md index e89f2df..46cbb13 100644 --- a/.sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md +++ b/.sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md @@ -304,6 +304,8 @@ Promotion condition: ## Stage 6 - Candidate Default +Status: planned. Execution remains candidate until `CTO-WORK-043` produces Harness comparison evidence after Stage 6 PRD validation. + Entry gates: - Stage 5 is validated. @@ -337,6 +339,11 @@ Promotion condition: - Case may be discussed as candidate default only after comparison evidence shows it matches or beats fake, Codex, and Pi where applicable on evidence completeness and failure closure. +Planning evidence: + +- Stage 6 PRD: `.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md`. +- Stage 6 issues: `.sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md`. + ## Final Guard These staged proof gates do not implement Case and do not authorize execution. They define the minimum route for later implementation. diff --git a/README.md b/README.md index e89e4f1..c78d205 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ This workspace is registered as a child-local planning workspace. Registration d | |-- CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md | |-- CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION-TEMPLATE.md | |-- CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json +| |-- CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md +| |-- CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md | |-- CTO-CASE-PROVIDER-ADMISSION-PRD.md | |-- CTO-CASE-PROVIDER-ADMISSION-ISSUES.md | |-- CTO-CASE-PROVIDER-BUILD-PRD.md diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 6f08af8..c174a8f 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -205,3 +205,13 @@ items: status: validated source: .sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md owner: "" + - id: CTO-WORK-042 + title: Stage 6 Candidate Default PRD + status: validated + source: .sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md + owner: "" + - id: CTO-WORK-043 + title: Stage 6 Harness Candidate Default Comparison Route + status: candidate + source: .sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md + owner: jp diff --git a/tools/validate_cto_child.py b/tools/validate_cto_child.py index 8747c9f..9ea84b6 100644 --- a/tools/validate_cto_child.py +++ b/tools/validate_cto_child.py @@ -36,6 +36,8 @@ REQUIRED_FILES = [ ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md", ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION-TEMPLATE.md", ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json", + ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md", + ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md", ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-PRD.md", ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md", ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md", @@ -339,6 +341,29 @@ REQUIRED_STAGE5_ISSUE_IDS = [ "CTO-WORK-041", ] +REQUIRED_STAGE6_PRD_PHRASES = [ + "Local planning SOT only. Not a Core Protocol. Not active Core authority.", + "Stage 6 allowed mutation scope is `scoped real-repo use only`.", + "Stage 5 validation before Stage 6", + "fake, Codex, and Pi where applicable", + "Harness Evidence Interface, not raw backend logs alone", + "report shape", + "event validity", + "allowed-path compliance", + "failure closure", + "artifact completeness", + "Case source admission freshness", + "Failure matrix rows are covered or explicitly blocked with rationale.", + "Operator acceptance is recorded after comparison proof.", + "Do not make Case the default backend.", + "Stage 6 is successful when the CTO Product Surface can record Case as a candidate-default backend only after Harness comparison evidence proves Case matches or beats fake, Codex, and Pi where applicable", +] + +REQUIRED_STAGE6_ISSUE_IDS = [ + "CTO-WORK-042", + "CTO-WORK-043", +] + REQUIRED_STAGE5_TARGET_ADMISSION_TEMPLATE_PHRASES = [ "Local planning SOT only. Not a Core Protocol. Not active Core authority.", "This artifact is a template only. No Target Repository is admitted by this file.", @@ -1093,6 +1118,28 @@ def main() -> int: if key.lower() in {"api_key", "apikey", "access_token", "token", "secret", "password", "credential_value"}: errors.append(f"stage5_target_admission_forbidden_secret_key:{key}") + stage6_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md" + if stage6_prd.is_file(): + text = stage6_prd.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("stage6_prd_missing_not_promoted_frontmatter") + for phrase in REQUIRED_STAGE6_PRD_PHRASES: + checked.append(f"stage6_prd_phrase:{phrase}") + if phrase not in text: + errors.append(f"missing_stage6_prd_phrase:{phrase}") + + stage6_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md" + if stage6_issues.is_file(): + text = stage6_issues.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("stage6_issues_missing_not_promoted_frontmatter") + if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text: + errors.append("stage6_issues_missing_local_planning_notice") + for issue_id in REQUIRED_STAGE6_ISSUE_IDS: + checked.append(f"stage6_issue_id:{issue_id}") + if issue_id not in text: + errors.append(f"missing_stage6_issue_id:{issue_id}") + provider_admission_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-PRD.md" if provider_admission_prd.is_file(): text = provider_admission_prd.read_text(encoding="utf-8") @@ -1296,6 +1343,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_STAGE6_ISSUE_IDS: + 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_PROVIDER_ADMISSION_ISSUE_IDS: checked.append(f"workboard_id:{issue_id}") if issue_id not in text: @@ -1354,6 +1405,8 @@ def main() -> int: "CTO-WORK-039": "validated", "CTO-WORK-040": "validated", "CTO-WORK-041": "validated", + "CTO-WORK-042": "validated", + "CTO-WORK-043": "candidate", } for issue_id, expected in expected_statuses.items(): checked.append(f"workboard_status:{issue_id}:{expected}") @@ -1396,6 +1449,10 @@ def main() -> int: errors.append("workboard_missing_stage5_target_admission_template_source") if "CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json" not in text: errors.append("workboard_missing_stage5_target_admission_json_source") + if "CTO-CASE-STAGE6-CANDIDATE-DEFAULT-PRD.md" not in text: + errors.append("workboard_missing_stage6_prd_source") + if "CTO-CASE-STAGE6-CANDIDATE-DEFAULT-ISSUES.md" not in text: + errors.append("workboard_missing_stage6_issues_source") if "CTO-CASE-PROVIDER-ADMISSION-PRD.md" not in text: errors.append("workboard_missing_provider_admission_prd_source") if "CTO-CASE-PROVIDER-ADMISSION-ISSUES.md" not in text: