diff --git a/CHANGELOG.md b/CHANGELOG.md index f00fe73..b47882b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- **`relationships(type, source)` on entities.** Tango API 4.20.0 added two keys to each entry in the entity `relationships` expand: `type`, the stable relationship-type code (`prime_sub`, `parent_subsidiary`, `ultimate_parent`, `predecessor`), and `source`, where the tie came from (`sam`, `subawards`). Both are shape-selectable, so `shape="uei,relationships(type,source,uei)"` now resolves against the SDK's schema. Re-vendored the contract and regenerated the shape overlay; the coverage gate reports 0 gaps. + +### Changed +- **The `relation` value vocabulary changed upstream — match on `type` instead.** In Tango API 4.20.0 the `relation` label stopped collapsing to `affiliate` for subcontracting and corporate-succession ties and now names the partner's role: `subcontractor` / `prime`, `predecessor` / `successor`, and `descendant` (rather than `child`) on the far side of an ultimate-parent tie. `affiliate` survives only as a fallback for a type the API doesn't recognize. This affects the large majority of relationship entries. + + No SDK code change is required — `relation` was and remains a `str`. But if you have application code branching on the string `affiliate`, switch it to `type`, which is stable and won't churn again. See the [entities data dictionary](https://docs.makegov.com/data-dictionary/entities/#relationships) for the full vocabulary table. + ## [1.4.0] - 2026-07-20 ### Added diff --git a/contracts/filter_shape_contract.json b/contracts/filter_shape_contract.json index 966ae93..ad569c8 100644 --- a/contracts/filter_shape_contract.json +++ b/contracts/filter_shape_contract.json @@ -1,5 +1,6 @@ { "meta": { + "api_version": "4.20.0", "description": "Canonical API filter/shape contract. Downstream consumers (SDK, MCP) should validate their conformance against this manifest.", "generated_from": "scripts/filter_shape_conformance.py", "schema_version": 2 @@ -2511,6 +2512,8 @@ "fields": [ "display_name", "relation", + "source", + "type", "uei" ] }, @@ -2685,6 +2688,8 @@ "relationships", "relationships.display_name", "relationships.relation", + "relationships.source", + "relationships.type", "relationships.uei", "sam_activation_date", "sam_expiration_date", diff --git a/tango/shapes/generated_overlay.py b/tango/shapes/generated_overlay.py index 4a93d0f..2b0d47f 100644 --- a/tango/shapes/generated_overlay.py +++ b/tango/shapes/generated_overlay.py @@ -716,6 +716,8 @@ RELATIONSHIPS_SCHEMA: dict[str, FieldSchema] = { "display_name": FieldSchema(name="display_name", type=str, is_optional=True, is_list=False), "relation": FieldSchema(name="relation", type=str, is_optional=True, is_list=False), + "source": FieldSchema(name="source", type=str, is_optional=True, is_list=False), + "type": FieldSchema(name="type", type=str, is_optional=True, is_list=False), "uei": FieldSchema(name="uei", type=str, is_optional=True, is_list=False), }