Skip to content

Commit 6bf7d65

Browse files
vdavezclaude
andcommitted
feat(dibbs,exclusions,sbir): add SDK support + refresh stale contract
The vendored API contract had gone stale by seven resources — it tracked 25 against Tango's current 32 — so both the conformance and shape-coverage checks were validating against out-of-date truth. They could not see DIBBS, exclusions, SBIR, or budget/accounts at all. Refreshing it surfaced those six unimplemented endpoint families plus 72 additional fields on existing resources. Add full SDK support for the six families Tango shipped in v4.16-v4.18: list_/get_ pairs for dibbs rfqs, rfps and awards, exclusions, and SBIR topics and solicitations, with all 85 filter params, shape schemas, ShapeConfig defaults, and new DibbsRfq/DibbsRfp/DibbsAward/Exclusion/SbirTopic/SbirSolicitation models. Documents the two API behaviors that bite: is_open / is_currently_excluded are derived at query time (filter with open/active instead), and DIBBS total_contract_price is the order total repeated per line item — never sum it. Fix the conformance checker's false stale-param reports. It resolved SDK args to API params only through an explicit api_param_mapping dict, so methods expressing the translation as tuple tables looked like they exposed ~55 params the API rejects. They do not — list_budget_accounts correctly sends apportioned__gte and account_title__icontains. The checker now understands both tuple forms across Assign, AnnAssign and inline for-iterables, with api_param_mapping still winning. That let budget/accounts be conformance-checked for the first time; its real missing lookup variants are baselined. Also allowlists budget/accounts `search`, which the endpoint honors but the contract omits (verified live). Verified: 450 tests pass, mypy clean, ruff clean, conformance passes with 0 errors, shape-coverage gate at 0, and all 12 new methods exercised against the live API (list + detail round-trip for each family). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e203c2b commit 6bf7d65

11 files changed

Lines changed: 10858 additions & 5573 deletions

CHANGELOG.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- **DIBBS, exclusions, and SBIR/STTR endpoint support.** Six endpoint families
12+
Tango shipped in v4.16–v4.18 had no SDK support at all — no models, no methods.
13+
Added `list_dibbs_rfqs`/`get_dibbs_rfq`, `list_dibbs_rfps`/`get_dibbs_rfp`,
14+
`list_dibbs_awards`/`get_dibbs_award`, `list_exclusions`/`get_exclusion`,
15+
`list_sbir_topics`/`get_sbir_topic`, and
16+
`list_sbir_solicitations`/`get_sbir_solicitation`, with all 85 filter params,
17+
shape schemas, and `ShapeConfig` defaults. New models: `DibbsRfq`, `DibbsRfp`,
18+
`DibbsAward`, `Exclusion`, `SbirTopic`, `SbirSolicitation`.
19+
20+
Two API behaviors are worth knowing. `is_open` (DIBBS) and
21+
`is_currently_excluded` (exclusions) are derived at query time, so filter with
22+
the `open` / `active` kwargs rather than shaping on those fields. And DIBBS
23+
`total_contract_price` is the *order* total repeated on every line item —
24+
never sum it across rows; deduplicate on award + delivery-order number first.
1125
- **Reverse shape-coverage: the SDK now captures every field and expand the API
1226
returns.** The conformance check only validated one direction — that the SDK's
1327
shape constants reference *allowed* fields. Nothing checked the reverse, so the
@@ -33,6 +47,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3347
Regenerate the overlay with `scripts/generate_shape_overlay.py` (from the vendored
3448
contract + `contracts/observed_shape_types.json`, no API key); refresh the type
3549
observations with `scripts/probe_shape_types.py` (maintainer-run, needs a key).
50+
51+
### Fixed
52+
- **Refreshed the vendored API contract, which had gone stale by seven
53+
resources.** It tracked 25 resources against Tango's current 32, so the
54+
conformance and coverage checks were validating against out-of-date truth and
55+
could not see DIBBS, exclusions, SBIR, or `budget/accounts` at all. Refreshing
56+
it also surfaced 72 additional fields on existing resources, now covered.
57+
Nested routes are keyed with a slash (`budget/accounts`), which silently broke
58+
the old `budget_accounts` mapping — both keys are now accepted.
59+
- **`check_filter_shape_conformance.py` no longer reports false stale params.**
60+
It resolved SDK arguments to API params only through an explicit
61+
`api_param_mapping` dict, so methods that express the translation as tuple
62+
tables — `("account_title__icontains", account_title)` and
63+
`range_filters = (("apportioned", apportioned, apportioned_gte, ...))` — looked
64+
like they exposed dozens of params the API rejects. They do not:
65+
`list_budget_accounts` correctly sends `apportioned__gte`, `fiscal_year__lte`,
66+
and `account_title__icontains`. The checker now understands both tuple forms
67+
(in `Assign`, `AnnAssign`, and inline `for` iterables), with an explicit
68+
`api_param_mapping` still taking precedence. This let `budget/accounts` be
69+
conformance-checked for the first time; its genuinely missing lookup variants
70+
(`agency_code__in`, `bureau_name__icontains`, …) are now baselined.
71+
72+
### Added
3673
- **Contract-first conformance system.** The canonical API filter/shape
3774
contract is now vendored at `contracts/filter_shape_contract.json` (refresh
3875
with the new `scripts/refresh_contract.py`), so the conformance check runs
Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
11
{
22
"_comment": "Accepted SDK coverage gaps vs the API contract. Params listed here downgrade from error to warning in scripts/check_filter_shape_conformance.py. Each entry is tracked backlog: remove it in the same PR that adds the param to the SDK. Run the checker with --suggest for ready-to-paste typed parameter scaffolds.",
33
"missing_filters": {
4-
"contracts": ["key"],
5-
"entities": ["cage"],
6-
"forecasts": ["id"],
7-
"idvs": ["key"],
8-
"opportunities": ["opportunity_id"],
9-
"otas": ["key"],
10-
"otidvs": ["key"]
4+
"contracts": [
5+
"key"
6+
],
7+
"entities": [
8+
"cage"
9+
],
10+
"forecasts": [
11+
"id"
12+
],
13+
"idvs": [
14+
"key"
15+
],
16+
"opportunities": [
17+
"opportunity_id"
18+
],
19+
"otas": [
20+
"key"
21+
],
22+
"otidvs": [
23+
"key"
24+
],
25+
"budget/accounts": [
26+
"agency_code__in",
27+
"bea_category__in",
28+
"bureau_name__icontains",
29+
"bureau_name__in",
30+
"federal_account_symbol__in",
31+
"fiscal_year__in",
32+
"subfunction_code__in"
33+
]
1134
}
1235
}

0 commit comments

Comments
 (0)