GCA · REFERENCE

    Upgrades & Migration

    Safely upgrading Gadriel Code across versions.

    Upgrades & Migration

    Once a repo is initialized with gadriel code init, keeping it current is two independent tracks:

    1. Upgrade the binary — pull a newer gadriel from npm.
    2. Refresh the scaffold — re-run init in 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

    Gadriel keeps state in two places. Knowing which is which tells you what an upgrade touches and what is safe to delete.

    ScopeLocationContentsCommitted?
    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 filesfindings.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:

    npm install -g gadriel@latest

    Verify:

    gadriel --version
    gadriel code --version

    Pin a specific release when you want reproducible CI:

    npm 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:

    FlagBehaviorUse when
    --upgradeMerge 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-missingAdd 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.
    --forceOverwrite 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.
    # 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 for github, gitlab, circleci, jenkins, or all. Templates carry a GADRIEL_MANAGED sentinel, so --upgrade rewrites 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-run to preview, or --uninstall to 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:

    ArtifactPurposeSkippable via
    .security/Per-repo output + store root (findings, reports, SBOM, history).
    Git hooksThe 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.jsonRegisters the MCP server so AI coding agents can read findings and drive fixes.part of --skip-claude scope on non-Claude setups
    CLAUDE.mdProject guidance for Claude Code and compatible assistants.--skip-claude
    .gitignoreIgnores .security/ runtime output while keeping committed config.
    .gadriel.tomlThe unified, version-controlled project config — a fully-commented starter file.
    .claude/Claude Code scaffold (hooks, rules, optional marketplace).--skip-claude
    CI templatesProvider 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:

    1. Generate / refresh the file. gadriel code init --upgrade writes (or tops up) .gadriel.toml from the live code defaults, so the scaffold never drifts from what the binary actually does. --upgrade appends any new section a later version ships and leaves sections you already customized untouched.
    2. Move machine-wide preferences into ~/.gadriel/config.toml (global) and repo-wide defaults into ./.gadriel.toml (committed). The project file wins.
    3. 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_env stores only the name of the env var to read the token from.
    4. Point at a non-default file for a one-off with --config <path>, which replaces ./.gadriel.toml in 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:

    # Migrate legacy NDJSON/JSONL store dirs into the RVF substrate
    gadriel 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 window
    gadriel code store migrate --backfill --from-date 2026-01-01 --to-date 2026-06-30

    Related store operations for verifying a migration:

    CommandPurpose
    gadriel code store listList every .rvf file in the per-machine and per-repo stores.
    gadriel code store verifyVerify 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 init writes is generated live from the binary's own Config::default(), so a fresh init --upgrade after 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 with store verify after 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 with gadriel 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.