Install gate: remove recency gate, keep publish-date provenance#119
Open
juangaitanv wants to merge 7 commits into
Open
Install gate: remove recency gate, keep publish-date provenance#119juangaitanv wants to merge 7 commits into
juangaitanv wants to merge 7 commits into
Conversation
A --force/--no-fail typed after the install verb is swept into clap's trailing-var-arg and forwarded to the package manager, so the gate never sees it and the block stands. Users (reasonably) read 'Pass --force' and retry with the flag in the same wrong slot. print_escape_hint now detects an accepted escape flag sitting in the forwarded args and prints a note naming the package manager that received it, plus the corrected invocation with the flag between manager and verb (corgea uv --force add requests). Covered by a pip integration test.
The recency block (a version published within --threshold blocks the
install) is gone, along with the -t/--threshold flag, the --no-fail
demotion flag, parse_threshold, and the RecencyOnly block reason. The
vuln-api verdict is now the gate's single block condition.
Every resolved package still shows its publish time for provenance
('published <age> ago at <UTC timestamp>') — now a neutral line on every
named target rather than a within-threshold warning. JSON drops
threshold_seconds and the per-result 'recent' status/count; verdict_mode
'recency-only' becomes 'none'.
Tests repurposed, not just deleted: fresh pins now assert they install;
the two npm gating tests assert the gate engaged via its Pre-checking
header / registry hit instead of a recency refusal. SKILL.md updated.
When pip backtracks a named target to a version the CLI never resolved, apply_verdicts adopts the installed version on the named row but its publish date / age belonged to the CLI-resolved version. Render then printed e.g. `flask@3.0.2 published … at <date-for-3.0.3>` — a wrong date presented as provenance, the one thing the recency-removal PR keeps. Make `TargetOutcome::Resolved.age` an `Option<Duration>`, set it to `None` in the backtrack collapse (rather than re-fetch on the gate's critical path), and have render omit the publish line (text) / null `published_at` + `age_seconds` (JSON) when it's absent. Tests assert the backtracked row carries no stale date and an exact match keeps its provenance. Also clean the stale "recency" wording the gate removal left behind: wrapper --help strings, SKILL.md, and the locked-install comments.
Bring back the recency block removed in dca9621, this time driven by ~/.corgea/config.toml instead of the -t/--threshold and --no-fail flags. Two new fields, both serde-defaulted so an upgraded config inherits the gate rather than silently disabling it: recency_gate = true (CORGEA_RECENCY_GATE) recency_threshold_days = 14 (CORGEA_RECENCY_THRESHOLD_DAYS) block_reason gains BlockReason::Recency as a softer second gate: a clean named target published within the window blocks only when no vulnerable/ unverifiable finding already did. Unknown publish dates (pip backtracking, age = None) never block, so the stale-provenance bug 1496887 fixed stays fixed. The refusal names each fresh package and points at the config toggle; --force still bypasses. JSON adds top-level recency_threshold_days (null when off) to pair with each result's age_seconds. Tests: a config unit test pins the opt-out default + back-compat; five e2e tests cover block-on, --force bypass, threshold-0 plumbing, old-pin allowed, and gate-off installs. The shared test harness pins the gate off so existing gate tests stay 'every block is the verdict's doing'. Docs: SKILL.md and README document the gate, window, and toggle.
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.
Summary
Removes the recency gate from the install wrappers (
corgea pip|npm|yarn|pnpm|uv). A freshly-published package version no longer blocks an install; the vuln-api verdict is now the gate's single block condition. Each resolved package still shows its publish time for provenance — that line is kept, just made non-blocking.Motivated by the recency gate causing friction on legitimate fresh releases (e.g. a 1-day-old
axios) and by the-t/--thresholdflag's misplacement footgun.Behavior change
Before — fresh pin blocked:
After — installs, publish time shown as neutral provenance:
What was removed / kept
BlockReason::RecencyOnly)-t/--thresholdflag,parse_thresholdformat_duration(age display)--no-failflag (only demoted recency)--force,--jsonis_recent,recent_count,thresholdfieldspublished_atfetch +age(threshold …),(within threshold), the-r"not recency-checked" notepublished <age> ago at <UTC ts>on every named targetthreshold_seconds, per-resultrecent;verdict_mode "recency-only"verdict_mode "none"Commits in this PR
dca9621Install gate: remove recency gate, keep publish-date provenance (the change above)45855c9Install gate: explain misplaced escape flag in refusal hint (--forcetyped after the verb)dad4e0f,218d800pyproject.toml project config (pre-existing on the branch)Test plan
Pre-checkingheader / registry hit instead of a recency refusal.clippystrict +rustfmtclean (pre-commit hook).corgea pnpm add axiosagainst a throwaway project — proceeds, prints the publish-date line, no refusal.🤖 Draft — review before merge.