contract-sync
Skill1 starsChanged 38 days agoMITView on GitHub
Vendors an OpenAPI contract at a pinned commit and regenerates its client — check, sync, bump against api-contract.lock. Triggers: 'absorb the contract bump', 'sync the API contract', 'our openapi.yaml is stale'.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- thefacelessdon/faceworktheir own version, first seen Aug 21, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- thefacelessdon/facework★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository23 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- harness-auditSkill
- skill-benchSkill
- ask-biginSkill
- bigin-harness-setupSkill
- debug-workflowSkill
- discovery-workflowSkill
- epic-workflowSkill
- flutter-figma-handoffSkill
- go-scaffoldSkill
- knowledge-distillSkill
- model-routerSkill
- napkinSkill
- next-scaffoldSkill
- nodejs-scaffoldSkill
- nuxt-marketing-scaffoldSkill
- nuxt-scaffoldSkill
- nuxt-ui-figma-handoffSkill
- project-scaffoldSkill
- session-handoffSkill
- sprint-distillSkill
- task-workflowSkill
- write-testsSkill
The file
Files
contract-sync
Keeps a consumer repo's vendored OpenAPI spec, its api-contract.lock, and its generated
client in lockstep with the contracts repo that owns them. The flow is one-way — contracts
→ consumers — and this script is the only thing that writes any of the three.
When not to use
- Changing an API. That work belongs in the contracts repo, in its own session. If a shape the app needs doesn't exist, say so and stop; do not add it to the vendored file.
- A repo with no
api-contract.lock. It isn't a consumer repo. Setting one up isbigin-harness-setupwith a repo type ofapi,webormobile. - Authoring a spec in a standalone (non-polyrepo) backend. A Go repo that owns its own
openapi.yamlkeeps themake generateloop it already has.
Step 1: Confirm the repo is set up
The script must be committed into the repo, not run from the plugin: CI runs it too, and CI has no plugin installed. Check both:
test -f api-contract.lock && test -f scripts/contract_sync.mjs && echo readyMissing scripts/contract_sync.mjs → copy this skill's own copy in and commit it:
mkdir -p scripts && cp ${CLAUDE_SKILL_DIR}/scripts/contract_sync.mjs scripts/Missing api-contract.lock → start from ${CLAUDE_SKILL_DIR}/templates/api-contract.lock.json,
fill in repo and file, then run bump <ref> to record commit and sha256. Never
hand-write those two fields; they are machine-verified and a wrong value fails every later
sync.
Step 2: Read the current state
node scripts/contract_sync.mjs checkOne line per contract:
core: lock v2.3.0 (8f2a91c) — latest v2.5.0; sync PR #142 opencheck writes nothing, never fails a session, and degrades to a skip line when offline,
unauthenticated or rate-limited. It caches for 15 minutes, so repeated runs cost one
network call — pass --no-cache to force a fresh look.
Step 3: Absorb a bump
node scripts/contract_sync.mjs bump v2.5.0Resolves the tag to a commit, fetches the spec blob at that commit, records the commit and its checksum in the lock, writes the vendored spec, and runs the repo's own codegen. Lock, spec and generated code move in one commit — that is the whole point, and a PR containing only two of the three is wrong.
To re-apply what the lock already pins (after a fresh clone, or to prove no drift):
node scripts/contract_sync.mjs syncThen review the type diff, which is what the reviewer is actually approving:
git diff --stat && git diff -- <generated client path>Command reference
| Command | Effect | Writes |
check [--contract <name>] [--no-cache] | compare lock against the contracts repo's latest tag; report | nothing |
verify [--contract <name>] | offline. re-hash the vendored spec and compare with the lock | nothing |
where [--contract <name>] [--json] | offline. print where this repo vendors its contract, one path per line | nothing |
sync [--contract <name>] | verify the pinned tag still resolves to the pinned commit, fetch, checksum, vendor, regenerate | spec + generated code |
bump <ref> [--contract <name>] [--file <path>] | resolve a new ref, record commit + checksum, vendor, regenerate | lock + spec + generated code |
--repo-type api\|web\|mobile overrides detection, which normally reads go.mod,
nuxt.config.* or pubspec.yaml. --file on bump switches which API version file this
repo consumes — that is how mobile stays on core.v1.yaml while web moves to core.v2.yaml.
Where the spec lands is resolved, not assumed — the lock's vendoredTo, then the spec
already on disk, then the repo type's default; --spec-path overrides all three and bump
records what it used. A Go service that vendors to api/openapi.yaml because it serves that
file at runtime keeps it there. where is that resolver exposed, and it is what everything
else asks rather than restating a path: bigin-harness-setup substitutes {SPEC_PATH} from
it, contract-drift.yml's trigger globs are filled from it at install time, and patch mode
repairs an existing repo's paths: globs from it. Precedence and the multi-contract rule:
references/lock-format.md.
Exit codes: 0 ok, 1 runtime failure, 2 bad usage.
When it refuses
Three failures are deliberate and must not be worked around. In every one, nothing was written — the repo is exactly as it was.
The tag moved. The lock's ref no longer resolves to its commit. A published version
number now points at different bytes. This is a contracts-repo problem: take it there. Do
not re-pin past it with a fresh bump to make the error go away.
Checksum mismatch. The blob fetched at the pinned commit is not the blob the lock recorded. Report it; do not re-record the new checksum.
Codegen entry point missing. The repo has no Makefile (api), no openapi-types
script (web), or no tool/generate_api.sh (mobile). Fix the repo's toolchain, then re-run.
The check happens before any write precisely so a missing generator can't leave a new spec
next to a stale client.
What holds this in place
- A PreToolUse guard denies
Edit/Writeon the vendored spec andapi-contract.lock— unconditionally, including for you. Editing either by hand is never the answer. - SessionStart surfaces
check's report as a notice. It writes nothing and never blocks. verifyat pre-commit re-hashes the vendored spec against the lock, offline and in milliseconds. This is the check with no other cover: the PreToolUse guard only sees edits made through an agent, so a human with an editor bypasses it entirely.- A CI job runs
syncandgit diff --exit-code, so drift between the lock and the generated client fails the build. Template:templates/workflows/contract-drift.yml— replace its{SPEC_PATH}line withwhere's output (one line per contract) when you copy it in, or the job never triggers on the contract it guards. That one is CI-only — reproducing it needs the toolchain and a network fetch, which a commit hook may not depend on. - A
repository_dispatchfrom the contracts repo opens the bump PR automatically. Template:templates/workflows/contract-bump.yml.
Lock field semantics, the auth chain, and the multi-contract path convention:
references/lock-format.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

