@agenticprimitives/content-primitives 1.0.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CLAUDE.md +62 -0
  2. package/LICENSE +21 -0
  3. package/README.md +63 -0
  4. package/dist/descriptor.d.ts +67 -0
  5. package/dist/descriptor.d.ts.map +1 -0
  6. package/dist/descriptor.js +128 -0
  7. package/dist/descriptor.js.map +1 -0
  8. package/dist/entitlement.d.ts +64 -0
  9. package/dist/entitlement.d.ts.map +1 -0
  10. package/dist/entitlement.js +64 -0
  11. package/dist/entitlement.js.map +1 -0
  12. package/dist/errors.d.ts +9 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +15 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +26 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/jcs.d.ts +4 -0
  21. package/dist/jcs.d.ts.map +1 -0
  22. package/dist/jcs.js +25 -0
  23. package/dist/jcs.js.map +1 -0
  24. package/dist/merkle.d.ts +29 -0
  25. package/dist/merkle.d.ts.map +1 -0
  26. package/dist/merkle.js +74 -0
  27. package/dist/merkle.js.map +1 -0
  28. package/dist/reference.d.ts +28 -0
  29. package/dist/reference.d.ts.map +1 -0
  30. package/dist/reference.js +35 -0
  31. package/dist/reference.js.map +1 -0
  32. package/dist/reserved.d.ts +12 -0
  33. package/dist/reserved.d.ts.map +1 -0
  34. package/dist/reserved.js +19 -0
  35. package/dist/reserved.js.map +1 -0
  36. package/dist/resolution.d.ts +41 -0
  37. package/dist/resolution.d.ts.map +1 -0
  38. package/dist/resolution.js +35 -0
  39. package/dist/resolution.js.map +1 -0
  40. package/dist/types.d.ts +194 -0
  41. package/dist/types.d.ts.map +1 -0
  42. package/dist/types.js +2 -0
  43. package/dist/types.js.map +1 -0
  44. package/package.json +64 -0
  45. package/spec.md +16 -0
