Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .changeset/fix-compliance-cache-version-marker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"@adcp/sdk": patch
---

Fix compliance cache staleness: write tracked `compliance/CACHE_VERSION` marker

`compliance/cache/` is gitignored (populated at sync/publish time) so
compliance-only spec bumps — new storyboard YAMLs, fixed `idempotency_key`
strings — never triggered a PR from `schema-sync.yml`. The diff guard only
watched `src/lib/types/`, `src/lib/agents/`, and `package.json`, making it
blind to spec changes that don't touch TypeScript schemas.

Fixes the silent mismatch where `--version` advertised one AdCP version while
`compliance/cache/` contained storyboards from an older release — causing false
positives and false negatives in buyer-side storyboard validation.

Changes:
- `scripts/sync-schemas.ts` now writes `compliance/CACHE_VERSION` (tracked in
git, one level above the gitignored `compliance/cache/`) after every tarball
sync; the file contains the `adcp_version` from the tarball's `index.json`.
- `schema-sync.yml` diff guard now includes `compliance/CACHE_VERSION` so
compliance-only spec bumps trigger an automated PR.
- `ci.yml` gains a post-sync validation step that asserts
`compliance/CACHE_VERSION` matches `ADCP_VERSION`, catching version drift
before it reaches npm.
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ jobs:
- name: Sync schemas from AdCP
run: npm run sync-schemas:all

- name: Validate compliance cache version matches spec
run: |
EXPECTED=$(cat ADCP_VERSION | tr -d '[:space:]')
if [ ! -f compliance/CACHE_VERSION ]; then
echo "❌ compliance/CACHE_VERSION not found after sync — sync-schemas may have failed silently."
echo " Run: npm run sync-schemas:all"
exit 1
fi
CACHED=$(cat compliance/CACHE_VERSION | tr -d '[:space:]')
if [ "$CACHED" != "$EXPECTED" ]; then
echo "❌ Compliance cache version mismatch: bundled '$CACHED', expected '$EXPECTED'"
echo " Stale storyboards cause false pass/fail in buyer-side validation."
echo " Run: npm run sync-schemas:all"
exit 1
fi
echo "✅ compliance/cache version matches spec: $CACHED"

- name: Validate generated files are in sync
run: |
npm run generate-types
Expand Down
21 changes: 13 additions & 8 deletions .github/workflows/schema-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,24 @@ jobs:
npm run generate-types
npm run generate-wellknown-schemas

if git diff --exit-code src/lib/types/ src/lib/agents/ package.json; then
# Always capture version so PR title is correct for compliance-only bumps too.
# compliance/CACHE_VERSION is always written by sync-schemas (tarball or per-file path).
ADCP_VERSION=$(cat compliance/CACHE_VERSION | tr -d '[:space:]')
echo "adcp_version=$ADCP_VERSION" >> $GITHUB_OUTPUT

# Include compliance/CACHE_VERSION in the diff guard so compliance-only
# spec bumps (e.g. fixed storyboard YAML, new idempotency_key strings)
# trigger a PR even when TypeScript types are unchanged.
# git status --short detects both new (untracked) and modified marker files.
COMPLIANCE_MARKER_CHANGED="$(git status --short compliance/CACHE_VERSION 2>/dev/null)"

if git diff --exit-code src/lib/types/ src/lib/agents/ package.json && \
[ -z "$COMPLIANCE_MARKER_CHANGED" ]; then
echo "changes_detected=false" >> $GITHUB_OUTPUT
echo "✅ No schema changes detected"
else
echo "changes_detected=true" >> $GITHUB_OUTPUT
echo "📋 Schema changes detected"

ADCP_VERSION=$(node -e "
const fs = require('fs');
const index = JSON.parse(fs.readFileSync('schemas/cache/latest/index.json', 'utf8'));
console.log(index.adcp_version);
")
echo "adcp_version=$ADCP_VERSION" >> $GITHUB_OUTPUT
fi

- name: Sync version if schemas changed
Expand Down
16 changes: 16 additions & 0 deletions scripts/sync-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,15 @@ async function syncFromTarball(version: string): Promise<boolean> {
updateLatestSymlink(SCHEMA_CACHE_DIR, version);
updateLatestSymlink(COMPLIANCE_CACHE_DIR, version);

// Write a tracked marker so schema-sync CI can detect compliance-only spec
// bumps. compliance/cache/ is gitignored (populated at sync/publish time),
// but compliance/CACHE_VERSION sits one level above and IS tracked in git.
// This lets the diff guard in schema-sync.yml fire even when no TypeScript
// types changed — preventing stale storyboards from shipping in npm releases.
const cacheVersionMarker = path.join(path.dirname(COMPLIANCE_CACHE_DIR), 'CACHE_VERSION');
writeFileSync(cacheVersionMarker, `${semanticVersion}\n`);
console.log(`📝 compliance/CACHE_VERSION → ${semanticVersion}`);

console.log(`📁 Schemas: ${path.join(SCHEMA_CACHE_DIR, version)}`);
console.log(`📁 Compliance: ${path.join(COMPLIANCE_CACHE_DIR, version)}`);
if (existsSync(`${path.join(SCHEMA_CACHE_DIR, version)}.previous`)) {
Expand Down Expand Up @@ -503,6 +512,13 @@ async function sync(version?: string): Promise<void> {
const viaTarball = await syncFromTarball(adcpVersion);
if (!viaTarball) {
await syncSchemasPerFile(adcpVersion);
// Per-file fallback doesn't sync compliance/. Write the marker anyway so
// ci:schema-check doesn't hard-fail with "not found". Version reflects the
// ADCP_VERSION pin — the mismatch risk is pre-existing in this fallback path.
const marker = path.join(path.dirname(COMPLIANCE_CACHE_DIR), 'CACHE_VERSION');
mkdirSync(path.dirname(marker), { recursive: true });
writeFileSync(marker, `${adcpVersion}\n`);
console.warn(`📝 compliance/CACHE_VERSION → ${adcpVersion} (per-file fallback — compliance storyboards not synced)`);
}

console.log(`✅ Sync complete for AdCP ${adcpVersion}`);
Expand Down
Loading