Repository navigation
feat(api-sync): enum + nested-object coverage checks, delivery manifest verification - #70
Merged
Merged
Conversation
…st verification - Add scripts/api-sync/enum-coverage.ts: every enum-constrained property (direct, items.enum array form, anyOf/oneOf wrapper) on every in-scope (reachable, non-ignored) schema must resolve to a mapped enum symbol in spec-map.json's enums[], be covered by the ordinary field-type comparison (direct/items enums on a map.types-covered schema; that path already catches drift today, just not via a dedicated enums[] entry), or have a recorded exclusion in .api-sync/unmodeled.json's new enumPropertyOmissions. The real, previously-invisible gap is anyOf/oneOf-wrapped enums: specTypeSignature never looks inside them. Wired into index.ts's main flow as a hard failure (blocks --check/--apply, so it gates the existing "sync:check (state + map validity)" CI job) and covered by a map-validation vitest test against the committed snapshot. Found zero violations against the current spec; enumPropertyOmissions starts empty. - Add scripts/api-sync/nested-coverage.ts: recursively enumerate inline object and array-item-object shapes under every in-scope schema. spec-map.json's format is flat (schema.property only), so every one of these needs a recorded omission in the new nestedShapeOmissions ledger; unrecorded ones fail a map-validation vitest test. Recorded honest, unreviewed-but-tracked omissions for the 72 nested shapes that predate this check (tracking_*, blindpay_bank_details, owners, etc.) so new unmapped nested shapes fail loudly going forward instead of joining the pile silently. - Verify .github/workflows/pipeline-alert.yml on main: event fields only via env:, jq --arg, quoted webhook URL, missing SLACK_WEBHOOK_URL exits non-zero. No changes needed. - Harden .github/workflows/api-sync.yml's spec-fetch step into a delivery-manifest verification: fetch both .api-sync/spec-current.json and .api-sync/delivery.json from api-sync-data, fail loudly if either is missing, fail if sha256(spec-current.json) != delivery.json's spec_sha256, and fail with "stale delivery" if the repository_dispatch client_payload carries a non-empty spec_sha256 that disagrees with delivery.json's. A dispatch without the manifest (today's state, until v2 PR #1922 ships it) fails loudly by design rather than syncing against an unverified spec. No version bump: infra/tooling only, no SDK surface change. Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
No version bump: infra/tooling only, no SDK surface change.
a) Enum coverage check (blocking in CI)
scripts/api-sync/enum-coverage.tswalks every in-scope (reachable, non-ignored) schema and finds every enum-constrained property: directenum, array-of-enum (items.enum), andanyOf/oneOf-wrapped enums. A property is covered if it resolves to a mapped enum symbol inspec-map.json'senums[], is covered by the ordinary field-type comparison (direct/items enums on any schema already covered by amap.typesentry already catch drift today viatype-check.ts'sspecTypeSignature, just without a dedicatedenums[]entry), or has a recorded exclusion in.api-sync/unmodeled.json's newenumPropertyOmissions.The one real, previously-invisible gap this closes:
specTypeSignaturenever looks insideanyOf/oneOf, so an enum wrapped that way was checked by nothing. Wired intoindex.ts's main flow as a hard failure, so it blocks--check/--applyand gates the existing "sync:check (state + map validity)" job inapi-sync-check.yaml. Also covered by amap.test.tsassertion against the committed snapshot. Found zero violations against the current spec;enumPropertyOmissionsstarts empty.b) Nested-object coverage (map validation)
scripts/api-sync/nested-coverage.tsrecursively enumerates inline object and array-item-object shapes under every in-scope schema (things likePayinOut.tracking_transaction.pse_instruction,VirtualAccountOut.us.ach).spec-map.json's format is flat (schema + top-level property only), so there's no way to "map" a nested shape today; every one of them needs a recorded, honest omission in the newnestedShapeOmissionsledger, ormap.test.ts's new assertion fails.Found 72 pre-existing nested shapes with no tracking at all; recorded all 72 as omissions with a shared, honest reason ("pre-existing, not yet modeled, needs a human pass") so this PR doesn't silently model 72 shapes it hasn't reviewed, but so that any new unmapped nested shape from here on fails loudly instead of joining the pile.
c) Delivery manifest verification
.github/workflows/api-sync.yml's spec-fetch step now fetches both.api-sync/spec-current.jsonand.api-sync/delivery.jsonfrom theapi-sync-databranch and:sha256(spec-current.json)doesn't matchdelivery.json'sspec_sha256,repository_dispatchclient_payload.spec_sha256is non-empty and disagrees withdelivery.json's.A dispatch without the manifest (today's state, until v2 PR #1922 ships it) fails loudly by design instead of syncing against an unverified spec — that's the intended failure mode while the two repos land this in parallel.
Sanity check: pipeline-alert.yml
Verified
.github/workflows/pipeline-alert.ymlon main is present and injection-safe: event fields (WF_NAME,WF_BRANCH,WF_URL,WF_ACTOR) come in only viaenv:, the Slack payload is built withjq --arg, the webhook URL is quoted, and a missingSLACK_WEBHOOK_URLexits non-zero. No changes made.Test plan
bun run test— 29 files, 178 tests, all pass (new:enum-coverage.test.ts,nested-coverage.test.ts, 2 newmap.test.tsassertions)bun run check-types,bun run lint:check— cleanbun run sync:check— OK, no pending drift (130 known divergences recorded and skipped)node scripts/contract-check.mjs— unaffected, still passesbun run build— cleanhttps://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs