Skip to content

feat: add pinned eCAD hardware authorization foundation - #158

Merged
srpatcha merged 3 commits into
masterfrom
issue-156-ecad-validation-gate
Oct 6, 2026
Merged

srpatcha merged 3 commits into
masterfrom
issue-156-ecad-validation-gate

Conversation

@srpatcha

Copy link
Copy Markdown
Member

Summary

  • Add immutable eCAD pins for the exact repository commit, contract version, complete schema set, product bundle, and receipt.
  • Validate all bundled v1 documents against pinned local schemas and reject remote schema resolution.
  • Independently recompute V0-V4 verdicts, execution completeness, eligibility, product-scoped requirement coverage, gate assignment, evidence bytes, and provenance.
  • Reject dirty sources, moving references, tampering, schema drift, unsafe paths, unrecognized tools, and every required non-pass result.
  • Provide an authorization-before-generation callback API; denial cannot invoke generation or mutate existing output.

Validation

  • python3 -m pytest tests/unit/test_hardware_validation_gate.py -q — 34 passed.
  • Actual clean eCAD product bundle from feat: define v1 hardware validation contracts and strict results eCAD-Hardware-Products#30 verified structurally and was denied only for genuine non-pass V2-V4 checks.
  • Complete repository suite: 707 passed, 4 skipped, 10 pre-existing failures.
    • 1 failure: local Python environment lacks the ninja package.
    • 9 failures: baseline PackageRecipe lacks to_dict() in index-sync tests.
  • Independent code review: clean after remediation.

Scope boundary

This PR delivers the verifier and authorization foundation. Parent issue #156 remains open for wiring every public generator, explicit BOM/controller role mapping, atomic output publication, and downstream generation receipts.

Related work

Fixes #157
Part of #156

nofollow = getattr(os, "O_NOFOLLOW", 0)
try:
descriptors.append(
os.open(str(root), os.O_RDONLY | os.O_DIRECTORY | nofollow)
Comment on lines +1411 to +1415
os.open(
part,
os.O_RDONLY | os.O_DIRECTORY | nofollow,
dir_fd=descriptors[-1],
)
Comment on lines +1417 to +1421
file_descriptor = os.open(
parts[-1],
os.O_RDONLY | getattr(os, "O_BINARY", 0) | nofollow,
dir_fd=descriptors[-1],
)
@Aswin-V

Aswin-V commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Code review — findings

Reviewed the pinned eCAD hardware-authorization foundation. The security design is sound:

  • Pinned local schemas, no remote resolution — the right call; a verifier that fetches schemas at verify time is a TOCTOU hole.
  • Dirty-source / moving-reference / tampering rejection and independently recomputed V0–V4 verdicts give the gate real teeth rather than checklist semantics.
  • Authorization-before-generation with denial not mutating output is the correct shape for a pre-generation gate.

Concerns:

  1. Single 1504-line verifier. ebuild/eos_ai/hardware_verifier.py does schema validation, verdict recomputation, evidence handling, and provenance in one module. Consider splitting along those seams — the test file (720 lines, 34 tests) suggests the seams are already there.
  2. Validation baseline. The PR description notes 10 pre-existing full-suite failures (9 from PackageRecipe lacking to_dict(), 1 missing ninja). The 9 are filled by PR fix(eos_ai): LLMClient URL normalization, env var support, and unit test suite #127's to_dict() — landing or rebasing onto fix(eos_ai): LLMClient URL normalization, env var support, and unit test suite #127 would let this PR's validation run on a green tree instead of a known-red one.
  3. Bundle provenance. Validation cites eCAD-Hardware-Products#30 as the clean bundle. If that PR is still open, the "clean" verdict is against a moving target — worth re-running once it lands.

Not merging per org policy (comment-only reviews). No competing implementation planned; the design direction here is good.

@srpatcha

srpatcha commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

@Aswin-V thanks for the review. On 2 (validation baseline), I merged current master (f361e90) instead of waiting on #127. New head: 399b28f. The merge was clean, and the PR's diff against master is still only its own 6 files.

The tree is green now, so the 10 pre-existing failures noted in the description are gone. The to_dict() gap was closed on master through #132, and ninja no longer blocks the suite. Local results on 399b28f (Python 3.12, pip install -e ".[dev]", CI's commands):

  • pytest -q: 892 passed, 3 skipped, 0 failed.
  • mypy . --ignore-missing-imports --no-strict-optional --exclude '^(layers|core|promo)/': no issues found in 127 source files. It failed on the old base.
  • ruff check .: passes.
  • yamllint .: 0 errors.

The red checks on the previous head came from the old base too. mypy failed on all six Linux and macOS jobs. On Windows, yamllint failed with [new-lines] wrong new line character on every YAML file because the runner checks out with autocrlf. The merge brings in master's .gitattributes fix (b25ff18, YAML pinned to LF).

On 3 (bundle provenance): eCAD-Hardware-Products#30 merged on 2026-09-23, so the clean-bundle reference is no longer a moving target.

On 1 (splitting hardware_verifier.py): agreed that the seams are there. I've kept it out of this PR so the gate lands as reviewed, and can split along schema validation / verdict recomputation / evidence / provenance as a follow-up.

@srpatcha

srpatcha commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

Re-verified on WSL today against master (PR head already contains master): pytest tests/unit/test_hardware_validation_gate.py 34 passed; full pytest tests/unit 597 passed, 3 skipped. CI green. Merging.

@srpatcha
srpatcha marked this pull request as ready for review October 6, 2026 23:01
@srpatcha
srpatcha requested a review from hshanmug12 as a code owner October 6, 2026 23:01
@srpatcha
srpatcha merged commit 6cb099c into master Oct 6, 2026
32 checks passed
@srpatcha
srpatcha deleted the issue-156-ecad-validation-gate branch October 6, 2026 23:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add fail-closed eCAD receipt verifier foundation

2 participants