policy_id to record the authorizing policy. Governance findings echo the same policy_id when emitting denials, so the trace runs end-to-end.
Three surfaces, one pattern
All three fields are optional. The first two were reserved in 3.0 GA; populating them in 3.1 is non-breaking for strict 3.0 validators. The third has been present on validation-result since 3.0.
When to populate policy_id
Populate policy_id when the filter or measurement exists because of a specific authorizing policy — and the producer chose the specific mechanism as their encoding of that policy.
Do not populate policy_id when the policy merely applies in general. Plan-level policy applicability is declared on the plan itself via policy_ids[] (sent to the buyer’s governance agent through sync_plans). The filter-level field is for mechanism authorship, not blanket applicability.
Plan-level vs filter-level
These are different jobs:
Only the third row carries filter-level
policy_id. The first two rows already capture intent at higher abstraction levels — the registry feature ID is itself the policy reference in the second case.
Round-trip via governance findings
The attribution loop runs filter → governance agent → finding → audit. The agent acting on the buyer’s plan callscheck_governance; depending on phase, this is either an intent check (orchestrator-side, before commitment) or an execution check (seller-side, before binding planned delivery). Both paths produce findings with the same shape.
policy_id on findings by reading the underlying requirement.
Contract for producers
Buyer (or buyer’s compliance tooling) authoringfeature-requirement:
- SHOULD populate
policy_idwhen the requirement encodes a specific policy threshold the buyer chose. - SHOULD NOT populate
policy_idwhen the requirement is a general feature filter unrelated to any policy. - MUST reference a
policy_idthat resolves either in the policy registry or in the plan’scustom_policies[].
creative-feature-result:
- SHOULD populate
policy_idwhen the feature was measured for the purpose of a specific policy evaluation. - SHOULD NOT populate
policy_idwhen the feature is a generic measurement (carbon score, brand consistency) unrelated to any policy.
- SHOULD echo
policy_idon findings when the underlying violation traces to a filter or measurement carryingpolicy_id. - MUST NOT invent a
policy_idthat wasn’t present on the originating filter — findingpolicy_idis for traceability, not for declaring new policy applicability (that belongs inpolicies_evaluated[]).
Worked examples
UK HFSS — buyer-encoded threshold
The buyer’s compliance team interprets UK HFSS as “audience must be less than 15% children.” They encode that interpretation as a feature requirement:COPPA — delegated to the seller’s registry feature
The buyer doesn’t pick a threshold for COPPA — they delegate the evaluation entirely. Theregistry: prefix is a feature-naming convention (see property-feature-definition and Policy Registry) where the feature ID registry:<policy_id> references a standardized policy directly:
policy_id: "us_coppa" here would be redundant — and would imply the buyer authored the mechanism, when in fact they delegated it.
Creative measurement — agent records the why
A creative agent evaluates a creative for HFSS compliance and records:policy_id answers “why did this evaluation run?” Anyone reviewing the creative’s measurement history can correlate this result with the originating policy.
When this result fails the creative-level governance check, the governance agent’s finding echoes the same policy_id:
policy_id across both records.
What attribution does not cover
- Top-down policy declaration from buyer to seller. When the buyer wants the seller to apply specialized handling for a policy (HIPAA vendor, COPPA dataset) without the buyer encoding the mechanism, that’s a separate surface tracked in #4629.
- Per-criterion attribution on audience selectors. Audience exclusions in a plan should be derived from plan-level
policy_ids[]by the buyer’s governance agent — not hand-authored by buyers and tagged with policy authority. Audience-selector schemas do not carrypolicy_id. - Per-criterion attribution on the targeting overlay. Targeting fields (
geo_countries_exclude, age restrictions, device platforms) use flat arrays without a per-entry shape; per-criterion attribution would require schema restructuring. Use plan-level declaration for these constraints.
See also
- Policy Registry — the shared library of
policy_ids - Policy Registry Sync — how plans reference policies via
policy_ids[]andcustom_policies[] check_governance— where findings are emitted withpolicy_idtraceability