ci: make audit gate scope explicit#62
Open
mbeacom wants to merge 1 commit into
Open
Conversation
The audit gate was giving a true but incomplete result: it audited the
workspace resolved tree after root overrides, not the dependency tree consumers
get from published @adrkit/* manifests. That distinction matters because root
overrides are not published, and @adrkit/mcp@0.2.0 still resolves the upstream-
blocked moderate @hono/node-server advisory for consumers.
This keeps the PR gate focused on the workspace tree, makes that scope explicit
in the output and workflow comment, records the known @adrkit/mcp consumer
exposure with an expiring narrow acceptance, and adds proposed ADR-0017 to
capture why published-artifact consumer audits belong in release evidence rather
than ordinary PR CI.
ADR-0016 observed-failing output before the implementation:
```text
$ bun test scripts/audit-gate.test.ts
bun test v1.3.14 (0d9b296a)
scripts/audit-gate.test.ts:
(pass) audit-gate — evaluateAudit > rejects the pre-fix tree and names the exact high-severity advisories [0.54ms]
(pass) audit-gate — evaluateAudit > passes a clean audit ({} — audit ran, found nothing) [0.10ms]
48 |
49 | test('states that the live gate audits the workspace resolved tree, not published consumer installs', async () => {
50 | const evaluation = evaluateAudit(await readFixture('clean.json'), { asOf: '2026-07-25' });
51 | const rendered = formatEvaluation(evaluation);
52 |
53 | expect(rendered).toContain('scope: workspace-resolved-dependency-tree');
^
error: expect(received).toContain(expected)
Expected to contain: "scope: workspace-resolved-dependency-tree"
Received: "audit-gate: examined 0 package(s) with advisories (critical=0, high=0, moderate=0, low=0, info=0).\naudit-gate: PASSED — no high- or critical-severity advisories."
at <anonymous> (/Users/markbeacom/github/mbeacom/copilot-worktrees/adrkit/audit-gate-published-scope/scripts/audit-gate.test.ts:53:22)
(fail) audit-gate — evaluateAudit > states that the live gate audits the workspace resolved tree, not published consumer installs [0.15ms]
58 | test('records the known upstream-blocked @adrkit/mcp consumer advisory without hiding the scope gap', async () => {
59 | const evaluation = evaluateAudit(await readFixture('clean.json'), { asOf: '2026-07-25' });
60 | const known = evaluation.knownConsumerAdvisories?.[0];
61 |
62 | expect(evaluation.ok).toBe(true);
63 | expect(known?.package).toBe('@hono/node-server');
^
error: expect(received).toBe(expected)
Expected: "@hono/node-server"
Received: undefined
at <anonymous> (/Users/markbeacom/github/mbeacom/copilot-worktrees/adrkit/audit-gate-published-scope/scripts/audit-gate.test.ts:63:28)
(fail) audit-gate — evaluateAudit > records the known upstream-blocked @adrkit/mcp consumer advisory without hiding the scope gap [0.12ms]
75 | });
76 |
77 | test('fails closed once the known consumer advisory acceptance expires', async () => {
78 | const evaluation = evaluateAudit(await readFixture('clean.json'), { asOf: '2026-11-01' });
79 |
80 | expect(evaluation.ok).toBe(false);
^
error: expect(received).toBe(expected)
Expected: false
Received: true
at <anonymous> (/Users/markbeacom/github/mbeacom/copilot-worktrees/adrkit/audit-gate-published-scope/scripts/audit-gate.test.ts:80:27)
(fail) audit-gate — evaluateAudit > fails closed once the known consumer advisory acceptance expires [0.11ms]
16 pass
3 fail
50 expect() calls
Ran 19 tests across 1 file. [14.00ms]
```
Validation after the fix:
```text
bun run typecheck && bun test && bun run lint
784 pass
0 fail
3495 expect() calls
```
Also ran `bun run adr lint` (checked 17 records, 0 errors, 0 warnings) and a
real consumer probe for `bun add @adrkit/mcp@0.2.0 && bun audit`, which reported
only GHSA-frvp-7c67-39w9 as one moderate advisory.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
There was a problem hiding this comment.
Pull request overview
Clarifies the audit gate’s workspace-only scope and records the known published-consumer advisory with an expiring acceptance.
Changes:
- Adds explicit audit scope and consumer advisory reporting.
- Fails the gate after the acceptance expires.
- Documents the decision in proposed ADR-0017 and updates tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
scripts/audit-gate.ts |
Implements scope reporting and expiring advisory acceptance. |
scripts/audit-gate.test.ts |
Tests scope, advisory details, and expiry. |
packages/cli/test/lint.test.ts |
Updates the ADR corpus count. |
docs/adr/0017-keep-dependency-audit-scope-explicit-and-release-scoped.md |
Records the proposed audit policy. |
.github/workflows/ci.yml |
Clarifies the audit job’s scope. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The current audit gate was true but over-broad in the assurance it appeared to give.
scripts/audit-gate.tsreadsbun audit --jsonfor this repository's resolved workspace tree after the rootpackage.jsonoverrides are applied. Those overrides are not published in@adrkit/*package manifests, so a clean workspace audit is not evidence that a consumer install of the published packages is clean.I re-verified the consumer gap with a real install of the published MCP package:
fast-uriis genuinely closed for consumers because the SDK resolves3.1.4. The remaining exposure is the moderateGHSA-frvp-7c67-39w9;@modelcontextprotocol/sdk@1.29.0is latest and still ranges@hono/node-serveras^1.19.9, so adrkit cannot fix this by bumping the SDK today. The stdio MCP server does not use Honoserve-staticor expose HTTP static files, so the advisory is low-consequence for adrkit, but it should not be invisible.Design
@adrkit/mcp@0.2.0consumer exposure inaudit-gateoutput with exact package, GHSA, published package/version, upstream path, why it is upstream-blocked, why it is low-consequence here, and the condition that resolves it.2026-10-31,evaluateAuditfails closed withconsumer-advisory-acceptance-expireduntil the exposure is removed, evidence is refreshed, or a human deliberately renews it.Alternatives rejected
@adrkit/core,@adrkit/cli,@adrkit/evaluator,@adrkit/mcp), and it audits the versions already on npm rather than the source tree under review. The repo is currently ahead of@adrkit/mcp@0.2.0, so this would be slow/flaky evidence about a different artifact.serve-staticpath.ADR-0016 observed-failing output
Before implementing the fix, I added the new assertions and ran them against the unfixed code:
What this does and does not guarantee
This PR guarantees that the existing gate says what it actually audited, keeps blind
bun auditstates failing closed, and makes the known@adrkit/mcp@0.2.0consumer exposure visible with an expiry.It does not continuously discover new consumer-only advisories for published packages on every PR. That should be added as release-time evidence at the artifact boundary, where the real published package versions are the intended subject.
Validation