Skip to content

feat(hook): add out-of-band recheck for verdict drift on installed deps#2

Open
adamsjack711-ux wants to merge 3 commits into
pkgxray-guard/harden-install-gatefrom
pkgxray-guard/recheck
Open

feat(hook): add out-of-band recheck for verdict drift on installed deps#2
adamsjack711-ux wants to merge 3 commits into
pkgxray-guard/harden-install-gatefrom
pkgxray-guard/recheck

Conversation

@adamsjack711-ux

Copy link
Copy Markdown
Owner

The install gate (OnBeforeExecution) only ever sees new installs. Dependencies already in the tree can go bad later — maintainer takeover, a trojaned patch release. This adds an out-of-band recheck that re-evaluates already-installed deps against current intelligence.

Hookshot dispatches only event hooks via RunCommand — there is no periodic entry point — so (per the integration triage) recheck is exposed as a plain subcommand of the same binary a cron/CI step invokes:

pkgxray-guard recheck            # auto-detect the project lockfile
pkgxray-guard recheck package-lock.json

Thin over the engine — no second dialect

  • pkgxrayguard/recheck.go shells out to pkgxray recheck <lockfile> --format json. All drift logic lives in the engine; the hook only orchestrates and maps the JSON.
  • Regressed deps fold through the existing DecideAll worst-fold with the same Verdict vocabulary as the gate (block → deny/notify, review → ask under balanced). It keys off the engine's worstRegression (the worst new regression), never the worst absolute verdict — a dep that was block at install and is still block stays silent.
  • Version drift (a newer-but-flagged version exists) is informational only: it populates the report but never enters the fold or moves the exit code — mirroring the engine's default.
  • Fail-mode honoured: an engine that can't be reached/parsed → Unknown, which denies under strict/balanced and is allowed only under permissive — never a false "nothing regressed". PKGXRAY_CACHE_URL is forwarded so recheck shares the gate's warm cache. The bounded-concurrency fan-out lives in the engine's single recheck call — not re-implemented here.
  • Exit codes mirror the gate/CLI: 0 clean, 3 regressed→review, 2 regressed→block or engine-unreachable under fail-closed.

Tests (offline, fake pkgxray binary)

regressed dep → notify/deny surface; review regression → ask; clean → silent/allow; engine-unreachable → Unknown (deny under balanced, allow under permissive); unparseable → Unknown; the fold keys off worst regression not worst absolute; version drift stays informational. go vet clean, full go test ./examples/pkgxray-guard/... green.

Base

Stacks on the install-gate hardening (CorridorSecurity#18); branched at the CLI-contract commit so the three-dot diff is only the recheck change, independent of the concurrent-install WIP. Needs the engine-side pkgxray recheck command (pkgxray PRs T1–T4).

🤖 Generated with Claude Code

The install gate (OnBeforeExecution) only ever sees NEW installs. Dependencies
already in the tree can go bad later — maintainer takeover, trojaned patch. This
adds an out-of-band recheck that re-evaluates already-installed deps against
current intelligence.

Hookshot dispatches only event hooks via RunCommand — there is no periodic
entry point — so recheck is exposed as a plain subcommand of the same binary a
cron/CI step invokes:  `pkgxray-guard recheck [lockfile]`.

- pkgxrayguard/recheck.go: Rechecker shells out to `pkgxray recheck <lockfile>
  --format json` and maps the engine's diff onto a surfaced report. All drift
  logic stays in the engine; this is a thin orchestration layer.
- Reuses the existing verdict vocabulary + DecideAll worst-fold: regressed deps
  fold exactly like a flagged install (block→deny/notify, review→ask). It keys
  off the engine's worstRegression (the worst NEW regression), never the worst
  absolute verdict — a still-block dep that was block at install stays silent.
- Version drift (newer-but-flagged versions) is informational only: it populates
  the report but never enters the fold or moves the exit code.
- Fail-mode honoured: an engine that can't be reached/parsed → Unknown, which
  denies under strict/balanced and is allowed only under permissive — never a
  false "nothing regressed". PKGXRAY_CACHE_URL is forwarded so recheck shares the
  gate's warm cache. The bounded-concurrency fan-out lives in the engine's single
  recheck call — the hook does not re-implement it.
- Exit codes mirror the gate/CLI: 0 clean, 3 regressed→review, 2 regressed→block
  or engine-unreachable under fail-closed.

Tests (offline, fake pkgxray binary): regressed dep → notify/deny surface; review
regression → ask; clean → silent/allow; engine-unreachable → Unknown (deny under
balanced, allow under permissive); unparseable → Unknown; fold keys off worst
regression not worst absolute; version drift stays informational.

Stacks on the install-gate hardening (CorridorSecurity#18); based at the CLI-contract commit,
independent of the concurrent-install WIP.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…idorSecurity#18)

Brings the recheck branch up to date with the pkgxray source-of-truth
copy after the recheck + parallel-guard PRs merged there: adds
pkgxrayguard/batch.go + batch_test.go and the main.go dispatch changes.
Byte-identical per sync-to-hookshot.sh --check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dapter (#3)

Mirror of pkgxray hook/mcp-gate (byte-identical Go per
sync-to-hookshot.sh): stdio launchers take the static package scan,
streamable-HTTP URLs are probed with pkgxray mcp <url> (>= 0.16.0),
legacy SSE / unreadable configs surface as Review. Fail-closed on
engine errors under strict/balanced.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant