Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
tnunamak
force-pushed
the
spec/client-terms-myterms-0903
branch
from
September 3, 2026 22:16
7d713df to
1d10f25
Compare
Two entries in spec-deferred.md called this prior art "ISO MyTerms." It is not an ISO standard. It is IEEE P7012, published in January 2026 as IEEE 7012-2025, "Standard for Machine Readable Personal Privacy Terms." Leaving the wrong name in a normative-adjacent document sends a reader looking for a standard that does not exist, and it hid the fact that the thing is now published rather than a draft we could ignore. The deeper gap was that the entry said MyTerms "has not been evaluated for fit," which left open whether PDPP was quietly drifting into an incompatibility. This adds an informative entry that does the evaluation. MyTerms inverts the usual direction of an online agreement: the individual is the first party and offers privacy terms, and the service provider is the second party that accepts one. The terms are not written per relationship — they are picked from a roster kept by a neutral non-business entity (today Customer Commons), where each term is a versioned dereferenceable URL. Against that model a PDPP grant is already the recorded agreement on the owner's side: it is immutable, it names the second party, and it carries the recipient-side commitments as structured fields (purpose_code, retention, access_mode) rather than prose. The entry states the two places the analogy breaks — MyTerms expects both sides to hold a record where PDPP defines only the authorization server's copy, and MyTerms allows a counter-offer where a PDPP grant is issued after consent rather than negotiated — so a later reader does not overclaim the fit. It also names the thing that would actually cause incompatibility: inventing a PDPP-specific vocabulary for terms a roster already names. We do not have that problem today, because purpose_code is an absolute URI the authorization server must accept even when it does not recognize it, so a rostered term is already expressible with no schema change. That is the positive path, and keeping purpose_code open is what preserves it. No Core change and no v0.1 commitment: the roster is small and the second-party record format is unsettled, so this records the analysis and the hedge rather than a dependency. The same wrong name also appears twice in the 2026-08-20 working-session notes. Those are left alone deliberately — they are a dated record of what was said in the room, not a statement of fact about the standard. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…s shown An owner approving a PDPP grant may be shown the requesting application's privacy policy and terms-of-service links, or may not be. Core left both halves of that soft. It said the authorization server "MAY display them as secondary links," and it never required the server to keep any trace of which links it put in front of the owner. So an owner who later disputes what a company was allowed to do with their data has no record of the terms they were pointed at when they agreed, and the server has no way to show one. Two changes, and the first is smaller than it looks. RFC 7591 Section 2 — the OAuth client-registration metadata vocabulary that Core already borrows `policy_uri` and `tos_uri` from — says of each field that "the authorization server SHOULD display this URL to the end-user if it is provided." Core's MAY was therefore weaker than the source it cites, which was a drafting slip rather than a decision. Raising it to SHOULD restores the strength the borrowed vocabulary already carries. The second change is a real addition: where the server displayed either link, the issued grant MUST carry the exact displayed values in `client.client_display`. This needs no new field. The grant schema already has an optional `client_display` holding server-resolved requester identity metadata, with `policy_uri` and `tos_uri` among its members — it was simply never obligatory to populate them. The rule also says a value the server resolved but did not show MUST NOT be recorded as displayed, so the record stays a record of the consent surface rather than of the server's internal lookup. That evidence is deliberately bounded, and the text now says so rather than overselling it. A recorded URI shows which documents the owner was pointed at, not what those documents said, because the target belongs to the client and can change after issuance. ISO/IEC 29184:2020 Section 5.2.8 — the ISO standard on online privacy notices and consent — sets the stronger bar, requiring that an organization "shall keep and make available the version of the notice presented when the PII principal gave consent." Core points deployments at that as a SHOULD instead of mandating it, because retaining the version means fetching and storing third-party documents: a real deployment cost and a new outbound-fetch surface, neither of which is an authorization semantic. Separately, a client requesting the `ai_training` purpose must now have a `policy_uri` in its resolved metadata, and the server must reject the request otherwise. Training on someone's personal data is already the one purpose code where Core treats consent as protocol-enforced rather than advisory, and consent to it is not informed if there is nowhere to read how the recipient handles the data. The requirement is on the resolved metadata, not on the inline request, so a client the server already knows through registration or a validated binding does not have to resend it. Confidence is uneven across the three and worth flagging for review. The SHOULD-display realignment is near-certain — it is what the cited RFC says. The recording obligation is well-precedented in the consent-receipt lineage (ISO/IEC 29184, Kantara Consent Receipt) but has no precedent in the OAuth or OpenID Connect family, so it is a genuine extension of that lineage rather than a gap-fill. The `ai_training` policy_uri rule is the weakest of the three: no regime found names AI training as a trigger for a heightened privacy-policy requirement, so it rests on Core's own existing decision to single that purpose out, not on outside prior art. Verified: `pnpm spec:check`, which regenerates the site's spec pages from these root files and fails on any drift between them, passes. `pnpm spec:dates` fails only on spec-reference-implementation-examples.md, a file this branch does not touch and which was already failing on origin/main. No reference-implementation code changes here; the consent card in packages/operator-ui renders neither link today, so the SHOULD-display rule describes work that surface has not done yet. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
An independent judge reviewed the two stances on offer for terms support and chose S1 over S2 (disagreeing with the research's own S2 recommendation at 82/100 confidence). S2 would have added an optional `agreement` object to the grant now. The judge's decisive reason: the argument for adding it early rested on RFC 9396 Section 5, which constrains what a *client* may send in an authorization request, while the proposed field was grant-side only. So Section 5 neither forces nor eases that field, and adding it would standardize a record shape before the flow that produces it exists — there is no client publishing accepted terms, no publication surface, and no acceptance step anywhere today. This is S1: say precisely how PDPP relates to the standards in question, and record the design a future version should implement, without inventing fields for it now. Section 1 gains four relationship rows. IEEE 7012-2025 (MyTerms) says a PDPP grant records an authorization and could later reference an agreement; it deliberately stops short of calling every grant an agreement record, which would overstate what the grant is. W3C DPV 2.3 is named for its consent-record vocabulary, and its extension for IEEE 7012 is described as live — it ships in DPV 2.3 as `STANDARD-IEEE-7012`, which corrects an earlier claim that the extension had been stranded at an old draft; the row keeps the caveat that DPV is a Community Group report and not a W3C standard. ISO/IEC TS 27560 is named as a deferred export mapping, and says PDPP records a notice reference only where a link was actually displayed, rather than claiming every grant carries 27560's mandatory notice field. ISO/IEC 29184 is kept as written, because it is the citation that explains why a recorded URI is weaker evidence than a retained version. ODRL was proposed as a fifth row and is deliberately omitted: the mapping is speculative and no v0.1 field depends on it. The UMA row gains one clause noting that UMA puts the resource owner's policy outside its own scope, which is why PDPP's structured commitments are an addition rather than a divergence. The deferred MyTerms entry drops the `purpose_code` route it previously offered as the positive path, and now warns against it: an agreement URI is a syntactically valid purpose code, so the route is legal and still wrong, because purpose and agreement are separate objects everywhere and the `ai_training` rule switches on the purpose code's value. In its place the entry records the two-sided design a future version should implement. The client publishes the rostered terms it accepts in its client metadata document. The authorization server holds the rostered term the owner chose from the IEEE 7012 roster. At grant time the server matches the two mechanically, with no negotiation round trip. The grant records the matched term — URI, version, acceptance time — in a future optional `agreement` object that introspection echoes. PDPP defines no terms vocabulary of its own, at this version or any later one; that is the thing that would create incompatibility with a roster-based standard. The entry also records why the request side is the half that needs a version to land in: RFC 9396 Section 5 requires the authorization server to reject an authorization details object of known type carrying unknown fields, so a request-side carrier cannot be adopted incrementally by clients and must be defined in the `https://pdpp.dev/data-access` type when that version arrives. The grant-side and metadata-side halves carry no such constraint. The client `policy_uri`/`tos_uri` display-and-record change from the earlier commits on this branch is unchanged. Verified: `pnpm spec:check` passes; `pnpm spec:dates` passes (the unrelated stale-date failure this branch reported earlier was fixed on main); and the spec prose gate, which merged into main after the earlier commits here, now reports no new findings against a merge-base baseline. That last one also required rewriting four over-long sentences this branch had itself introduced before the gate existed. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Applying a weight test to the rows this branch added: a row in Section 1's standards table earns its place only if it explains something the spec does today, or names a bar the spec is measured against. A row that is merely adjacent and interesting is table weight without a reader benefit. Four rows went in; three survive that test. ISO/IEC 29184 stays as written. It is the reason Core records what was displayed rather than treating a bare URI as sufficient evidence, so it explains a rule the spec already carries. ISO/IEC TS 27560 stays as the deferred consent-record mapping, and now absorbs what the separate DPV row was carrying. The Data Privacy Vocabulary did not describe anything Core does today: it is the vocabulary such a mapping would be expressed in, which makes it a detail of the 27560 row rather than a relationship of its own. Naming it inside that row keeps the useful part — DPV keeps purpose, consent, and the consent record as distinct classes the way PDPP does, and its consent record points at a notice object rather than a bare URL — and keeps the caveat that DPV is a Community Group report and not a W3C standard. The separate row is dropped. IEEE 7012 shrinks to the two short sentences that carry the load: the individual proffers terms as the first party and both sides keep a matching record, and a PDPP grant records an authorization rather than an agreement and could later reference one. The conformance disclaimer and the counter-offer detail move out of the table; the deferred entry in spec-deferred.md already states both at length, and repeating them in a one-line-per-cell table was duplication rather than emphasis. The row is worth keeping at this size because the question it answers came out of workshop feedback, so a reader arriving at the table will look for it. ODRL is not added. It describes no current PDPP surface and the mapping to it is speculative, so it fails the same test. One consequential follow-on: the deferred entry's closing line listed the four standards Section 1 relates to. It now lists three, because claiming a DPV row that no longer exists would send a reader looking for it. Verified: pnpm spec:check, pnpm spec:dates, and the spec prose gate against a merge-base baseline all pass, the last reporting no new findings. Writing the IEEE row as a single sentence tripped the gate's 25-word cap at 43 words, so it is two sentences. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
tnunamak
force-pushed
the
spec/client-terms-myterms-0903
branch
from
September 10, 2026 22:12
07fd2de to
128d32e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A grant is the durable record of consent, but it never had to say which privacy policy and terms the owner was shown before approving. If the owner later disputes what the client did with their data, neither side can establish which documents were on screen at approval. This adds the display and recording obligations in
spec-core.mdand corrects a prior-art entry inspec-deferred.md. Three obligations change, each at a different confidence.Client terms links
policy_uriandtos_uririse from MAY-display to SHOULD-display. RFC 7591 Section 2, which Core cites as the source of these two field names, already says the AS SHOULD display each URL when provided, so Core stated a weaker obligation than the vocabulary it reuses.The AS MUST now record the exact displayed values in the grant's
client.client_display, and MUST NOT record a resolved-but-undisplayed value as displayed. That way the grant captures the consent surface rather than the server's lookup. The text also bounds what the record is worth: a recorded URI establishes which documents the owner was pointed at, not what they said, because the target is under client control and can change after issuance. Retaining a snapshot or digest stays a SHOULD, citing ISO/IEC 29184:2020 §5.2.8 as the stronger bar, because fetching and storing third-party documents is a deployment cost and a new outbound-fetch surface rather than an authorization semantic.Last, an
ai_trainingrequest MUST havepolicy_uriin resolved metadata or the AS rejects it. Core already treats that purpose as the only one with protocol-level mandatory consent, and this attaches the policy link to it. No outside regime I found names AI training as a trigger for a heightened policy requirement, so this rests entirely on Core's own decision to single that purpose out. Push back here first.MyTerms and the agreement standards
The deferred entry for this prior art named the wrong body and the wrong status: it is IEEE 7012-2025, published January 2026, not "ISO MyTerms".
No protocol field is added. An optional grant-level
agreementobject was considered and rejected: nothing publishes accepted terms today and no acceptance step exists, so the field would fix the shape of a record before the flow that produces it. Instead the entry records the two-sided design a future version should implement — the client publishes the rostered terms it accepts, the AS holds the term the owner chose, and the AS matches the two at grant time with no negotiation round trip.The entry also rules out
purpose_codeas the route to a rostered term. An agreement URI is a syntactically valid purpose code, so that route is legal and still wrong: theai_trainingrule switches on that field's value, and an agreement URI there defeats it.Three citation rows are added, each explaining a rule Core now carries or naming a bar Core is measured against. ISO/IEC 29184 is why a recorded URI is weaker evidence than a retained version. ISO/IEC TS 27560 is named as a deferred export mapping. IEEE 7012 is why a PDPP grant records an authorization rather than an agreement.
Not verified
The reference implementation is untouched.
packages/operator-ui/src/components/pdpp/consent-card.tsxrenders neither link today, so the new SHOULD-display rule describes work that surface has not done, and this PR adds no conformance test for it.Every standards citation here is second-hand, read through public previews and DPV's published mapping guide rather than the paywalled normative text, and each row is written to survive that. None makes a conformance claim: the TS 27560 row names four sections and defers the mapping rather than citing a clause, and the IEEE 7012 row states a relationship only.
pnpm spec:checkandpnpm spec:datespass on a rebase ontoorigin/main.Assisted-by: AI