Skip to content

feat(sandbox): restack patch-validator image on current main - #407

Merged
seonghobae merged 188 commits into
mainfrom
feat/patch-validator-image-on-main
Aug 23, 2026
Merged

feat(sandbox): restack patch-validator image on current main#407
seonghobae merged 188 commits into
mainfrom
feat/patch-validator-image-on-main

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Canonical patch-validator image/runtime/supply-chain owner. Historical #67 remains frozen predecessor evidence only and must not be merged.

Current branch-integrity state

Protected main is 47ba59ed972a0002a4446844bb385c08bbfdc31a, including #492 pilot-readiness future-date rejection. #407 was converged non-destructively onto that exact protected truth with two-parent commit 871490009a65336003047a85b994581ed3e36b44; no force-push or destructive rebase was used.

The convergence tree preserves the patch-validator feature slice, adopts the exact protected-main scripts/lib/pilot-readiness.mjs and test/pilot-readiness-future-date.test.ts blobs, and preserves both the protected pilot-readiness changelog entry and the patch-validator changelog entry. Fresh compare reports protected main as the exact merge base and behind 0; the remaining main-to-head delta contains only the patch-validator image/runtime/reviewer/supply-chain slice plus bounded changelog/package/vitest integration.

Current repair lineage

The branch retains the exact-head patch-validator image pipeline, fully-static Node runtime, embedded-runtime inventory, exact image/SBOM/receipt binding, reviewed vulnerability identities, CPE applicability evidence, duplicate CycloneDX ImageID rejection, Noema-bound smoke receipts, receipt-path identity stability, valid-calendar/non-future scanner provenance validation, and whole-image/binary Grype database provenance binding.

RED 7f3472edde93d3b3a61691440c398f6738ac00f7 reproduced acceptance of otherwise-valid whole-image/binary Grype evidence with no vulnerability-database provenance. Candidate c70acb2759635c5cac448d2ff3d1089e5da02b98 binds whole-image/binary Grype database identity to the already strictly validated embedded-runtime Grype snapshot without weakening vulnerability thresholds or reviewed applicability.

Preserved hardening

The slice keeps the fully-static numeric-non-root scratch runtime, no-network/read-only/capability-dropped smoke path, checksum-pinned Trivy/Syft/Grype tools, reviewed bundled-runtime identities, frozen scanner DB behavior, raw scanner evidence, and the --fail-on medium fail-closed vulnerability policy. Historical inline findings remain resolved.

Current exact identity and evidence

Exact head: 871490009a65336003047a85b994581ed3e36b44.

Live base: 47ba59ed972a0002a4446844bb385c08bbfdc31a, exact merge base, behind 0.

Fresh same-head evidence is non-passing until terminal:

  • Application CI 32619804074: in progress
  • reviewer-ci 32619804030: in progress
  • central Security Scan 32619804069: queued
  • dedicated patch-validator-image 32619804032: pending

Central read-only .github protected source is 23a776ed37027d8ab8ab2aefcf81fac586352e2f. Current Security Scan authority remains OSV/dependency-review hard where enforceable, Trivy repo-wide fixable MEDIUM/HIGH/CRITICAL hard, Scorecard soft.

Merge boundary

Keep Draft until all four applicable checks on unchanged exact head 871490009a65... are terminal-success and zero valid unresolved findings remain. Immediately before Ready/merge classification, refetch exact head, protected live base, ancestry, reviews/threads, central .github revision, and Security Scan authority. #67 remains frozen until #407 reaches protected main and a final semantic comparison proves every valuable predecessor-only delta is preserved or intentionally rejected.

Summary by CodeRabbit

  • 새로운 기능

    • 패치 변경 사항을 안전하게 검증하는 Docker 기반 이미지 검증 기능을 추가했습니다.
    • 패치 파싱, 적용, TypeScript 검사 및 테스트 실행 결과를 구조화된 형식으로 제공합니다.
    • 이미지 및 런타임의 SBOM과 취약점 검사 증빙을 생성·검증합니다.
    • 비루트·네트워크 차단·읽기 전용 환경 등 강화된 격리 조건에서 검증합니다.
  • 문서

    • 이미지 구성, 보안 통제, 취약점 평가 기준 및 검증 절차를 문서화했습니다.
  • 테스트

    • 패치 처리, 이미지 계약, 보안 경계, 증빙 무결성 및 취약점 정책에 대한 회귀 테스트를 추가했습니다.

@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: de1a9d9a-d444-4b7a-bb6f-99159b31c8ca

📥 Commits

Reviewing files that changed from the base of the PR and between 47ba59e and 8714900.

