Record Stage 5 preflight evidence

This commit is contained in:
Svrnty 2026-05-31 23:55:11 -04:00
parent 3f8a2eeeab
commit 1fc678fd54
4 changed files with 47 additions and 0 deletions

View File

@ -147,6 +147,45 @@ Validator: `python3 tools/validate_cto_child.py`
Done evidence for current blocked state: admission JSON, issue reference, validator JSON, clean worktree, commit.
### CTO-WORK-041 - Stage 5 Harness Target Admission Preflight
Type: AFK
Status: validated.
Blocked by: CTO-WORK-039
User stories covered: CTO Case Candidate Backend PRD stories 4, 5, 7, 8, 9, 10, 11, 13.
What to build: Implement the Stage 5 Harness preflight that blocks missing, invalid, or `not_admitted` Target Repository admission before Case process start and before owned repository mutation.
Acceptance criteria:
- [x] `case` remains disabled by default.
- [x] `CTO_HARNESS_ALLOW_CASE=1` remains required.
- [x] `CTO_HARNESS_CASE_STAGE=5` is recognized only as a gated Stage 5 route.
- [x] Missing Stage 5 gate emits blocked evidence and does not run Case.
- [x] Missing Target Repository admission file blocks before `case_process_started`.
- [x] `not_admitted` Target Repository admission blocks before `case_process_started`.
- [x] Blocked reports record `allowed_mutation_scope: explicitly owned low-risk repository only`.
- [x] Blocked reports do not expose a Target Repository path.
- [x] Fake remains the default validation lane and broad health remains green after focused Stage 5 preflight validation.
Allowed files: Hermes CTO harness engine, focused Stage 5 validator, harness docs, and tests. WebUI, Core, Case source, vendor source, unowned repositories, critical repositories, production repositories, and external developer repositories are forbidden.
Validator: `python3 harness/runner/validate-case-stage5.py --harness-root harness --json`, then `harness/evals/health.sh --json`.
Done evidence:
- Hermes commit: `6e68a1a Add Case Stage 5 target admission preflight`.
- Focused Stage 5 validator on Hermes main: `python3 harness/runner/validate-case-stage5.py --harness-root harness --json`.
- Focused Stage 5 validator status: `ok: true`.
- Failure fixture reports: `/home/svrnty/.hermes/profiles/cto-planb/harness-runs/20260601T035339Z-r1-string-slugify-3187514/report.json`, `/home/svrnty/.hermes/profiles/cto-planb/harness-runs/20260601T035339Z-r1-string-slugify-3187546/report.json`, and `/home/svrnty/.hermes/profiles/cto-planb/harness-runs/20260601T035340Z-r1-string-slugify-3187577/report.json`.
- Post-merge aggregate Harness health: `harness/evals/health.sh --json`, status `pass`.
- Aggregate matrix artifact: `/home/svrnty/.hermes/profiles/cto-planb/harness-runs/20260601T035347Z-run-all-fake-3188313/report.json`.
- This validates Stage 5 admission preflight only. Stage 5 owned repository execution remains blocked by `CTO-WORK-040`.
## Granularity Check
This is intentionally two slices: one planning route and one executable harness route. Stage 5 is not over-granular because it is the first proof involving an admitted owned repository and must separate repository ownership, approval, allowed paths, verification, and operator outcome before default candidacy.

View File

@ -264,6 +264,7 @@ Planning evidence:
- Stage 5 PRD: `.sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-PRD.md`.
- Stage 5 issues: `.sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md`.
- Stage 5 admission preflight evidence: Hermes commit `6e68a1a Add Case Stage 5 target admission preflight`; focused validator `ok: true`; aggregate harness health `pass`. This validates admission preflight only, not owned repository execution.
Validator expectation:

View File

@ -200,3 +200,8 @@ items:
status: blocked
source: .sot/03-PROTOCOLS/CTO-CASE-STAGE5-TARGET-REPOSITORY-ADMISSION.json
owner: jp
- id: CTO-WORK-041
title: Stage 5 Harness Target Admission Preflight
status: validated
source: .sot/03-PROTOCOLS/CTO-CASE-STAGE5-OWNED-NONCRITICAL-REPO-ISSUES.md
owner: ""

View File

@ -336,6 +336,7 @@ REQUIRED_STAGE5_ISSUE_IDS = [
"CTO-WORK-038",
"CTO-WORK-039",
"CTO-WORK-040",
"CTO-WORK-041",
]
REQUIRED_STAGE5_TARGET_ADMISSION_TEMPLATE_PHRASES = [
@ -1348,6 +1349,7 @@ def main() -> int:
"CTO-WORK-038": "blocked",
"CTO-WORK-039": "validated",
"CTO-WORK-040": "blocked",
"CTO-WORK-041": "validated",
}
for issue_id, expected in expected_statuses.items():
checked.append(f"workboard_status:{issue_id}:{expected}")