[10/10] docs(spec): stamp Date headers for this stack's changes - #299
Closed
tnunamak wants to merge 12 commits into
Closed
[10/10] docs(spec): stamp Date headers for this stack's changes#299tnunamak wants to merge 12 commits into
tnunamak wants to merge 12 commits into
Conversation
…ent shape
spec-core.md told a resource server to return stream metadata "whole
rather than field-projected by the grant" for GET /v1/streams/{stream}.
That sentence was written for an owner reading their own data, where
there's no grant to project against, but it applied unqualified to a
client-token request too. A resource server built strictly from that
prose would hand an approved app every current field, query capability,
view, and relationship a data source declares -- not just the ones the
user actually consented to. The reference implementation already does
the opposite for client tokens: it returns a closed projection scoped to
the frozen grant. An independent post-merge review of PR #243 (see
local/pdpp-pr243-retroactive-independent-review-2026-08-29.md) flagged
this as the one P1 left after that PR's owner-filter fixes landed.
This is a fix-forward on that review, not a rollback:
- spec-core.md: split "Get stream metadata" into owner (full current
metadata, unchanged) and client (closed grant projection: granted
fields only, no current query/view/relationship/expansion/aggregation
capability, and a post-grant declaration addition never becomes
visible) response shapes, with two separate example bodies. Extended
RS conformance (Section 9, items 14-15) and the plain-English
grant-enforcement algorithm / trust-boundary table (Section 8/10) to
branch on pdpp_token_kind instead of reading as if every request needs
a grant. Split the GET /v1/streams "under the current grant" sentence
the same way.
- reference-implementation/test/spec-metadata-projection-consistency.test.ts:
pins the three RI fixture facts the review named against a live
server -- owner gets full capabilities, client gets only frozen grant
fields, a field added after grant issuance stays invisible to that
grant.
- .github/workflows/spec-check.yml: wires the existing but previously
CI-unused `pnpm spec:owner-filter-check` scanner into the spec-check
job, per the review's own follow-up ask.
- spec-data-query-api.md / its site header: relabels the
self-contradictory "(original)" date tail to "(last corrected)" --
the file can't have originated four months after it was superseded.
Verified: pnpm spec:check, spec:dates, and spec:owner-filter-check all
pass; the new test file and the existing
reference-implementation/test/query-contract.test.ts (61 tests) pass
unmodified against the reference implementation; tsc --noEmit clean.
Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Assisted-by: AI
Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
OWNER-DECISION: normative. Not ratified. Source: owner alignment 2026-09-02 17:05 (OWNER-COMMITMENTS.md rows 68-69); research in local/CIMD-STANDARDS-ANSWER-0902.md and ai/research/protocols/oauth-client-id-metadata-documents-vs-gnap-client-identity-2026-09-02.md. Row 68 recorded the gap: spec-core.md never addresses client ID metadata documents (CIMD), the mechanism deployed MCP clients such as ChatGPT actually use. Core knew only RFC 7591 vocabulary and "dynamic self-registration when registration_endpoint is advertised". Three things were undefined: where CIMD-derived name and logo rank in the client_display precedence, whether a fetched https document counts as the "domain verification" obligation 4 names only as an example, and who owes the fetch and validation obligations. Row 69 set the shape of the answer: the OAuth binding is where dynamic registration and CIMD are required, so Core stays binding-neutral and adds only what a binding-neutral core can state. Three changes: 1. Section 1's standards table gains a CIMD row, recording that MCP 2025-11-25 ranks CIMD SHOULD and RFC 7591 DCR MAY (backward compatibility), and that the fetch/validation obligations sit in the binding, not in Core. 2. Section 6 defines "validated binding metadata" and inserts it into the requester-identity precedence between validated software statements and inline client_display. The rationale is stated in the text: the AS checked it; the client did not merely assert it. 3. Obligation 4's parenthetical becomes "verified domain control", and a new obligation 5 defines what verified domain control is and constrains how it may be presented: name the domain, never claim an unqualified "verified app", and never imply review of the client's conduct. This matches the trust-model decision at OWNER-COMMITMENTS.md row 64. RFC 7591 field names are kept verbatim inside client_display, per row 69. Obligations 5 and 6 renumber to 6 and 7; no other text changed. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…open OWNER-DECISION: normative only in that it changes what v0.1 claims to have decided. Not ratified. Sources: - Geneva notes (d), Anna, relayed 2026-09-02: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1788337128917169 "derivative data should be in scope. PDPP doesn't have an answer for derivative data." - Geneva notes (e), Art, same message: users will want to grant by category across sources ("my health data", not five named providers), similar to PDPP's views within a source. Standards to look at were cited but not named in the message; the candidate list is recorded as unevaluated. - Art, 2026-09-02: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1788351571550459 ToIP's Trust Registry Query Protocol; expose the register as a TRQP endpoint from phase 2, DTI recognition becomes a TRQP query. Explicitly "a design commitment, not a date" — it is in public review with no test suite. Three entries added to spec-deferred.md's open design questions, and two rows added to Core's Section 12 out-of-scope table so the first two are findable from Core. Anna's observation that (d) and (e) are related is not folded into one entry. Granting "my health data" across providers is a vocabulary and scope-widening problem; whether an embedding of those records needs its own grant is an authorization-object problem. They meet in the case where a category is defined by derivation rather than by source, and each entry names the other's neighbourhood, but merging them would hide two questions inside one. The derivative-data entry states that v0.1's silence is not permission. That is the sentence to argue with if any of this is wrong: it is the only place these three entries make a claim rather than record a question. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…gateway OWNER-DECISION: normative (adds one SHOULD NOT). Not ratified. Sources: Geneva notes (c) and (f), relayed 2026-09-02: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1788337128917169 and the owner's clarification in-thread: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1788342568209169 "the spec could refer to authorization and resource servers without defining how data gets into the resource server ... The Collection Profile spec can define how data connectors can get data into a resource server." Note (f) asked for a sanity check on a personal server acting as a gateway to platform data using an owner credential against the platform's PDPP API. Two additions to Section 3, after Example B. First, Core states plainly that it defines no ingest path and that conformance does not depend on one. Section 3 already called its two examples a spectrum rather than a closed set; this says the same thing as a statement about Core's scope rather than as a caveat about the examples. Second, the gateway idea is recorded as already permitted, because it is: the personal server is a conformant client in the first relationship and a conformant resource server in the second. Nothing new is needed to build it. The open part is not whether it works but what the onward grant may say about the originating one, so the paragraph names that question and adds an interim SHOULD NOT against issuing an onward grant broader or longer than the grant the records arrived under. WHAT THIS DOES NOT DO, and why: The instinct in note (c) was that connectors and native mode "are currently superficial and can be edited out of the core spec entirely". They are not superficial, and this branch does not remove them. `source.kind` is a required field of the source declaration, its two values are validated against the accepted declaration before consent, a mismatch is a Source validation failure, and the derived provenance is recorded in consent evidence and in the issued grant. Art's open #283 adds a further normative rule keyed on `provider_native`. Removing `source.kind` is a breaking change to the declaration schema and the grant, not an editorial deletion, and it would conflict with #283 rather than compose with it. What note (c) actually asked for -- that Core not define how data reaches the resource server -- is what this commit states, and what #283 delivers from the other direction by making the Collection Profile informative. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…ated one OWNER-DECISION: normative. Not ratified. Revises the gateway paragraph added earlier on this branch (8e0d96a) rather than adding a second one. Source: owner scope addendum 2026-09-02 ~17:40, item C: follow precedent, invent nothing. The earlier commit already said the gateway works and needs no new protocol element. What it did not do was name the precedent or state the negative, and it left the UMA-style topology unaddressed rather than deferred. Three changes: 1. States the negative explicitly: PDPP defines no delegated-grant, sub-grant, or grant-chaining construct, and none is needed. The chain is two independent grants, each issued by the owner, each revocable on its own. A reader who arrives looking for a delegation primitive now finds the answer instead of an absence. 2. Names the precedent rather than reasoning from first principles: open banking aggregators already work this way -- consent at each bank plus consent from the user, not one authorization subdivided. RFC 8693 OAuth Token Exchange is named as the binding-level mechanism where a credential must cross the two relationships, and is explicitly placed in the binding rather than in Core, consistent with how this branch handles CIMD. Plaid is deliberately NOT named. It is the same pattern as the open banking aggregator already cited, and naming a single commercial vendor in a normative specification invites both a fairness objection and a staleness problem. The pattern is what carries the argument. 3. Records the UMA-style topology -- owner runs their own authorization server in front of a platform's data -- as NOT introduced here, and points at spec-deferred.md rather than leaving a reader to wonder whether it was overlooked or excluded. The deferred entry itself is a separate commit. The interim SHOULD NOT on onward grant scope and duration is unchanged from the earlier commit; only its surrounding context moved. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…itions OWNER-DECISION: normative. The sector-regimes paragraph states that the stricter regime governs, which is a requirement, not a description. Not ratified. Source: Art, 2026-08-25, before the GDC handouts printed: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1787815124927929 He asked for two positions to be printable, and asked where the spec says them. Both asks were "is this accurate to the spec, and where do we say it?" -- and for both, the answer was that the spec did not say it. 1. UMA/GNAP. His proposed position, printed here close to his own wording: PDPP is a data-portability profile, not a general authorization framework; it rides OAuth + RAR because that is what is deployed; it adds what neither UMA nor GNAP defines; a GNAP binding is possible later. The standards table already carried the raw material in the UMA and GNAP rows, but as two entries a reader had to assemble. This states the conclusion, and adds the reason a later GNAP binding stays possible: the record model, the grant, and the resource server interface do not depend on the protocol that produced the grant. 2. Sector regimes. Floor, not ceiling. His ask was to confirm the connector model supports the claim as stated. It does, but the specification never said so, and "recognized, plug in via connectors, keep every guarantee" is not derivable from silence. The paragraph states that the stricter requirement governs, that PDPP authorizes no disclosure the source's own regime forbids, and that a PDPP grant does not substitute for a consent that regime requires. Art also asked that (2) be filed as one of the first public review issues, "Recognition of sector-specific consent regimes", so the position lands with a paper trail. That is an issue to open, not a spec edit, and this branch does not open it. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
OWNER-DECISION: not normative. Three open questions recorded, no requirement added or changed. Not ratified. Source: PDPP working session on grants, 2026-08-19, recapped in #vana-org by Kat: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1787246400660469 and in the session summary: https://vana-org.slack.com/archives/C0B9AKY6ZDH/p1787249010667589 The recap listed six questions and named the owner as the next step on several. Grepping the specification set for each: subgrants, change of client ownership, undisclosed sub-processing, ISO MyTerms and bulk export appear nowhere in any spec-*.md file. They existed only in Slack and in the session recording. Three entries are added so they are referenceable from Core and survive the next person who looks. The other two questions in that recap already have homes and are not duplicated here: cursor-based sync prior art (WebDAV report/sync token and the rest) is a design input rather than an open question, and the adoption argument is not a specification concern. Subgrants and change-of-ownership are stated as questions with a v0.1 posture, not as answers. The bulk export entry records that half of it is already decided -- owner self-export is a SHOULD-level RS conformance item in Core Section 9 -- so the open part is only the client-under-grant case. The change-of-ownership entry says `client_claims` is not an ownership record and must not be read as one. That is a reading of the existing trust-boundary text, which already says client claims are self-asserted, unverifiable, and outside the resolved grant. If it reads as a new restriction rather than a restatement, it should be cut. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
…'s own server OWNER-DECISION: normative. Adds a MUST NOT. Not ratified. Source: owner framing relayed 2026-09-02 ~18:10, covering Linear DEL-239 (https://linear.app/vana-team/issue/DEL-239/decide-whether-a-grant-recipient-can-pass-part-of-their-access-to) and its distinction from the topology-B case. Two rules, and the point is the line between them. 1. Onward transfer by a THIRD PARTY is forbidden by default. A client holding a grant MUST NOT transfer or re-delegate that access; a second party gets a grant from the owner or gets nothing. Stated with the precedent rather than as a bare assertion: an OAuth access token is not transferable, open banking authorizations are per recipient, and GNAP routes a new party back through the authorization server. It also follows from PDPP's own purpose limitation -- a grant records the purpose the owner approved for one named requester, so a transfer would carry access without the approval that scoped it. 2. The owner's own personal server is NOT that case. The copy it holds is the owner's data, and the app grant is issued fresh by the owner there. No delegation construct, because no access is passed along: the owner authorizes twice, in two places. In the passthrough posture only -- server does not retain a copy, reads from the platform to fulfill as requests arrive -- the owner's grant to their own server at the platform covers fulfillment for clients that owner authorizes at that server. Account aggregation is the precedent: the user's consent at the bank covers the services the user chose, and the bank never sees the downstream app. No new construct is introduced by either rule. That is the substance of the decision, not an aside: the alternative reading -- that fulfilling on the owner's behalf requires a delegated or chained grant -- is what this text exists to foreclose. spec-deferred.md's Subgrants entry is rewritten to match. It previously read as an open question with transfer merely "out of scope"; it now records that transfer is forbidden today and that what remains open is whether a future version defines a supervised relaxation. It also names the two cases that are NOT subgrants, so a later design does not re-describe them as delegation. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
OWNER-DECISION: not normative. Two deferred-register additions. Not ratified. Sources: owner scope addendum 2026-09-02 ~17:40, items C and E. Item C's second half: the topology where the owner runs their own authorization server in front of a platform's data is explicitly NOT introduced. It is added as a named deferred entry rather than left unmentioned, so a reader who knows UMA can tell the omission is a decision. The entry states why it is hard -- it needs a platform's resource server to honor grants from an authorization server the platform neither operates nor chose -- and distinguishes it from the on-behalf-of chain now in Section 3, which is a different shape and is permitted. Item E: the existing TRQP entry on this branch already recorded the mechanism, the "design commitment, not a date" framing, and phase 2. What it did not say is where it would live. Added: in a profile or binding, not in Core's normative text, with the reason -- naming a document still in public review and without a test suite inside Core would bind the specification to it. This matches how this branch places the CIMD fetch rules and RFC 8693 in the binding rather than in Core. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
OWNER-DECISION: normative. Three new requirements in Core; two documents demoted out of the normative set. Not ratified. Source: owner scope addendum 2026-09-02 ~17:40, item B; text taken from the sibling audit at local/SPEC-SURFACE-AUDIT-0902.md (inserts A, B and C of its section 1.5). The audit is read-only analysis by a separate lane; this commit applies its proposed text, it does not re-derive it. Art wants v0.1.0's normative surface to be the core spec alone. The audit traced what actually depends on the two companion documents and found the load-bearing residue is about 200 words. Applied here: 1. Equivocation, into Section 5 Versioning and snapshots. Core already said declaration_version is opaque with no implied ordering; it never said what happens when the SAME version label later carries DIFFERENT content. That is the security property -- it is what stops a publisher swapping content under a label an authorization server already consented against -- and it was the single genuine gap. Now a MUST. 2. Source acceptance, as a new Section 6 subsection. Core described what a selection request contains, never what it may not name. The rule that a client cannot introduce a source authority, declaration location, or revision during authorization is enforced fail-closed in the reference implementation's PAR path today; Core now states it. 3. Publisher attribution, replacing two dangling pointers. Core deferred twice to "discovery and trust policy" -- a document that, after Art's #279 removes Official Source, has zero inbound references anywhere in the repository. The rule is now stated where the field is defined. Both companion documents are relabelled Informative in their root status lines, and both header sidecars gain the Informative callout they never had, so the site stops rendering them beside Core with no visible status distinction. WHAT THIS DELIBERATELY DOES NOT DO: The Collection Profile is NOT moved to data-connectors tonight, on the audit's recommendation and for a reason worth repeating: a manifest written to its published bindings table is rejected by the reference implementation's own validator (the spec publishes `browser_automation`; the validator accepts `browser` and hard-rejects unknown keys; 0 of 45 shipping manifests use the published name). Moving a known-wrong contract into the repo whose authors are its primary readers ships the defect to exactly the people most likely to follow it. Reclassify now, refresh, then move something true. The three extension profiles are left alone. They are already allowlisted in ratified OpenSpec governance, CI-enforced, status-labelled, and required not to be depended on by Core. They are the pattern, not the problem. README.md and the site rail's grouping are NOT touched here, though both are stale in exactly this respect. Art's open #283 makes those same edits. Duplicating them guarantees a conflict and gains nothing. The slug list keeps a comment explaining why it was left unrestructured. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Not an owner decision. spec:dates reported four stale files on this branch. Two are caused by this branch (spec-core.md, spec-deferred.md) and are stamped 2026-09-02. The other two, spec-collection-profile.md and spec-reference-implementation-examples.md, already fail on origin/main untouched -- verified by running scripts/spec-date-check.ts in a clean worktree at origin/main, which reports exactly those two and nothing else. They are left alone, because stamping them would claim a substantive change this branch did not make. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
Not an owner decision. Both documents changed substantively on this branch -- their status lines moved from normative-companion to informative -- so both are stamped 2026-09-02. spec-reference-implementation-examples.md remains unstamped and remains the one spec:dates failure on this branch. It fails identically on origin/main untouched; stamping it would claim a substantive change this branch did not make. spec-collection-profile.md was in that same pre-existing category until this branch edited it, and is stamped now because that is no longer true. Assisted-by: AI Signed-off-by: Tim Nunamaker <tnunamak@gmail.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
tnunamak
force-pushed
the
spec/int0902-09-normative-surface-reduction
branch
from
September 2, 2026 23:48
d11106a to
2e5c0c0
Compare
Contributor
Author
|
Closing: the date stamps this PR carried now travel with the changes that make them stale — spec-core in #290, spec-deferred in #293, and the two demoted companions in #298. That way each PR in the stack is individually green on
|
tnunamak
force-pushed
the
spec/int0902-09-normative-surface-reduction
branch
from
September 2, 2026 23:49
2e5c0c0 to
155d545
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.
Housekeeping, not a decision. One row of the stack under #285.
Four files stamped
2026-09-02across two commits:spec-core.mdandspec-deferred.md, and — after the surface-reduction sub-PR edited them —spec-collection-profile.mdandspec-discovery-and-trust.md.spec-reference-implementation-examples.mdis deliberately left unstamped and is the stack's onespec:datesfailure. It fails identically onorigin/mainuntouched — verified by running the checker in a clean worktree atorigin/main, which reports exactly that file and nothing else. Stamping it would claim a substantive change this work did not make. Art's #283 makes the same call for the same reason.spec-collection-profile.mdwas in that same pre-existing category until this stack edited it, and is stamped now because that is no longer true.Assisted-by: AI