📒 Files selected for processing (72)
  • .github/workflows/patch-validator-image.yml
  • CHANGELOG.md
  • Dockerfile.patch-validator
  • Dockerfile.patch-validator.dockerignore
  • docs/doctoring/patch-validator-embedded-scan-assessment.md
  • docs/doctoring/patch-validator-image.md
  • docs/patch-validator-image.md
  • package.json
  • patch-validator/entrypoint.mjs
  • patch-validator/runtime.mjs
  • patch-validator/validate-patch.mjs
  • patch-validator/validator-tsconfig.json
  • patch-validator/validator-vitest.config.mjs
  • reviewer/noema_reviewer/__init__.py
  • reviewer/noema_reviewer/patch_image_validation.py
  • reviewer/tests/test_patch_validation_image_control_paths.py
  • reviewer/tests/test_patch_validation_image_create_delete.py
  • reviewer/tests/test_patch_validation_image_profile.py
  • reviewer/tests/test_patch_validation_image_result_isolation.py
  • reviewer/tests/test_patch_validation_image_runner_edges.py
  • scripts/check-kpi.mjs
  • scripts/lib/patch-validator-binary-grype-database-binding.mjs
  • scripts/lib/patch-validator-embedded-runtime-applicability.mjs
  • scripts/lib/patch-validator-embedded-runtime-catalog.mjs
  • scripts/lib/patch-validator-embedded-runtime-inventory.mjs
  • scripts/lib/patch-validator-image-receipts.mjs
  • scripts/lib/patch-validator-smoke-diagnostic.mjs
  • scripts/lib/patch-validator-static-runtime-evidence.mjs
  • scripts/verify-patch-validator-image.mjs
  • test/patch-validator-binary-grype-database-binding.test.ts
  • test/patch-validator-binary-grype-database-provenance.test.ts
  • test/patch-validator-control-plane-isolation.test.mjs
  • test/patch-validator-cpe-match-provenance.test.ts
  • test/patch-validator-cyclonedx-imageid-ambiguity.test.ts
  • test/patch-validator-embedded-runtime-assessment.test.ts
  • test/patch-validator-embedded-runtime-catalog-parity.test.ts
  • test/patch-validator-embedded-runtime-digest-binding.test.ts
  • test/patch-validator-embedded-runtime-inventory.test.ts
  • test/patch-validator-embedded-runtime-workflow.test.ts
  • test/patch-validator-entrypoint.test.mjs
  • test/patch-validator-grype-provider-provenance.test.ts
  • test/patch-validator-grype-timestamp-calendar-integrity.test.ts
  • test/patch-validator-grype-timestamp-future-integrity.test.ts
  • test/patch-validator-image-build-regression.test.ts
  • test/patch-validator-image-contract.test.ts
  • test/patch-validator-image-documentation-current.test.ts
  • test/patch-validator-openssl-quic-applicability.test.ts
  • test/patch-validator-package-note-identity.test.ts
  • test/patch-validator-receipt-json-integrity.test.ts
  • test/patch-validator-receipt-path-stability.test.ts
  • test/patch-validator-receipt-verifier.test.ts
  • test/patch-validator-reviewed-applicability.test.ts
  • test/patch-validator-runtime-bom.test.mjs
  • test/patch-validator-runtime-branch-coverage.test.mjs
  • test/patch-validator-runtime-coverage.test.mjs
  • test/patch-validator-runtime-entrypoint.test.mjs
  • test/patch-validator-runtime-final-coverage.test.mjs
  • test/patch-validator-runtime-result-isolation.test.mjs
  • test/patch-validator-runtime.test.mjs
  • test/patch-validator-smoke-diagnostic-workflow.test.mjs
  • test/patch-validator-smoke-diagnostic.test.mjs
  • test/patch-validator-static-binary-vulnerability-scan.test.ts
  • test/patch-validator-static-runtime-evidence.test.ts
  • test/patch-validator-static-runtime-identity-binding.test.ts
  • test/patch-validator-static-runtime-metadata.test.ts
  • test/patch-validator-static-runtime.test.ts
  • test/patch-validator-trusted-typescript-transform.test.mjs
  • test/patch-validator-vite-config-loader.test.mjs
  • test/patch-validator-vulnerability-policy.test.mjs
  • test/patch-validator-workflow.test.ts
  • test/upload-artifact-node24-integrity.test.ts
  • vitest.config.ts

📝 Walkthrough

Walkthrough

패치 검증 이미지와 Docker 실행 API를 추가했다. Node.js 24.19.0 정적 scratch 이미지를 빌드하고, exact-head smoke 검증과 Trivy·Syft·Grype 증거를 생성한다. 영수증 검증기와 embedded runtime 식별자 검증은 불일치와 지원되지 않는 입력을 차단한다.

Changes

패치 검증 이미지와 워크플로

