Skip to content

Commit 3b0fc51

Browse files
committed
fix: psp-1 review edits
- Removes the Atom/Sym/Var contradiction in the current Terminology and introduces the official name for TAP to avoid "profile" overload later. - PCF must not refer to literal kinds that the language forbids; we keep the ordering rules purely over builtin operator id and arguments. - Without pinning, comparator evolution can change allow/deny decisions over time. We make the snapshot mandatory and chain-stable; this is the single biggest determinism hardener. - The spec mentions normalization in multiple places; this consolidates a single, normative rule where evaluators look first. (The "Grants -> Determinism and normalization invariants" bullet remains consistent.) - Edge-consistent timing: half-open `[iat,exp)` is already used in the algorithm; this makes precedence explicit so independent CEPs agree on acceptance at the boundary. - Aligns all time semantics to half-open windows, preventing "double-counting the endpoint" and making ttl_ok consistent with the Presentation lifetime check. - Replaces "controls authority" (subjective) with a mechanical, verifier-checkable rule. This is the cornerstone of safe delegation. - Keeps comparator fingerprints as additional evidence even with mandatory pinning; also makes snapshot equality a first-class chain condition. - Eliminates ambiguity about where profile strings come from, and ties their interpretation to the pinned lattice snapshot. - Aligns terminology with "Threat and Acceptance Policy"; avoids overloading "profile" in TAP contexts while preserving the separate concept of PSP-level "Profiles" elsewhere in the doc. - Makes the same syntactic rule explicit in both delegation sections to avoid reader confusion and implementation drift. - Codifies your note about keeping PoAR fingerprints for fast replay/audit while keeping snapshot pinning as the source of truth. - Disambiguates "Profiles" here as specification profiles, so it doesn't collide with the TAP policy concept.
1 parent ab24200 commit 3b0fc51

File tree

1 file changed

+70
-44
lines changed

1 file changed

+70
-44
lines changed

docs/reference/specifications/psp-1.mdx

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<summary>Metadata</summary>
55
<dl>
66
<dt>Status:</dt>
7-
<dd>Draft</dd>
7+
<dd>Review</dd>
88
<dt>Edition:</dt>
99
<dd>2025-09-04</dd>
1010
<dt>Extends:</dt>
@@ -70,8 +70,9 @@ and only when, they appear in all capitals, as shown here.
7070
verify Lease freshness per TAP policy.
7171
- **CPL**: Capability Programming Language.
7272
- **Program (CPL/0):** A monotone policy evaluated by CEPs, composed of Checks
73-
(OR of Queries), Queries (AND of Literals), and Literals (Atoms or pure,
74-
bounded Builtins) over typed Terms (Sym/Str/Int/Bytes/Bool/Var).
73+
(OR of Queries), Queries (AND of Literals), and Literals that are pure,
74+
bounded Builtins over ground Terms (Str/Int/Bytes/Bool). CPL/0 has no
75+
user-defined atoms, symbols, or variables.
7576
- **Declarations:** Finite sets/relations used by programs: PairSet of (action,
7677
resource), ActionSet, and ResourceSet.
7778
- **Program Canonical Form (PCF):** The normalized, deterministically encoded
@@ -84,6 +85,10 @@ and only when, they appear in all capitals, as shown here.
8485
delegation chain to a resource domain.
8586
- **Access PoAR:** The Proof-of-Action receipt written by the enforcing CEP
8687
(defined in PSP-2).
88+
- **TAP (Threat and Acceptance Policy):** The acceptance policy that governs
89+
time discipline, chain depth and anchoring requirements, resolver/mirroring
90+
allowances, replay defenses, and other deployment-specific constraints used by
91+
CEPs during verification.
8792
- **Pin:** A self-describing, content-addressed identifier (e.g., multihash/CID)
8893
that refers to an immutable artifact (of any kind). Pins may be expressed as
8994
URIs when a scheme/protocol is defined (e.g., cid://..., ipfs://..., https://
@@ -191,8 +196,9 @@ Deterministic Evaluation and PSP-4).
191196
- Each builtin op_id, its type signature, and its tightening rule are defined in
192197
the Builtins registry (PSP-4). The exact set in use is pinned by builtins_id
193198
in the Grant.
194-
- Channel comparisons (e.g., channel_geq) consult a pinned channel_lattice_id
195-
when present.
199+
- Channel comparisons (e.g., channel_geq) consult the pinned channel_lattice_id,
200+
which defines the set of recognized channel profile identifiers and their
201+
partial order. Unknown profiles or an unknown lattice MUST cause deny.
196202
- Resource subset checks in declaration-aware builtins (e.g., in_pairset)
197203
consult the scheme comparator selected by the resource's scheme name.
198204
- If a builtin, lattice, or comparator required by the Program is unknown or
@@ -228,7 +234,7 @@ Deterministic Evaluation and PSP-4).
228234
deterministic, ms-class verification and compact proof traces.
229235
- Interop: Biscuit tokens in the checks-only fragment can be normalized into
230236
CPL/0. If rules are required in a domain, precompute finite sets and ship a
231-
CPL/0 guard, or use a TAP-gated profile that supplies a compiled guard or an
237+
CPL/0 guard, or use a TAP-gated policy that supplies a compiled guard or an
232238
approved CEP runtime.
233239

