sync
Update the pinned API inputs from the stable endpoint. The only command that writes them.
sync is the sole writer of the pinned inputs — openapi.json and chowbea.bus.json. It fetches from the committed stable endpoints, validates everything, writes only the pins whose content actually changed, then regenerates so your tree stays consistent. In practice, CI runs it; you run it by hand mostly during migration.
Usage
chowbea-axios sync [flags]Requires pinned mode: api_endpoint + spec_file set, and [bus].file whenever [bus] is configured. Anything less exits with an actionable error.
What it does
- Loads the committed config only —
api.config.local.tomlis deliberately ignored (and logged as skipped), so nobody's tunnel can become the pinned contract. - Fetches and validates everything first — the spec (normalized to canonical JSON) and the bus manifest (full trust-boundary validation: version gate, hash integrity, declaration parsing). A failure anywhere means nothing is written — not even the artifact that succeeded.
- Writes pins hash-gated — unchanged content writes zero bytes, so a no-op sync leaves a clean tree (and therefore no PR in CI). The bus request sends
If-None-Matchfrom the current pin's hash; a304counts as unchanged. Parent directories are created for nested pin paths. - Regenerates
_generated/from the (possibly updated) pins and prints the contract diff:bus: + Grade,~ Plan,- LegacyGrade (removed).
Loud by design
Where fetch degrades gracefully, sync refuses:
- Network failure after retries → error. There is no cache fallback — pinning a stale cached spec silently is the one thing this command must never do. Your current pins remain the last known good.
- Basic Auth over cleartext
http://to a non-loopback host → error before any request (localhost dev endpoints stay allowed). - A manifest that fails validation → error, nothing written.
Exit code is non-zero on any failure; 0 whether or not something changed (CI detects changes via the working tree).
Flags
| Flag | Short | Description | Default |
|---|---|---|---|
--config | -c | Path to api.config.toml | Auto-detected |
--quiet | -q | Suppress non-error output | false |
--verbose | -v | Show detailed output | false |
No --endpoint override, on purpose: the pins only ever come from the committed config.
Examples
# First sync of a freshly pinned repo — creates both pins
chowbea-axios sync
# CI (the chowbea-sync.yml template does exactly this)
npx chowbea-axios sync --quietDev loop against your local backend? That's fetch — it writes only gitignored paths and never touches the pins.