Skip to content

fix(sync): stop schema syncs from clobbering the primary pin's shared surfaces#2353

Merged
andybevan-scope3 merged 1 commit into
mainfrom
fix/sync-schemas-shared-surfaces
Jul 9, 2026
Merged

fix(sync): stop schema syncs from clobbering the primary pin's shared surfaces#2353
andybevan-scope3 merged 1 commit into
mainfrom
fix/sync-schemas-shared-surfaces

Conversation

@andybevan-scope3

Copy link
Copy Markdown
Collaborator

Fixes #2352

Problem

scripts/sync-schemas.ts wrote non-version-scoped, checked-in state on every run, so syncing a side-bundle version (3.0.12, v2.5, the opt-in 3.1.0-beta.7) disturbed the primary pin (ADCP_VERSION, currently 3.1.2). Because npm run sync-schemas:all syncs several versions in sequence, contributors kept seeing phantom diffs and reverting files they never touched.

Three shared surfaces were affected:

  1. Protocol skills (skills/adcp-*) — stored in one shared folder (no per-version copy). A 3.0.12 sync overwrote the pinned 3.1.2 skills with older content. The beta script papered over this with a fragile git checkout HEAD restore (RESTORE_PATHS) that ran after a network fetch and needed a hand-maintained path list.
  2. The latest/ cache pointer — a standalone sync-schemas -- 3.0.12 silently repointed schemas/cache/latest at the old version, making the SDK validate against it by default. (Surfaced in review.)
  3. schemas/registry/registry.yaml — not really part of the versioned bundle. Its real owner is scripts/generate-registry-types.ts --sync, which downloads it from https://agenticadvertising.org/openapi/registry.yaml (a live spec ahead of the pinned tarball). sync-schemas copying the tarball's staler copy only downgraded the committed file.

Fix

All three shared surfaces are now tied to the primary pin:

  • syncFromTarball gains an includeSharedSurfaces flag (threaded into the per-file fallback too). It defaults on only when the synced version equals ADCP_VERSION. Skill writes and the latest/ pointer are gated behind it, so side-bundle syncs leave them alone.
  • The registry.yaml write is removed from sync-schemas entirelygenerate-registry-types --sync is its sole owner.
  • The restoreFromHead/RESTORE_PATHS workaround is deleted from scripts/sync-3-1-beta-schemas.ts; nothing gets clobbered anymore, so ordering in sync-schemas:all no longer matters.

Not affected

  • Multi-version schema validation — schemas remain per-version in schemas/cache/<version>/, untouched.
  • SDK-authored skills (build-*, call-adcp-agent) — already never overwritten.
  • CI / publishci:schema-check and ci-validate.js already run generate-registry-types --sync after sync-schemas, so the committed registry.yaml invariant is unchanged; prepublishOnly ships skills that deterministically track the primary pin.

Verification

  • Primary sync (3.1.2): still writes skills, latest → 3.1.2, registry untouched.
  • Non-primary sync (3.0.12): skills unchanged, latest stays 3.1.2, registry untouched.
  • generate-registry-types --sync confirmed as registry's sole owner (zero diff vs committed).
  • Typecheck clean; changeset added; two independent code-review passes (full + delta) came back clean.

… surfaces

sync-schemas wrote non-version-scoped, checked-in state on every run, so
syncing a side-bundle version (3.0.12, v2.5, the opt-in beta) disturbed the
primary pin (ADCP_VERSION, currently 3.1.2):

- Protocol skills (skills/adcp-*): a side-bundle sync overwrote them with an
  older version's content. Gate the skill write behind includeSharedSurfaces,
  which defaults on only for the primary pin.
- latest/ cache pointer: a standalone side-bundle sync silently repointed it,
  making the SDK validate against the older version by default. Gate it the
  same way (both syncFromTarball and the per-file fallback).
- schemas/registry/registry.yaml: owned by generate-registry-types --sync from
  a different upstream (agenticadvertising.org) that runs ahead of the pinned
  protocol bundle. sync-schemas copying the tarball's stale copy only downgraded
  it and dirtied every working tree. Stop writing it here entirely.

