Skip to content
Back to skills

Dependency Update Sweep

ASecurity

When a tracked host tool (Claude Code, Copilot CLI/Chat, Codex CLI, Cursor, Gemini CLI, Aider, Windsurf — read live from host-support.json) ships a new version, scan the repo for citation-marked drift, auto-apply safe mechanical fixes, and queue judgment calls for review. Reach for this skill on "a host tool updated, what needs to change" or via the SessionStart nudge.

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentsrustgoexpressgitapi

Works with

  • claude code
  • cursor
  • cli
  • api

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 23, 2026

npx -y skills add mcorbett51090/RavenClaude --skill dependency-update-sweep --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dependency Update Sweep?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dependency Update Sweep
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mcorbett51090-dependency-update-sweep/badge)](https://www.skillsdirectory.com/skills/mcorbett51090-dependency-update-sweep)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dependency-update-sweep
description: When a tracked host tool (Claude Code, Copilot CLI/Chat, Codex CLI, Cursor, Gemini CLI, Aider, Windsurf — read live from host-support.json) ships a new version, scan the repo for citation-marked drift, auto-apply safe mechanical fixes, and queue judgment calls for review. Reach for this skill on "a host tool updated, what needs to change" or via the SessionStart nudge.
---

# Skill: dependency-update-sweep

Answers one question on demand: *a tracked host tool shipped a new version — what in this repo now
needs updating or deprecating because of it?* It does not answer "is every fact about this host
current" — see Honesty / known limits below.

## When to invoke this skill

- You (or a maintainer) know a tracked host tool bumped its version and want to know what's affected.
- The SessionStart capability banner nudges "run `dependency-update-sweep` — <host> may have moved" (a
  zero-subprocess, file-read-only signal — see [`capability-orientation.py`](../../scripts/capability-orientation.py)).
- Before a release, as a targeted pre-flight for the hosts that changed since the last sweep.

**Not this skill's job:** general knowledge-file staleness (calendar-driven, any topic) — that's
[`knowledge-file-staleness-sweep`](../knowledge-file-staleness-sweep/SKILL.md), the sibling sweep. This
one is host-version-triggered; that one is calendar-triggered. Also not this skill's job: whether a
claim is cited *at all* — that's Gate 208; this sweep answers whether a claim that *is* dated is now
stale.

## Scope

Tracked hosts are **`host-support.json`'s top-level `hosts{}` keys, read live** at run time — never
hardcoded here. As of this writing: `claude-code`, `copilot`, `codex`, `cursor`, `gemini`, `aider`,
`windsurf`. **Grok Build CLI is explicitly out of scope** — no entry in `host-support.json`, no
`scripts/ravenclaude install --host` wiring; it is tracked only in `substrate-tier-map.json` for
model-tier resolution, an unrelated system. Do not "fix" the roster back to a hardcoded list.

## Discovery mechanism

A bounded `git grep -n` for the fixed citation-marker family (`[docs-verified YYYY-MM-DD]`,
`[verified YYYY-MM-DD]`, `[web-sourced …]`, `[unverified — training knowledge]`), plus a direct JSON
walk of `host-support.json`/`model-catalog.json`, plus a structural match over `_SKIP` dict entries in
the `generate-copilot-hooks.py` / `-gemini-hooks.py` / `-cursor-hooks.py` generators and any
`_FLOOR=`/`_RECOMMENDED=`-shaped constant in `scripts/ravenclaude`. This is **not** a general-purpose
repo scan — every version-sensitive fact this repo already carries by convention already has a marker,
and a full-repo re-scan multiplies judgment cost for a benefit the marker convention already exists to
make unnecessary. The one confirmed gap in this approach is fixed forward, not silently accepted — see
Honesty / known limits.

## Sweep mechanics

1. **`scan --host <id> --old-version <v> --new-version <v>`** — read-only. Walks the scan surfaces
   above, produces a citation map + a `_meta.skipped_surfaces` list naming any absent surface (a
   consumer's installed project won't have the marketplace-dev-only surfaces).
2. **`classify`** — applies the rule table below to every citation-map row, producing a disposition
   (`mechanical` / `judgment` / `no-finding`) + priority + which check was performed.
3. **`apply --host <id> --yes`** — handles every `mechanical` row, from inside a fixed-slug FORGE
   worktree (`forge-dependency-sweep-<host>`), with dirty-tree refusal, per-write covering-gate
   re-verification, and the fingerprint update landing in the same commit as any content fixes. Two
   distinct outcomes, never conflated: `applied` (a file's bytes actually changed — reported only when a
   real editor exists for that row's citation kind) and `verified` (nothing was written — the row's
   floor comparison was re-confirmed, its own mechanical action). As of this writing the only shipped
   citation kind (`version_floor_constant`, §3 row 2) always resolves to `verified` — the floor constant
   itself is never edited by a version bump, only re-checked.

   `--old-version` is **optional**. When omitted, `apply` reads the fingerprint's own current
   `last_swept_version` for `--host` and uses that as the prior version for its `changed` comparison —
   it never silently treats an omitted flag as "no prior version," which used to make `changed` come
   out `False` even when a real prior version was sitting in the state file this same run was about to
   overwrite. The report's `old_version_source` field (`cli` / `fingerprint` / `none`) says which path
   supplied the value, so a report never implies a comparison it didn't actually make.
4. **The judgment queue** (written by `apply`, not a separate subcommand) — `apply` writes `judgment`
   rows to a capped, priority-ordered PR-review queue (top 25, P0 first, overflow to a continuation
   file) as part of its run — reuses `/repo-review`'s P0-P3 shape rather than inventing a second
   scheme. (The CLI subcommands are `scan`, `classify`, `apply`, plus the `queue-self-test` /
   `apply-self-test` harnesses; there is no standalone `queue` subcommand.)

## Merged classification rule table

| Citation kind | Example (this repo) | Disposition | Priority if judgment | Why |
|---|---|---|---|---|
| Pinned exact version string, no behavior claim | a bare version literal, no interpretive claim | **Mechanical** | — | Pure substitution; nothing about host behavior is asserted. |
| Version-floor comparison that still holds | `COPILOT_FLOOR="1.0.52"`; an `activation_gate: version_floor` cell already satisfied | **Mechanical** (the one case a date bump is ever auto-applied — the re-check *is* the re-verification) | — | Deterministic comparison the sweep itself just ran; the row records which check ran. |
| Version-floor comparison the sweep cannot establish `>=` for | non-semver host versioning, a date-expressed floor | **Judgment** | P2 | Needs a human/agent read of the version scheme. |
| `[docs-verified]`/`[verified]`/`[web-sourced]` date stamp on a capability claim (not the floor-still-holds case above) | any prose marker describing what a host can do | **Judgment** | P2 | Requires reading the changelog delta — exactly what `knowledge-file-staleness-sweep`'s anti-pattern forbids automating. |
| `host-support.json` capability cell (`supported`/`basis`/`caveat`) naming the bumped host | any `hosts.<host>.<component>` cell | **Judgment, always** | **P0** if the changelog delta names the same event by name, else P1 | Gate 154/208 exist precisely because this class needs a dated citation a human writes. |
| `activation_gate` cross-reference | Codex's hash-trust re-arm cross-reference | **Judgment, always** | P1 | A two-file fact; changing one without the other is a real, already-seen drift class. |
| `model-catalog.json` entry/slot decision | `current`/`stale` moves | **Judgment, out of this sweep's write path entirely** | P1 (note only) | Gate 134 already owns model-ID drift, CI-enforced. |
| `_SKIP` reason whose text names an absent event/capability **and** the changelog delta mentions it by name | `_SKIP["agent-dispatch-evaluator.sh"]` | **Judgment (high-priority)** | **P0** | The skip might now be falsified; closing it is design work. |
| `_SKIP` reason with no changelog match | same shape, no match | **No finding — silent** | — | Matches `knowledge-file-staleness-sweep`'s "don't flood the queue" discipline. |
| Version-gated code path whose branch condition names the bumped host | macOS-door-style `if version >= X:` shape | **Judgment, always** | P1 | Behavior-shaping code; retiring a compatibility branch changes runtime behavior. |
| Bare, uncited host-capability claim | anything Gate 208 would flag as missing-citation | **Not this sweep's job** — advisory pointer to Gate 208 | — | Out of scope by construction: this sweep answers "is a *dated* citation stale," not "is a claim cited at all." |

**Never blind-bumps a date.** A `[docs-verified]` date is mechanical **only** when the sweep's own
deterministic sub-check positively confirms the underlying claim still holds (the version-floor row
above) — every other date-stamped citation is judgment, always, even when the resulting edit looks like
a one-liner. `knowledge-file-staleness-sweep`'s own anti-pattern: *"Fixing the date without
re-verifying is worse than letting it go stale — it silently launders untrustworthy content."*

## State file

`plugins/ravenclaude-core/knowledge/host-version-fingerprint.json` — `schema_version: 1`, one entry per
`host-support.json` key, each carrying `last_swept_version` / `last_checked_at` (updated on every
sweep run, mechanical fixes or not) / `last_change_detected_at` (updated only on a real delta) /
`written_by` (provenance, `dependency-sweep.py vN`) / `version_history`. Written only by `apply`'s
step 5, always in the same commit as the content fixes it reports on — never a silent, separate,
local-only write.

`version_history` is an **append-only log of the distinct versions** this host has been swept at, each
entry `{"version": ..., "recorded_at": ...}`. It records real transitions, not every run: a
re-confirmation (`changed=False` because the version didn't move) never duplicates the most recent
entry — `last_checked_at` already carries "I looked, nothing moved." An entry lands only when the host
has no history yet (first-ever sweep) or the new version differs from the last recorded one. Capped at
`_VERSION_HISTORY_CAP` (200) entries in `dependency-sweep.py`, oldest dropped first — a defensive bound
against unbounded growth, not expected to bind given real hosts bump on the order of monthly. This is
what makes `last_swept_version`'s single flat value auditable over time instead of a value that
silently overwrites its own past — the gap flagged when the sweep first ran against five never-swept
hosts and had no way to say what any of them had been *before*.

## Routing table (judgment rows)

| Citation kind | Route to |
|---|---|
| `host-support.json` cell | maintainer (binding edit) + `deep-researcher` if the basis needs re-verifying against the host's own docs |
| `_SKIP` reason in a generator | maintainer — closing a `_SKIP` is a small feature (new wiring + test), not a data edit |
| Version-floor candidate | maintainer, with the *exact* changelog citation the sweep found |
| Version-gated code path retirement | maintainer, explicitly flagged "confirm the floor host no longer needs this" — never auto-proposed as a deletion |

## Anti-patterns

- **Blind date-bumping.** See "Never blind-bumps a date" above — a `[docs-verified]` date is mechanical
  only in the one deterministic-floor-comparison case, never as a general rule.
- **Classifying by diff size or file path.** Diff size is anti-correlated with risk here (a boolean
  flip in `host-support.json` is one line and highly dangerous); file path collapses citation kinds
  that need different treatment purely because they share an extension.
- **Writing the fingerprint separately from the content fixes it reports on.** An unmerged, separate
  fingerprint-only write is exactly the worktree-artifact-loss exposure this skill's own design run
  hit on this machine — see Honesty / known limits and Phase 4's same-commit requirement.
- **Silently truncating an oversized judgment queue.** Cap at 25/run, priority-ordered, overflow to a
  named continuation file — never a flat unreviewable wall of findings.
- **Minting a new worktree slug per run.** `apply` reuses one fixed slug per host
  (`forge-dependency-sweep-<host>`) so `worktree-guard`'s lease actually protects concurrent runs.

## Honesty / known limits

This sweep discovers drift by finding citation **markers** — `[docs-verified]`/`[verified]`/
`[web-sourced]` prose, `host-support.json` JSON cells, `_SKIP` dict entries. **A version-sensitive fact
with no marker of any kind is structurally invisible to it, permanently, by construction — not a bug to
be fixed, a limitation to be stated.** The confirmed example that motivated this note:
`docs/best-practices/2026-q1-q2-failure-modes.md`'s "Tool-version floors that prevent regression-class
failures" table carried zero markers before this skill's Phase 1 fixed it forward — and, once checked,
turned out to carry **fabricated and unsourced facts** (three Copilot floors that don't exist in the
real changelog, and an uncited Cursor floor), already corrected once in this repo's
`external-agent-onboarding/SKILL.md` but never back-ported to that table until this fix. A second,
structurally identical instance — `AGENTS.md`'s inline "Requires Copilot CLI ≥ 1.0.52" bolded-prose
floor with no adjacent marker — is named here but deliberately left unmarked (a docs-only edit outside
this skill's own file inventory), a stated follow-up, not hidden. No success report from a real sweep
run may claim completeness beyond "every marked citation naming the bumped host was found and
classified" — never "every fact about this host is now current."

A consumer's installed project lacks the marketplace-dev-only scan surfaces (`scripts/ravenclaude`, the
three `_SKIP` generators) — `_meta.skipped_surfaces` exists specifically so that shrinkage is visible,
never silently read as "clean."

## Output

```
---RESULT_START---
{
  "status": "complete",
  "summary": "swept <host> N->M; X mechanical applied, Y judgment queued, Z overflow",
  "deliverables": [".ravenclaude/runs/<sweep-id>/citation-map.json", ".ravenclaude/runs/<sweep-id>/dependency-sweep-queue.md"],
  "handoff_recommendation": {"to_specialist": "maintainer", "reason": "review the judgment queue"},
  "confidence": 0.9,
  "risks_or_open_questions": ["marker-blind-spot limitation — see Honesty / known limits"],
  "next_actions": ["review .ravenclaude/runs/<sweep-id>/dependency-sweep-queue.md", "open the apply PR if not already open"]
}
---RESULT_END---
```

## See also

- [`knowledge-file-staleness-sweep`](../knowledge-file-staleness-sweep/SKILL.md) — the calendar-triggered
  sibling sweep.
- [`plugins/ravenclaude-core/scripts/dependency-sweep.py`](../../scripts/dependency-sweep.py) — the tool
  this skill drives.
- [`plugins/ravenclaude-core/scripts/host-version-probe.py`](../../scripts/host-version-probe.py) — the
  manual-invocation-only version probe (never called from SessionStart).
- [`plugins/ravenclaude-core/knowledge/host-support.json`](../../knowledge/host-support.json) — the host
  roster this skill reads live.

Files in this skill

  • SKILL.md14.3 KB
  • tests/fixtures/changelog-delta.txt321 B
  • tests/fixtures/fake-doc.md354 B
  • tests/fixtures/generate-fake-hooks.py266 B
  • tests/fixtures/host-support-slice.json794 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…