234240
Because CPL/0 is checks-only over ground terms with pure, bounded builtins, CEPs
@@ -261,9 +267,12 @@ reference these facts by name.
261267
jurisdiction tags, or digest references) and define how they are obtained
262268
and verified. PSP-1 does not enumerate these; Programs assert them via
263269
equality (e.g., ctx_eq).
264-
- Missing facts (normative)
270+
- Missing facts and normalization
265271
- If a builtin present in the Program requires an environment fact that is
266272
missing, evaluation MUST fail closed.
273+
- The CEP MUST normalize `resource` using the same comparator semantics used
274+
to canonicalize declarations before any literal evaluation. Normalization
275+
failure MUST cause deny.
267276

268277
### Declarations
269278

@@ -327,7 +336,7 @@ Normative requirements
327336
bounded (e.g., explicit sets, bounded prefixes/namespaces) with a defined
328337
subset proof. Unbounded globs/regex MUST NOT be permitted unless the registry
329338
specifies a safe comparator and proof strategy.
330-
- TAP scoping: TAP profiles MAY restrict acceptable schemes per domain and MAY
339+
- TAP scoping: TAP policies MAY restrict acceptable schemes per domain and MAY
331340
further constrain resource forms (e.g., disallow selectors).
332341

333342
#### PairSet
@@ -408,10 +417,11 @@ action in A over any resource in R"). Use PairSet when the matrix is irregular.
408417
#### Profiles
409418

410419
This specification standardizes exactly three Declaration kinds: PairSet,
411-
ActionSet, ResourceSet. Profiles MAY further constrain their usage (e.g.,
412-
disallow ResourceSet for certain actions) or prescribe default comparators per
413-
scheme. A CEP MUST deny if a Program references a declaration kind not supported
414-
by the active profile or if a required comparator is not available.
420+
ActionSet, ResourceSet. Specification Profiles MAY further constrain their usage
421+
(e.g., disallow ResourceSet for certain actions) or prescribe default
422+
comparators per scheme. A CEP MUST deny if a Program references a declaration
423+
kind not supported by the active profile or if a required comparator is not
424+
available.
415425

416426
### Semantic Pinning for Deterministic Evaluation
417427

@@ -461,9 +471,11 @@ Resource schemes / comparators:
461471

462472
- Each resource scheme (vault:, net:, k8s:, ...) has a registry entry defining
463473
normalization and a decidable subset comparator.
464-
- In PSP-1, CEPs select comparator semantics by scheme name. No per-scheme ID is
465-
pinned in Grants. If a scheme is unknown or its comparator is unavailable at
466-
verification, the CEP MUST deny
474+
- **schemes_snapshot_id**: Grants pin a content-addressed manifest that maps
475+
each scheme name referenced by declarations to the exact comparator artifact
476+
used for normalization and subset comparison. CEPs select comparator semantics
477+
by scheme name within this pinned snapshot. Unknown or unavailable comparators
478+
at verification MUST cause deny.
467479

468480
#### Pinning in Grants
469481

@@ -473,8 +485,8 @@ A Grant MUST include references to the exact rulebooks its Program depends on:
473485
- builtins_id: ID of the Builtins set used by the Program.
474486
- channel_lattice_id: REQUIRED if the Program contains channel_geq; otherwise
475487
OPTIONAL.
476-
- Resource schemes: comparator semantics are selected by the scheme name present
477-
in each resource string; no per-scheme ID is pinned in PSP-1.
488+
- schemes_snapshot_id: REQUIRED. Content-addressed manifest that pins comparator
489+
semantics for all scheme names referenced by this Grant's declarations.
478490
- No action registry is required in PSP-1. Actions are plain strings compared
479491
for equality. Any allowlists or required constraints tied to action names are
480492
governed by TAP and MAY be enforced by requiring corresponding Program
@@ -490,10 +502,9 @@ In a delegation chain, a child Grant MUST use the same rulebooks as its parent:
490502
- lang_version must equal the parent's value.
491503
- builtins_id must equal the parent's value.
492504
- channel_lattice_id, when present in either parent or child, must be equal.
493-
- For each resource scheme name referenced by declarations, the same comparator
494-
semantics MUST apply consistently across the chain. If any hop references a
495-
scheme the CEP cannot resolve to the same comparator semantics, verification
496-
MUST fail.
505+
- schemes_snapshot_id must equal the parent's value. For each referenced scheme
506+
name, the same comparator semantics MUST apply consistently across the chain;
507+
any mismatch or unavailability MUST cause deny.
497508
- Unknown builtins, lattices, or scheme comparators at any hop MUST cause deny.
498509

