ci: gate vendored _vendor tree behind a sha256 manifest (#492) - #2392
Conversation
Opus 4.8 Review — ✅ no blocking findingsReviewed Review detailsThis PR adds a CI checksum-gate script ( Key observations for scope:
No AUTOSDE violation and no residual-class defect on the changed lines survives falsification. No findings. [OPUS-REVIEWED] b10b5c6 Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Design Review (Fable 5) — ✅ PASSAdvisory design-level review of Design-Verdict: PASS A real, well-scoped supply-chain blind spot closed with the minimal proportionate mechanism: a reviewable out-of-tree hash manifest plus an always-on, undodgeable CI job. The design gets the hard parts right: the manifest lives outside the excluded tree so tampering becomes a visible diff; added files are a first-class failure like modified ones; symlinks and [DESIGN-REVIEWED] b10b5c6 |
0b338e1 to
b10b5c6
Compare
|
Disposition for GPT 5.6 findings on
|
Problem
src/kiro_crew/_vendor(vendored llama-cpp-python 0.3.34: ~616K of executable Python plus ~26MB of native libs, 46 files) is deliberately excluded from every source-level content review —.semgrepignore, the AI reviewers' reviewable-diff computation incode-review.yml/claude-review.yml, and the black/isort/flake8/mypy configs. The existingscripts/verify_vendored_payload.pyonly checks that built artifacts contain the declared native libs; nothing verifies the content of any vendored file.Why it matters
A malicious or accidental modification to vendored Python source, a swapped native
.so/.dylib/.dll, or a rogue.pyadded to the vendoredsys.pathroot passes every current gate unnoticed. The vendored code runs in-process (ctypes-loaded native libs included), so this is a supply-chain-grade blind spot in an otherwise heavily gated repo.Fix (symptoms → root cause → change)
The root cause is that the review exclusion covers the whole tree with nothing standing in for it. The change adds a content gate whose review surface lives outside the excluded tree:
scripts/verify_vendor_manifest.py(new, stdlib-only): walks_vendordeterministically, SHA-256 per file. Default--checkcompares against the committed manifest and exits non-zero naming every MODIFIED, MISSING, and UNEXPECTED (added) file — an added importable file is as dangerous as a modified one.--writeregenerates the manifest (the documented path for legitimate vendored bumps). Symlinks anywhere in the tree are refused in both modes: a broken symlink is invisible tois_file()on the Linux runner but can resolve on another OS, and--writeregenerating over one would bake the blind spot into the manifest.__pycache__artifacts are excluded — they are machine-local import residue, and hashing them would make the documented--writeprocedure emit a manifest that fails on CI's clean checkout.scripts/vendor_manifest.sha256(new, generated): 46sha256sum-compatible lines (<hex> src/kiro_crew/_vendor/<relpath>, sorted, trailing newline) — independently verifiable withsha256sum -cfrom the repo root. Deliberately outside_vendor/, so a manifest change is in the reviewable diff;scripts/**is also in ci.yml'smetapaths-filter bucket, so a manifest-touching PR runs the full CI matrix..github/workflows/ci.yml: new always-onvendor-manifestjob (modeled onscrub-lint: ubuntu-latest, pinned checkout SHA, workflow-levelcontents: read, 10-min timeout). Deliberately not gated behind thechangesjob — hashing 26MB takes seconds, and an always-on job cannot be dodged by a path-filter edge case.src/kiro_crew/_vendor/README.md: "Updating the vendored tree" section — verify upstream sha256s against the existing source table, then--write+ commit the manifest diff alongside the vendored changes.docs/ci/ci-and-reviews.md:vendor-manifestrow in the blocking-jobs table.This is a separate concern from
scripts/verify_vendored_payload.py(artifact completeness — untouched); this gate covers source-tree content integrity.Tests
test/test_vendor_manifest.py(new, fixture-tree only — never hashes the real 26MB tree; that is the CI job's role):--write→--checkround-trip green; byte-identical deterministic output in the exactsha256sum -cshape--checkeven when broken;--writeover a symlinked tree refuses without mutating the manifest__pycache__ignored by both modes and never baked into the manifest--writeregeneration pathManual verification
--checkround-trip andsha256sum -c scripts/vendor_manifest.sha256 --quietpassing from the repo root.BACKEND_DESELECTS).Closes #492