Problem
In 3.0 we unified on policy-entry.json as the shape for all policies (registry-published and buyer-authored), and established policy_id as the universal cross-surface pointer (governance findings, validation feature verdicts, etc.).
What's missing: when a buyer adds a property filter or creative constraint because of a policy, there's no way to tag the filter with its authorizing policy. The mechanism and the policy are decoupled — which means audit trails can't answer "why does this property list exclude children's programming?" without human interpretation.
Proposal
Add optional policy_id: string to the schemas that define mechanism-level constraints:
static/schemas/source/core/feature-requirement.json — feature predicates used by property list filters today (and other surfaces in the future)
static/schemas/source/creative/creative-feature-result.json — creative feature measurements
- Any audience-filter schemas where buyers author targeting constraints
Example:
```json
{
"feature_requirements": [
{
"feature_id": "audience_children_composition",
"max_value": 15,
"policy_id": "uk_hfss"
}
]
}
```
Why bottom-up tagging (not top-down in policy-entry)
Considered an alternative: add `implementation_hints.property_filters[]` to policy-entry so policies declare their mechanisms. Rejected because:
- Audit trail is natural bottom-up. Looking at a filter and asking "why is this here?" — answer lives on the filter itself, not in a remote policy declaration.
- Policies stay thin. PolicyEntry doesn't need to know about every tool that might implement it.
- Extends the pattern we already committed to in 3.0. `policy_id` is the universal pointer across findings, validation verdicts, validation features. Adding it to mechanism-level constraints is consistent.
Use cases enabled
- Audit: "Why is this property list filtering out children's audiences?" → `policy_id: uk_hfss`, look it up in registry.
- Compliance reporting: group filters and constraints by authorizing policy.
- Governance agents: when emitting findings, populate `policy_id` on the finding from the underlying filter's `policy_id`.
- Policy lifecycle: when `uk_hfss` sunsets (via `sunset_date`), identify all constraints that cite it and notify buyers to remove them.
Non-breaking
Purely additive. Optional field. 3.0 clients populate nothing; 3.1 clients populate when applicable. No schema surgery on existing fields.
Related
Scope for 3.1
Problem
In 3.0 we unified on
policy-entry.jsonas the shape for all policies (registry-published and buyer-authored), and establishedpolicy_idas the universal cross-surface pointer (governance findings, validation feature verdicts, etc.).What's missing: when a buyer adds a property filter or creative constraint because of a policy, there's no way to tag the filter with its authorizing policy. The mechanism and the policy are decoupled — which means audit trails can't answer "why does this property list exclude children's programming?" without human interpretation.
Proposal
Add optional
policy_id: stringto the schemas that define mechanism-level constraints:static/schemas/source/core/feature-requirement.json— feature predicates used by property list filters today (and other surfaces in the future)static/schemas/source/creative/creative-feature-result.json— creative feature measurementsExample:
```json
{
"feature_requirements": [
{
"feature_id": "audience_children_composition",
"max_value": 15,
"policy_id": "uk_hfss"
}
]
}
```
Why bottom-up tagging (not top-down in policy-entry)
Considered an alternative: add `implementation_hints.property_filters[]` to policy-entry so policies declare their mechanisms. Rejected because:
Use cases enabled
Non-breaking
Purely additive. Optional field. 3.0 clients populate nothing; 3.1 clients populate when applicable. No schema surgery on existing fields.
Related
Scope for 3.1