Upgrades & Migration
Once a repo is initialized with gadriel code init,
keeping it current is two independent tracks:
- Upgrade the binary — pull a newer
gadrielfrom npm. - Refresh the scaffold — re-run
initin a mode that merges (not clobbers) the newer defaults into the files already in your repo.
This page covers both, plus the one-time config consolidation onto the unified
.gadriel.toml and the RVF store migration
(store migrate).
Contents
- Where state lives
- Upgrading the binary (npm)
- Refreshing the scaffold (
initmodes) - What
initscaffolds - Config migration to
.gadriel.toml - RVF store migration
- Version compatibility
Where state lives
Gadriel keeps state in two places. Knowing which is which tells you what an upgrade touches and what is safe to delete.
| Scope | Location | Contents | Committed? |
|---|---|---|---|
| Per-machine | ~/.gadriel/ | Auth token (auth/token.jwt, mode 0600), the OSV snapshot + cross-repo store (store/), global config (config.toml), calibration table. Override the store with GADRIEL_STORE_DIR. | No |
| Per-repo | .security/ + config/scaffold files | findings.json, reports, SBOM, compliance, history snapshots, and the repo-local store (.security/store/), plus the version-controlled .gadriel.toml, git hooks, .mcp.json, and CLAUDE.md. | Mixed — .gadriel.toml and the scaffold are committed; .security/ runtime output is .gitignored. |
An upgrade of the binary never rewrites either location on its own — you rerun
init (for the per-repo scaffold) and/or store migrate (for the store) when
you want them brought forward.
Upgrading the binary (npm)
Gadriel ships as a single self-contained binary distributed through npm. Upgrade in place:
bashnpm install -g gadriel@latest
Verify:
bashgadriel --versiongadriel code --version
Pin a specific release when you want reproducible CI:
bashnpm install -g gadriel@0.11.5
Upgrading the binary changes the code defaults and the scaffold templates it knows about — but it does not reach into your repo. To pull those newer defaults into an already-initialized repo, refresh the scaffold (next section).
Refreshing the scaffold (init modes)
gadriel code init refuses to run blindly in a repo that already contains
Gadriel-owned files, so it never clobbers your customizations. Instead it points
you at three explicit modes. Pick the one that matches your intent:
| Flag | Behavior | Use when |
|---|---|---|
--upgrade | Merge new settings into existing files; preserve your (and other tools') customizations. Appends any new .gadriel.toml section a later version ships; never touches a section you already changed. | Routine "bring me up to the latest defaults" after an npm upgrade. |
--add-missing | Add only missing files/keys; never modify anything that already exists. | You deleted or never generated part of the scaffold (e.g. skipped hooks earlier) and want just the gaps filled. |
--force | Overwrite all Gadriel-owned files. An interactive prompt confirms; pass --yes to skip it. | You want a clean slate and have no local scaffold customizations worth keeping. |
bash# Routine refresh after `npm install -g gadriel@latest`gadriel code init --upgrade# Fill only the gaps (e.g. add hooks you skipped at first init)gadriel code init --add-missing# Nuke and repave the scaffold (destructive; confirm or pass --yes)gadriel code init --force --yes
These are the same flags surfaced when init detects an existing install — see
"gadriel is already initialized".
Two composable extras that also apply on a refresh:
--ci <providers>— (re)install CI templates forgithub,gitlab,circleci,jenkins, orall. Templates carry aGADRIEL_MANAGEDsentinel, so--upgraderewrites Gadriel-authored files idempotently and leaves yours alone. See CI/CD Integration.--platform <names>— add or refresh AI-assistant scaffolds (cursor,windsurf,copilot,codex,jetbrains,claude-desktop, …). Pair with--dry-runto preview, or--uninstallto remove a platform's config.
What init scaffolds
A full init writes the W1 consolidated scaffold. Knowing the inventory
tells you what --upgrade / --add-missing operate over:
| Artifact | Purpose | Skippable via |
|---|---|---|
.security/ | Per-repo output + store root (findings, reports, SBOM, history). | — |
| Git hooks | The pre-commit gate (L2) — non-destructively wired between # >>> gadriel-code-security >>> markers, or as a manager-native entry for husky / lefthook / pre-commit-rs. | --skip-hooks |
.mcp.json | Registers the MCP server so AI coding agents can read findings and drive fixes. | part of --skip-claude scope on non-Claude setups |
CLAUDE.md | Project guidance for Claude Code and compatible assistants. | --skip-claude |
.gitignore | Ignores .security/ runtime output while keeping committed config. | — |
.gadriel.toml | The unified, version-controlled project config — a fully-commented starter file. | — |
.claude/ | Claude Code scaffold (hooks, rules, optional marketplace). | --skip-claude |
| CI templates | Provider workflows (default: github). | --ci selects; none installed if you never pass workloads you want |
By default init also syncs the OSV snapshot for the ecosystems it detects, so
the first scan runs with CVE detection already on; pass --skip-osv (or
--offline) for air-gapped / CI setups that sync separately.
For the full flag list see init in the CLI reference.
Config migration to .gadriel.toml
Gadriel reads a single unified project config file,
.gadriel.toml, at the repo root — one file with [scan], [report], [init],
[mcp], [tier2], and [secrets] sections. It replaces the scattering of
per-concern settings earlier versions used. The layered precedence is:
CLI flag > GADRIEL_*/env > ./.gadriel.toml > ~/.gadriel/config.toml > built-in default
Migrating an older repo:
- Generate / refresh the file.
gadriel code init --upgradewrites (or tops up).gadriel.tomlfrom the live code defaults, so the scaffold never drifts from what the binary actually does.--upgradeappends any new section a later version ships and leaves sections you already customized untouched. - Move machine-wide preferences into
~/.gadriel/config.toml(global) and repo-wide defaults into./.gadriel.toml(committed). The project file wins. - Never put secrets in the file. Tokens/keys
(
ANTHROPIC_API_KEY,GADRIEL_TOKEN, …) are dropped and surfaced as a warning — set them as environment variables.[mcp] auth_token_envstores only the name of the env var to read the token from. - Point at a non-default file for a one-off with
--config <path>, which replaces./.gadriel.tomlin the stack.
Full key reference, env-var mappings, and the commented starter file: Configuration.
RVF store migration
Gadriel's operational state (audit log, findings history, timeseries,
embeddings, learned priors) lives in the RVF substrate — .rvf files under
the per-machine (~/.gadriel/store/) and per-repo (.security/store/) roots.
Repos initialized before the RVF substrate keep legacy NDJSON / JSONL store
directories. Bring them forward with store migrate:
bash# Migrate legacy NDJSON/JSONL store dirs into the RVF substrategadriel code store migrate# Also synthesise ScanRun (S-01) + FindingsHistory (S-02) rows from# .security/history/<date>/findings.json snapshots (idempotent)gadriel code store migrate --backfill# Bound the backfill to a date windowgadriel code store migrate --backfill --from-date 2026-01-01 --to-date 2026-06-30
Related store operations for verifying a migration:
| Command | Purpose |
|---|---|
gadriel code store list | List every .rvf file in the per-machine and per-repo stores. |
gadriel code store verify | Verify signatures / witness chains; exits non-zero on any failure. |
gadriel code store rebuild --kind <kind> | Rebuild a store's RVF companion from its sidecar JSON. |
The --backfill path is idempotent across re-runs, so it's safe to run
again after adding more history snapshots. Without --backfill, the backfill
step is dry-run only. See store in the CLI reference
for every subcommand and flag.
Version compatibility
- Binary ↔ scaffold. The scaffold
initwrites is generated live from the binary's ownConfig::default(), so a freshinit --upgradeafter an npm bump always matches the running binary — the two can't silently drift. - Binary ↔ store. The RVF substrate is forward-migrated via
store migrate; verify withstore verifyafter an upgrade. Legacy NDJSON/JSONL stores keep working until migrated. - Binary ↔ policies. The GVL rule corpus and OSV snapshots are versioned
independently of the binary. Pin a corpus revision with
gadriel code init --rev <commit>, and refresh advisories withgadriel code policies --osv. A stale-beyond-threshold OSV snapshot surfaces as DEGRADED coverage (or a tooling error at the staleness cap), not a silent gap — see Troubleshooting. - Reproducible CI. Pin the npm version (
gadriel@<x.y.z>) and the policies revision (--rev) together so a pipeline is byte-reproducible across runs.
Related documentation
- CLI Reference —
init·store - Configuration — the unified
.gadriel.toml. - Installation — first-time install via npm.
- CI/CD Integration — keeping CI templates current with
--ci. - Troubleshooting — "already initialized", DEGRADED coverage, and where state lives. </content>