Layer / File(s) Summary
이미지 빌드와 검증 워크플로
.github/workflows/patch-validator-image.yml, Dockerfile.patch-validator, Dockerfile.patch-validator.dockerignore, package.json
Node.js 24.19.0을 정적으로 빌드하고 scratch 런타임으로 패키징한다. exact PR head, non-root smoke 실행, SBOM·취약점 스캔과 90일 증거 업로드를 연결한다.
패치 검증 런타임
patch-validator/*
unified diff 파싱, 경로·파일·크기 검증, 원자적 패치 적용, 고정 TypeScript·Vitest 실행과 제한된 결과 기록을 추가한다.
Docker 실행 계약
reviewer/noema_reviewer/__init__.py, reviewer/noema_reviewer/patch_image_validation.py
고정 이미지 digest와 프로파일을 사용하는 Docker 실행 API를 추가한다. 네트워크, 권한, 리소스와 결과 identity를 검증한다.
증거 검증
scripts/lib/patch-validator-*.mjs, scripts/verify-patch-validator-image.mjs
이미지 영수증, CycloneDX, Syft·Grype 결과, embedded runtime inventory와 데이터베이스 provenance를 검증한다.
검증 문서와 회귀 테스트
docs/doctoring/*, docs/patch-validator-image.md, test/*, reviewer/tests/*, vitest.config.ts, CHANGELOG.md
런타임 범위와 증거 정책을 문서화하고 이미지, 패치, Docker 격리, 영수증 및 취약점 검증 경로를 테스트한다.

Estimated code review effort: 5 (Critical) | ~120 minutes

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/patch-validator-image-on-main

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

github-advanced-security[bot]

This comment was marked as resolved.

github-code-quality[bot]

This comment was marked as resolved.

@seonghobae
seonghobae marked this pull request as ready for review August 23, 2026 07:02
@seonghobae
seonghobae merged commit 8ce7c75 into main Aug 23, 2026
16 of 18 checks passed
@seonghobae
seonghobae deleted the feat/patch-validator-image-on-main branch August 23, 2026 07:03

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 4 potential issues.

Open in Devin Review

Comment on lines +42 to +46
IMAGE_PROFILE_FORBIDDEN_PREFIXES = (
".github/",
"patch-validator/",
"reviewer/",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: node_modules parity gap between host and image path filters

The mjs runtime forbids node_modules/ (patch-validator/validate-patch.mjs:63-69), but the Python host image profile omits it (reviewer/noema_reviewer/patch_image_validation.py:42-46), as does the base prefix list. A node_modules patch passes the host pre-filter yet the image runtime still rejects it via validateRepositoryPath/copySourceTree, so the outcome stays fail-closed but the two boundaries diverge from the documented parity.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +47 to +54
IMAGE_PROFILE_UNSUPPORTED_METADATA_PREFIXES = (
"copy from ",
"copy to ",
"new mode ",
"old mode ",
"rename from ",
"rename to ",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 Unsupported-metadata prefix lists differ between host and runtime

The runtime rejects dissimilarity index metadata (patch-validator/validate-patch.mjs:70-79), but the host image profile prefix list omits it (reviewer/noema_reviewer/patch_image_validation.py:47-54). The base module's PERCENT_METADATA_PATTERN appears to cover it, so rejection is likely consistent; worth confirming both boundaries reject a dissimilarity-index patch identically.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +226 to +255
function verifyEmbeddedMatchArtifact(match, component, expectedIdentity) {
const artifact = requireRecord(
match.artifact,
`embedded runtime component ${component.key} match artifact`,
);
requireCondition(
artifact.version === component.version,
`embedded runtime component ${component.key} match artifact version does not match the reviewed component`,
);
if (artifact.name != null) {
requireCondition(
artifact.name === component.name,
`embedded runtime component ${component.key} match artifact name does not match the reviewed component`,
);
}

if (expectedIdentity.startsWith("pkg:")) {
requireCondition(
artifact.name === component.name && artifact.purl === expectedIdentity,
`embedded runtime component ${component.key} match artifact identity does not match the reviewed PURL component`,
);
return;
}

requireCondition(
Array.isArray(artifact.cpes) &&
artifact.cpes.some((candidate) => artifactCpeValue(candidate) === expectedIdentity),
`embedded runtime component ${component.key} match artifact identity does not match the reviewed CPE component`,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Real V8 match hard-errors instead of counting as blocking

verifyEmbeddedMatchArtifact requires each match artifact version to equal the component version (scripts/lib/patch-validator-static-runtime-evidence.mjs:226-255). For V8 the inventory version is 13.6.233.17-node.51 but Grype normalizes the CPE artifact to 13.6.233.17. Reviewed legacy CVEs are filtered out first, but any non-legacy V8 match throws a version-mismatch error rather than being counted as blocking. Still fail-closed, but the failure mode differs from other components.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +461 to +462
export GRYPE_DB_AUTO_UPDATE=false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 Info: Embedded scan relies on DB from an earlier step

The embedded-runtime step sets GRYPE_DB_AUTO_UPDATE=false and never runs grype db update (.github/workflows/patch-validator-image.yml:461-500), relying on the on-disk DB from the earlier binary step (line 380). This holds only because both steps share the runner and the DB persists on disk. Reordering or split runners would leave the embedded scan without a DB; the cross-component DB-identity checks still fail closed.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: medium Normal-priority or P2 work status: draft Draft pull request type: feature New or expanded product capability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants