QVAC-21554 infra: license/compliance CI gate on qvac (warn-only, SKILL fallback)#3270
Conversation
Wires the canonical license compliance gate into this Tier-1 repo as a thin caller of tetherto/qvac-actions public-reusable-license.yml, per the approved design (qvac-actions/docs/license-compliance-ci.md). The gate becomes primary; the qv-notice-generate SKILL becomes the documented human fallback. - .github/workflows/license-compliance.yml: thin caller in warn-only (shadow) mode, so findings are annotated on PRs but never block a merge yet. Pinned to the qvac-actions branch commit pending the 0.3.0 release tag. - .github/license-allowlist.yml: CODEOWNERS-protected exception allowlist (empty seed, schema documented), plus a CODEOWNERS entry routing edits to a Tier-1 reviewer. - docs/ci/LABELS.md: documents the license-override label (High-only, per-PR stop-gap vs the durable allowlist entry). - .cursor/skills/qv-notice-generate/SKILL.md: demoted to the fallback for the long tail the gate cannot classify + full transitive audits + NOTICE authoring. - docs/devops/TIER-1-SCOPE.md: new scope doc; B1 defines the license/compliance enforcement surface (resolves the ticket's dangling reference; full scope lock remains QVAC-19052).
Review StatusCurrent Status: ❌ PENDING Pending reviews: Needs 1 Management or Team Lead, and 1 more from Management, Team Lead, or Member. |
License compliance — findings detected (warn-only)Critical: 0 · High: 1 · Medium: 0
How to resolve a blocking finding:
Warn-only (shadow) mode — this check does not block merges yet. Updated automatically by the canonical license compliance workflow. NOTICE presence (advisory)Missing NOTICE (advisory, does not block):
|
|
Reviewed against QVAC-21554 ("License / compliance enforced in CI on Tier-1 — SKILL becomes fallback"). This consumer-side wiring, plus qvac-actions#12 (the reusable engine), aligns well with the ticket: CI gate on the first Tier-1 repo,
No blockers, but points 1 and 2 gate whether this is "done" vs. "shadow-mode landed". |
…d engine Addresses Olu's review on #3270: - Make the manifest-only (no transitive) coverage limitation visible consumer-side, not only in the SKILL doc: adds a note to the caller header and to docs/devops/TIER-1-SCOPE.md B1. - Repin the provisional caller to the latest qvac-actions branch commit (ce61672c) which adds the pull_request_target guard and the transitive-limit doc. Still provisional pending the 0.3.0 tag.
|
Thanks @Proletter — responses below (code changes in 1. "Enforced" vs warn-only — closure semantics. Agreed this delivers the v0 / shadow-mode milestone, not literal blocking enforcement, matching the design doc's telemetry-gated rollout. Your call on how to track it — two clean options:
2. Merge-order + provisional pin. Confirmed — not to be treated as complete until qvac-actions#12 merges, 3. Manifest-only coverage visible to consumers. Done — surfaced beyond the SKILL doc: a coverage-limitation note in the caller header ( |
🎯 What problem does this PR solve?
qv-notice-generateSKILL. It is opt-in, non-blocking, and leaves no durable record, so a disallowed license (AGPL, SSPL, GPL on a runtime path) or a missing attribution can reach a shipped artifact unnoticed.tetherto/qvac-actions/docs/license-compliance-ci.md) makes license/compliance a deterministic CI gate on Tier-1 repos with the SKILL demoted to the fallback. This PR is the consumer-side wiring for this repo, the first Tier-1 pilot (QVAC-21554).📝 How does it solve it?
.github/workflows/license-compliance.yml: a thin caller (mirroringsecurity-baseline.yml) that delegates to the org reusable workflowpublic-reusable-license.yml. It runs in warn-only (shadow) mode — findings are annotated on the PR and in the job summary but never block a merge yet..github/license-allowlist.yml: the exception allowlist (empty seed, schema + process documented in-file)..github/CODEOWNERSroutes edits to@tetherto/qvac-internal-merge, so exceptions require a Tier-1 reviewer rather than being self-served by the PR author.docs/ci/LABELS.md: documents thelicense-overridelabel (downgrades a High finding for one PR; Critical can never be overridden; the durable record is an allowlist entry)..cursor/skills/qv-notice-generate/SKILL.md: demoted to the documented fallback — for novel/unclassifiable licenses, full transitive audits (the gate is manifest-only since lockfiles are gitignored here), and NOTICE authoring.docs/devops/TIER-1-SCOPE.md: new scope doc; §B1 defines the license/compliance enforcement surface and resolves the ticket's reference. The full Tier-1 scope lock remains QVAC-19052.🧪 How was it tested?
actionlintclean on.github/workflows/license-compliance.yml.tetherto/qvac-actionsPR fix npm publish qvac-lib-dl-hyperdrive-integration-test1 #12 (QVAC-21554 feat: canonical license compliance reusable workflow qvac-actions#12); itslicense-policy.mjswas validated locally against the full fail-vs-warn matrix and is covered by a negative + positive self-test there.license-compliancerun.🔐 Action pinning
tetherto/qvac-actions/.github/workflows/public-reusable-license.yml@0f4f710756ffb063d7b81686b84271d6601052ae.0.3.0release tag's immutable commit SHA (freeze-and-pin convention) once qvac-actions fix npm publish qvac-lib-dl-hyperdrive-integration-test1 #12 merges and the tag is cut. A# pending 0.3.0comment marks it.🛡️ Permissions changes
license-compliance.yml— top-level and joblicense.contents: read; joblicensewidens tocontents: read+pull-requests: write.contents: readfor checkout + the dependency-review graph API;pull-requests: writeonly to upsert the single summary comment. No write to code. Uses plainpull_request(neverpull_request_target), so fork PRs stay read-only and secret-free.