diff --git a/README.md b/README.md index b5a854d..08230d7 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,8 @@ This workspace is registered as a child-local planning workspace. Registration d | |-- CTO-CASE-LOCAL-PROVIDER-ROUTE-PRD.md | |-- CTO-CASE-LOCAL-PROVIDER-ROUTE-ISSUES.md | |-- CTO-CASE-PROVIDER-DECISION-PACKET-PRD.md -| `-- CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md +| |-- CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md +| `-- CTO-CASE-PROVIDER-DECISION-RECORD.md `-- tools/ `-- validate_cto_child.py ``` diff --git a/WORKBOARD.yaml b/WORKBOARD.yaml index 8948165..346f8e5 100644 --- a/WORKBOARD.yaml +++ b/WORKBOARD.yaml @@ -120,3 +120,8 @@ items: status: blocked source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md owner: jp + - id: CTO-WORK-025 + title: Current Case Provider Decision Record + status: validated + source: sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md + owner: jp diff --git a/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md index 250fc4c..bea133b 100644 --- a/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md +++ b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md @@ -58,3 +58,27 @@ Blocked by: - JP choosing external provider approval or local provider requirement. - Governed Core route if the decision must be promoted before provider use. + +## CTO-WORK-025 - Current Case Provider Decision Record + +Status: validated. + +Record the current fail-closed `CTO-WORK-020` decision state as `not_decided`. + +Acceptance: + +- Decision record has `decision_status`: `not_decided`. +- Provider class, provider, model, approval source, credential source class, allowed network class, and review trigger remain empty while blocked. +- Evidence sources reference existing admission and decision packet files only. +- Record says `not_decided` means no provider/model may run. +- Record says it is not provider/model admission, not Stage 2 pass evidence, and not approval for external or local provider use. +- Record says `CTO-WORK-024` remains blocked because this record does not select `external_provider_approved` or `local_provider_required`. +- Record says only JP or a governed Core route may change it away from `not_decided`. +- Record allows only `external_provider_approved` or `local_provider_required` as future non-`not_decided` values. +- Record requires no secret value in SOT, task file, argv, report, trace, backend logs, generated config, or commit. +- Record says no Target Repository path may be inspected or copied. +- Record keeps `CTO-WORK-020` as provider/model admission authority. +- Record keeps `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` as execution admission gate. +- Record keeps `CTO-WORK-024` blocked while `decision_status=not_decided`. +- Record keeps `CTO-WORK-022` blocked unless `decision_status=local_provider_required`. +- Record keeps real Case Stage 2 blocked until admitted provider/model and Harness Evidence Interface pass report exist. diff --git a/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md new file mode 100644 index 0000000..9e703f1 --- /dev/null +++ b/sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md @@ -0,0 +1,55 @@ +--- +title: CTO Case Provider Decision Record +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 Decision Record + +Local planning SOT only. Not a Core Protocol. Not active Core authority. + +## Current Decision State + +- `decision_status`: `not_decided`. +- `provider_class`: empty while blocked. +- `provider`: empty while blocked. +- `model`: empty while blocked. +- `approval_source`: empty while blocked. +- `credential_source_class`: empty while blocked; no secret value. +- `allowed_network_class`: empty while blocked. +- `review_trigger`: empty while blocked. +- `evidence_sources`: `CTO-CASE-MODEL-PROVIDER-ADMISSION-ISSUES.md`, `CTO-CASE-PROVIDER-DECISION-PACKET-PRD.md`, `CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md`. +- `effect`: `CTO-WORK-020 remains blocked until admitted provider/model and real Stage 2 pass report exist`. + +## Meaning + +`not_decided` means no provider/model may run. This record is not provider/model admission, not Stage 2 pass evidence, and not approval for external or local provider use. + +`CTO-WORK-024` remains blocked because this record does not select `external_provider_approved` or `local_provider_required`. + +## Required Change To Leave Not Decided + +Only JP or a governed Core route may change this record away from `not_decided`. + +Allowed future values: + +- `external_provider_approved`. +- `local_provider_required`. + +Any future non-`not_decided` state must include exact non-secret fields required by `CTO-WORK-020`: provider/model when applicable, approval source, credential source class, allowed network class, review trigger, and evidence expectations. + +## Safety Constraints + +- No secret value may appear in SOT, task file, argv, report, trace, backend logs, generated config, or commit. +- No Target Repository path may be inspected or copied. +- `CTO-WORK-020` remains provider/model admission authority. +- `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` remains execution admission gate. +- `CTO-WORK-024` remains blocked while `decision_status=not_decided`. +- `CTO-WORK-022` remains blocked unless `decision_status=local_provider_required`. +- Real Case Stage 2 remains blocked until admitted provider/model and Harness Evidence Interface pass report exist. +- Existing evidence paths and commits are referenced only; runtime evidence is not copied into this record. diff --git a/tools/validate_cto_child.py b/tools/validate_cto_child.py index bcd343f..5d98e45 100644 --- a/tools/validate_cto_child.py +++ b/tools/validate_cto_child.py @@ -38,6 +38,7 @@ REQUIRED_FILES = [ "sot/03-PROTOCOLS/CTO-CASE-LOCAL-PROVIDER-ROUTE-ISSUES.md", "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-PRD.md", "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md", + "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md", ] REQUIRED_BRIEF_PHRASES = [ @@ -536,6 +537,7 @@ REQUIRED_PROVIDER_DECISION_PACKET_PRD_PHRASES = [ REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_IDS = [ "CTO-WORK-023", "CTO-WORK-024", + "CTO-WORK-025", ] REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_PHRASES = [ @@ -561,6 +563,45 @@ REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_PHRASES = [ "`CTO-WORK-020` remains blocked until admitted provider/model and real Stage 2 pass report exist.", "`CTO-WORK-022` remains blocked unless `decision_status=local_provider_required`.", "Real Case Stage 2 remains blocked unless `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` exists and matches `CTO_HARNESS_CASE_MODEL_PROVIDER` and `CTO_HARNESS_CASE_MODEL`.", + "Decision record has `decision_status`: `not_decided`.", + "Provider class, provider, model, approval source, credential source class, allowed network class, and review trigger remain empty while blocked.", + "Record says `not_decided` means no provider/model may run.", + "Record says it is not provider/model admission, not Stage 2 pass evidence, and not approval for external or local provider use.", + "Record says `CTO-WORK-024` remains blocked because this record does not select `external_provider_approved` or `local_provider_required`.", + "Record says only JP or a governed Core route may change it away from `not_decided`.", + "Record allows only `external_provider_approved` or `local_provider_required` as future non-`not_decided` values.", + "Record keeps `CTO-WORK-020` as provider/model admission authority.", + "Record keeps `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` as execution admission gate.", + "Record keeps `CTO-WORK-024` blocked while `decision_status=not_decided`.", + "Record keeps `CTO-WORK-022` blocked unless `decision_status=local_provider_required`.", + "Record keeps real Case Stage 2 blocked until admitted provider/model and Harness Evidence Interface pass report exist.", +] + +REQUIRED_PROVIDER_DECISION_RECORD_PHRASES = [ + "Local planning SOT only. Not a Core Protocol. Not active Core authority.", + "`decision_status`: `not_decided`.", + "`provider_class`: empty while blocked.", + "`provider`: empty while blocked.", + "`model`: empty while blocked.", + "`approval_source`: empty while blocked.", + "`credential_source_class`: empty while blocked; no secret value.", + "`allowed_network_class`: empty while blocked.", + "`review_trigger`: empty while blocked.", + "`effect`: `CTO-WORK-020 remains blocked until admitted provider/model and real Stage 2 pass report exist`.", + "`not_decided` means no provider/model may run.", + "not provider/model admission, not Stage 2 pass evidence, and not approval for external or local provider use", + "`CTO-WORK-024` remains blocked because this record does not select `external_provider_approved` or `local_provider_required`.", + "Only JP or a governed Core route may change this record away from `not_decided`.", + "`external_provider_approved`.", + "`local_provider_required`.", + "No secret value may appear in SOT, task file, argv, report, trace, backend logs, generated config, or commit.", + "No Target Repository path may be inspected or copied.", + "`CTO-WORK-020` remains provider/model admission authority.", + "`CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` remains execution admission gate.", + "`CTO-WORK-024` remains blocked while `decision_status=not_decided`.", + "`CTO-WORK-022` remains blocked unless `decision_status=local_provider_required`.", + "Real Case Stage 2 remains blocked until admitted provider/model and Harness Evidence Interface pass report exist.", + "Existing evidence paths and commits are referenced only; runtime evidence is not copied into this record.", ] @@ -832,6 +873,16 @@ def main() -> int: if phrase not in text: errors.append(f"missing_provider_decision_packet_issue_phrase:{phrase}") + provider_decision_record = ROOT / "sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-RECORD.md" + if provider_decision_record.is_file(): + text = provider_decision_record.read_text(encoding="utf-8") + if "core_promotion_status: not-promoted" not in text: + errors.append("provider_decision_record_missing_not_promoted_frontmatter") + for phrase in REQUIRED_PROVIDER_DECISION_RECORD_PHRASES: + checked.append(f"provider_decision_record_phrase:{phrase}") + if phrase not in text: + errors.append(f"missing_provider_decision_record_phrase:{phrase}") + board = ROOT / "WORKBOARD.yaml" if board.is_file(): text = board.read_text(encoding="utf-8") @@ -891,6 +942,7 @@ def main() -> int: "CTO-WORK-022": "blocked", "CTO-WORK-023": "validated", "CTO-WORK-024": "blocked", + "CTO-WORK-025": "validated", } for issue_id, expected in expected_statuses.items(): checked.append(f"workboard_status:{issue_id}:{expected}") @@ -937,6 +989,8 @@ def main() -> int: errors.append("workboard_missing_provider_decision_packet_prd_source") if "CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md" not in text: errors.append("workboard_missing_provider_decision_packet_issues_source") + if "CTO-CASE-PROVIDER-DECISION-RECORD.md" not in text: + errors.append("workboard_missing_provider_decision_record_source") payload = { "ok": not errors,