Add CTO Case provider admission route
This commit is contained in:
parent
6afe95f6b6
commit
81ebbc7666
@ -41,7 +41,9 @@ This workspace is registered as a child-local planning workspace. Registration d
|
|||||||
| |-- CTO-CASE-STAGE1-GATED-ENGINE-PRD.md
|
| |-- CTO-CASE-STAGE1-GATED-ENGINE-PRD.md
|
||||||
| |-- CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md
|
| |-- CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md
|
||||||
| |-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md
|
| |-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md
|
||||||
| `-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md
|
| |-- CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md
|
||||||
|
| |-- CTO-CASE-PROVIDER-ADMISSION-PRD.md
|
||||||
|
| `-- CTO-CASE-PROVIDER-ADMISSION-ISSUES.md
|
||||||
`-- tools/
|
`-- tools/
|
||||||
`-- validate_cto_child.py
|
`-- validate_cto_child.py
|
||||||
```
|
```
|
||||||
|
|||||||
@ -60,3 +60,13 @@ items:
|
|||||||
status: blocked
|
status: blocked
|
||||||
source: sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md
|
source: sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md
|
||||||
owner: jp
|
owner: jp
|
||||||
|
- id: CTO-WORK-013
|
||||||
|
title: Case Provider Admission PRD
|
||||||
|
status: validated
|
||||||
|
source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-PRD.md
|
||||||
|
owner: jp
|
||||||
|
- id: CTO-WORK-014
|
||||||
|
title: Hermes Case CLI Task Adapter Route
|
||||||
|
status: candidate
|
||||||
|
source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md
|
||||||
|
owner: jp
|
||||||
|
|||||||
45
sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md
Normal file
45
sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
title: CTO Case Provider Admission 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 Admission Issues
|
||||||
|
|
||||||
|
Local planning SOT only. Not a Core Protocol. Not active Core authority.
|
||||||
|
|
||||||
|
## CTO-WORK-013 - Case Provider Admission PRD
|
||||||
|
|
||||||
|
Status: validated.
|
||||||
|
|
||||||
|
Register the provider-admission product requirement that separates discovery evidence from executable admission.
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- Records WorkOS Case source as `https://github.com/workos/case.git`.
|
||||||
|
- Records pinned commit `7959ac917cdeb0983b4aaa20bb9f42021747fed8`.
|
||||||
|
- Records that the CLI binary is `ca`.
|
||||||
|
- Records that `case` on public npm is not WorkOS Case.
|
||||||
|
- Records that Bun and `bun run build:binary` are required for `dist/ca`.
|
||||||
|
- Records that Stage 2 must use `ca run --task <task-file>`.
|
||||||
|
|
||||||
|
## CTO-WORK-014 - Hermes Case CLI Task Adapter Route
|
||||||
|
|
||||||
|
Status: candidate.
|
||||||
|
|
||||||
|
Implement the smallest Hermes CTO harness change that converts the Stage 2 artificial fixture contract into a Case task file and invokes the admitted Case provider with the correct command shape.
|
||||||
|
|
||||||
|
Acceptance:
|
||||||
|
|
||||||
|
- `CTO_HARNESS_CASE_BIN` points to an admitted `ca` executable.
|
||||||
|
- Stage 2 invokes `ca run --task <task-file>`.
|
||||||
|
- The adapter does not pass a raw prompt as argv.
|
||||||
|
- Missing provider, wrong provider, wrong command shape, or wrong task contract blocks.
|
||||||
|
- The Stage 2 pass report is produced only by real Case execution.
|
||||||
|
- Provider-unavailable fail-closed behavior remains tested.
|
||||||
|
- No Target Repository path is inspected or copied.
|
||||||
67
sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-PRD.md
Normal file
67
sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-PRD.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: CTO Case Provider Admission 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 Admission PRD
|
||||||
|
|
||||||
|
Local planning SOT only. Not a Core Protocol. Not active Core authority.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Unblock Stage 2 by admitting a real WorkOS Case executable through a governed provider route, without treating Case as Cortex authority and without mutating any target repository.
|
||||||
|
|
||||||
|
## Current Evidence
|
||||||
|
|
||||||
|
- Source repo: `https://github.com/workos/case.git`.
|
||||||
|
- Pinned source commit: `7959ac917cdeb0983b4aaa20bb9f42021747fed8`.
|
||||||
|
- Package name: `case`.
|
||||||
|
- Package status: `private: true`.
|
||||||
|
- Public npm package `case` is not WorkOS Case.
|
||||||
|
- Case CLI binary name is `ca`, because `case` is a shell reserved word.
|
||||||
|
- Case setup requires Bun.
|
||||||
|
- Case standalone executable is produced by `bun run build:binary` as `dist/ca`.
|
||||||
|
- Case task execution uses `ca run --task <task-file>` or `ca session <repo-path> --task <task-file>`.
|
||||||
|
|
||||||
|
## Problem
|
||||||
|
|
||||||
|
The Hermes CTO harness has a provider-unavailable failure path, but it does not yet have an admitted durable Case provider. `CTO_HARNESS_CASE_BIN` alone is insufficient if the adapter passes a raw prompt as argv. WorkOS Case expects a task file and a Case command shape, not an arbitrary prompt string.
|
||||||
|
|
||||||
|
## Product Requirement
|
||||||
|
|
||||||
|
Create a provider admission route that proves the exact executable, command contract, and task contract before Stage 2 can pass.
|
||||||
|
|
||||||
|
## Required Contract
|
||||||
|
|
||||||
|
- The provider path must be explicit and durable; `/tmp` clones are discovery evidence only.
|
||||||
|
- The provider must be pinned to `7959ac917cdeb0983b4aaa20bb9f42021747fed8` or a later recorded pin.
|
||||||
|
- The provider must identify itself as WorkOS Case, not the unrelated npm package.
|
||||||
|
- The adapter must call `ca run --task <task-file>` for Stage 2 artificial fixture work.
|
||||||
|
- The adapter must not pass the task brief as a raw positional prompt.
|
||||||
|
- The task file must contain no Target Repository path for Stage 2.
|
||||||
|
- The run must preserve `Stage 2 allowed mutation scope is copied artificial case only`.
|
||||||
|
- Missing Bun, missing `dist/ca`, wrong commit, wrong command shape, or wrong task file means blocked.
|
||||||
|
- Case may execute only inside the Harness Evidence Interface.
|
||||||
|
- Case may recommend. Case must not approve itself.
|
||||||
|
|
||||||
|
## Acceptance Evidence
|
||||||
|
|
||||||
|
- Provider admission report records executable path, source URL, pinned commit, build command, binary digest, and command shape.
|
||||||
|
- Stage 2 pass report exists only after a real `ca run --task <task-file>` execution.
|
||||||
|
- Provider-unavailable report remains available and fail-closed.
|
||||||
|
- Fake remains the default validation lane.
|
||||||
|
- No Cortex Core, Case source, vendor source, or Target Repository file is mutated.
|
||||||
|
|
||||||
|
## Explicit Non-Goals
|
||||||
|
|
||||||
|
- Do not vendor Case source into Cortex OS Core.
|
||||||
|
- Do not install or use the unrelated npm `case` package.
|
||||||
|
- 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.
|
||||||
@ -28,6 +28,8 @@ REQUIRED_FILES = [
|
|||||||
"sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md",
|
"sot/03-PROTOCOLS/CTO-CASE-STAGE1-GATED-ENGINE-ISSUES.md",
|
||||||
"sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md",
|
"sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md",
|
||||||
"sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md",
|
"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",
|
||||||
]
|
]
|
||||||
|
|
||||||
REQUIRED_BRIEF_PHRASES = [
|
REQUIRED_BRIEF_PHRASES = [
|
||||||
@ -252,6 +254,37 @@ REQUIRED_STAGE2_ISSUE_IDS = [
|
|||||||
"CTO-WORK-012",
|
"CTO-WORK-012",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
REQUIRED_PROVIDER_ADMISSION_PRD_PHRASES = [
|
||||||
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
||||||
|
"https://github.com/workos/case.git",
|
||||||
|
"7959ac917cdeb0983b4aaa20bb9f42021747fed8",
|
||||||
|
"Package status: `private: true`.",
|
||||||
|
"Public npm package `case` is not WorkOS Case.",
|
||||||
|
"Case CLI binary name is `ca`",
|
||||||
|
"Case setup requires Bun.",
|
||||||
|
"bun run build:binary",
|
||||||
|
"dist/ca",
|
||||||
|
"ca run --task <task-file>",
|
||||||
|
"ca session <repo-path> --task <task-file>",
|
||||||
|
"CTO_HARNESS_CASE_BIN",
|
||||||
|
"WorkOS Case expects a task file and a Case command shape, not an arbitrary prompt string.",
|
||||||
|
"The provider path must be explicit and durable",
|
||||||
|
"The adapter must not pass the task brief as a raw positional prompt.",
|
||||||
|
"The task file must contain no Target Repository path for Stage 2.",
|
||||||
|
"Missing Bun, missing `dist/ca`, wrong commit, wrong command shape, or wrong task file means blocked.",
|
||||||
|
"Case may execute only inside the Harness Evidence Interface.",
|
||||||
|
"Case may recommend. Case must not approve itself.",
|
||||||
|
"Stage 2 pass report exists only after a real `ca run --task <task-file>` execution.",
|
||||||
|
"Fake remains the default validation lane.",
|
||||||
|
"Do not install or use the unrelated npm `case` package.",
|
||||||
|
"Do not treat Case as CTO authority.",
|
||||||
|
]
|
||||||
|
|
||||||
|
REQUIRED_PROVIDER_ADMISSION_ISSUE_IDS = [
|
||||||
|
"CTO-WORK-013",
|
||||||
|
"CTO-WORK-014",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def workboard_status(text: str, issue_id: str) -> str | None:
|
def workboard_status(text: str, issue_id: str) -> str | None:
|
||||||
pattern = rf"- id: {re.escape(issue_id)}\n(?: .+\n)*? status: ([^\n]+)"
|
pattern = rf"- id: {re.escape(issue_id)}\n(?: .+\n)*? status: ([^\n]+)"
|
||||||
@ -399,6 +432,28 @@ def main() -> int:
|
|||||||
if issue_id not in text:
|
if issue_id not in text:
|
||||||
errors.append(f"missing_stage2_issue_id:{issue_id}")
|
errors.append(f"missing_stage2_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")
|
||||||
|
if "core_promotion_status: not-promoted" not in text:
|
||||||
|
errors.append("provider_admission_prd_missing_not_promoted_frontmatter")
|
||||||
|
for phrase in REQUIRED_PROVIDER_ADMISSION_PRD_PHRASES:
|
||||||
|
checked.append(f"provider_admission_prd_phrase:{phrase}")
|
||||||
|
if phrase not in text:
|
||||||
|
errors.append(f"missing_provider_admission_prd_phrase:{phrase}")
|
||||||
|
|
||||||
|
provider_admission_issues = ROOT / "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-ADMISSION-ISSUES.md"
|
||||||
|
if provider_admission_issues.is_file():
|
||||||
|
text = provider_admission_issues.read_text(encoding="utf-8")
|
||||||
|
if "core_promotion_status: not-promoted" not in text:
|
||||||
|
errors.append("provider_admission_issues_missing_not_promoted_frontmatter")
|
||||||
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
||||||
|
errors.append("provider_admission_issues_missing_local_planning_notice")
|
||||||
|
for issue_id in REQUIRED_PROVIDER_ADMISSION_ISSUE_IDS:
|
||||||
|
checked.append(f"provider_admission_issue_id:{issue_id}")
|
||||||
|
if issue_id not in text:
|
||||||
|
errors.append(f"missing_provider_admission_issue_id:{issue_id}")
|
||||||
|
|
||||||
board = ROOT / "WORKBOARD.yaml"
|
board = ROOT / "WORKBOARD.yaml"
|
||||||
if board.is_file():
|
if board.is_file():
|
||||||
text = board.read_text(encoding="utf-8")
|
text = board.read_text(encoding="utf-8")
|
||||||
@ -414,6 +469,10 @@ def main() -> int:
|
|||||||
checked.append(f"workboard_id:{issue_id}")
|
checked.append(f"workboard_id:{issue_id}")
|
||||||
if issue_id not in text:
|
if issue_id not in text:
|
||||||
errors.append(f"missing_workboard_id:{issue_id}")
|
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:
|
||||||
|
errors.append(f"missing_workboard_id:{issue_id}")
|
||||||
expected_statuses = {
|
expected_statuses = {
|
||||||
"CTO-WORK-002": "validated",
|
"CTO-WORK-002": "validated",
|
||||||
"CTO-WORK-003": "validated",
|
"CTO-WORK-003": "validated",
|
||||||
@ -426,6 +485,8 @@ def main() -> int:
|
|||||||
"CTO-WORK-010": "validated",
|
"CTO-WORK-010": "validated",
|
||||||
"CTO-WORK-011": "validated",
|
"CTO-WORK-011": "validated",
|
||||||
"CTO-WORK-012": "blocked",
|
"CTO-WORK-012": "blocked",
|
||||||
|
"CTO-WORK-013": "validated",
|
||||||
|
"CTO-WORK-014": "candidate",
|
||||||
}
|
}
|
||||||
for issue_id, expected in expected_statuses.items():
|
for issue_id, expected in expected_statuses.items():
|
||||||
checked.append(f"workboard_status:{issue_id}:{expected}")
|
checked.append(f"workboard_status:{issue_id}:{expected}")
|
||||||
@ -452,6 +513,10 @@ def main() -> int:
|
|||||||
errors.append("workboard_missing_stage2_prd_source")
|
errors.append("workboard_missing_stage2_prd_source")
|
||||||
if "CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md" not in text:
|
if "CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md" not in text:
|
||||||
errors.append("workboard_missing_stage2_issues_source")
|
errors.append("workboard_missing_stage2_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:
|
||||||
|
errors.append("workboard_missing_provider_admission_issues_source")
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"ok": not errors,
|
"ok": not errors,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user