1936 lines
100 KiB
Python
1936 lines
100 KiB
Python
#!/usr/bin/env python3
|
|
"""Validate the child-local Cortex OS CTO workspace."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
REQUIRED_FILES = [
|
|
"AGENTS.md",
|
|
"README.md",
|
|
"WORKBOARD.yaml",
|
|
"CONTEXT.md",
|
|
".sot/00-START/CTO-WORKSPACE-INTENT.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-BACKEND-BRIEF.md",
|
|
".sot/03-PROTOCOLS/CTO-ARCHITECTURE-BRIEF-CLOSEOUT-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-ARCHITECTURE-BRIEF-CLOSEOUT-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-CANDIDATE-BACKEND-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-CANDIDATE-BACKEND-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-HARNESS-EVIDENCE-INTERFACE-CONTRACT.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-SOURCE-ADMISSION-RECORD.md",
|
|
".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",
|
|
".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-STAGE3-COPIED-REPO-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE3-COPIED-REPO-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-PRD.md",
|
|
".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-STAGE6-REAL-GOVERNED-REFRESH-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE6-REAL-GOVERNED-REFRESH-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE6-REAL-GOVERNED-REFRESH-EVIDENCE.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-CONTROL-SURFACE-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-CONTROL-SURFACE-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-EVIDENCE.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-EVIDENCE.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-APPROVAL-PACKET.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",
|
|
".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-LOCAL-PROVIDER-ROUTE-PRD.md",
|
|
".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",
|
|
".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION.openai-codex-gpt-5.5.json",
|
|
".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION.qwen-local-qwen3.6-35b-a3b.json",
|
|
".sot/03-PROTOCOLS/CTO-CASE-SPARK-ENDPOINT-CONFIG-PRD.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-SPARK-ENDPOINT-CONFIG-ISSUES.md",
|
|
".sot/03-PROTOCOLS/CTO-CASE-AGENT-PROTOCOL-BLOCKER.md",
|
|
]
|
|
|
|
REQUIRED_BRIEF_PHRASES = [
|
|
"Cortex governs.",
|
|
"Hermes controls.",
|
|
"Case executes.",
|
|
"Harness proves.",
|
|
"Core promotes only through SOT route.",
|
|
"Case is the candidate CTO execution backend, not the CTO authority layer.",
|
|
"This brief is child-local planning.",
|
|
"Status: validated by later child-local CTO evidence.",
|
|
"Stage 1 through Stage 6 proof gates are recorded as validated in `WORKBOARD.yaml`.",
|
|
"`CTO-WORK-043` records Stage 6 candidate-default comparison evidence.",
|
|
"`CTO-WORK-045` records Hermes Control Surface evidence for Harness-backed visibility and replay.",
|
|
"Runtime default activation remains false until a later governed route changes it.",
|
|
]
|
|
|
|
REQUIRED_ARCHITECTURE_CLOSEOUT_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"`CTO-WORK-001` remains `candidate`",
|
|
"Close `CTO-WORK-001` as validated by referencing later evidence instead of changing authority.",
|
|
"Stage 1 through Stage 6 validation",
|
|
"`CTO-WORK-043` Stage 6 candidate-default comparison",
|
|
"`CTO-WORK-045` Hermes Control Surface validation",
|
|
"runtime default activation remains false",
|
|
]
|
|
|
|
REQUIRED_ARCHITECTURE_CLOSEOUT_ISSUE_IDS = [
|
|
"CTO-WORK-046",
|
|
"CTO-WORK-047",
|
|
]
|
|
|
|
REQUIRED_FIRST_REAL_WORKFLOW_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"The next useful proof is not another synthetic stage.",
|
|
"Governed Workflow Delegation",
|
|
"precise task contract",
|
|
"explicitly admitted owned low-risk Target Repository",
|
|
"JP approval before mutation",
|
|
"CTO Harness Case seam",
|
|
"Harness Evidence Interface artifacts",
|
|
"Hermes Control Surface replay paths",
|
|
"runtime default activation false",
|
|
"`CTO-WORK-049` stays candidate until a concrete Target Repository and task contract are admitted.",
|
|
"future focused Harness command",
|
|
]
|
|
|
|
REQUIRED_FIRST_REAL_WORKFLOW_ISSUE_IDS = [
|
|
"CTO-WORK-048",
|
|
"CTO-WORK-049",
|
|
"CTO-WORK-050",
|
|
]
|
|
|
|
REQUIRED_FIRST_REAL_WORKFLOW_APPROVAL_PACKET_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"This packet does not authorize execution.",
|
|
"`CTO-WORK-049` remains candidate until JP approves the exact Target Repository and task contract.",
|
|
"/home/svrnty/workspaces/cortex-os/cto-stage5-target-sandbox",
|
|
".sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json",
|
|
"align `src/strings.py` `slugify` behavior",
|
|
"`src/strings.py`",
|
|
"`test_strings.py`",
|
|
"python3 -m pytest -q",
|
|
"I approve CTO-WORK-049 against /home/svrnty/workspaces/cortex-os/cto-stage5-target-sandbox for the src/strings.py slugify alignment task.",
|
|
"Without that exact approval, execution remains blocked.",
|
|
"Runtime default activation remains false.",
|
|
]
|
|
|
|
REQUIRED_HERMES_WEBUI_CONTROL_PANEL_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Hermes WebUI consumer panel",
|
|
"Hermes-owned extension/plugin surface",
|
|
"Do not edit upstream `hermes-webui`.",
|
|
"Do not edit upstream `hermes-agent`.",
|
|
"Harness-backed summary data as the source of truth",
|
|
"Stage 6 real-governed refresh status",
|
|
"refresh comparison, real Stage 5 pass report, and Stage 5 proof",
|
|
"target repository read-only proof status",
|
|
"candidate-default refresh eligibility from runtime default activation",
|
|
"blocked Codex/Pi lane rationale",
|
|
"Do not activate Case as default backend.",
|
|
]
|
|
|
|
REQUIRED_HERMES_WEBUI_CONTROL_PANEL_EVIDENCE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"CTO-WORK-059",
|
|
"9c8f345 Add CTO harness control panel",
|
|
"/api/cto/control-summary",
|
|
"cto_control_panel.js",
|
|
"cto_control_panel.css",
|
|
"routes/cto_control_summary.py",
|
|
"CONNECTION-MAP.md is fresh",
|
|
"104 passed",
|
|
"Case runtime default active: false",
|
|
"target repository mutation: false",
|
|
"upstream `hermes-webui` edited: false",
|
|
"upstream `hermes-agent` edited: false",
|
|
"Harness-backed summary data remains the source of truth.",
|
|
]
|
|
|
|
REQUIRED_HERMES_WEBUI_LIVE_SMOKE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Hermes WebUI live smoke",
|
|
"existing plugin smoke machinery",
|
|
"/api/cto/control-summary",
|
|
"/plugins/svrnty/cto_control_panel.js",
|
|
"/plugins/svrnty/cto_control_panel.css",
|
|
"Harness-backed summary data remains the source of truth.",
|
|
"Do not edit upstream `hermes-webui`.",
|
|
"Do not edit upstream `hermes-agent`.",
|
|
"Do not activate Case as default backend.",
|
|
"Do not mutate target repositories.",
|
|
]
|
|
|
|
REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_EVIDENCE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"CTO-WORK-057",
|
|
"1f53307 Expose real refresh in control summary",
|
|
"validate-webui-summary.py --json",
|
|
"webui-summary.json",
|
|
"case_stage6_real_governed_refresh",
|
|
"stage6_real_governed_refresh_comparison_path",
|
|
"real Stage 5 pass report replay path",
|
|
"real Stage 5 proof replay path",
|
|
"target repository read-only proof status",
|
|
"candidate-default refresh eligibility separately from `runtime_default_activation`",
|
|
"Codex blocked-lane rationale",
|
|
"Pi blocked-lane rationale",
|
|
"runtime default activation: false",
|
|
"Runtime default activation remains false.",
|
|
]
|
|
|
|
REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Hermes may display and replay evidence; it must not govern",
|
|
"Harness Evidence Interface artifacts",
|
|
"Stage 6 real-governed refresh status",
|
|
"refresh comparison artifact path",
|
|
"real Stage 5 pass report and Stage 5 proof paths",
|
|
"read-only target repository proof status",
|
|
"candidate-default refresh eligibility separately from runtime default activation",
|
|
"blocked Codex/Pi lane rationale",
|
|
"Do not build a full Hermes WebUI panel in this slice.",
|
|
"Do not activate Case as default backend.",
|
|
"Do not rerun or mutate the real Target Repository.",
|
|
]
|
|
|
|
REQUIRED_STAGE6_REAL_REFRESH_EVIDENCE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"CTO-WORK-055",
|
|
"2b6e114 Add Stage 6 real governed refresh",
|
|
"validate-case-stage6-real-refresh.py --json",
|
|
"stage6-real-governed-refresh-comparison.json",
|
|
"target repository read-only check passed",
|
|
"report shape passed",
|
|
"event validity passed",
|
|
"allowed-path compliance passed",
|
|
"prior Stage 6 failure closure passed",
|
|
"artifact completeness passed",
|
|
"forbidden-action closure passed",
|
|
"operator acceptance passed",
|
|
"runtime default activation: false",
|
|
"no target repository mutation attempted",
|
|
"Runtime default activation remains false.",
|
|
]
|
|
|
|
REQUIRED_STAGE6_REAL_REFRESH_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"CTO-WORK-049",
|
|
"real pass report",
|
|
"Stage 5 proof",
|
|
"report shape",
|
|
"event validity",
|
|
"allowed-path compliance",
|
|
"failure closure",
|
|
"artifact completeness",
|
|
"forbidden-action closure",
|
|
"operator acceptance",
|
|
"runtime default activation false",
|
|
"read-only",
|
|
"without mutating a Target Repository",
|
|
]
|
|
|
|
REQUIRED_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Case Candidate Backend",
|
|
"Harness Evidence Interface",
|
|
"Case may recommend; CTO Harness records; Hermes or operator approval is the only human approval signal.",
|
|
"Candidate Cortex Work Packet is an unpromoted term.",
|
|
"Staged Proof Gates",
|
|
"Source Admission Requirements",
|
|
"Failure-Mode Matrix",
|
|
"Fake remains the default validation lane.",
|
|
]
|
|
|
|
FORBIDDEN_PRD_PHRASES = [
|
|
"Case should be the default real-repo execution backend",
|
|
"Case is the default real-repo execution backend",
|
|
]
|
|
|
|
REQUIRED_ISSUE_IDS = [
|
|
"CTO-WORK-003",
|
|
"CTO-WORK-004",
|
|
"CTO-WORK-005",
|
|
"CTO-WORK-006",
|
|
"CTO-WORK-007",
|
|
"CTO-WORK-008",
|
|
]
|
|
|
|
REQUIRED_EVIDENCE_INTERFACE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"This contract does not authorize Runtime behavior",
|
|
"The Harness Evidence Interface is the only accepted proof surface for backend comparison.",
|
|
"report.json",
|
|
"events.normalized.jsonl",
|
|
"patch.diff",
|
|
"test.log",
|
|
"trace.jsonl",
|
|
"artifact_digests",
|
|
"SHA-256",
|
|
"run_started_at",
|
|
"run_finished_at",
|
|
"backend_exit_code",
|
|
"allowed_writes_passed",
|
|
"approval.requested",
|
|
"approval.granted",
|
|
"approval.denied",
|
|
"Case may recommend. Case must not approve itself.",
|
|
"No merge, push, deploy, close, or real-repo mutation is allowed without explicit task-contract permission.",
|
|
"fail closed",
|
|
]
|
|
|
|
REQUIRED_SOURCE_ADMISSION_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"This record does not authorize Runtime behavior",
|
|
"https://github.com/workos/case.git",
|
|
"7959ac917cdeb0983b4aaa20bb9f42021747fed8",
|
|
"2026-05-31",
|
|
"git clone --depth 1 https://github.com/workos/case.git",
|
|
"License status is unresolved.",
|
|
"package private: true",
|
|
"Status: not admitted for execution.",
|
|
"Current allowed execution mode: planning-only.",
|
|
"do not mutate the Case repository",
|
|
"do not vendor Case source into Cortex OS Core",
|
|
"No moving branch reference may be used as proof without a pinned commit or tag.",
|
|
]
|
|
|
|
REQUIRED_ADAPTER_CONTRACT_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"This contract does not authorize Runtime behavior",
|
|
"register backend id `case` as a gated engine before execution",
|
|
"require the harness to accept `--engine case` only when explicitly enabled",
|
|
"prevent a parallel runner path outside the existing harness seam",
|
|
"`case` must be disabled by default.",
|
|
"No missing gate may degrade to a warning. Missing gate means blocked.",
|
|
"Adapter Input Contract",
|
|
"Adapter Output Contract",
|
|
"CTO Eligibility Decision",
|
|
"`selected_backend`",
|
|
"`denied_backends`",
|
|
"`required_gates`",
|
|
"`missing_gates`",
|
|
"`allowed_mutation_mode`",
|
|
"Case must not create or override the Eligibility Decision.",
|
|
"Case may recommend. Case must not approve itself or select its own authority.",
|
|
"This contract deliberately does not create `case-engine.sh`.",
|
|
]
|
|
|
|
REQUIRED_FAILURE_FIXTURE_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"This matrix does not authorize Runtime behavior",
|
|
"This matrix is planning-only and does not run Case.",
|
|
"no-diff",
|
|
"disallowed-file",
|
|
"failed-tests",
|
|
"missing-test-command",
|
|
"missing-event",
|
|
"reviewer-reject",
|
|
"approval-denied",
|
|
"timeout",
|
|
"dirty-starting-tree",
|
|
"dirty-ending-tree",
|
|
"artifact-write-failure",
|
|
"provider-unavailable",
|
|
"`no_diff`",
|
|
"`disallowed_file_change`",
|
|
"`verification_failed`",
|
|
"`missing_test_command`",
|
|
"`missing_required_event`",
|
|
"`reviewer_rejected`",
|
|
"`approval_denied`",
|
|
"`dirty_starting_tree`",
|
|
"`dirty_ending_tree`",
|
|
"`artifact_write_failure`",
|
|
"`provider_unavailable`",
|
|
"report.json",
|
|
"events.normalized.jsonl",
|
|
"patch.diff",
|
|
"test.log",
|
|
"trace.jsonl",
|
|
"artifact_digests",
|
|
"freshness proof",
|
|
"fail closed",
|
|
]
|
|
|
|
REQUIRED_STAGED_PROOF_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Default status is earned, not assumed.",
|
|
"Stages must be completed in order.",
|
|
"Missing evidence means blocked, not partially accepted.",
|
|
"Stage 1 - Gated Case Engine",
|
|
"Stage 2 - Artificial Fixture",
|
|
"Stage 3 - Copied Repo Fixture",
|
|
"Stage 4 - Disposable Sandbox Repo",
|
|
"Stage 5 - Owned Noncritical Repo",
|
|
"Stage 6 - Candidate Default",
|
|
"Allowed mutation scope: none.",
|
|
"Allowed mutation scope: copied artificial case only.",
|
|
"Allowed mutation scope: copied local repository fixture only.",
|
|
"Allowed mutation scope: disposable repository only.",
|
|
"Allowed mutation scope: explicitly owned low-risk repository only.",
|
|
"Allowed mutation scope: scoped real-repo use only.",
|
|
"fake, Codex, and Pi where applicable",
|
|
"Case matches or beats existing lanes on report shape",
|
|
"Case matches or beats existing lanes on failure closure",
|
|
"Any future implementation must start with Stage 1",
|
|
"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",
|
|
]
|
|
|
|
REQUIRED_STAGE2_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Stage 2 must prove only one narrow executable behavior",
|
|
"copied artificial fixture",
|
|
"Stage 2 allowed mutation scope is `copied artificial case only`.",
|
|
"CTO_HARNESS_ALLOW_CASE=1",
|
|
"CTO_HARNESS_CASE_STAGE=2",
|
|
"Missing Stage 2 gate means blocked, not warning.",
|
|
"runtime_workspace_root",
|
|
"run_artifact_dir",
|
|
"Fake remains the default validation lane.",
|
|
"No Target Repository path is inspected or copied.",
|
|
"task contract contains no Target Repository path",
|
|
"source_admission_status: not_admitted",
|
|
"allowed_writes_passed",
|
|
"report.md",
|
|
"backend raw logs under `backend/`",
|
|
"backend: case",
|
|
"case_process_started",
|
|
"changed_files",
|
|
"blockers",
|
|
"artifact digests",
|
|
"freshness proof",
|
|
"same-run fake baseline",
|
|
"no diff",
|
|
"disallowed file",
|
|
"failed tests",
|
|
"missing test command",
|
|
"missing required event",
|
|
"provider unavailable",
|
|
"python3 harness/runner/validate-case-stage2.py --harness-root harness --json",
|
|
"python3 harness/runner/validate-case-stage1.py --harness-root harness --json",
|
|
"Stage 2 does not authorize copied repo, sandbox repo, owned repo, default backend, WebUI product, or Core promotion behavior.",
|
|
]
|
|
|
|
REQUIRED_STAGE2_ISSUE_IDS = [
|
|
"CTO-WORK-011",
|
|
"CTO-WORK-012",
|
|
]
|
|
|
|
REQUIRED_STAGE3_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Stage 3 must prove the next narrow behavior",
|
|
"copied local repository fixture only",
|
|
"CTO_HARNESS_ALLOW_CASE=1",
|
|
"CTO_HARNESS_CASE_STAGE=3",
|
|
"Source repository HEAD and status are recorded before and after Case execution.",
|
|
"Source repository after-proof matches before-proof.",
|
|
"Copied fixture starts clean",
|
|
"Copied fixture ends clean",
|
|
"source_repository_mutated: false",
|
|
"dirty-starting-tree",
|
|
"dirty-ending-tree",
|
|
"artifact-write-failure",
|
|
"Stage 3 does not authorize sandbox, owned-repo, default backend, WebUI Runtime, or Core promotion behavior.",
|
|
]
|
|
|
|
REQUIRED_STAGE3_ISSUE_IDS = [
|
|
"CTO-WORK-033",
|
|
"CTO-WORK-034",
|
|
]
|
|
|
|
REQUIRED_STAGE4_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Stage 4 must prove the next narrow behavior",
|
|
"disposable repository only",
|
|
"CTO_HARNESS_ALLOW_CASE=1",
|
|
"CTO_HARNESS_CASE_STAGE=4",
|
|
"approval requested/granted/denied",
|
|
"branch policy proof",
|
|
"No push, merge, deploy, close, PR open, or public publication occurs by default.",
|
|
"approval-denied",
|
|
"reviewer-reject",
|
|
"Stage 4 is successful when Case changes only a disposable repository",
|
|
]
|
|
|
|
REQUIRED_STAGE4_ISSUE_IDS = [
|
|
"CTO-WORK-035",
|
|
"CTO-WORK-036",
|
|
]
|
|
|
|
REQUIRED_STAGE5_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Stage 5 allowed mutation scope is `explicitly owned low-risk repository only`.",
|
|
"CTO_HARNESS_ALLOW_CASE=1",
|
|
"CTO_HARNESS_CASE_STAGE=5",
|
|
"Target Repository ownership proof and noncritical classification",
|
|
"approval requested/granted/denied events before mutation",
|
|
"allowed paths and forbidden actions before mutation",
|
|
"Operator acceptance or rejection is recorded after verification.",
|
|
"No push, merge, deploy, close, PR open, issue close, or public publication occurs by default.",
|
|
"approval denied, unowned repository, critical repository, disallowed file, dirty starting tree, dirty ending tree, failed tests, timeout, provider unavailable, and missing operator outcome",
|
|
"Stage 5 is successful when Case changes only approved paths inside an explicitly owned low-risk noncritical repository",
|
|
]
|
|
|
|
REQUIRED_STAGE5_ISSUE_IDS = [
|
|
"CTO-WORK-037",
|
|
"CTO-WORK-038",
|
|
"CTO-WORK-039",
|
|
"CTO-WORK-040",
|
|
"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_HERMES_CONTROL_SURFACE_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"Hermes controls visibility, approval, and replay but does not govern.",
|
|
"Harness Evidence Interface artifacts",
|
|
"proof ladder status through Stage 6",
|
|
"candidate-default eligibility separately from runtime default activation",
|
|
"replay paths for matrix and Stage 6 comparison evidence",
|
|
"blocked comparison lanes to include rationale",
|
|
"Do not build a full Hermes WebUI panel in this slice.",
|
|
"Do not activate Case as default backend.",
|
|
"Do not store secrets, endpoints, or credential values in reports.",
|
|
"This slice succeeds when Hermes can consume one Harness-generated summary",
|
|
]
|
|
|
|
REQUIRED_HERMES_CONTROL_SURFACE_ISSUE_IDS = [
|
|
"CTO-WORK-044",
|
|
"CTO-WORK-045",
|
|
]
|
|
|
|
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.",
|
|
"Stage 5 execution remains blocked until JP records a concrete admission record",
|
|
"admission_status",
|
|
"target_repository_path",
|
|
"repository_owner",
|
|
"ownership_evidence",
|
|
"risk_classification",
|
|
"low_risk_noncritical",
|
|
"allowed_paths",
|
|
"forbidden_actions",
|
|
"approval_source",
|
|
"operator_outcome_required",
|
|
"Missing admission record blocks before `case_process_started`.",
|
|
"This template does not authorize Case execution.",
|
|
"This template does not authorize owned repository mutation.",
|
|
]
|
|
|
|
REQUIRED_STAGE5_TARGET_ADMISSION_JSON = {
|
|
"admission_status": "admitted",
|
|
"target_repository_path": "/home/svrnty/workspaces/cortex-os/cto-stage5-target-sandbox",
|
|
"repository_owner": "jp",
|
|
"ownership_evidence": "JP chat approval on 2026-06-01 to create this dedicated Stage 5 target sandbox under /home/svrnty/workspaces/cortex-os.",
|
|
"risk_classification": "low_risk_noncritical",
|
|
"noncritical_rationale": "Dedicated owned Stage 5 sandbox repo, not production, no customer data, no secrets, no deploy path, no external users, safe to delete after validation.",
|
|
"approval_source": "JP chat approval on 2026-06-01",
|
|
"approval_timestamp": "2026-06-01",
|
|
"operator_outcome_required": True,
|
|
}
|
|
|
|
REQUIRED_STAGE5_TARGET_FORBIDDEN_ACTIONS = [
|
|
"push",
|
|
"merge",
|
|
"deploy",
|
|
"close",
|
|
"pr_open",
|
|
"issue_close",
|
|
"public_publication",
|
|
"credential_change",
|
|
"vendor_source_mutation",
|
|
"cortex_core_mutation",
|
|
]
|
|
|
|
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",
|
|
]
|
|
|
|
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 <task-file> --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=<admitted-ca>` 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",
|
|
"9811f870af2f85616e359d42ba70566c9af08ca20d8660456929a56ec761513f",
|
|
"20260531T233721Z-r1-string-slugify-1814067",
|
|
"CTO-WORK-016` remains blocked because no real Case Stage 2 pass report exists",
|
|
"CTO-WORK-017 - Case Provider Timeout Fail-Closed Route",
|
|
"CTO_HARNESS_CASE_TIMEOUT_SECONDS",
|
|
"backend/provider-timeout.txt",
|
|
"provider_timeout_fail_closed",
|
|
"d23c492 Fail closed on Case provider timeout",
|
|
"anthropic",
|
|
"claude-sonnet-4-6",
|
|
"20260531T234205Z-r1-string-slugify-1834617/report.json",
|
|
"CTO_HARNESS_CASE_MODEL_PROVIDER",
|
|
"CTO_HARNESS_CASE_MODEL",
|
|
"backend/provider-model-not-admitted.txt",
|
|
"model_provider_gate_blocks",
|
|
"4500082 Gate Case execution on admitted model",
|
|
]
|
|
|
|
REQUIRED_PROVIDER_BUILD_ISSUE_IDS = [
|
|
"CTO-WORK-015",
|
|
"CTO-WORK-016",
|
|
"CTO-WORK-017",
|
|
"CTO-WORK-018",
|
|
]
|
|
|
|
REQUIRED_MODEL_PROVIDER_ADMISSION_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"CTO-WORK-018",
|
|
"anthropic",
|
|
"claude-sonnet-4-6",
|
|
"unadmitted external model path",
|
|
"explicit admitted provider/model pair",
|
|
"credential source class",
|
|
"allowed network class",
|
|
"admission timestamp",
|
|
"CTO_HARNESS_CASE_MODEL_PROVIDER",
|
|
"CTO_HARNESS_CASE_MODEL",
|
|
"backend/provider-model-not-admitted.txt",
|
|
"unadmitted provider/model blocks before `case_process_started`",
|
|
"models.default",
|
|
"CASE_DATA_DIR/config.json",
|
|
"ca run --task <task-file> --mode unattended",
|
|
"case_model_provider",
|
|
"case_model",
|
|
"case_model_admission_status",
|
|
"case_process_started",
|
|
"allowed_writes_passed",
|
|
"changed_files",
|
|
"blockers",
|
|
"Fake remains the default validation lane.",
|
|
"Same-run fake baseline comparison remains required.",
|
|
"No secrets appear in task file, argv, report, trace, backend logs, SOT, or commits.",
|
|
"4500082 Gate Case execution on admitted model",
|
|
"model_provider_gate_blocks",
|
|
"f39d8ab Require admitted Case model pair",
|
|
"CTO_HARNESS_CASE_MODEL_ADMISSION_FILE",
|
|
"Env provider/model is now a requested pair, not admission authority.",
|
|
"The admission JSON is the authority for real Case Stage 2 model admission.",
|
|
"admitted",
|
|
"missing_admission",
|
|
"mismatch",
|
|
"invalid_admission",
|
|
"not_admitted",
|
|
"report.md",
|
|
"Case stdout/stderr",
|
|
"20260531T235421Z-r1-string-slugify-1875638",
|
|
"20260531T235448Z-r1-string-slugify-1876884",
|
|
"`CTO-WORK-020` remains blocked because no real provider/model has been approved and no real Case Stage 2 pass report exists.",
|
|
"Decision Record Template For CTO-WORK-020",
|
|
"`decision_status`: `not_decided`, `external_provider_approved`, or `local_provider_required`.",
|
|
"`provider_class`: `external_anthropic`, `external_openai_codex`, or `local_case_compatible`.",
|
|
"`provider`: exact provider string, or empty while blocked.",
|
|
"`model`: exact model string, or empty while blocked.",
|
|
"`approval_source`: JP approval reference or governed Core route reference.",
|
|
"`credential_source_class`: credential class only; no secret value.",
|
|
"`allowed_network_class`: allowed network class for this provider.",
|
|
"`review_trigger`: expiry, date, or condition that forces review.",
|
|
"`evidence_sources`: references to existing admission/build evidence, not copied runtime evidence.",
|
|
"`effect`: `CTO-WORK-020 remains blocked until admitted provider/model and real Stage 2 pass report exist`.",
|
|
"`not_decided`: no provider/model may run.",
|
|
"`local_provider_required`: no external provider may run; create a Case-compatible local provider route first.",
|
|
"`external_provider_approved`: may proceed only when the approval source, credential source class, allowed network class, and admission JSON are recorded.",
|
|
]
|
|
|
|
REQUIRED_MODEL_PROVIDER_ADMISSION_ISSUE_IDS = [
|
|
"CTO-WORK-019",
|
|
"CTO-WORK-020",
|
|
"CTO-WORK-027",
|
|
"CTO-WORK-029",
|
|
]
|
|
|
|
REQUIRED_MODEL_PROVIDER_ADMISSION_ISSUE_PHRASES = [
|
|
"f39d8ab Require admitted Case model pair",
|
|
"`f39d8ab` proves admission gating implementation only; it is not a real Case Stage 2 pass.",
|
|
"CTO_HARNESS_CASE_MODEL_ADMISSION_FILE",
|
|
"admission JSON is the authority",
|
|
"Missing admission blocks before `case_process_started`.",
|
|
"Mismatched admission blocks before `case_process_started`.",
|
|
"case_model_provider",
|
|
"case_model",
|
|
"case_model_admission_status",
|
|
"admitted",
|
|
"missing_admission",
|
|
"mismatch",
|
|
"invalid_admission",
|
|
"not_admitted",
|
|
"report.md",
|
|
"Case stdout/stderr",
|
|
"20260531T235421Z-r1-string-slugify-1875638",
|
|
"20260531T235448Z-r1-string-slugify-1876884",
|
|
"`CTO-WORK-020` remains blocked until a provider/model is explicitly approved and real Case Stage 2 produces a pass report.",
|
|
"CTO-WORK-020 Decision Record Template",
|
|
"This template belongs to `CTO-WORK-020`; it is not a new provider approval.",
|
|
"`decision_status`: `not_decided`, `external_provider_approved`, or `local_provider_required`.",
|
|
"`provider_class`: `external_anthropic`, `external_openai_codex`, or `local_case_compatible`.",
|
|
"`provider`: exact provider string, or empty while blocked.",
|
|
"`model`: exact model string, or empty while blocked.",
|
|
"`approval_source`: JP approval reference or governed Core route reference.",
|
|
"`credential_source_class`: credential class only; no secret value.",
|
|
"`allowed_network_class`: allowed network class for this provider.",
|
|
"`review_trigger`: expiry, date, or condition that forces review.",
|
|
"`evidence_sources`: references to existing admission/build evidence, not copied runtime evidence.",
|
|
"`effect`: `CTO-WORK-020 remains blocked until admitted provider/model and real Stage 2 pass report exist`.",
|
|
"CTO-WORK-027 - OpenAI Codex Model Admission JSON",
|
|
"Admission file path is `.sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION.openai-codex-gpt-5.5.json`.",
|
|
"Admission JSON has `status`: `admitted`.",
|
|
"Admission JSON has `provider`: `openai-codex`.",
|
|
"Admission JSON has `model`: `gpt-5.5`.",
|
|
"Admission JSON has `credential_source_class`: `hermes-openai-codex-oauth-and-local-vllm-config`.",
|
|
"Admission JSON has `allowed_network_class`: `codex-oauth-hosted-model-plus-local-vllm-fallback`.",
|
|
"Admission JSON has `approval_source`: `JP chat approval on 2026-05-31`.",
|
|
"Admission JSON contains no secret keys or secret values.",
|
|
"Fallback to `openai-codex` / `gpt-5.5` remains explicit decision-record context and must be represented in runtime evidence before it may count as a Case provider/model path.",
|
|
"`CTO-WORK-020` remains blocked until real Case Stage 2 produces a Harness Evidence Interface pass report using this admission file.",
|
|
"Real Case Stage 2 command must set `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` to this admission JSON path.",
|
|
]
|
|
|
|
REQUIRED_OPENAI_CODEX_ADMISSION_JSON = {
|
|
"status": "admitted",
|
|
"provider": "openai-codex",
|
|
"model": "gpt-5.5",
|
|
"credential_source_class": "hermes-openai-codex-oauth-and-local-vllm-config",
|
|
"allowed_network_class": "codex-oauth-hosted-model-plus-local-vllm-fallback",
|
|
"approval_source": "JP chat approval on 2026-05-31",
|
|
}
|
|
|
|
REQUIRED_QWEN_LOCAL_ADMISSION_JSON = {
|
|
"status": "admitted",
|
|
"provider": "qwen-local",
|
|
"model": "qwen3.6-35b-a3b",
|
|
"credential_source_class": "pi-models-json-local-provider-no-secret",
|
|
"allowed_network_class": "local-tailscale-vllm-spark1",
|
|
"approval_source": "JP chat approval on 2026-05-31",
|
|
}
|
|
|
|
REQUIRED_LOCAL_PROVIDER_ROUTE_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"`CTO-WORK-020` remains blocked until the selected local Qwen provider path produces real Case Stage 2 pass evidence.",
|
|
"`decision_status=local_provider_required`",
|
|
"local_case_compatible",
|
|
"CTO-WORK-020` admission JSON gate as authority",
|
|
"CTO_HARNESS_CASE_MODEL_ADMISSION_FILE",
|
|
"CTO_HARNESS_CASE_MODEL_PROVIDER",
|
|
"CTO_HARNESS_CASE_MODEL",
|
|
"no external provider fallback",
|
|
"missing local adapter config to block before `case_process_started`",
|
|
"admission JSON mismatch to block before `case_process_started`",
|
|
"`decision_status != local_provider_required` to block route execution",
|
|
"No Target Repository path exposure.",
|
|
"Do not approve a local provider.",
|
|
"Do not implement a provider adapter.",
|
|
"Do not admit a provider/model.",
|
|
"Do not approve Anthropic or any external provider.",
|
|
"Do not run real Case Stage 2.",
|
|
"case_model_provider",
|
|
"case_model",
|
|
"case_model_admission_status",
|
|
"anthropic",
|
|
"claude-sonnet-4-6",
|
|
"same-run fake baseline comparison required",
|
|
"Harness Evidence Interface",
|
|
]
|
|
|
|
REQUIRED_LOCAL_PROVIDER_ROUTE_ISSUE_IDS = [
|
|
"CTO-WORK-021",
|
|
"CTO-WORK-022",
|
|
]
|
|
|
|
REQUIRED_LOCAL_PROVIDER_ROUTE_ISSUE_PHRASES = [
|
|
"Status: validated.",
|
|
"`decision_status=local_provider_required`",
|
|
"local_case_compatible",
|
|
"Uses `CTO-WORK-020` admission JSON gate as authority instead of redefining admission.",
|
|
"CTO_HARNESS_CASE_MODEL_ADMISSION_FILE",
|
|
"no external fallback to `anthropic` or `claude-sonnet-4-6`",
|
|
"negative gates for missing local adapter config, admission JSON mismatch, and `decision_status != local_provider_required`",
|
|
"Completion of this route does not admit a provider/model and does not change `CTO-WORK-020` status.",
|
|
"Keeps `CTO-WORK-020` blocked until admitted provider/model and real Case Stage 2 pass evidence exist.",
|
|
"Does not approve or implement any provider.",
|
|
"Provider/model admission remains owned by `CTO-WORK-020`.",
|
|
"Missing local adapter config blocks before `case_process_started`.",
|
|
"Admission JSON mismatch blocks before `case_process_started`.",
|
|
"External provider fallback blocks before `case_process_started`.",
|
|
"Harness report proves `case_model_provider`, `case_model`, and `case_model_admission_status`.",
|
|
"Real Case Stage 2 produces a pass report only through the Harness Evidence Interface.",
|
|
]
|
|
|
|
REQUIRED_PROVIDER_DECISION_PACKET_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"`CTO-WORK-020` is blocked by a provider policy decision.",
|
|
"`external_provider_approved`",
|
|
"`local_provider_required`",
|
|
"`local_provider_required` as the current selected state",
|
|
"does not approve a provider/model",
|
|
"does not approve or admit any provider/model",
|
|
"is not Stage 2 pass evidence",
|
|
"structured decision record using only `not_decided`, `external_provider_approved`, or `local_provider_required`",
|
|
"Reference existing evidence paths and commits; do not copy runtime evidence into the packet.",
|
|
"Keep `CTO-WORK-020` as the admission authority.",
|
|
"CTO_HARNESS_CASE_MODEL_ADMISSION_FILE",
|
|
"exact provider/model, approval source, credential source class, allowed network class, review trigger, and evidence expectations",
|
|
"no secret value in SOT, task file, argv, report, trace, backend logs, generated config, or commit",
|
|
"`CTO-WORK-022` blocked until explicit local provider config is supplied and real Case Stage 2 pass evidence exists",
|
|
"real Case Stage 2 blocked unless a provider/model is admitted and a pass report exists through the Harness Evidence Interface",
|
|
"no Target Repository path may be inspected or copied",
|
|
"`provider_class`: `external_anthropic`",
|
|
"`provider_class`: `external_anthropic` or `external_openai_codex`.",
|
|
"`openai-codex` with model `gpt-5.5` may be recorded as the primary approved external provider only when the approval source, credential source class, allowed network class, review trigger, and admission JSON are recorded.",
|
|
"`vllm` with model `qwen3.6-35b-a3b` may be recorded as an explicit fallback only when fallback use is represented in admission evidence and does not hide provider/model switching.",
|
|
"Packet permits provider class `external_openai_codex` only as a decision branch, not as admission or Stage 2 proof.",
|
|
"`provider_class`: `local_case_compatible`",
|
|
"No external fallback to `anthropic` or `claude-sonnet-4-6` is allowed.",
|
|
"Missing local adapter config blocks before `case_process_started`.",
|
|
"Admission JSON mismatch blocks before `case_process_started`.",
|
|
]
|
|
|
|
REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_IDS = [
|
|
"CTO-WORK-023",
|
|
"CTO-WORK-024",
|
|
"CTO-WORK-025",
|
|
"CTO-WORK-026",
|
|
]
|
|
|
|
REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_PHRASES = [
|
|
"Status: validated.",
|
|
"`local_provider_required` is current selected state",
|
|
"`external_provider_approved`",
|
|
"`local_provider_required`",
|
|
"does not approve or admit any provider/model",
|
|
"Says it is not Stage 2 pass evidence.",
|
|
"Requires a structured decision record using only `not_decided`, `external_provider_approved`, or `local_provider_required`.",
|
|
"References existing evidence paths and commits instead of copying runtime evidence.",
|
|
"Keeps `CTO-WORK-020` as provider/model admission authority.",
|
|
"Keeps `CTO_HARNESS_CASE_MODEL_ADMISSION_FILE` as execution admission gate.",
|
|
"Requires exact provider/model, approval source, credential source class, allowed network class, review trigger, and evidence expectations before admission.",
|
|
"Requires no secrets in SOT, task file, argv, report, trace, backend logs, generated config, or commits.",
|
|
"States `CTO-WORK-022` stays blocked until explicit local provider config and real Case Stage 2 pass evidence exist.",
|
|
"States real Case Stage 2 remains blocked until admitted provider/model and Harness Evidence Interface pass report exist.",
|
|
"States no Target Repository path may be inspected or copied.",
|
|
"Decision record selects exactly one branch: `external_provider_approved` or `local_provider_required`.",
|
|
"Decision record is structured and uses only `not_decided`, `external_provider_approved`, or `local_provider_required`.",
|
|
"Decision record references existing evidence paths and commits instead of copying runtime evidence.",
|
|
"`CTO-WORK-020` remains blocked until admitted provider/model and real Stage 2 pass report exist.",
|
|
"`CTO-WORK-022` remains blocked until explicit local provider config and real Case Stage 2 pass evidence exist.",
|
|
"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.",
|
|
"Status: validated.",
|
|
"Record JP approval of the local Qwen primary provider decision branch for the current Hermes model stack.",
|
|
"Decision record has `decision_status`: `local_provider_required`.",
|
|
"Decision record has `provider_class`: `local_case_compatible`.",
|
|
"Decision record has `provider`: `qwen-local`.",
|
|
"Decision record has `model`: `qwen3.6-35b-a3b`.",
|
|
"Decision record has `fallback_provider`: `openai-codex`.",
|
|
"Decision record has `fallback_model`: `gpt-5.5`.",
|
|
"Decision record has `credential_source_class`: `pi-models-json-local-provider-no-secret-plus-codex-oauth-fallback`; no secret value.",
|
|
"Decision record has `allowed_network_class`: `local-tailscale-vllm-spark1-plus-codex-oauth-fallback`.",
|
|
"Decision record references Hermes model policy and local Hermes config as evidence sources without copying secrets.",
|
|
"Record says `CTO-WORK-024` is resolved by selecting `local_provider_required`.",
|
|
"Record keeps `CTO-WORK-020` blocked until admission JSON and real Stage 2 pass evidence exist.",
|
|
"Record keeps `CTO-WORK-022` blocked until explicit local provider config and real Case Stage 2 pass evidence exist.",
|
|
"Record requires fallback to `openai-codex` with `gpt-5.5` to be explicit in admission evidence before it may count as a Case provider/model path.",
|
|
]
|
|
|
|
REQUIRED_PROVIDER_DECISION_RECORD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"`decision_status`: `local_provider_required`.",
|
|
"`provider_class`: `local_case_compatible`.",
|
|
"`provider`: `qwen-local`.",
|
|
"`model`: `qwen3.6-35b-a3b`.",
|
|
"`fallback_provider`: `openai-codex`.",
|
|
"`fallback_model`: `gpt-5.5`.",
|
|
"`approval_source`: JP chat approval on 2026-05-31.",
|
|
"`credential_source_class`: `pi-models-json-local-provider-no-secret-plus-codex-oauth-fallback`; no secret value.",
|
|
"`allowed_network_class`: `local-tailscale-vllm-spark1-plus-codex-oauth-fallback`.",
|
|
"`review_trigger`: before real Case Stage 2 admission JSON is written, before any credential source change, and before any default/fallback model change.",
|
|
"/home/svrnty/workspaces/hermes/scripts/apply-hermes-model-policy.py",
|
|
"/home/svrnty/.hermes/config.yaml",
|
|
"`effect`: `CTO-WORK-020 remains blocked until admitted provider/model and real Stage 2 pass report exist`.",
|
|
"`local_provider_required` means JP approved the provider decision branch for the existing Hermes model stack: `qwen-local` with model `qwen3.6-35b-a3b` as primary, and `openai-codex` with model `gpt-5.5` as fallback.",
|
|
"This record is not provider/model admission and is not Stage 2 pass evidence.",
|
|
"`CTO-WORK-024` is resolved by this record selecting `local_provider_required`.",
|
|
"Previous state:",
|
|
"`decision_status`: `not_decided`.",
|
|
"`not_decided` means no provider/model may run.",
|
|
"Only JP or a governed Core route may change this record away from `local_provider_required`.",
|
|
"Allowed future values remain `external_provider_approved` or `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-022` remains blocked until explicit local provider config is supplied and real Case Stage 2 pass evidence exists.",
|
|
"Real Case Stage 2 remains blocked until admitted provider/model and Harness Evidence Interface pass report exist.",
|
|
"Fallback to `openai-codex` with `gpt-5.5` must be explicit in admission evidence before it may count as a Case provider/model path.",
|
|
"Existing evidence paths and commits are referenced only; runtime evidence is not copied into this record.",
|
|
]
|
|
|
|
REQUIRED_SPARK_ENDPOINT_CONFIG_PRD_PHRASES = [
|
|
"Local planning SOT only. Not a Core Protocol. Not active Core authority.",
|
|
"`qwen-local` / `qwen3.6-35b-a3b` is now the selected primary Case provider policy",
|
|
"CTO_HARNESS_CASE_LOCAL_BASE_URL",
|
|
"missing. The harness correctly blocks before `case_process_started`",
|
|
"Treat the endpoint value as runtime config, not SOT content.",
|
|
"Do not store endpoint secrets or credential values in SOT, argv, task file, backend logs, report, trace, generated config, or commit.",
|
|
"Require missing endpoint config to write `backend/provider-local-config-unavailable.txt`.",
|
|
"Keep `CTO-WORK-020`, `CTO-WORK-016`, `CTO-WORK-022`, and Stage 2 blocked until real pass evidence exists.",
|
|
"endpoint presence is not Stage 2 pass evidence",
|
|
"configured endpoint alone does not validate `CTO-WORK-016`, `CTO-WORK-020`, `CTO-WORK-022`, or `CTO-WORK-028`",
|
|
"no Target Repository path may be inspected or copied",
|
|
"Harness Evidence Interface",
|
|
"same-run fake baseline comparison required",
|
|
]
|
|
|
|
REQUIRED_SPARK_ENDPOINT_CONFIG_ISSUE_PHRASES = [
|
|
"CTO-WORK-030 - Spark Local Provider Endpoint Config",
|
|
"Status: validated.",
|
|
"CTO_HARNESS_CASE_LOCAL_BASE_URL",
|
|
"Missing endpoint config blocks before `case_process_started`.",
|
|
"Missing endpoint config writes `backend/provider-local-config-unavailable.txt`.",
|
|
"Endpoint values are not written to SOT, task file, argv, backend logs, report, trace, generated config, or commit.",
|
|
"Harness report proves `case_model_provider`: `qwen-local`.",
|
|
"Harness report proves `case_model`: `qwen3.6-35b-a3b`.",
|
|
"Harness report proves `case_model_admission_status`: `admitted`.",
|
|
"Harness report proves no fallback to `anthropic` or `claude-sonnet-4-6`.",
|
|
"Real Case Stage 2 pass evidence exists only through the Harness Evidence Interface.",
|
|
"A configured endpoint alone does not validate `CTO-WORK-016`, `CTO-WORK-020`, `CTO-WORK-022`, or `CTO-WORK-028`.",
|
|
"No Target Repository path may be inspected or copied.",
|
|
"Same-run fake baseline comparison remains required for any pass claim.",
|
|
"`CTO-WORK-016` remains blocked until real Case Stage 2 pass evidence exists.",
|
|
"`CTO-WORK-022` remains blocked until explicit endpoint config and real Case Stage 2 pass evidence exist.",
|
|
"Non-secret readiness check on 2026-06-01 showed `CTO_HARNESS_CASE_LOCAL_BASE_URL=missing`.",
|
|
]
|
|
|
|
|
|
def workboard_status(text: str, issue_id: str) -> str | None:
|
|
pattern = rf"- id: {re.escape(issue_id)}\n(?: .+\n)*? status: ([^\n]+)"
|
|
match = re.search(pattern, text)
|
|
return match.group(1).strip() if match else None
|
|
|
|
|
|
def main() -> int:
|
|
checked: list[str] = []
|
|
errors: list[str] = []
|
|
|
|
for rel in REQUIRED_FILES:
|
|
path = ROOT / rel
|
|
checked.append(rel)
|
|
if not path.is_file():
|
|
errors.append(f"missing_required_file:{rel}")
|
|
|
|
brief = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-BACKEND-BRIEF.md"
|
|
if brief.is_file():
|
|
text = brief.read_text(encoding="utf-8")
|
|
if "status: validated" not in text:
|
|
errors.append("brief_missing_validated_frontmatter")
|
|
for phrase in REQUIRED_BRIEF_PHRASES:
|
|
checked.append(f"brief_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_brief_phrase:{phrase}")
|
|
|
|
architecture_closeout_prd = ROOT / ".sot/03-PROTOCOLS/CTO-ARCHITECTURE-BRIEF-CLOSEOUT-PRD.md"
|
|
if architecture_closeout_prd.is_file():
|
|
text = architecture_closeout_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("architecture_closeout_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_ARCHITECTURE_CLOSEOUT_PRD_PHRASES:
|
|
checked.append(f"architecture_closeout_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_architecture_closeout_prd_phrase:{phrase}")
|
|
|
|
architecture_closeout_issues = ROOT / ".sot/03-PROTOCOLS/CTO-ARCHITECTURE-BRIEF-CLOSEOUT-ISSUES.md"
|
|
if architecture_closeout_issues.is_file():
|
|
text = architecture_closeout_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("architecture_closeout_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("architecture_closeout_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_ARCHITECTURE_CLOSEOUT_ISSUE_IDS:
|
|
checked.append(f"architecture_closeout_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_architecture_closeout_issue_id:{issue_id}")
|
|
|
|
first_real_workflow_prd = ROOT / ".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-PRD.md"
|
|
if first_real_workflow_prd.is_file():
|
|
text = first_real_workflow_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("first_real_workflow_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_FIRST_REAL_WORKFLOW_PRD_PHRASES:
|
|
checked.append(f"first_real_workflow_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_first_real_workflow_prd_phrase:{phrase}")
|
|
|
|
first_real_workflow_issues = ROOT / ".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-ISSUES.md"
|
|
if first_real_workflow_issues.is_file():
|
|
text = first_real_workflow_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("first_real_workflow_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("first_real_workflow_issues_missing_local_planning_notice")
|
|
if "Human gate: JP must approve the concrete Target Repository and task contract before execution." not in text:
|
|
errors.append("first_real_workflow_issues_missing_human_gate")
|
|
for issue_id in REQUIRED_FIRST_REAL_WORKFLOW_ISSUE_IDS:
|
|
checked.append(f"first_real_workflow_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_first_real_workflow_issue_id:{issue_id}")
|
|
|
|
first_real_workflow_approval_packet = ROOT / ".sot/03-PROTOCOLS/CTO-FIRST-REAL-GOVERNED-WORKFLOW-APPROVAL-PACKET.md"
|
|
if first_real_workflow_approval_packet.is_file():
|
|
text = first_real_workflow_approval_packet.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("first_real_workflow_approval_packet_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_FIRST_REAL_WORKFLOW_APPROVAL_PACKET_PHRASES:
|
|
checked.append(f"first_real_workflow_approval_packet_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_first_real_workflow_approval_packet_phrase:{phrase}")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("brief_missing_not_promoted_frontmatter")
|
|
|
|
stage6_real_refresh_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-REAL-GOVERNED-REFRESH-PRD.md"
|
|
if stage6_real_refresh_prd.is_file():
|
|
text = stage6_real_refresh_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage6_real_refresh_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE6_REAL_REFRESH_PHRASES:
|
|
checked.append(f"stage6_real_refresh_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage6_real_refresh_prd_phrase:{phrase}")
|
|
|
|
stage6_real_refresh_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-REAL-GOVERNED-REFRESH-ISSUES.md"
|
|
if stage6_real_refresh_issues.is_file():
|
|
text = stage6_real_refresh_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage6_real_refresh_issues_missing_not_promoted_frontmatter")
|
|
for phrase in [
|
|
"CTO-WORK-054",
|
|
"CTO-WORK-055",
|
|
"runtime_default_activation: false",
|
|
"harness/evals/health.sh --json",
|
|
]:
|
|
checked.append(f"stage6_real_refresh_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage6_real_refresh_issue_phrase:{phrase}")
|
|
|
|
hermes_real_refresh_control_replay_prd = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-PRD.md"
|
|
if hermes_real_refresh_control_replay_prd.is_file():
|
|
text = hermes_real_refresh_control_replay_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_real_refresh_control_replay_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_PHRASES:
|
|
checked.append(f"hermes_real_refresh_control_replay_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_real_refresh_control_replay_prd_phrase:{phrase}")
|
|
|
|
hermes_real_refresh_control_replay_issues = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-ISSUES.md"
|
|
if hermes_real_refresh_control_replay_issues.is_file():
|
|
text = hermes_real_refresh_control_replay_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_real_refresh_control_replay_issues_missing_not_promoted_frontmatter")
|
|
for phrase in ["CTO-WORK-056", "CTO-WORK-057", "case_stage6_real_governed_refresh", "stage6_real_governed_refresh_comparison_path", "runtime_default_activation"]:
|
|
checked.append(f"hermes_real_refresh_control_replay_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_real_refresh_control_replay_issue_phrase:{phrase}")
|
|
|
|
hermes_webui_control_panel_prd = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-PRD.md"
|
|
if hermes_webui_control_panel_prd.is_file():
|
|
text = hermes_webui_control_panel_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_webui_control_panel_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_WEBUI_CONTROL_PANEL_PHRASES:
|
|
checked.append(f"hermes_webui_control_panel_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_webui_control_panel_prd_phrase:{phrase}")
|
|
|
|
hermes_webui_control_panel_issues = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-ISSUES.md"
|
|
if hermes_webui_control_panel_issues.is_file():
|
|
text = hermes_webui_control_panel_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_webui_control_panel_issues_missing_not_promoted_frontmatter")
|
|
for phrase in ["CTO-WORK-058", "CTO-WORK-059", "upstream `hermes-webui`", "upstream `hermes-agent`", "runtime default activation"]:
|
|
checked.append(f"hermes_webui_control_panel_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_webui_control_panel_issue_phrase:{phrase}")
|
|
|
|
hermes_webui_control_panel_evidence = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-CONTROL-PANEL-EVIDENCE.md"
|
|
if hermes_webui_control_panel_evidence.is_file():
|
|
text = hermes_webui_control_panel_evidence.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_webui_control_panel_evidence_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_WEBUI_CONTROL_PANEL_EVIDENCE_PHRASES:
|
|
checked.append(f"hermes_webui_control_panel_evidence_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_webui_control_panel_evidence_phrase:{phrase}")
|
|
|
|
hermes_webui_live_smoke_prd = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-PRD.md"
|
|
if hermes_webui_live_smoke_prd.is_file():
|
|
text = hermes_webui_live_smoke_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_webui_live_smoke_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_WEBUI_LIVE_SMOKE_PHRASES:
|
|
checked.append(f"hermes_webui_live_smoke_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_webui_live_smoke_prd_phrase:{phrase}")
|
|
|
|
hermes_webui_live_smoke_issues = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-WEBUI-LIVE-SMOKE-ISSUES.md"
|
|
if hermes_webui_live_smoke_issues.is_file():
|
|
text = hermes_webui_live_smoke_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_webui_live_smoke_issues_missing_not_promoted_frontmatter")
|
|
for phrase in ["CTO-WORK-060", "CTO-WORK-061", *REQUIRED_HERMES_WEBUI_LIVE_SMOKE_PHRASES]:
|
|
checked.append(f"hermes_webui_live_smoke_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_webui_live_smoke_issue_phrase:{phrase}")
|
|
|
|
hermes_real_refresh_control_replay_evidence = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-REAL-REFRESH-CONTROL-REPLAY-EVIDENCE.md"
|
|
if hermes_real_refresh_control_replay_evidence.is_file():
|
|
text = hermes_real_refresh_control_replay_evidence.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_real_refresh_control_replay_evidence_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_REAL_REFRESH_CONTROL_REPLAY_EVIDENCE_PHRASES:
|
|
checked.append(f"hermes_real_refresh_control_replay_evidence_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_real_refresh_control_replay_evidence_phrase:{phrase}")
|
|
|
|
stage6_real_refresh_evidence = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE6-REAL-GOVERNED-REFRESH-EVIDENCE.md"
|
|
if stage6_real_refresh_evidence.is_file():
|
|
text = stage6_real_refresh_evidence.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage6_real_refresh_evidence_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE6_REAL_REFRESH_EVIDENCE_PHRASES:
|
|
checked.append(f"stage6_real_refresh_evidence_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage6_real_refresh_evidence_phrase:{phrase}")
|
|
|
|
prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-CANDIDATE-BACKEND-PRD.md"
|
|
if prd.is_file():
|
|
text = prd.read_text(encoding="utf-8")
|
|
for phrase in REQUIRED_PRD_PHRASES:
|
|
checked.append(f"prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_prd_phrase:{phrase}")
|
|
for phrase in FORBIDDEN_PRD_PHRASES:
|
|
checked.append(f"prd_forbidden_phrase:{phrase}")
|
|
if phrase in text:
|
|
errors.append(f"forbidden_prd_phrase:{phrase}")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("prd_missing_not_promoted_frontmatter")
|
|
|
|
issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-CANDIDATE-BACKEND-ISSUES.md"
|
|
if issues.is_file():
|
|
text = issues.read_text(encoding="utf-8")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("issues_missing_local_planning_notice")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("issues_missing_not_promoted_frontmatter")
|
|
for issue_id in REQUIRED_ISSUE_IDS:
|
|
checked.append(f"issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_issue_id:{issue_id}")
|
|
|
|
spark_endpoint_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-SPARK-ENDPOINT-CONFIG-PRD.md"
|
|
if spark_endpoint_prd.is_file():
|
|
text = spark_endpoint_prd.read_text(encoding="utf-8")
|
|
for phrase in REQUIRED_SPARK_ENDPOINT_CONFIG_PRD_PHRASES:
|
|
checked.append(f"spark_endpoint_config_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_spark_endpoint_config_prd_phrase:{phrase}")
|
|
|
|
spark_endpoint_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-SPARK-ENDPOINT-CONFIG-ISSUES.md"
|
|
if spark_endpoint_issues.is_file():
|
|
text = spark_endpoint_issues.read_text(encoding="utf-8")
|
|
for phrase in REQUIRED_SPARK_ENDPOINT_CONFIG_ISSUE_PHRASES:
|
|
checked.append(f"spark_endpoint_config_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_spark_endpoint_config_issue_phrase:{phrase}")
|
|
|
|
evidence_interface = ROOT / ".sot/03-PROTOCOLS/CTO-HARNESS-EVIDENCE-INTERFACE-CONTRACT.md"
|
|
if evidence_interface.is_file():
|
|
text = evidence_interface.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("evidence_interface_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_EVIDENCE_INTERFACE_PHRASES:
|
|
checked.append(f"evidence_interface_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_evidence_interface_phrase:{phrase}")
|
|
|
|
source_admission = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-SOURCE-ADMISSION-RECORD.md"
|
|
if source_admission.is_file():
|
|
text = source_admission.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("source_admission_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_SOURCE_ADMISSION_PHRASES:
|
|
checked.append(f"source_admission_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_source_admission_phrase:{phrase}")
|
|
|
|
adapter_contract = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-ADAPTER-CONTRACT.md"
|
|
if adapter_contract.is_file():
|
|
text = adapter_contract.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("adapter_contract_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_ADAPTER_CONTRACT_PHRASES:
|
|
checked.append(f"adapter_contract_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_adapter_contract_phrase:{phrase}")
|
|
|
|
failure_matrix = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-FAILURE-FIXTURE-MATRIX.md"
|
|
if failure_matrix.is_file():
|
|
text = failure_matrix.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("failure_matrix_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_FAILURE_FIXTURE_PHRASES:
|
|
checked.append(f"failure_matrix_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_failure_matrix_phrase:{phrase}")
|
|
|
|
staged_proof = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGED-PROOF-GATES.md"
|
|
if staged_proof.is_file():
|
|
text = staged_proof.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("staged_proof_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGED_PROOF_PHRASES:
|
|
checked.append(f"staged_proof_phrase:{phrase}")
|
|
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}")
|
|
|
|
stage2_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md"
|
|
if stage2_prd.is_file():
|
|
text = stage2_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage2_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE2_PRD_PHRASES:
|
|
checked.append(f"stage2_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage2_prd_phrase:{phrase}")
|
|
|
|
stage2_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md"
|
|
if stage2_issues.is_file():
|
|
text = stage2_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage2_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("stage2_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_STAGE2_ISSUE_IDS:
|
|
checked.append(f"stage2_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_stage2_issue_id:{issue_id}")
|
|
|
|
stage3_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE3-COPIED-REPO-PRD.md"
|
|
if stage3_prd.is_file():
|
|
text = stage3_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage3_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE3_PRD_PHRASES:
|
|
checked.append(f"stage3_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage3_prd_phrase:{phrase}")
|
|
|
|
stage3_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE3-COPIED-REPO-ISSUES.md"
|
|
if stage3_issues.is_file():
|
|
text = stage3_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage3_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("stage3_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_STAGE3_ISSUE_IDS:
|
|
checked.append(f"stage3_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_stage3_issue_id:{issue_id}")
|
|
|
|
stage4_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-PRD.md"
|
|
if stage4_prd.is_file():
|
|
text = stage4_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage4_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE4_PRD_PHRASES:
|
|
checked.append(f"stage4_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage4_prd_phrase:{phrase}")
|
|
|
|
stage4_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-ISSUES.md"
|
|
if stage4_issues.is_file():
|
|
text = stage4_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage4_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("stage4_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_STAGE4_ISSUE_IDS:
|
|
checked.append(f"stage4_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_stage4_issue_id:{issue_id}")
|
|
|
|
stage5_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-PRD.md"
|
|
if stage5_prd.is_file():
|
|
text = stage5_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage5_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE5_PRD_PHRASES:
|
|
checked.append(f"stage5_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage5_prd_phrase:{phrase}")
|
|
|
|
stage5_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md"
|
|
if stage5_issues.is_file():
|
|
text = stage5_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage5_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("stage5_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_STAGE5_ISSUE_IDS:
|
|
checked.append(f"stage5_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_stage5_issue_id:{issue_id}")
|
|
|
|
stage5_target_admission_template = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION-TEMPLATE.md"
|
|
if stage5_target_admission_template.is_file():
|
|
text = stage5_target_admission_template.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("stage5_target_admission_template_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_STAGE5_TARGET_ADMISSION_TEMPLATE_PHRASES:
|
|
checked.append(f"stage5_target_admission_template_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_stage5_target_admission_template_phrase:{phrase}")
|
|
|
|
stage5_target_admission = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json"
|
|
if stage5_target_admission.is_file():
|
|
checked.append("stage5_target_admission_json:parse")
|
|
try:
|
|
payload = json.loads(stage5_target_admission.read_text(encoding="utf-8"))
|
|
except json.JSONDecodeError as exc:
|
|
errors.append(f"stage5_target_admission_invalid_json:{exc}")
|
|
payload = {}
|
|
if not isinstance(payload, dict):
|
|
errors.append("stage5_target_admission_must_be_object")
|
|
payload = {}
|
|
for key, expected in REQUIRED_STAGE5_TARGET_ADMISSION_JSON.items():
|
|
checked.append(f"stage5_target_admission_json:{key}")
|
|
if payload.get(key) != expected:
|
|
errors.append(f"stage5_target_admission_mismatch:{key}:expected_{expected}:actual_{payload.get(key)}")
|
|
for key in ["allowed_paths", "forbidden_paths", "forbidden_actions"]:
|
|
checked.append(f"stage5_target_admission_json_list:{key}")
|
|
if not isinstance(payload.get(key), list):
|
|
errors.append(f"stage5_target_admission_missing_list:{key}")
|
|
forbidden_actions = payload.get("forbidden_actions", [])
|
|
if isinstance(forbidden_actions, list):
|
|
for action in REQUIRED_STAGE5_TARGET_FORBIDDEN_ACTIONS:
|
|
checked.append(f"stage5_target_admission_forbidden_action:{action}")
|
|
if action not in forbidden_actions:
|
|
errors.append(f"stage5_target_admission_missing_forbidden_action:{action}")
|
|
allowed_paths = payload.get("allowed_paths")
|
|
if not isinstance(allowed_paths, list) or allowed_paths != ["strings.py", "test_strings.py", "src/", "tests/", "README.md"]:
|
|
errors.append(f"stage5_target_admission_allowed_paths_mismatch:actual_{allowed_paths}")
|
|
forbidden_paths = payload.get("forbidden_paths")
|
|
if not isinstance(forbidden_paths, list) or ".git/" not in forbidden_paths or "secrets/" not in forbidden_paths or "deploy/" not in forbidden_paths:
|
|
errors.append("stage5_target_admission_forbidden_paths_incomplete")
|
|
if not isinstance(payload.get("review_trigger"), str) or not payload.get("review_trigger"):
|
|
errors.append("stage5_target_admission_missing_review_trigger")
|
|
for key in payload:
|
|
checked.append(f"stage5_target_admission_json_secret_key:{key}")
|
|
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}")
|
|
|
|
hermes_control_surface_prd = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-CONTROL-SURFACE-PRD.md"
|
|
if hermes_control_surface_prd.is_file():
|
|
text = hermes_control_surface_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_control_surface_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_HERMES_CONTROL_SURFACE_PRD_PHRASES:
|
|
checked.append(f"hermes_control_surface_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_hermes_control_surface_prd_phrase:{phrase}")
|
|
|
|
hermes_control_surface_issues = ROOT / ".sot/03-PROTOCOLS/CTO-HERMES-CONTROL-SURFACE-ISSUES.md"
|
|
if hermes_control_surface_issues.is_file():
|
|
text = hermes_control_surface_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("hermes_control_surface_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("hermes_control_surface_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_HERMES_CONTROL_SURFACE_ISSUE_IDS:
|
|
checked.append(f"hermes_control_surface_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_hermes_control_surface_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}")
|
|
|
|
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}")
|
|
|
|
model_provider_admission_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION-PRD.md"
|
|
if model_provider_admission_prd.is_file():
|
|
text = model_provider_admission_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("model_provider_admission_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_MODEL_PROVIDER_ADMISSION_PRD_PHRASES:
|
|
checked.append(f"model_provider_admission_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_model_provider_admission_prd_phrase:{phrase}")
|
|
|
|
model_provider_admission_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION-ISSUES.md"
|
|
if model_provider_admission_issues.is_file():
|
|
text = model_provider_admission_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("model_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("model_provider_admission_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_MODEL_PROVIDER_ADMISSION_ISSUE_IDS:
|
|
checked.append(f"model_provider_admission_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_model_provider_admission_issue_id:{issue_id}")
|
|
for phrase in REQUIRED_MODEL_PROVIDER_ADMISSION_ISSUE_PHRASES:
|
|
checked.append(f"model_provider_admission_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_model_provider_admission_issue_phrase:{phrase}")
|
|
|
|
openai_codex_admission = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION.openai-codex-gpt-5.5.json"
|
|
if openai_codex_admission.is_file():
|
|
checked.append("openai_codex_admission_json:parse")
|
|
try:
|
|
payload = json.loads(openai_codex_admission.read_text(encoding="utf-8"))
|
|
except json.JSONDecodeError as exc:
|
|
errors.append(f"openai_codex_admission_invalid_json:{exc}")
|
|
payload = {}
|
|
if not isinstance(payload, dict):
|
|
errors.append("openai_codex_admission_must_be_object")
|
|
payload = {}
|
|
for key, expected in REQUIRED_OPENAI_CODEX_ADMISSION_JSON.items():
|
|
checked.append(f"openai_codex_admission_json:{key}")
|
|
if payload.get(key) != expected:
|
|
errors.append(f"openai_codex_admission_mismatch:{key}:expected_{expected}:actual_{payload.get(key)}")
|
|
for key in ["admission_timestamp", "review_trigger"]:
|
|
checked.append(f"openai_codex_admission_json:{key}")
|
|
if not isinstance(payload.get(key), str) or not payload.get(key):
|
|
errors.append(f"openai_codex_admission_missing:{key}")
|
|
for key in payload:
|
|
checked.append(f"openai_codex_admission_json_secret_key:{key}")
|
|
if key.lower() in {"api_key", "apikey", "access_token", "token", "secret", "password", "credential_value"}:
|
|
errors.append(f"openai_codex_admission_forbidden_secret_key:{key}")
|
|
|
|
qwen_local_admission = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-MODEL-PROVIDER-ADMISSION.qwen-local-qwen3.6-35b-a3b.json"
|
|
if qwen_local_admission.is_file():
|
|
checked.append("qwen_local_admission_json:parse")
|
|
try:
|
|
payload = json.loads(qwen_local_admission.read_text(encoding="utf-8"))
|
|
except json.JSONDecodeError as exc:
|
|
errors.append(f"qwen_local_admission_invalid_json:{exc}")
|
|
payload = {}
|
|
if not isinstance(payload, dict):
|
|
errors.append("qwen_local_admission_must_be_object")
|
|
payload = {}
|
|
for key, expected in REQUIRED_QWEN_LOCAL_ADMISSION_JSON.items():
|
|
checked.append(f"qwen_local_admission_json:{key}")
|
|
if payload.get(key) != expected:
|
|
errors.append(f"qwen_local_admission_mismatch:{key}:expected_{expected}:actual_{payload.get(key)}")
|
|
for key in ["admission_timestamp", "review_trigger"]:
|
|
checked.append(f"qwen_local_admission_json:{key}")
|
|
if not isinstance(payload.get(key), str) or not payload.get(key):
|
|
errors.append(f"qwen_local_admission_missing:{key}")
|
|
for key in payload:
|
|
checked.append(f"qwen_local_admission_json_secret_key:{key}")
|
|
if key.lower() in {"api_key", "apikey", "access_token", "token", "secret", "password", "credential_value"}:
|
|
errors.append(f"qwen_local_admission_forbidden_secret_key:{key}")
|
|
|
|
local_provider_route_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-LOCAL-PROVIDER-ROUTE-PRD.md"
|
|
if local_provider_route_prd.is_file():
|
|
text = local_provider_route_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("local_provider_route_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_LOCAL_PROVIDER_ROUTE_PRD_PHRASES:
|
|
checked.append(f"local_provider_route_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_local_provider_route_prd_phrase:{phrase}")
|
|
|
|
local_provider_route_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-LOCAL-PROVIDER-ROUTE-ISSUES.md"
|
|
if local_provider_route_issues.is_file():
|
|
text = local_provider_route_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("local_provider_route_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("local_provider_route_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_LOCAL_PROVIDER_ROUTE_ISSUE_IDS:
|
|
checked.append(f"local_provider_route_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_local_provider_route_issue_id:{issue_id}")
|
|
for phrase in REQUIRED_LOCAL_PROVIDER_ROUTE_ISSUE_PHRASES:
|
|
checked.append(f"local_provider_route_issue_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_local_provider_route_issue_phrase:{phrase}")
|
|
|
|
provider_decision_packet_prd = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-PRD.md"
|
|
if provider_decision_packet_prd.is_file():
|
|
text = provider_decision_packet_prd.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("provider_decision_packet_prd_missing_not_promoted_frontmatter")
|
|
for phrase in REQUIRED_PROVIDER_DECISION_PACKET_PRD_PHRASES:
|
|
checked.append(f"provider_decision_packet_prd_phrase:{phrase}")
|
|
if phrase not in text:
|
|
errors.append(f"missing_provider_decision_packet_prd_phrase:{phrase}")
|
|
|
|
provider_decision_packet_issues = ROOT / ".sot/03-PROTOCOLS/CTO-CASE-PROVIDER-DECISION-PACKET-ISSUES.md"
|
|
if provider_decision_packet_issues.is_file():
|
|
text = provider_decision_packet_issues.read_text(encoding="utf-8")
|
|
if "core_promotion_status: not-promoted" not in text:
|
|
errors.append("provider_decision_packet_issues_missing_not_promoted_frontmatter")
|
|
if "Local planning SOT only. Not a Core Protocol. Not active Core authority." not in text:
|
|
errors.append("provider_decision_packet_issues_missing_local_planning_notice")
|
|
for issue_id in REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_IDS:
|
|
checked.append(f"provider_decision_packet_issue_id:{issue_id}")
|
|
if issue_id not in text:
|
|
errors.append(f"missing_provider_decision_packet_issue_id:{issue_id}")
|
|
for phrase in REQUIRED_PROVIDER_DECISION_PACKET_ISSUE_PHRASES:
|
|
checked.append(f"provider_decision_packet_issue_phrase:{phrase}")
|
|
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")
|
|
for issue_id in ["CTO-WORK-002", *REQUIRED_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_STAGE1_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_STAGE2_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_STAGE3_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_STAGE5_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_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_HERMES_CONTROL_SURFACE_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_ARCHITECTURE_CLOSEOUT_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_FIRST_REAL_WORKFLOW_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:
|
|
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}")
|
|
for issue_id in REQUIRED_MODEL_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}")
|
|
for issue_id in REQUIRED_LOCAL_PROVIDER_ROUTE_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_DECISION_PACKET_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-001": "validated",
|
|
"CTO-WORK-002": "validated",
|
|
"CTO-WORK-003": "validated",
|
|
"CTO-WORK-004": "validated",
|
|
"CTO-WORK-005": "validated",
|
|
"CTO-WORK-006": "validated",
|
|
"CTO-WORK-007": "validated",
|
|
"CTO-WORK-008": "validated",
|
|
"CTO-WORK-009": "validated",
|
|
"CTO-WORK-010": "validated",
|
|
"CTO-WORK-011": "validated",
|
|
"CTO-WORK-012": "validated",
|
|
"CTO-WORK-013": "validated",
|
|
"CTO-WORK-014": "validated",
|
|
"CTO-WORK-015": "validated",
|
|
"CTO-WORK-016": "validated",
|
|
"CTO-WORK-017": "validated",
|
|
"CTO-WORK-018": "validated",
|
|
"CTO-WORK-019": "validated",
|
|
"CTO-WORK-020": "validated",
|
|
"CTO-WORK-021": "validated",
|
|
"CTO-WORK-022": "validated",
|
|
"CTO-WORK-023": "validated",
|
|
"CTO-WORK-024": "validated",
|
|
"CTO-WORK-025": "validated",
|
|
"CTO-WORK-026": "validated",
|
|
"CTO-WORK-027": "validated",
|
|
"CTO-WORK-029": "validated",
|
|
"CTO-WORK-030": "validated",
|
|
"CTO-WORK-033": "validated",
|
|
"CTO-WORK-034": "validated",
|
|
"CTO-WORK-035": "validated",
|
|
"CTO-WORK-036": "validated",
|
|
"CTO-WORK-037": "validated",
|
|
"CTO-WORK-038": "validated",
|
|
"CTO-WORK-039": "validated",
|
|
"CTO-WORK-040": "validated",
|
|
"CTO-WORK-041": "validated",
|
|
"CTO-WORK-042": "validated",
|
|
"CTO-WORK-043": "validated",
|
|
"CTO-WORK-044": "validated",
|
|
"CTO-WORK-045": "validated",
|
|
"CTO-WORK-046": "validated",
|
|
"CTO-WORK-047": "validated",
|
|
"CTO-WORK-048": "validated",
|
|
"CTO-WORK-049": "validated",
|
|
"CTO-WORK-050": "validated",
|
|
"CTO-WORK-051": "blocked",
|
|
"CTO-WORK-052": "validated",
|
|
"CTO-WORK-053": "validated",
|
|
"CTO-WORK-054": "validated",
|
|
"CTO-WORK-055": "validated",
|
|
"CTO-WORK-056": "validated",
|
|
"CTO-WORK-057": "validated",
|
|
"CTO-WORK-058": "validated",
|
|
"CTO-WORK-059": "validated",
|
|
"CTO-WORK-060": "validated",
|
|
"CTO-WORK-061": "candidate",
|
|
}
|
|
for issue_id, expected in expected_statuses.items():
|
|
checked.append(f"workboard_status:{issue_id}:{expected}")
|
|
actual = workboard_status(text, issue_id)
|
|
if actual != expected:
|
|
errors.append(f"workboard_status_mismatch:{issue_id}:expected_{expected}:actual_{actual}")
|
|
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:
|
|
errors.append("workboard_cto_work_004_not_validated")
|
|
if "CTO-CASE-SOURCE-ADMISSION-RECORD.md" not in text:
|
|
errors.append("workboard_missing_source_admission_record_source")
|
|
if "CTO-CASE-ADAPTER-CONTRACT.md" not in text:
|
|
errors.append("workboard_missing_adapter_contract_source")
|
|
if "CTO-CASE-FAILURE-FIXTURE-MATRIX.md" not in text:
|
|
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")
|
|
if "CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-PRD.md" not in text:
|
|
errors.append("workboard_missing_stage2_prd_source")
|
|
if "CTO-CASE-STAGE2-ARTIFICIAL-FIXTURE-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_stage2_issues_source")
|
|
if "CTO-CASE-STAGE3-COPIED-REPO-PRD.md" not in text:
|
|
errors.append("workboard_missing_stage3_prd_source")
|
|
if "CTO-CASE-STAGE3-COPIED-REPO-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_stage3_issues_source")
|
|
if "CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-PRD.md" not in text:
|
|
errors.append("workboard_missing_stage4_prd_source")
|
|
if "CTO-CASE-STAGE4-DISPOSABLE-SANDBOX-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_stage4_issues_source")
|
|
if "CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-PRD.md" not in text:
|
|
errors.append("workboard_missing_stage5_prd_source")
|
|
if "CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_stage5_issues_source")
|
|
if "CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION-TEMPLATE.md" not in text:
|
|
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-HERMES-CONTROL-SURFACE-PRD.md" not in text:
|
|
errors.append("workboard_missing_hermes_control_surface_prd_source")
|
|
if "CTO-HERMES-CONTROL-SURFACE-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_hermes_control_surface_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")
|
|
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")
|
|
if "CTO-CASE-MODEL-PROVIDER-ADMISSION-PRD.md" not in text:
|
|
errors.append("workboard_missing_model_provider_admission_prd_source")
|
|
if "CTO-CASE-MODEL-PROVIDER-ADMISSION-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_model_provider_admission_issues_source")
|
|
if "CTO-CASE-LOCAL-PROVIDER-ROUTE-PRD.md" not in text:
|
|
errors.append("workboard_missing_local_provider_route_prd_source")
|
|
if "CTO-CASE-LOCAL-PROVIDER-ROUTE-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_local_provider_route_issues_source")
|
|
if "CTO-CASE-PROVIDER-DECISION-PACKET-PRD.md" not in text:
|
|
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")
|
|
if "CTO-CASE-MODEL-PROVIDER-ADMISSION.openai-codex-gpt-5.5.json" not in text:
|
|
errors.append("workboard_missing_openai_codex_admission_json_source")
|
|
if "CTO-CASE-MODEL-PROVIDER-ADMISSION.qwen-local-qwen3.6-35b-a3b.json" not in text:
|
|
errors.append("workboard_missing_qwen_local_admission_json_source")
|
|
if "CTO-CASE-SPARK-ENDPOINT-CONFIG-ISSUES.md" not in text:
|
|
errors.append("workboard_missing_spark_endpoint_config_issues_source")
|
|
|
|
payload = {
|
|
"ok": not errors,
|
|
"validator": "cto-child-v1",
|
|
"checked": checked,
|
|
"errors": errors,
|
|
"warnings": [],
|
|
}
|
|
print(json.dumps(payload, indent=2, sort_keys=True))
|
|
return 0 if not errors else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|