Removes the fragile restoreFromHead/RESTORE_PATHS workaround in the beta sync.

Fixes #2352

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@aao-ipr-bot aao-ipr-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. Ties three non-version-scoped surfaces to the primary pin instead of letting whichever side-bundle synced last win — the right shape: version-scoped state stays per-version, shared state tracks one owner.

Things I checked

  • Registry ownership claim is real. sync-schemas no longer writes schemas/registry/registry.yaml. Verified the sole owner is generate-registry-types --sync, which pulls from a different upstream (scripts/generate-registry-types.ts:15https://agenticadvertising.org/openapi/registry.yaml). Both CI gates run it after sync-schemas and then git diff --exit-code the committed file: package.json:357 (ci:schema-check) and scripts/ci-validate.js:117 + :129. The committed-in-sync invariant is unchanged. This also quietly fixes a latent publish bug — prepublishOnlysync-schemas:all used to overwrite the authoritative committed registry with the staler tarball copy right before publish; now it leaves the committed file alone.
  • Gate defaults to fail-safe. sync() computes includeSharedSurfaces = options.includeSharedSurfaces ?? adcpVersion === primaryPin (scripts/sync-schemas.ts ~L556). === binds tighter than ??, so this reads ?? (adcpVersion === primaryPin) — correct. CLI sync-schemas -- 3.0.12false; bare sync-schemas and explicit -- 3.1.2true. Side-bundle syncs leave skills and latest/ alone; the primary pin still refreshes both.
  • Cross-file contract matches. The beta script's syncSchemas(BETA_VERSION, { includeSharedSurfaces: primary === BETA_VERSION }) lines up with the new sync(version?, options) signature (export { sync as syncSchemas }, scripts/sync-schemas.ts:574). When the beta is the primary pin, includeSharedSurfaces is true and skills get written — the intended-bump case is preserved.
  • No dangling refs after the removals. REGISTRY_SPEC_PATH and its only uses are gone; copyFileSync/mkdirSync stay imported because they're used elsewhere (sync-schemas.ts:274, several mkdirSync sites). In the beta script, restoreFromHead/RESTORE_PATHS are fully removed but spawnSync survives for the GitHub-dist fallback (L129) and existsSync survives in hasBetaCache.
  • Per-file fallback gated consistently. syncSchemasPerFile never wrote skills or registry; it now gates only the latest/ pointer behind the same flag. Consistent.
  • Changeset present and correctly typed. .changeset/sync-schemas-shared-surfaces.md is a patch. This is build-tooling that shapes published content (skills, cache, registry), and the change restores intended behavior with no API/export surface change — patch is the right call. MUST-FIX #5 satisfied.

Follow-ups (non-blocking — file as issues)

  • The RESTORE_PATHS deletion removes the one place that enumerated "shared surfaces syncSchemas touches." The invariant now lives implicitly in the includeSharedSurfaces gates. If a future surface gets added to syncFromTarball, there's no list forcing the author to gate it. A one-line assertion or test that a 3.0.12 sync leaves skills/adcp-* and schemas/cache/latest byte-identical would lock the contract down.

Minor nits (non-blocking)

  1. Renaming the inner syncWithBase param optionsfallback is good hygiene now that the outer sync owns an options param (scripts/sync-schemas.ts ~L540). No behavior change, avoids a shadow. Noting it so a future reader doesn't "fix" it back.

Removing a hand-maintained git checkout HEAD restore list and replacing it with a gate that defaults off for side-bundles is the correct direction — fail-closed beats papering over the clobber after the fact.

LGTM. Follow-up noted below.

@andybevan-scope3 andybevan-scope3 merged commit 4bb51b5 into main Jul 9, 2026
31 checks passed
@andybevan-scope3 andybevan-scope3 deleted the fix/sync-schemas-shared-surfaces branch July 9, 2026 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sync-schemas clobbers checked-in skills and registry.yaml on every sync

1 participant