499510
These constraints ensure attenuation is checked and evaluated under identical
@@ -513,6 +524,10 @@ A CEP MUST deny if any of the following holds:
513524
- In a delegation chain, any of the compatibility requirements above are
514525
violated.
515526
- Any required registry entry cannot be loaded or applied at verification time.
527+
- schemes_snapshot_id is missing, unknown, or cannot be loaded; or
528+
schemes_snapshot_id does not match across delegation hops.
529+
- A declaration contains a resource whose scheme cannot be normalized under the
530+
comparator semantics pinned by schemes_snapshot_id.
516531

517532
- A declaration contains a resource whose scheme cannot be normalized under the
518533
active comparator semantics.
@@ -545,7 +560,6 @@ normalization rules (PCF).
545560
#### Normalization rules
546561

547562
- Literals within a Query MUST be sorted by a total order over:
548-
- literal kind (e.g., Builtin before Atom if Atoms are present),
549563
- operator/predicate identifier (text in NFC, bytewise),
550564
- arguments tuple under canonical term order.
551565
- Duplicate Literals within a Query MUST be removed.
@@ -736,11 +750,13 @@ compatibility:
736750
- Custody (enforced elsewhere): issuer(child) MUST equal subject(parent) with
737751
proper sigchain linkage; see Delegation & Attenuation.
738752
- Program attenuation (syntactic):
739-
- A child Program MAY add Checks; it MUST NOT remove any parent Check that
740-
controls authority.
741-
- Within retained Checks and Queries, a child MAY add Literals and MAY tighten
742-
constants of existing Literals only according to the Builtins tightening
743-
rules defined in the Builtins registry.
753+
- A child Program MUST include all parent Checks (by PCF identity) and MAY add
754+
additional Checks.
755+
- For each retained parent Check, the child MAY remove any subset of the
756+
parent's Queries (narrowing the OR). For each retained Query, the child's
757+
literal multiset MUST be a superset of the parent's; literal constants MAY
758+
only tighten according to the Builtins tightening rules defined in the
759+
Builtins registry.
744760
- Declarations subset:
745761
- PairSet_child $\subseteq$ PairSet_parent.
746762
- ActionSet_child $\subseteq$ ActionSet_parent.
@@ -843,10 +859,10 @@ normative on-wire field names and encodings are defined in PSP-3.
843859
resolution hints. Resolution, if allowed, is a TAP-governed, pre-enforcement
844860
step outside CPL/0 evaluation. At enforcement, if required parent Grants are
845861
not locally available, the CEP MUST deny.
846-
- A TAP/PSP-3 profile MAY define alternate, bounded chain attestation
847-
artifacts (e.g., a stapled chain receipt or a zero-knowledge chain proof).
848-
PSP-1 core does not define or require such artifacts and forbids embedding
849-
raw Grant bodies in Presentations.
862+
- A TAP policy (with PSP-3 bindings) MAY define alternate, bounded chain
863+
attestation artifacts (e.g., a stapled chain receipt or a zero-knowledge
864+
chain proof). PSP-1 core does not define or require such artifacts and
865+
forbids embedding raw Grant bodies in Presentations.
850866

851867
### Normative Requirements
852868

@@ -861,6 +877,9 @@ normative on-wire field names and encodings are defined in PSP-3.
861877
early (now < iat), subject to TAP clock discipline.
862878
- If the Program contains ttl_ok or within_time literals, the CEP MUST enforce
863879
them using iat/now/exp as appropriate.
880+
- Effective lifetime: When both `[iat, exp)` and `ttl_ok` appear, both MUST
881+
pass at the captured `now`. The effective acceptance window is the
882+
intersection of these constraints.
864883
- If the Grant envelope carries a validity window (not_before/not_after) per
865884
PSP-3, the CEP MUST enforce it and, where both apply, MUST enforce the
866885
intersection with the Presentation's lifetime.
@@ -1003,11 +1022,13 @@ hop-by-hop. Children MAY only narrow or preserve authority.
10031022