@@ -0,0 +1,29 @@
1
+ import { type Hex } from 'viem';
2
+ /** Hash an ordered pair after sorting: keccak256(min || max). */
3
+ export declare function hashPair(a: Hex, b: Hex): Hex;
4
+ /**
5
+ * Leaf hash for a descriptor commitment. Double-hash (`keccak256(keccak256(c))`)
6
+ * to domain-separate leaves from internal nodes (second-preimage resistance).
7
+ */
8
+ export declare function leafHash(descriptorCommitment: Hex): Hex;
9
+ export interface CorpusTree {
10
+ root: Hex;
11
+ /** layers[0] = leaves, layers[n] = [root]. */
12
+ layers: Hex[][];
13
+ }
14
+ /**
15
+ * Build a Merkle tree over already-hashed leaves (see {@link leafHash}). An odd
16
+ * node at any level is promoted unchanged to the next level. Empty input yields
17
+ * the zero root.
18
+ */
19
+ export declare function buildCorpusTree(leaves: Hex[]): CorpusTree;
20
+ /** Convenience: root of a fresh tree over `leaves`. */
21
+ export declare function merkleRoot(leaves: Hex[]): Hex;
22
+ /**
23
+ * Inclusion proof (sibling path) for the leaf at `index`. Promoted (odd) nodes
24
+ * contribute no sibling at that level — matching {@link buildCorpusTree}.
25
+ */
26
+ export declare function merkleProof(tree: CorpusTree, index: number): Hex[];
27
+ /** Fold a leaf with its proof and compare against the root. */
28
+ export declare function verifyInclusion(leaf: Hex, proof: Hex[], root: Hex): boolean;
29
+ //# sourceMappingURL=merkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAa5D,iEAAiE;AACjE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,GAAG,CAG5C;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,oBAAoB,EAAE,GAAG,GAAG,GAAG,CAEvD;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,GAAG,CAAC;IACV,8CAA8C;IAC9C,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,UAAU,CAezD;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,CAE7C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,CAWlE;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAI3E"}
package/dist/merkle.js ADDED
@@ -0,0 +1,74 @@
1
+ import { keccak256, concat, toBytes } from 'viem';
2
+ // Generic Merkle commitment over a corpus of descriptor commitments (spec 266
3
+ // §4). Net-new to the monorepo (the repo previously had only flat keccak
4
+ // commitments in `agreements`). Sorted-pair hashing (OpenZeppelin-compatible)
5
+ // so inclusion proofs are sibling-order-independent and verifiable on-chain in
6
+ // a future ContentCorpusRegistry (spec 266 Phase 3).
7
+ /** Order two hashes ascending (sorted-pair convention). */
8
+ function sortPair(a, b) {
9
+ return a.toLowerCase() <= b.toLowerCase() ? [a, b] : [b, a];
10
+ }
11
+ /** Hash an ordered pair after sorting: keccak256(min || max). */
12
+ export function hashPair(a, b) {
13
+ const [lo, hi] = sortPair(a, b);
14
+ return keccak256(concat([lo, hi]));
15
+ }
16
+ /**
17
+ * Leaf hash for a descriptor commitment. Double-hash (`keccak256(keccak256(c))`)
18
+ * to domain-separate leaves from internal nodes (second-preimage resistance).
19
+ */
20
+ export function leafHash(descriptorCommitment) {
21
+ return keccak256(toBytes(keccak256(toBytes(descriptorCommitment))));
22
+ }
23
+ /**
24
+ * Build a Merkle tree over already-hashed leaves (see {@link leafHash}). An odd
25
+ * node at any level is promoted unchanged to the next level. Empty input yields
26
+ * the zero root.
27
+ */
28
+ export function buildCorpusTree(leaves) {
29
+ if (leaves.length === 0) {
30
+ return { root: ('0x' + '0'.repeat(64)), layers: [[]] };
31
+ }
32
+ const layers = [leaves.slice()];
33
+ while (layers[layers.length - 1].length > 1) {
34
+ const prev = layers[layers.length - 1];
35
+ const next = [];
36
+ for (let i = 0; i < prev.length; i += 2) {
37
+ if (i + 1 === prev.length)
38
+ next.push(prev[i]);
39
+ else
40
+ next.push(hashPair(prev[i], prev[i + 1]));
41
+ }
42
+ layers.push(next);
43
+ }
44
+ return { root: layers[layers.length - 1][0], layers };
45
+ }
46
+ /** Convenience: root of a fresh tree over `leaves`. */
47
+ export function merkleRoot(leaves) {
48
+ return buildCorpusTree(leaves).root;
49
+ }
50
+ /**
51
+ * Inclusion proof (sibling path) for the leaf at `index`. Promoted (odd) nodes
52
+ * contribute no sibling at that level — matching {@link buildCorpusTree}.
53
+ */
54
+ export function merkleProof(tree, index) {
55
+ const proof = [];
56
+ let idx = index;
57
+ for (let level = 0; level < tree.layers.length - 1; level++) {
58
+ const nodes = tree.layers[level];
59
+ const isRight = idx % 2 === 1;
60
+ const siblingIdx = isRight ? idx - 1 : idx + 1;
61
+ if (siblingIdx < nodes.length)
62
+ proof.push(nodes[siblingIdx]);
63
+ idx = Math.floor(idx / 2);
64
+ }
65
+ return proof;
66
+ }
67
+ /** Fold a leaf with its proof and compare against the root. */
68
+ export function verifyInclusion(leaf, proof, root) {
69
+ let computed = leaf;
70
+ for (const sibling of proof)
71
+ computed = hashPair(computed, sibling);
72
+ return computed.toLowerCase() === root.toLowerCase();
73
+ }
74
+ //# sourceMappingURL=merkle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { type Hex } from 'viem';
2
+ import type { Address } from '@agenticprimitives/types';
3
+ import type { CanonicalLocusEnvelope, CanonicalReference } from './types.js';
4
+ /** The single canonical-locus id construction (pick-one; spec 266 §2.1). */
5
+ export declare const LOCUS_ID_SCHEME: "ap-locus-id-v1";
6
+ /**
7
+ * Deterministic, scheme-independent canonical-locus id (spec 266 §2.1):
8
+ * `keccak256(utf8(DOMAIN_SEP) || utf8(JCS(envelope)))`.
9
+ *
10
+ * The CORE treats `envelope.canonicalLocus` as opaque controlled-token bytes;
11
+ * the vertical extension owns its meaning + validates it before this call.
12
+ * Because the id hashes a *normalized structured envelope* (not a surface
13
+ * string) under an explicit `locusProfile`, all surface grammars that denote the
14
+ * same locus collide to the same id, and only a deliberate profile/versification
15
+ * change moves it. Registry-free + reproducible — no allocator, no Smart Agent
16
+ * (ADR-0033). keccak keeps it EVM-anchorable for the Phase-3 registry. JCS does
17
+ * NOT Unicode-normalize strings, so callers MUST pass controlled tokens only.
18
+ */
19
+ export declare function computeCanonicalId(envelope: CanonicalLocusEnvelope): Hex;
20
+ /** Build a {@link CanonicalReference} from an envelope (+ optional human alias). */
21
+ export declare function canonicalReference(envelope: CanonicalLocusEnvelope, alias?: string): CanonicalReference;
22
+ /**
23
+ * Deterministic corpus reference (spec 266 §2.2).
24
+ * `corpusRef = keccak256(utf8(`${issuer}/${edition}/${version}`))`. Issuer
25
+ * address is lowercased so the id is independent of checksum casing.
26
+ */
27
+ export declare function corpusRef(issuer: Address, edition: string, version: string): Hex;
28
+ //# sourceMappingURL=reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAE7E,4EAA4E;AAC5E,eAAO,MAAM,eAAe,EAAG,gBAAyB,CAAC;AAKzD;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,GAAG,CAExE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,sBAAsB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAEvG;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,CAEhF"}
@@ -0,0 +1,35 @@
1
+ import { keccak256, concat, toBytes } from 'viem';
2
+ import { jcsCanonicalize } from '@agenticprimitives/verifiable-credentials';
3
+ /** The single canonical-locus id construction (pick-one; spec 266 §2.1). */
4
+ export const LOCUS_ID_SCHEME = 'ap-locus-id-v1';
5
+ /** Domain separator — prevents cross-primitive / cross-version hash collisions. */
6
+ const LOCUS_ID_DOMAIN_SEP = 'ap:canonical-locus-id:v1\0';
7
+ /**
8
+ * Deterministic, scheme-independent canonical-locus id (spec 266 §2.1):
9
+ * `keccak256(utf8(DOMAIN_SEP) || utf8(JCS(envelope)))`.
10
+ *
11
+ * The CORE treats `envelope.canonicalLocus` as opaque controlled-token bytes;
12
+ * the vertical extension owns its meaning + validates it before this call.
13
+ * Because the id hashes a *normalized structured envelope* (not a surface
14
+ * string) under an explicit `locusProfile`, all surface grammars that denote the
15
+ * same locus collide to the same id, and only a deliberate profile/versification
16
+ * change moves it. Registry-free + reproducible — no allocator, no Smart Agent
17
+ * (ADR-0033). keccak keeps it EVM-anchorable for the Phase-3 registry. JCS does
18
+ * NOT Unicode-normalize strings, so callers MUST pass controlled tokens only.
19
+ */
20
+ export function computeCanonicalId(envelope) {
21
+ return keccak256(concat([toBytes(LOCUS_ID_DOMAIN_SEP), toBytes(jcsCanonicalize(envelope))]));
22
+ }
23
+ /** Build a {@link CanonicalReference} from an envelope (+ optional human alias). */
24
+ export function canonicalReference(envelope, alias) {
25
+ return { id: computeCanonicalId(envelope), envelope, ...(alias ? { alias } : {}) };
26
+ }
27
+ /**
28
+ * Deterministic corpus reference (spec 266 §2.2).
29
+ * `corpusRef = keccak256(utf8(`${issuer}/${edition}/${version}`))`. Issuer
30
+ * address is lowercased so the id is independent of checksum casing.
31
+ */
32
+ export function corpusRef(issuer, edition, version) {
33
+ return keccak256(toBytes(`${issuer.toLowerCase()}/${edition}/${version}`));
34
+ }
35
+ //# sourceMappingURL=reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference.js","sourceRoot":"","sources":["../src/reference.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAY,MAAM,MAAM,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAG5E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAyB,CAAC;AAEzD,mFAAmF;AACnF,MAAM,mBAAmB,GAAG,4BAA4B,CAAC;AAEzD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgC;IACjE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,QAAgC,EAAE,KAAc;IACjF,OAAO,EAAE,EAAE,EAAE,kBAAkB,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,MAAe,EAAE,OAAe,EAAE,OAAe;IACzE,OAAO,SAAS,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,OAAO,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Zero-knowledge inclusion / "AI-cited-correctly" proof (spec 266 Phase 4).
3
+ * Reserved — proves a commitment is in a corpus (or that a citation is
4
+ * faithful) without revealing the rendering.
5
+ */
6
+ export declare function buildInclusionZkProof(): Promise<never>;
7
+ /**
8
+ * Bind a payment mandate to entitlement issuance for paid access (spec 266
9
+ * Phase 5). Reserved.
10
+ */
11
+ export declare function bindPaymentMandate(): never;
12
+ //# sourceMappingURL=reserved.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved.d.ts","sourceRoot":"","sources":["../src/reserved.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,KAAK,CAAC,CAE5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,CAE1C"}
@@ -0,0 +1,19 @@
1
+ // Reserved API surface for later phases (spec 266 §6). These lock the shape so
2
+ // apps can be written against them, and throw until implemented — mirroring the
3
+ // agent-naming Phase-1 skeleton discipline. NO silent no-ops (ADR-0013).
4
+ /**
5
+ * Zero-knowledge inclusion / "AI-cited-correctly" proof (spec 266 Phase 4).
6
+ * Reserved — proves a commitment is in a corpus (or that a citation is
7
+ * faithful) without revealing the rendering.
8
+ */
9
+ export async function buildInclusionZkProof() {
10
+ throw new Error('verifiable-content: ZK proofs are reserved (spec 266 Phase 4)');
11
+ }
12
+ /**
13
+ * Bind a payment mandate to entitlement issuance for paid access (spec 266
14
+ * Phase 5). Reserved.
15
+ */
16
+ export function bindPaymentMandate() {
17
+ throw new Error('verifiable-content: paid access is reserved (spec 266 Phase 5)');
18
+ }
19
+ //# sourceMappingURL=reserved.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reserved.js","sourceRoot":"","sources":["../src/reserved.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,yEAAyE;AAEzE;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;AACpF,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Address } from '@agenticprimitives/types';
2
+ import type { ContentDescriptor, CanonicalReference, RightsStatus, TrustProfile } from './types.js';
3
+ export interface ResolutionConstraints {
4
+ contentType?: string;
5
+ language?: string;
6
+ /** Acceptable rights postures (e.g. ['public-domain']). */
7
+ rightsStatus?: RightsStatus[];
8
+ trustProfile?: TrustProfile;
9
+ }
10
+ /** A descriptor plus the profile/constraint screening outcome (pre-verification). */
11
+ export interface Candidate {
12
+ descriptor: ContentDescriptor;
13
+ /** True iff the descriptor's issuer is in the active trust profile's allowlist. */
14
+ issuerTrusted: boolean;
15
+ /** True iff the descriptor passed all constraint filters. */
16
+ admitted: boolean;
17
+ /** Why a candidate was screened out (when !admitted). */
18
+ reason?: string;
19
+ }
20
+ export interface ResolutionResult {
21
+ canonicalReference: CanonicalReference;
22
+ candidates: Candidate[];
23
+ }
24
+ /** A trust profile = an issuer allowlist + posture flags. Phase 1 wires
25
+ * `public-domain-demo` only; the rest are reserved shapes (spec 266 §policy). */
26
+ export interface TrustProfileConfig {
27
+ profile: TrustProfile;
28
+ /** Issuer Smart Agent addresses trusted under this profile. Empty = trust none. */
29
+ trustedIssuers: Address[];
30
+ /** If set, only these rights postures are admitted. */
31
+ allowedRightsStatus?: RightsStatus[];
32
+ /** If true, an untrusted issuer is screened out (admitted=false). */
33
+ requireTrustedIssuer: boolean;
34
+ }
35
+ /**
36
+ * Screen descriptors for a canonical reference into a candidate set under a
37
+ * trust profile + constraints. Pure + deterministic. Does NOT verify signatures
38
+ * (that is the caller's per-candidate step) — it screens *eligibility*.
39
+ */
40
+ export declare function resolveCandidates(reference: CanonicalReference, descriptors: ContentDescriptor[], profile: TrustProfileConfig, constraints?: ResolutionConstraints): ResolutionResult;
41
+ //# sourceMappingURL=resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAQpB,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,YAAY,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,mFAAmF;IACnF,aAAa,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,EAAE,OAAO,CAAC;IAClB,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB;AAED;kFACkF;AAClF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,YAAY,CAAC;IACtB,mFAAmF;IACnF,cAAc,EAAE,OAAO,EAAE,CAAC;IAC1B,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,YAAY,EAAE,CAAC;IACrC,qEAAqE;IACrE,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,kBAAkB,EAC7B,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,kBAAkB,EAC3B,WAAW,GAAE,qBAA0B,GACtC,gBAAgB,CAsBlB"}
@@ -0,0 +1,35 @@
1
+ function issuerIn(list, issuer) {
2
+ return list.some((a) => a.toLowerCase() === issuer.toLowerCase());
3
+ }
4
+ /**
5
+ * Screen descriptors for a canonical reference into a candidate set under a
6
+ * trust profile + constraints. Pure + deterministic. Does NOT verify signatures
7
+ * (that is the caller's per-candidate step) — it screens *eligibility*.
8
+ */
9
+ export function resolveCandidates(reference, descriptors, profile, constraints = {}) {
10
+ const candidates = descriptors
11
+ .filter((d) => d.canonicalId.toLowerCase() === reference.id.toLowerCase())
12
+ .map((descriptor) => {
13
+ const issuerTrusted = issuerIn(profile.trustedIssuers, descriptor.issuer.address);
14
+ let reason;
15
+ if (descriptor.status !== 'active')
16
+ reason = `status ${descriptor.status}`;
17
+ else if (profile.requireTrustedIssuer && !issuerTrusted)
18
+ reason = 'issuer not in trust profile allowlist';
19
+ else if (constraints.contentType && descriptor.contentType !== constraints.contentType)
20
+ reason = 'contentType mismatch';
21
+ else if (constraints.language && descriptor.work?.language && descriptor.work.language !== constraints.language)
22
+ reason = 'language mismatch';
23
+ else {
24
+ const allowedRights = constraints.rightsStatus ?? profile.allowedRightsStatus;
25
+ if (allowedRights && allowedRights.length > 0) {
26
+ const rs = descriptor.work?.rightsStatus ?? 'unknown';
27
+ if (!allowedRights.includes(rs))
28
+ reason = `rightsStatus ${rs} not permitted`;
29
+ }
30
+ }
31
+ return { descriptor, issuerTrusted, admitted: reason === undefined, reason };
32
+ });
33
+ return { canonicalReference: reference, candidates };
34
+ }
35
+ //# sourceMappingURL=resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.js","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAkDA,SAAS,QAAQ,CAAC,IAAe,EAAE,MAAe;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAA6B,EAC7B,WAAgC,EAChC,OAA2B,EAC3B,cAAqC,EAAE;IAEvC,MAAM,UAAU,GAAgB,WAAW;SACxC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;SACzE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAClB,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClF,IAAI,MAA0B,CAAC;QAE/B,IAAI,UAAU,CAAC,MAAM,KAAK,QAAQ;YAAE,MAAM,GAAG,UAAU,UAAU,CAAC,MAAM,EAAE,CAAC;aACtE,IAAI,OAAO,CAAC,oBAAoB,IAAI,CAAC,aAAa;YAAE,MAAM,GAAG,uCAAuC,CAAC;aACrG,IAAI,WAAW,CAAC,WAAW,IAAI,UAAU,CAAC,WAAW,KAAK,WAAW,CAAC,WAAW;YAAE,MAAM,GAAG,sBAAsB,CAAC;aACnH,IAAI,WAAW,CAAC,QAAQ,IAAI,UAAU,CAAC,IAAI,EAAE,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,KAAK,WAAW,CAAC,QAAQ;YAAE,MAAM,GAAG,mBAAmB,CAAC;aACzI,CAAC;YACJ,MAAM,aAAa,GAAG,WAAW,CAAC,YAAY,IAAI,OAAO,CAAC,mBAAmB,CAAC;YAC9E,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9C,MAAM,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,YAAY,IAAI,SAAS,CAAC;gBACtD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAAE,MAAM,GAAG,gBAAgB,EAAE,gBAAgB,CAAC;YAC/E,CAAC;QACH,CAAC;QACD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,EAAE,MAAM,EAAE,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEL,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,194 @@
1
+ import type { Address, Hex } from '@agenticprimitives/types';
2
+ import type { VerifiableCredential } from '@agenticprimitives/verifiable-credentials';
3
+ /**
4
+ * Who may retrieve a rendering (apcnt:accessPolicy codelist; spec 266 §2.2).
5
+ * `public` needs no entitlement; `licensed`/`private` are gated. An accessPolicy
6
+ * is a POLICY INPUT, never a legal grant (ADR-0033 R5; spec 266 §threat-model).
7
+ */
8
+ export type AccessPolicy = 'public' | 'licensed' | 'private';
9
+ /**
10
+ * How a descriptor's authenticity/inclusion is proven (apcnt:proofPolicy). The
11
+ * enum is fixed now so apps can target it; Phase 1 implements the `*-v1`
12
+ * signature/hash/merkle paths — the rest are reserved (spec 266 §6/§8).
13
+ */
14
+ export type ProofPolicy = 'issuer-signature-v1' | 'issuer-signature-and-hash-v1' | 'merkle-membership-v1' | 'signed-api-response-v1' | 'entitlement-attestation-v1' | 'zk-membership-v1';
15
+ /** Lifecycle of a descriptor. Verification is fail-closed on non-`active`. */
16
+ export type DescriptorStatus = 'active' | 'revoked' | 'superseded';
17
+ /** Rights posture of the underlying work (a policy input, not a grant). */
18
+ export type RightsStatus = 'public-domain' | 'open-license' | 'licensed' | 'unknown';
19
+ /** Phase-1 trust profiles (spec 266 §policy). Only `public-domain-demo` is wired.
20
+ * Generic, vertical-agnostic names — an app may map them to domain labels. */
21
+ export type TrustProfile = 'public-domain-demo' | 'strict-verified-issuer' | 'community-experimental' | 'restricted-high-assurance';
22
+ /**
23
+ * A scheme-independent, structured canonical locus. The CORE treats this as an
24
+ * OPAQUE record. Its keys MUST be controlled tokens (never user strings, display
25
+ * labels, or surface-grammar strings) supplied by a vertical-extension package,
26
+ * because JCS does NOT Unicode-normalize strings — the extension normalizes all
27
+ * surface forms to controlled tokens BEFORE they reach the hash. Two surface
28
+ * grammars that denote the same locus MUST produce an equal canonical locus.
29
+ */
30
+ export type CanonicalLocus = Record<string, unknown>;
31
+ /**
32
+ * The hashed envelope (spec 266 §2.1). The id commits not just to the locus
33
+ * fields but to the PROFILE that defines their meaning + the domain — so the
34
+ * same JSON can never conceptually collide across primitives or versions.
35
+ */
36
+ export interface CanonicalLocusEnvelope {
37
+ /** Fixed id construction scheme, e.g. 'ap-locus-id-v1'. */
38
+ idScheme: string;
39
+ /** Vertical domain tag, e.g. 'lyrics' / 'legal-code' / 'doc'. */
40
+ contentDomain: string;
41
+ /** Versioned locus profile (the governance seam), e.g. 'ap.<domain>.locus.v1'. */
42
+ locusProfile: string;
43
+ /** The controlled-token canonical locus (opaque to the core). */
44
+ canonicalLocus: CanonicalLocus;
45
+ }
46
+ /** FRBR Work locus: the deterministic, domain-separated id of an envelope. */
47
+ export interface CanonicalReference {
48
+ /** keccak256("ap:canonical-locus-id:v1\0" || JCS(envelope)) — registry-free. */
49
+ id: Hex;
50
+ /** The envelope the id was computed from. */
51
+ envelope: CanonicalLocusEnvelope;
52
+ /** Optional human alias that resolved to this reference (e.g. 'doc:section-1.2'). */
53
+ alias?: string;
54
+ }
55
+ /** Commitment to off-platform rendering text (structured + versioned; spec 266 §7). */
56
+ export interface ContentCommitment {
57
+ type: 'canonicalTextCommitment';
58
+ /** The frozen normalization profile id, e.g. 'ap:normalization:canonical-text-v1'. */
59
+ normalization: string;
60
+ /** Digest algorithm of the normalized text. */
61
+ algorithm: 'sha-256';
62
+ /** Digest value (hex). NEVER the text (ADR-0033 R3). */
63
+ value: Hex;
64
+ }
65
+ /**
66
+ * FRBR Expression/Manifestation — a versioned body of renderings published by an
67
+ * issuer Smart Agent, committed by a Merkle `corpusRoot` + signed manifest.
68
+ * Carries NO rendering text (ADR-0033 R3).
69
+ */
70
+ export interface CorpusManifest {
71
+ /** keccak256(utf8(`${issuer}/${edition}/${version}`)). */
72
+ corpusRef: Hex;
73
+ issuer: Address;
74
+ edition: string;
75
+ version: string;
76
+ /** The content type this corpus renders (e.g. 'text.passage'). */
77
+ scheme: string;
78
+ /** Merkle root over the per-locus descriptor commitments. */
79
+ corpusRoot: Hex;
80
+ accessPolicy: AccessPolicy;
81
+ proofPolicy: ProofPolicy;
82
+ /** keccak/sha digest of the off-chain license-terms doc (R5). Never the terms. */
83
+ licenseTermsHash: Hex;
84
+ metadataUri?: string;
85
+ }
86
+ /** Bibliographic metadata about the underlying work (policy inputs). */
87
+ export interface WorkMeta {
88
+ title?: string;
89
+ abbreviation?: string;
90
+ language?: string;
91
+ edition?: string;
92
+ rightsStatus?: RightsStatus;
93
+ }
94
+ /** Issuer reference — a Smart Agent address plus an optional DID/CAIP-10 label. */
95
+ export interface IssuerIdentityRef {
96
+ address: Address;
97
+ /** Optional CAIP-10 / DID label for display + verificationMethod. */
98
+ did?: string;
99
+ }
100
+ /**
101
+ * FRBR Item — an issuer's signed claim about a rendering of a canonical locus.
102
+ * Points AT off-chain text via `retrievalPointer`; NEVER contains it (R3).
103
+ * Trust flows from `signature` (issuer ERC-1271), not the platform (R5).
104
+ */
105
+ export interface ContentDescriptor {
106
+ /** Stable descriptor id (issuer-scoped), e.g. 'desc_bsb_<canonicalIdShort>'. */
107
+ id: string;
108
+ /** The scheme-independent canonical locus this describes. */
109
+ canonicalId: Hex;
110
+ /** Opaque app content type, e.g. 'text.passage'. */
111
+ contentType: string;
112
+ issuer: IssuerIdentityRef;
113
+ issuedAt: string;
114
+ status: DescriptorStatus;
115
+ version?: string;
116
+ validFrom?: string;
117
+ validUntil?: string;
118
+ revocationRef?: string;
119
+ /** Bibliographic metadata (title/language/edition/rightsStatus). */
120
+ work?: WorkMeta;
121
+ /** Structured domain semantics supplied by the vertical (e.g. section/line/edition). */
122
+ selector?: Record<string, unknown>;
123
+ /** Commitment to the off-platform rendering (optional for signature-only proofs). */
124
+ commitment?: ContentCommitment;
125
+ /** URI/locator for the off-chain text. NEVER the text itself (R3). */
126
+ retrievalPointer: string;
127
+ proofPolicy: ProofPolicy;
128
+ accessPolicy: AccessPolicy;
129
+ /** Membership corpus (when proofPolicy is merkle-membership-v1). */
130
+ corpusRef?: Hex;
131
+ /** Signature over descriptorHash(unsigned). Either the issuer's own ERC-1271 signature, OR — when
132
+ * `delegatingSigner` is present — a signature by the delegated signing key the issuer authorized. */
133
+ signature: Hex;
134
+ /** Present when the descriptor was signed by an issuer-AUTHORIZED operational key (e.g. a Cloud-KMS
135
+ * key the issuer delegated) rather than the issuer's own custodian. Trust still roots in the issuer
136
+ * SA (`delegatorIssuer` == `issuer.address`); the leaf proves the issuer authorized `delegateKey`. */
137
+ delegatingSigner?: DelegatingSigner;
138
+ }
139
+ /** An issuer's authorization of an operational signing key (spec 266 + spec 270 session-delegation). */
140
+ export interface DelegatingSigner {
141
+ /** The canonical issuer SA the descriptor's trust roots in (e.g. lbsb.impact). Equals `issuer.address`. */
142
+ delegatorIssuer: Address;
143
+ /** The operational key that actually signed the descriptor — authorized by `delegatorIssuer`. */
144
+ delegateKey: Address;
145
+ /** The signed delegation binding `delegateKey` → `delegatorIssuer`. OPAQUE here; the app's injected
146
+ * {@link DelegatedAuthorityVerifier} validates it (keeps content-primitives delegation-agnostic). */
147
+ delegationLeaf: unknown;
148
+ }
149
+ /**
150
+ * Verifies a signature over a hash by `signer`. Apps inject one backed by an
151
+ * `AgentAccountClient.isValidSignature` (ERC-1271/6492); tests inject a fake.
152
+ * Decoupled per ADR-0006's injected-context pattern.
153
+ */
154
+ export type SignatureVerifier = (args: {
155
+ signer: Address;
156
+ hash: Hex;
157
+ signature: Hex;
158
+ }) => Promise<boolean> | boolean;
159
+ /**
160
+ * Verifies that `delegatorIssuer` authorized `delegateKey` to sign content on its behalf, by validating
161
+ * the signed `delegationLeaf` (the leaf's delegator == delegatorIssuer, delegate == delegateKey, signed by
162
+ * delegatorIssuer's ERC-1271, within caveats). Injected (ADR-0006) so content-primitives stays free of the
163
+ * delegation package.
164
+ */
165
+ export type DelegatedAuthorityVerifier = (args: DelegatingSigner) => Promise<boolean> | boolean;
166
+ /** Input to {@link buildContentDescriptor} (everything but the signature + how-it-was-signed metadata). */
167
+ export type BuildDescriptorInput = Omit<ContentDescriptor, 'signature' | 'delegatingSigner'>;
168
+ /** A credential asserting a subject may access a corpus (apcnt:Entitlement). */
169
+ export type Entitlement = VerifiableCredential<{
170
+ id: string;
171
+ corpusRef: Hex;
172
+ accessPolicy: AccessPolicy;
173
+ terms?: string;
174
+ }>;
175
+ /** The AI-safe citation record (apcnt:CitationAssertion). Carries provenance,
176
+ * never rendering text. */
177
+ export type CitationAssertion = VerifiableCredential<{
178
+ id: string;
179
+ /** Agentic provenance — which run/output cited this. */
180
+ agentRunId?: string;
181
+ outputId?: string;
182
+ citationKind: 'quote' | 'reference' | 'summary' | 'paraphrase';
183
+ canonicalId: Hex;
184
+ descriptorId: string;
185
+ contentType: string;
186
+ commitment?: ContentCommitment;
187
+ commitmentVerified: boolean;
188
+ /** Optional hash of the specific quoted span + the normalization used. */
189
+ quoteSpanHash?: Hex;
190
+ normalizationSpec?: string;
191
+ issuer: Address;
192
+ underEntitlement?: string;
193
+ }>;
194
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@agenticprimitives/content-primitives",
3
+ "version": "1.0.0-alpha.10",
4
+ "description": "Verifiable Content Substrate SDK: name, resolve, commit, entitlement-gate, and cite off-platform content controlled by third-party rights holders. Owns CanonicalLocus / CorpusManifest / ContentDescriptor / CitationAssertion / Entitlement (FRBR-aligned), deterministic locusId, Merkle corpus commitments, and issuer-signature verification. Content-agnostic — no vertical/faith vocabulary, no content text (ADR-0033).",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
9
+ "directory": "packages/content-primitives"
10
+ },
11
+ "homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/content-primitives",
12
+ "bugs": {
13
+ "url": "https://github.com/agentictrustlabs/agenticprimitives/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ },
23
+ "./merkle": {
24
+ "types": "./dist/merkle.d.ts",
25
+ "import": "./dist/merkle.js"
26
+ }
27
+ },
28
+ "files": [
29
+ "LICENSE",
30
+ "dist",
31
+ "spec.md",
32
+ "README.md",
33
+ "CLAUDE.md"
34
+ ],
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "viem": "^2.52.2",
40
+ "@agenticprimitives/types": "1.0.0-alpha.9",
41
+ "@agenticprimitives/verifiable-credentials": "0.0.0-alpha.6"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.7.0",
45
+ "vitest": "^4.1.8"
46
+ },
47
+ "keywords": [
48
+ "content",
49
+ "commitment",
50
+ "merkle",
51
+ "provenance",
52
+ "citation",
53
+ "agentic"
54
+ ],
55
+ "scripts": {
56
+ "build": "tsc -p tsconfig.build.json",
57
+ "typecheck": "tsc -p tsconfig.json --noEmit",
58
+ "test": "vitest run",
59
+ "test:unit": "vitest run test/reference.test.ts test/merkle.test.ts test/descriptor.test.ts test/entitlement.test.ts test/resolution.test.ts --passWithNoTests",
60
+ "test:integration": "vitest run test/integration --passWithNoTests",
61
+ "test:watch": "vitest",
62
+ "clean": "rm -rf dist"
63
+ }
64
+ }
package/spec.md ADDED
@@ -0,0 +1,16 @@
1
+ # @agenticprimitives/content-primitives — spec
2
+
3
+ The full design lives in
4
+ [`../../specs/266-verifiable-content-substrate.md`](../../specs/266-verifiable-content-substrate.md).
5
+
6
+ Architecture decision:
7
+
8
+ - [ADR-0033](../../docs/architecture/decisions/0033-content-agnostic-verifiable-content-firewall.md)
9
+ — content-agnostic firewall; content loci are scheme-anchored (an ADR-0010
10
+ carve-out); no licensed content (R1), no content text on-chain (R3).
11
+
12
+ First usage domain: the scripture demo vertical
13
+ ([spec 267](../../specs/267-scripture-demo-vertical.md)) — all Bible/faith
14
+ specifics live in `apps/demo-bible-*`, never here.
15
+
16
+ Do not edit a divergent copy here — edit the canonical spec.