Parity with tango-python: new resources, full filter surface, shape overlay, conformance gates, cassette tests - #14
Merged
Merged
Conversation
…se shape-coverage gates Ports tango-python's contract-vendoring architecture: conformance now runs offline against contracts/filter_shape_contract.json as a hard CI gate, with a token-gated warn-only staleness diff. Adds scripts/check-shape-coverage.ts (reverse gate), conformance + shape-coverage baselines capturing the current parity backlog, and gate tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, full shape schemas Mirrors tango-python v1.3.0: listExclusions/getExclusion, listSbirTopics/getSbirTopic, listSbirSolicitations/getSbirSolicitation, listDibbsRfqs/getDibbsRfq, listDibbsRfps/getDibbsRfp, listDibbsAwards/getDibbsAward, each with every contract filter as an explicit typed option, ShapeConfig presets, registered schemas (13 incl. nested refs), models, and iterate wrappers. Conformance baseline shrinks to events/news only; shape-coverage gaps 422 → 416. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… burn-down ListBudgetAccountsOptions now carries all 96 contract params as explicit typed properties; legacy fiscal_year_gte/fiscal_year_lte/account_title aliases are remapped to the dunder wire names they silently missed before. Adds getGsaElibraryContract, psc has_awards, and explicit props for every filter previously reachable only via index signatures (contracts/idvs/otas key, entities cage, forecasts id, opportunities opportunity_id, itdashboard previous_uii, protests naics_code verbatim). Conformance gate: 0 errors, warnings down to the two permanently baselined resources. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…esponse diagnostics; structured shape errors Ports python's overlay mechanism: scripts/generate-shape-overlay.ts deterministically emits src/shapes/generatedOverlay.ts (358 fields across 25 containers + 56 nested schemas) from the vendored contract + observed types, merged under curated schemas with explicit-wins semantics. PaginatedResponse gains meta with parsed agencyWarnings/unresolvedAgencyTokens/resolvedAgencies; TangoValidationError gains issues/availableFields. Shape-coverage baseline is now empty: 0 gaps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…verage Adds a record/replay harness around fetchImpl (tests/integration/harness.ts) with 44 recorded cassettes replayed offline in CI, per-resource integration tests across the full surface, an env-gated production smoke suite, and a coverage step on the Node 20 CI leg. Recording scrubs all request headers and allowlists response headers; the serializer throws if key material would be persisted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…m ci; drop dead .eslintrc.cjs API_REFERENCE/README/SHAPES/DEVELOPERS now cover the wave-2/3 surface and the conformance + cassette workflows, and stale getIdvSummary/listIdvSummaryAwards sections are gone. package-lock.json is committed and CI/publish use npm ci for reproducible installs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s, CI gate strength, harness fidelity Collapses the 13 new resource methods into _shapedPaginatedList/_shapedGet helpers, fixing the joiner leak the copy-paste introduced; makes the new PaginatedResponse diagnostic fields optional so existing consumer literals keep compiling; restores hard token-present conformance gates against tango HEAD and adds an overlay regen-diff gate; replays non-JSON cassette bodies verbatim; shares one isRecord guard; unwraps hard-wrapped comments; single coverage-aware CI test run with npm caching. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Merged
vdavez
added a commit
that referenced
this pull request
Aug 14, 2026
Reapplied on top of the reworked CI from #14; all eight action references across ci, publish, and docs-dispatch move to v5. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vdavez
added a commit
that referenced
this pull request
Aug 14, 2026
Reapplied on top of the reworked CI from #14; all eight action references across ci, publish, and docs-dispatch move to v5. Co-authored-by: V. David Zvenyach <dave@zvenyach.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Brings tango-node to feature and quality parity with tango-python (v1.5.1-equivalent surface, API contract 4.22.0).
What
New resources (mirroring tango-python v1.3.0): exclusions, SBIR topics + solicitations, and DIBBS RFQs/RFPs/awards — 12 methods with every contract filter as an explicit typed option, plus 6
iterate*async iterators, ShapeConfig presets, registered shape schemas, and model interfaces.Filter-surface catch-up:
ListBudgetAccountsOptionsnow carries all 96 contract params (the 26 numeric range-triplet families plus categorical variants);getGsaElibraryContractdetail method;has_awardson PSC; and explicit typed props for every filter previously reachable only through index signatures (keyon contracts/IDVs/OTAs,cageon entities, verbatimnaics_codeon protests,previous_uiion IT Dashboard, and more). Along the way this fixed a real bug: the legacyfiscal_year_gte/fiscal_year_lte/account_titlebudget options were sent verbatim and silently ignored by the API; they now remap to the dunder wire names.Shape-registry parity (mirroring python v1.4.0/v1.5.0): a deterministic overlay generator (
scripts/generate-shape-overlay.ts→src/shapes/generatedOverlay.ts) closes all 416 reverse shape-coverage gaps to zero;PaginatedResponsegains optionalmetadiagnostics with parsedagencyWarnings/unresolvedAgencyTokens/resolvedAgencies;TangoValidationErrorgains structuredissues/availableFields; entityrelationships(type, source)shapes are covered.Conformance architecture (mirroring python's): the API contract is vendored at
contracts/filter_shape_contract.jsonand both gates — forward filter conformance and reverse shape coverage — run offline as hard CI gates, no token required, fork-safe. With a token present, both gates additionally run hard against the fresh contract from the API repo's HEAD, and CI fails if the committed overlay is stale against the vendored contract.Integration test layer: a record/replay cassette harness around the injectable
fetchImplwith 44 cassettes recorded against the live API and replayed offline (~3s), per-resource integration tests across the full surface, and an env-gated production smoke suite. Recording scrubs all request headers and refuses to persist key material.Docs + packaging: API_REFERENCE/README/SHAPES/DEVELOPERS now document the full surface (and drop stale
getIdvSummary/listIdvSummaryAwardssections);package-lock.jsonis committed and CI/publish usenpm ci; the dead legacy.eslintrc.cjsis gone; the repo gets a realCLAUDE.md.Testing
358 tests across 45 files (was 220), all passing offline in ~3s: unit, request-construction parity, schema/preset parity, gate self-tests, cassette integration, and env-gated production smoke (verified live once during recording).
tsc --noEmit, ESLint, and both conformance gates are green; the overlay regen-diff is clean.An adversarial review pass ran before this PR; all ten verified findings were fixed with regression tests that fail against the pre-fix code (notably a
joinerparam leak in the first cut of the new list methods, since collapsed into shared_shapedPaginatedList/_shapedGethelpers).Risks / notes
PaginatedResponsediagnostic fields are optional, so existing consumer literals keep compiling; the SDK always populates them.requested_ba__gte) rather than python's single-underscore spellings; node sends option keys verbatim, and the legacy single-underscore aliases still work via remap.naics_codeprotest filter, so whichever lands second has a trivial merge.events/newsremain intentionally unimplemented (permanently baselined, matching python).Next steps
Version bump + changelog promotion at release time (this PR keeps everything under
[Unreleased]).Cassette refresh workflow is documented in DEVELOPERS.md (
TANGO_REFRESH_CASSETTES=true).mark 🤖
🤖 Generated with Claude Code