Skip to content

Parity with tango-python: new resources, full filter surface, shape overlay, conformance gates, cassette tests - #14

Merged
vdavez merged 7 commits into
mainfrom
feat/python-parity
Aug 14, 2026
Merged

Parity with tango-python: new resources, full filter surface, shape overlay, conformance gates, cassette tests#14
vdavez merged 7 commits into
mainfrom
feat/python-parity

Conversation

@makegov-mark

@makegov-mark makegov-mark Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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: ListBudgetAccountsOptions now carries all 96 contract params (the 26 numeric range-triplet families plus categorical variants); getGsaElibraryContract detail method; has_awards on PSC; and explicit typed props for every filter previously reachable only through index signatures (key on contracts/IDVs/OTAs, cage on entities, verbatim naics_code on protests, previous_uii on IT Dashboard, and more). Along the way this fixed a real bug: the legacy fiscal_year_gte/fiscal_year_lte/account_title budget 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.tssrc/shapes/generatedOverlay.ts) closes all 416 reverse shape-coverage gaps to zero; PaginatedResponse gains optional meta diagnostics with parsed agencyWarnings/unresolvedAgencyTokens/resolvedAgencies; TangoValidationError gains structured issues/availableFields; entity relationships(type, source) shapes are covered.

Conformance architecture (mirroring python's): the API contract is vendored at contracts/filter_shape_contract.json and 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 fetchImpl with 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/listIdvSummaryAwards sections); package-lock.json is committed and CI/publish use npm ci; the dead legacy .eslintrc.cjs is gone; the repo gets a real CLAUDE.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 joiner param leak in the first cut of the new list methods, since collapsed into shared _shapedPaginatedList/_shapedGet helpers).

Risks / notes

  • The new PaginatedResponse diagnostic fields are optional, so existing consumer literals keep compiling; the SDK always populates them.
  • New budget filter options use the API's dunder wire names (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.
  • Overlaps with SBA OHA on protests: naics_code filter, five OHA fields, conformance mapping #12 (SBA OHA protests): this branch adds the same verbatim naics_code protest filter, so whichever lands second has a trivial merge.
  • events/news remain 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

vdavez and others added 7 commits August 14, 2026 11:33
…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>
@vdavez
vdavez merged commit 147d7fb into main Aug 14, 2026
7 checks passed
@vdavez
vdavez deleted the feat/python-parity branch August 14, 2026 18:08
@makegov-mark makegov-mark Bot mentioned this pull request Aug 14, 2026
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>
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.

1 participant