10041023
- Program (checks/queries/literals)
10051024
- Checks (Program is AND of Checks):
1006-
- A child Program MAY add Checks; it MUST NOT remove any parent Check that
1007-
controls authority.
1025+
- A child Program MUST include all parent Checks (by PCF identity) and MAY
1026+
add additional Checks.
10081027
- Queries (each Check is OR of Queries):
1009-
- For any retained parent Query, the child Query MUST include all parent
1010-
Literals (L_child $\supseteq$ L_parent) and MAY add additional Literals.
1028+
- The child MAY remove any subset of the parent's Queries (narrowing the
1029+
OR). For any retained parent Query, the child Query MUST include all
1030+
parent Literals (L_child $\supseteq$ L_parent) and MAY add additional
1031+
Literals.
10111032
- Literal tightening (constants only narrow):
10121033
- Literal constants MAY only be tightened according to the Builtins
10131034
tightening rules pinned by builtins_id (see PSP-4). Examples:
@@ -1193,7 +1214,7 @@ Preconditions (TAP-governed, outside evaluation)
11931214
- Depth and cycles: no cycles; deny if TAP depth cap exceeded.
11941215
- Pinned semantics compatibility: lang_version matches; builtins_id
11951216
matches; channel_lattice_id matches whenever channel_geq is used by
1196-
either hop; else deny.
1217+
either hop; schemes_snapshot_id matches; else deny.
11971218
- Scheme comparator availability: comparators required by referenced
11981219
schemes are known/available; else deny.
11991220
- Syntactic attenuation:
@@ -1225,7 +1246,8 @@ Preconditions (TAP-governed, outside evaluation)
12251246
- Ensure all Declarations referenced by the Program are present as bundled
12261247
canonical bytes; else deny.
12271248
- Confirm pinned semantics are usable: builtins_id known; if Program uses
1228-
channel_geq, channel_lattice_id present and known; else deny.
1249+
channel_geq, channel_lattice_id present and known; schemes_snapshot_id
1250+
present and known; else deny.
12291251
7. Evaluate Program (closed-world, bounded)
12301252
- Evaluate the CPL/0 Program against the environment facts and bundled
12311253
Declarations with pinned semantics:
@@ -1248,9 +1270,11 @@ Preconditions (TAP-governed, outside evaluation)
12481270
outside PSP-1).
12491271
- The enforcing CEP MUST emit an Access PoAR per PSP-2 on its own sigchain
12501272
(P/R/S depending on placement) and deliver it to the Subject. PoAR SHOULD
1251-
include program_id, declaration CIDs, pins, a minimal evaluation trace
1252-
(which check/query passed), and revocation/freshness decision context as
1253-
applicable.
1273+
include program_id, declaration CIDs, pins (including
1274+
schemes_snapshot_id), a minimal evaluation trace (which check/query
1275+
passed), and revocation/freshness decision context as applicable. For
1276+
audit acceleration, the PoAR SHOULD also record comparator fingerprints
1277+
(per scheme) actually used during evaluation.
12541278
- On failure:
12551279
- The enforcing CEP MUST emit a DenyReceipt per PSP-2 with an appropriate
12561280
reason code and deliver it to the Subject.
@@ -1405,8 +1429,10 @@ across delegation, and (d) TAP-governed acceptance and deployment hygiene.
14051429
content-addressed snapshots. Operators SHOULD monitor and pin approved
14061430
versions via TAP; deny unknown pins.
14071431
- Comparator drift
1408-
- Scheme comparator semantics MUST be stable. If comparator behavior changes
1409-
or is unavailable, CEPs MUST deny rather than assume.
1432+
- Scheme comparator semantics MUST be stable. The schemes_snapshot_id pins the
1433+
exact comparator set; CEPs MUST deny on unknown or mismatched snapshots. For
1434+
audit acceleration, PoARs SHOULD record the snapshot id and comparator
1435+
fingerprints actually used by the enforcer.
14101436

14111437
### Side-Channels and Error Signaling
14121438

@@ -1853,15 +1879,15 @@ definitions.
18531879

18541880
- within_time(now:Int, nbf:Int, exp:Int)
18551881

1856-
- Semantics: true iff `nbf <= now <= exp`.
1882+
- Semantics: true iff `nbf <= now < exp`.
18571883
- Types: all Int.
18581884
- Tightening: child interval $\subseteq$ parent interval (i.e.,
18591885
`nbf_child >= nbf_parent` and `exp_child <= exp_parent`).
18601886
- Fail-closed: ill-typed or now outside [nbf, exp] => false; unknown => deny.
18611887

18621888
- ttl_ok(iat:Int, now:Int, ttl_max:Int)
18631889

1864-
- Semantics: true iff `now <= iat + ttl_max`.
1890+
- Semantics: true iff `now < iat + ttl_max`.
18651891
- Types: all Int.
18661892
- Tightening: `ttl_max_child <= ttl_max_parent`.
18671893
- Fail-closed: ill-typed => deny; else boolean result.

0 commit comments

Comments
 (0)