Restore openenv validate skeleton - #1112
Conversation
|
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
There was a problem hiding this comment.
Alignment Review Report
Two-tier alignment review of the RFC 008 openenv validate skeleton restore. I ran the repo's hooks, read PRINCIPLES/INVARIANTS and every RFC, traced the new runner/parser/grader/signature code against the existing contracts, and ran the test suites.
Automated Checks
- Lint: PASS (for this PR).
.claude/hooks/lint.shexits FAIL, but all 25 flagged files are pre-existing formatting drift underenvs/(e.g.envs/opencode_env/*,envs/pi_env/*) unrelated to this change. The PR's own 16 changed.pyfiles passusort check,ruff format --check, andruff checkcleanly. - Debug code: CLEAN (for this PR).
check-debug.shlists print/TODO statements, but every one is pre-existing; the new modules usetyper.echo, and noprint()/breakpoint()is introduced. - Tests (beyond the skill's required checks, run for confidence): PASS. All 114 tests in
tests/test_validation/+tests/test_cli/test_validate.pypass (new parser/runner/signature/CLI-validate suites andtest_schema_sync), and the fulltests/test_cli/suite (130) passes.
Open RFCs Context
- RFC 008 — Environment Auto-Validation (In Review, @zkwentz) — this PR implements the RFC's walking skeleton (signature detection → parser → normalized manifest → static grader → severity policy → report → exit code). Reviewed closely for fidelity; see Tier 2.
- No other open RFC (000–005 In Review, 010 Draft) touches this surface.
Tier 1: Fixes Required
None. No lint, debug, type, import, syntax, or security issues in the PR's code. yaml.safe_load is used (not yaml.load), and parsers are verified pure reads (test_parse_is_a_pure_read).
Tier 2: Alignment Discussion
Principle Conflicts
None identified. The change is confined to the openenv validate CLI and the openenv.validation package; it does not touch the Gymnasium reset/step/state API, the MCP/WebSocket boundaries, client-server separation, or in-environment reward computation. Contract types are Pydantic throughout (aligns with the type-safety principle). The validator reads a declared reward contract to grade well-formedness — it does not compute or augment training rewards, so "rewards in environment" is not implicated.
RFC Conflicts
No true conflicts — the implementation is faithful to RFC 008 (exit-code taxonomy 0/1/2/3; exactly-one-signature-or-ambiguous detection that never guesses; ManifestError surfaced as a graded static.manifest FAIL rather than a crash or exit 2; versioned severity policy owns the verdict; report embeds the manifest verbatim + source digest). Three heads-ups, all consistent with the RFC's staged delivery rather than deviations:
ALIGNMENT FLAG: CLI behavior change — openenv validate <dir> now requires a validation: manifest block
- Principle/RFC at stake: RFC 008 (manifest-driven validation replaces the old structural checks)
- The concern: The old multi-mode structural checks are fully detached;
validatenow parses thevalidation:block and FAILsstatic.manifestwhen it is absent. Onlyecho_envis migrated here — the other 37 of 38 envs that ship anopenenv.yamlhave novalidation:block and will now FAIL (or exit 2unrecognizedif they lackopenenv.yaml). This is the intended RFC direction, but env migration and any CI wiring should be tracked so the rollout doesn't surprise env authors. - Suggested reviewer: @zkwentz
ALIGNMENT FLAG: Skeleton stubs — --level / --skip-build are currently inert
- Principle/RFC at stake: RFC 008 delivery plan ("PR3+ … one vertical slice per PR")
- The concern:
run_validationdoesdel skip_buildand hardcodeslevels_run=[Level.STATIC], so the default--level semanticruns only static graders and aPASSverdict reflects static-only checks. The report stays honest (levels_runshows only static ran), so this is fine for the skeleton — flagging only so the level/skip-build wiring is completed when runtime/semantic graders land. (Inline note below.) - Suggested reviewer: @zkwentz
ALIGNMENT FLAG: Helpers in cli/_validation.py now dead relative to the CLI
- Principle/RFC at stake: "one canonical way" (PRINCIPLES.md)
- The concern:
validate_multi_mode_deployment,get_deployment_modes,format_validation_report, andbuild_local_validation_json_reportare no longer referenced by any non-testsrc/code (only by tests). Keeping them tested during the transition is reasonable, but they should be folded into a grader or removed in a later slice to avoid two parallel notions of "local validation." - Suggested reviewer: @burtenshaw
Summary
- 0 mechanical issues to fix — Tier 1 clean; the PR's files pass lint and introduce no debug code.
- 3 alignment heads-ups for human awareness (all staged-rollout consequences of RFC 008, not conflicts) + 2 minor non-blocking robustness notes left inline.
- 0 true RFC conflicts — the PR implements RFC 008's skeleton faithfully, and the tests are thorough (signature ambiguity, pure-read parsing, policy bounds, schema round-trip, deterministic source digest).
Sent by Cursor Automation: Pre-review
| """ | ||
| source = Path(package_root) / "openenv.yaml" | ||
| try: | ||
| raw = yaml.safe_load(source.read_text(encoding="utf-8")) |
There was a problem hiding this comment.
Minor robustness (non-blocking): only yaml.YAMLError is wrapped into ManifestError here. source.read_text(encoding="utf-8") can also raise UnicodeDecodeError (or other OSError), and since detect_signature only confirms that openenv.yaml exists (not that it decodes as UTF-8), a non-UTF-8 file escapes as an uncaught exception. The CLI then reports it as exit 3 (internal error) instead of the graded static.manifest FAIL / exit 1 that YAML syntax errors get. Consider catching (OSError, UnicodeError) around the read and wrapping it as a ManifestError, mirroring _has_yaml_frontmatter in signature.py.
| manifest=manifest, | ||
| policy_version=policy.policy_version, | ||
| lane=Lane.LOCAL, | ||
| levels_run=[Level.STATIC], |
There was a problem hiding this comment.
Skeleton note (non-blocking): levels_run is hardcoded to [Level.STATIC] and skip_build is dropped (del skip_build above), so --level/--skip-build don't yet influence what runs — the default --level semantic executes only static graders. The report stays honest (it shows only static ran), so this is fine for the walking skeleton; flagging so the level/skip-build wiring is completed when the runtime/semantic graders land per the RFC 008 delivery plan.


This PR reapplies #1091 on #1111. Stack: #1110 → #1111 → #1112.