From 272ff4550e98dd6b1307658d646d1e53f9b80810 Mon Sep 17 00:00:00 2001 From: Svrnty Date: Sun, 31 May 2026 19:36:00 -0400 Subject: [PATCH] Add CTO Case provider build route --- README.md | 4 +- WORKBOARD.yaml | 10 +++ .../CTO-CASE-PROVIDER-BUILD-ISSUES.md | 49 ++++++++++++ .../CTO-CASE-PROVIDER-BUILD-PRD.md | 73 +++++++++++++++++ tools/validate_cto_child.py | 80 +++++++++++++++++++ 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md create mode 100644 sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md diff --git a/README.md b/README.md index a55e1a9..7bd4a42 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,9 @@ This workspace is registered as a child-local planning workspace. Registration d | |-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md | |-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md | |-- CTO-CASE-PROVIDER-ADMISSION-PRD.md -| `-- CTO-CASE-PROVIDER-ADMISSION-ISSUES.md +| |-- CTO-CASE-PROVIDER-ADMISSION-ISSUES.md +| |-- CTO-CASE-PROVIDER-BUILD-PRD.md +| `-- CTO-CASE-PROVIDER-BUILD-ISSUES.md `-- tools/ `-- validate_cto_child.py ``` diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 53a32a8..1a7ea0e 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -70,3 +70,13 @@ items: status: validated source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md owner: jp + - id: CTO-WORK-015 + title: Durable Case Provider Build PRD + status: validated + source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md + owner: jp + - id: CTO-WORK-016 + title: Real Case Provider Stage 2 Run + status: blocked + source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md + owner: jp diff --git a/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md new file mode 100644 index 0000000..cb8e027 --- /dev/null +++ b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md @@ -0,0 +1,49 @@ +--- +title: CTO Case Provider Build Issues +status: draft +lifecycle_classification: sot +owner: jp +created: 2026-05-31 +last_reviewed: 2026-05-31 +core_promotion_status: not-promoted +route: cto +--- + +# CTO Case Provider Build Issues + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## CTO-WORK-015 - Durable Case Provider Build PRD + +Status: validated. + +Register the provider build route that separates source discovery from executable admission. + +Acceptance: + +- Records WorkOS Case source `https://github.com/workos/case.git`. +- Records pinned commit `7959ac917cdeb0983b4aaa20bb9f42021747fed8`. +- Records local build dependency status: Node `v20.19.5` present, Bun missing. +- Requires `bun run build:binary` to produce `dist/ca` before real Stage 2 can pass. +- Requires SHA-256 digest for admitted `dist/ca`. +- Keeps `/tmp` clone as discovery evidence only. + +## CTO-WORK-016 - Real Case Provider Stage 2 Run + +Status: blocked. + +Build or supply a durable admitted WorkOS Case `ca` executable, then run the existing Hermes CTO Stage 2 artificial fixture through real Case. + +Acceptance: + +- Bun is available, or a durable admitted `dist/ca` path is supplied with source pin and digest. +- `CTO_HARNESS_CASE_BIN` points to the admitted `ca` executable. +- Stage 2 invokes `ca run --task --mode unattended`. +- Real Case execution produces a Stage 2 pass report through the Harness Evidence Interface. +- Provider-unavailable fail-closed behavior remains tested. +- Fake remains the default validation lane. +- No Target Repository path is inspected or copied. + +Blocked by: + +- Missing local `bun` executable, unless a prebuilt admitted `dist/ca` is supplied. diff --git a/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md new file mode 100644 index 0000000..acbf1c4 --- /dev/null +++ b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md @@ -0,0 +1,73 @@ +--- +title: CTO Case Provider Build PRD +status: draft +lifecycle_classification: sot +owner: jp +created: 2026-05-31 +last_reviewed: 2026-05-31 +core_promotion_status: not-promoted +route: cto +--- + +# CTO Case Provider Build PRD + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Problem Statement + +Stage 2 now has a validated Case task adapter, but it still cannot complete with real WorkOS Case because no durable admitted `ca` executable exists. Discovery found Node `v20.19.5`, no local `bun` executable, no `dist/ca`, no PATH `ca`, and a pinned WorkOS Case source checkout at commit `7959ac917cdeb0983b4aaa20bb9f42021747fed8` under `/tmp`, which is discovery evidence only. + +## Solution + +Create a governed provider build and admission route that can produce or accept a durable WorkOS Case `ca` executable, record its source pin and SHA-256 digest, and then allow the Hermes CTO harness to run Stage 2 with `CTO_HARNESS_CASE_BIN` only after identity and command-shape checks pass. + +## Scope + +- Build or admit WorkOS Case from `https://github.com/workos/case.git` at pinned commit `7959ac917cdeb0983b4aaa20bb9f42021747fed8` or a later recorded pin. +- Require Bun before `bun install` or `bun run build:binary` can run. +- Record the resulting `dist/ca` path and SHA-256 digest. +- Prove the executable is WorkOS Case, not the unrelated npm `case` package. +- Run Stage 2 through the existing Hermes CTO Harness Evidence Interface. +- Preserve `ca run --task --mode unattended` as the only Stage 2 command shape. +- Require the task file to expose only copied artificial fixture inputs, allowed paths, forbidden actions, verification command, and evidence expectations. + +## Non-Goals + +- Do not vendor Case source into Cortex OS Core. +- Do not install or use the unrelated public npm `case` package. +- Do not mutate vendor source. +- Do not skip Stage 2. +- Do not authorize copied repo, sandbox repo, owned repo, default backend, WebUI product, or Core promotion behavior. +- Do not treat Case as CTO authority. + +## Acceptance Criteria + +- Provider build report records source URL, pinned commit, build command, `dist/ca` path, binary digest, Node version, Bun version, and build timestamp. +- Missing Bun blocks before build; it does not degrade to warning. +- Missing `dist/ca`, wrong source commit, wrong provider identity, non-executable binary, missing credentials, wrong command shape, or wrong task contract blocks. +- Current Hermes source admission status remains `not_admitted` until the provider build report is recorded. +- Stage 2 with `CTO_HARNESS_CASE_BIN=` produces a pass report only through real Case execution. +- Stage 2 without provider continues to fail closed as `provider unavailable`. +- Fake remains the default validation lane. +- Same-run fake baseline comparison remains required. +- Stage 2 records `report.json`, `report.md`, `events.normalized.jsonl`, `trace.jsonl`, `patch.diff`, `test.log`, backend raw logs, artifact digests, and freshness proof. +- Stage 2 records `source_admission_status`, `case_process_started`, `backend_exit_code`, `allowed_writes_passed`, `changed_files`, and `blockers`. +- No Cortex Core, Case source, vendor source, or Target Repository file is mutated by admission. + +## Validation + +- `python3 tools/validate_cto_child.py` validates this child-local route. +- Hermes provider validation must include `python3 harness/runner/validate-case-provider-adapter.py --harness-root harness --json`. +- Real provider validation must include `CTO_HARNESS_ALLOW_CASE=1 CTO_HARNESS_CASE_STAGE=2 CTO_HARNESS_CASE_BIN= harness/evals/run-case.sh r1-string-slugify --engine case --json`. +- Aggregate validation remains `harness/evals/health.sh --json` after focused gates pass. + +## Risks And Dependencies + +- Bun is not currently available on this host; provider build is blocked until Bun is installed or an admitted `dist/ca` is supplied. +- WorkOS Case is `private: true`; public npm `case` is unrelated. +- License status remains unresolved for broader execution modes. +- Case may need model credentials for real execution; no secrets may be placed in docs, argv, logs, or task files. + +## Success Definition + +Stage 2 moves from provider-unavailable blocked status to a real Case pass report while preserving the same harness evidence shape, allowed-write control, artifact digests, no-target-inspection proof, and fail-closed behavior. diff --git a/tools/validate_cto_child.py b/tools/validate_cto_child.py index 9600fd3..a6d7bc9 100644 --- a/tools/validate_cto_child.py +++ b/tools/validate_cto_child.py @@ -30,6 +30,8 @@ REQUIRED_FILES = [ "sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-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", + "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md", ] REQUIRED_BRIEF_PHRASES = [ @@ -285,6 +287,52 @@ REQUIRED_PROVIDER_ADMISSION_ISSUE_IDS = [ "CTO-WORK-014", ] +REQUIRED_PROVIDER_BUILD_PRD_PHRASES = [ + "Local planning SOT only. Not a Core Protocol. Not active Core authority.", + "no durable admitted `ca` executable exists", + "Node `v20.19.5`, no local `bun` executable", + "no `dist/ca`, no PATH `ca`", + "https://github.com/workos/case.git", + "7959ac917cdeb0983b4aaa20bb9f42021747fed8", + "discovery evidence only", + "durable WorkOS Case `ca` executable", + "source pin and SHA-256 digest", + "CTO_HARNESS_CASE_BIN", + "bun run build:binary", + "dist/ca", + "unrelated npm `case` package", + "ca run --task --mode unattended", + "allowed paths, forbidden actions, verification command, and evidence expectations", + "Missing Bun blocks before build; it does not degrade to warning.", + "missing credentials", + "Stage 2 with `CTO_HARNESS_CASE_BIN=` produces a pass report only through real Case execution.", + "Current Hermes source admission status remains `not_admitted` until the provider build report is recorded.", + "Same-run fake baseline comparison remains required", + "report.json", + "report.md", + "events.normalized.jsonl", + "trace.jsonl", + "patch.diff", + "test.log", + "backend raw logs", + "artifact digests", + "freshness proof", + "source_admission_status", + "case_process_started", + "backend_exit_code", + "allowed_writes_passed", + "changed_files", + "blockers", + "No Cortex Core, Case source, vendor source, or Target Repository file is mutated by admission.", + "harness/evals/health.sh --json", + "Stage 2 moves from provider-unavailable blocked status to a real Case pass report", +] + +REQUIRED_PROVIDER_BUILD_ISSUE_IDS = [ + "CTO-WORK-015", + "CTO-WORK-016", +] + def workboard_status(text: str, issue_id: str) -> str | None: pattern = rf"- id: {re.escape(issue_id)}\n(?: .+\n)*? status: ([^\n]+)" @@ -454,6 +502,28 @@ def main() -> int: if issue_id not in text: errors.append(f"missing_provider_admission_issue_id:{issue_id}") + provider_build_prd = ROOT / "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-PRD.md" + if provider_build_prd.is_file(): + text = provider_build_prd.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("provider_build_prd_missing_not_promoted_frontmatter") + for phrase in REQUIRED_PROVIDER_BUILD_PRD_PHRASES: + checked.append(f"provider_build_prd_phrase:{phrase}") + if phrase not in text: + errors.append(f"missing_provider_build_prd_phrase:{phrase}") + + provider_build_issues = ROOT / "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-BUILD-ISSUES.md" + if provider_build_issues.is_file(): + text = provider_build_issues.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("provider_build_issues_missing_not_promoted_frontmatter") + if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text: + errors.append("provider_build_issues_missing_local_planning_notice") + for issue_id in REQUIRED_PROVIDER_BUILD_ISSUE_IDS: + checked.append(f"provider_build_issue_id:{issue_id}") + if issue_id not in text: + errors.append(f"missing_provider_build_issue_id:{issue_id}") + board = ROOT / "WORKBOARD.yaml" if board.is_file(): text = board.read_text(encoding="utf-8") @@ -473,6 +543,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_PROVIDER_BUILD_ISSUE_IDS: + 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-002": "validated", "CTO-WORK-003": "validated", @@ -487,6 +561,8 @@ def main() -> int: "CTO-WORK-012": "blocked", "CTO-WORK-013": "validated", "CTO-WORK-014": "validated", + "CTO-WORK-015": "validated", + "CTO-WORK-016": "blocked", } for issue_id, expected in expected_statuses.items(): checked.append(f"workboard_status:{issue_id}:{expected}") @@ -517,6 +593,10 @@ def main() -> int: errors.append("workboard_missing_provider_admission_prd_source") if "CTO-CASE-PROVIDER-ADMISSION-ISSUES.md" not in text: errors.append("workboard_missing_provider_admission_issues_source") + if "CTO-CASE-PROVIDER-BUILD-PRD.md" not in text: + errors.append("workboard_missing_provider_build_prd_source") + if "CTO-CASE-PROVIDER-BUILD-ISSUES.md" not in text: + errors.append("workboard_missing_provider_build_issues_source") payload = { "ok": not errors,