@peac/schema 0.9.18 → 0.10.0

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 (50) hide show
  1. package/LICENSE +190 -0
  2. package/dist/agent-identity.d.ts +684 -0
  3. package/dist/agent-identity.d.ts.map +1 -0
  4. package/dist/agent-identity.js +357 -0
  5. package/dist/agent-identity.js.map +1 -0
  6. package/dist/attribution.d.ts +792 -0
  7. package/dist/attribution.d.ts.map +1 -0
  8. package/dist/attribution.js +444 -0
  9. package/dist/attribution.js.map +1 -0
  10. package/dist/constants.d.ts +46 -5
  11. package/dist/constants.d.ts.map +1 -1
  12. package/dist/constants.js +46 -5
  13. package/dist/constants.js.map +1 -1
  14. package/dist/control.d.ts +2 -1
  15. package/dist/control.d.ts.map +1 -1
  16. package/dist/dispute.d.ts +1279 -0
  17. package/dist/dispute.d.ts.map +1 -0
  18. package/dist/dispute.js +832 -0
  19. package/dist/dispute.js.map +1 -0
  20. package/dist/envelope.d.ts +14 -7
  21. package/dist/envelope.d.ts.map +1 -1
  22. package/dist/errors.d.ts +19 -8
  23. package/dist/errors.d.ts.map +1 -1
  24. package/dist/errors.js +35 -7
  25. package/dist/errors.js.map +1 -1
  26. package/dist/evidence.d.ts +127 -3
  27. package/dist/evidence.d.ts.map +1 -1
  28. package/dist/index.d.ts +17 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +133 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/json.d.ts +114 -0
  33. package/dist/json.d.ts.map +1 -0
  34. package/dist/json.js +267 -0
  35. package/dist/json.js.map +1 -0
  36. package/dist/obligations.d.ts +364 -0
  37. package/dist/obligations.d.ts.map +1 -0
  38. package/dist/obligations.js +337 -0
  39. package/dist/obligations.js.map +1 -0
  40. package/dist/purpose.d.ts +272 -0
  41. package/dist/purpose.d.ts.map +1 -0
  42. package/dist/purpose.js +296 -0
  43. package/dist/purpose.js.map +1 -0
  44. package/dist/types.d.ts +85 -19
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/validators.d.ts +327 -61
  47. package/dist/validators.d.ts.map +1 -1
  48. package/dist/validators.js +138 -7
  49. package/dist/validators.js.map +1 -1
  50. package/package.json +10 -10
@@ -0,0 +1,337 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ObligationsExtensionSchema = exports.OBLIGATIONS_EXTENSION_KEY = exports.ContributionObligationSchema = exports.CreditObligationSchema = exports.CONTRIBUTION_TYPES = exports.ContributionTypeSchema = exports.CREDIT_METHODS = exports.CreditMethodSchema = void 0;
4
+ exports.validateCreditObligation = validateCreditObligation;
5
+ exports.validateContributionObligation = validateContributionObligation;
6
+ exports.validateObligationsExtension = validateObligationsExtension;
7
+ exports.extractObligationsExtension = extractObligationsExtension;
8
+ exports.isCreditRequired = isCreditRequired;
9
+ exports.isContributionRequired = isContributionRequired;
10
+ exports.createCreditObligation = createCreditObligation;
11
+ exports.createContributionObligation = createContributionObligation;
12
+ exports.createObligationsExtension = createObligationsExtension;
13
+ /**
14
+ * PEAC Obligations Extension Types (v0.9.26+)
15
+ *
16
+ * Defines credit and contribution obligations for receipts,
17
+ * aligned with Creative Commons Signals framework.
18
+ *
19
+ * The `peac/obligations` extension allows content owners to specify
20
+ * requirements for credit/attribution and contribution models.
21
+ *
22
+ * @see https://creativecommons.org/signals/ for CC Signals background
23
+ */
24
+ const zod_1 = require("zod");
25
+ // =============================================================================
26
+ // CREDIT METHOD (v0.9.26+)
27
+ // =============================================================================
28
+ /**
29
+ * How credit/attribution should be provided.
30
+ *
31
+ * - 'inline': Credit appears inline with the generated content
32
+ * - 'references': Credit appears in a references/sources section
33
+ * - 'model-card': Credit appears in model documentation/card
34
+ */
35
+ exports.CreditMethodSchema = zod_1.z.enum(['inline', 'references', 'model-card']);
36
+ /**
37
+ * Array of valid credit methods for runtime checks.
38
+ */
39
+ exports.CREDIT_METHODS = ['inline', 'references', 'model-card'];
40
+ // =============================================================================
41
+ // CONTRIBUTION TYPE (v0.9.26+)
42
+ // =============================================================================
43
+ /**
44
+ * Type of contribution model.
45
+ *
46
+ * - 'direct': Direct payment to content owner
47
+ * - 'ecosystem': Contribution to ecosystem fund/coalition
48
+ * - 'open': Freely usable (no payment required)
49
+ */
50
+ exports.ContributionTypeSchema = zod_1.z.enum(['direct', 'ecosystem', 'open']);
51
+ /**
52
+ * Array of valid contribution types for runtime checks.
53
+ */
54
+ exports.CONTRIBUTION_TYPES = ['direct', 'ecosystem', 'open'];
55
+ // =============================================================================
56
+ // CREDIT OBLIGATION (v0.9.26+)
57
+ // =============================================================================
58
+ /**
59
+ * CreditObligation - specifies attribution/credit requirements.
60
+ *
61
+ * Content owners can require credit when their content is used,
62
+ * specifying where and how the credit should appear.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const credit: CreditObligation = {
67
+ * required: true,
68
+ * citation_url: 'https://publisher.example/collection',
69
+ * method: 'references',
70
+ * };
71
+ * ```
72
+ */
73
+ exports.CreditObligationSchema = zod_1.z
74
+ .object({
75
+ /** Whether credit is required (REQUIRED) */
76
+ required: zod_1.z.boolean(),
77
+ /** URL for citation/attribution (OPTIONAL) */
78
+ citation_url: zod_1.z.string().url().max(2048).optional(),
79
+ /** How credit should be provided (OPTIONAL, defaults to implementation choice) */
80
+ method: exports.CreditMethodSchema.optional(),
81
+ /** Human-readable credit text template (OPTIONAL) */
82
+ credit_text: zod_1.z.string().max(1024).optional(),
83
+ })
84
+ .strict()
85
+ .superRefine((data, ctx) => {
86
+ // If credit is required, at least one of citation_url, credit_text, or method must be specified
87
+ if (data.required && !data.citation_url && !data.credit_text && !data.method) {
88
+ ctx.addIssue({
89
+ code: zod_1.z.ZodIssueCode.custom,
90
+ message: 'When credit is required, at least one of citation_url, credit_text, or method must be specified',
91
+ path: ['required'],
92
+ });
93
+ }
94
+ });
95
+ // =============================================================================
96
+ // CONTRIBUTION OBLIGATION (v0.9.26+)
97
+ // =============================================================================
98
+ /**
99
+ * ContributionObligation - specifies contribution/payment model.
100
+ *
101
+ * Aligned with CC Signals reciprocity framework:
102
+ * - direct: Payment goes directly to content owner
103
+ * - ecosystem: Payment goes to shared ecosystem fund
104
+ * - open: Content is freely usable
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const contribution: ContributionObligation = {
109
+ * type: 'ecosystem',
110
+ * destination: 'https://fund.creativecommons.org',
111
+ * };
112
+ * ```
113
+ */
114
+ exports.ContributionObligationSchema = zod_1.z
115
+ .object({
116
+ /** Type of contribution (REQUIRED) */
117
+ type: exports.ContributionTypeSchema,
118
+ /** Destination for contributions (OPTIONAL, e.g., fund URL, wallet address) */
119
+ destination: zod_1.z.string().max(2048).optional(),
120
+ /** Minimum contribution amount in minor units (OPTIONAL) */
121
+ min_amount: zod_1.z.number().int().min(0).optional(),
122
+ /** Currency for min_amount (OPTIONAL, ISO 4217 or crypto symbol like USDC) */
123
+ currency: zod_1.z
124
+ .string()
125
+ .min(3)
126
+ .max(8)
127
+ .regex(/^[A-Z0-9]{3,8}$/)
128
+ .optional(),
129
+ })
130
+ .strict()
131
+ .superRefine((data, ctx) => {
132
+ // If type is 'direct' or 'ecosystem', destination is required
133
+ if ((data.type === 'direct' || data.type === 'ecosystem') && !data.destination) {
134
+ ctx.addIssue({
135
+ code: zod_1.z.ZodIssueCode.custom,
136
+ message: `Destination is required when contribution type is '${data.type}'`,
137
+ path: ['destination'],
138
+ });
139
+ }
140
+ // min_amount requires currency
141
+ if (data.min_amount !== undefined && !data.currency) {
142
+ ctx.addIssue({
143
+ code: zod_1.z.ZodIssueCode.custom,
144
+ message: 'Currency is required when min_amount is specified',
145
+ path: ['currency'],
146
+ });
147
+ }
148
+ });
149
+ // =============================================================================
150
+ // OBLIGATIONS EXTENSION (v0.9.26+)
151
+ // =============================================================================
152
+ /**
153
+ * Extension key for obligations
154
+ */
155
+ exports.OBLIGATIONS_EXTENSION_KEY = 'peac/obligations';
156
+ /**
157
+ * ObligationsExtension - the full obligations extension block.
158
+ *
159
+ * This extension is added to receipt extensions under the key `peac/obligations`.
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * const receipt = {
164
+ * // ... receipt fields ...
165
+ * extensions: {
166
+ * 'peac/obligations': {
167
+ * credit: {
168
+ * required: true,
169
+ * citation_url: 'https://publisher.example/collection',
170
+ * method: 'references',
171
+ * },
172
+ * contribution: {
173
+ * type: 'ecosystem',
174
+ * destination: 'https://fund.example.org',
175
+ * },
176
+ * },
177
+ * },
178
+ * };
179
+ * ```
180
+ */
181
+ exports.ObligationsExtensionSchema = zod_1.z
182
+ .object({
183
+ /** Credit/attribution obligations (OPTIONAL) */
184
+ credit: exports.CreditObligationSchema.optional(),
185
+ /** Contribution/payment model (OPTIONAL) */
186
+ contribution: exports.ContributionObligationSchema.optional(),
187
+ })
188
+ .strict();
189
+ // =============================================================================
190
+ // VALIDATION HELPERS (v0.9.26+)
191
+ // =============================================================================
192
+ /**
193
+ * Validate a CreditObligation.
194
+ *
195
+ * @param data - Unknown data to validate
196
+ * @returns Result with validated obligation or error message
197
+ */
198
+ function validateCreditObligation(data) {
199
+ const result = exports.CreditObligationSchema.safeParse(data);
200
+ if (result.success) {
201
+ return { ok: true, value: result.data };
202
+ }
203
+ return { ok: false, error: result.error.message };
204
+ }
205
+ /**
206
+ * Validate a ContributionObligation.
207
+ *
208
+ * @param data - Unknown data to validate
209
+ * @returns Result with validated obligation or error message
210
+ */
211
+ function validateContributionObligation(data) {
212
+ const result = exports.ContributionObligationSchema.safeParse(data);
213
+ if (result.success) {
214
+ return { ok: true, value: result.data };
215
+ }
216
+ return { ok: false, error: result.error.message };
217
+ }
218
+ /**
219
+ * Validate an ObligationsExtension.
220
+ *
221
+ * @param data - Unknown data to validate
222
+ * @returns Result with validated extension or error message
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * const result = validateObligationsExtension(data);
227
+ * if (result.ok) {
228
+ * if (result.value.credit?.required) {
229
+ * console.log('Credit required:', result.value.credit.citation_url);
230
+ * }
231
+ * }
232
+ * ```
233
+ */
234
+ function validateObligationsExtension(data) {
235
+ const result = exports.ObligationsExtensionSchema.safeParse(data);
236
+ if (result.success) {
237
+ return { ok: true, value: result.data };
238
+ }
239
+ return { ok: false, error: result.error.message };
240
+ }
241
+ /**
242
+ * Extract obligations extension from a receipt's extensions object.
243
+ *
244
+ * @param extensions - Extensions object from receipt
245
+ * @returns Validated obligations or undefined if not present
246
+ */
247
+ function extractObligationsExtension(extensions) {
248
+ if (!extensions || !(exports.OBLIGATIONS_EXTENSION_KEY in extensions)) {
249
+ return undefined;
250
+ }
251
+ const result = validateObligationsExtension(extensions[exports.OBLIGATIONS_EXTENSION_KEY]);
252
+ if (result.ok) {
253
+ return result.value;
254
+ }
255
+ return undefined;
256
+ }
257
+ /**
258
+ * Check if credit is required based on obligations.
259
+ *
260
+ * @param obligations - Obligations extension
261
+ * @returns True if credit is explicitly required
262
+ */
263
+ function isCreditRequired(obligations) {
264
+ return obligations?.credit?.required === true;
265
+ }
266
+ /**
267
+ * Check if contribution is required (non-open type).
268
+ *
269
+ * @param obligations - Obligations extension
270
+ * @returns True if contribution type is 'direct' or 'ecosystem'
271
+ */
272
+ function isContributionRequired(obligations) {
273
+ const type = obligations?.contribution?.type;
274
+ return type === 'direct' || type === 'ecosystem';
275
+ }
276
+ /**
277
+ * Create a credit-only obligations extension.
278
+ *
279
+ * @param params - Credit parameters
280
+ * @returns ObligationsExtension with credit only
281
+ */
282
+ function createCreditObligation(params) {
283
+ const credit = { required: params.required };
284
+ if (params.citation_url)
285
+ credit.citation_url = params.citation_url;
286
+ if (params.method)
287
+ credit.method = params.method;
288
+ if (params.credit_text)
289
+ credit.credit_text = params.credit_text;
290
+ return { credit };
291
+ }
292
+ /**
293
+ * Create a contribution-only obligations extension.
294
+ *
295
+ * @param params - Contribution parameters
296
+ * @returns ObligationsExtension with contribution only
297
+ */
298
+ function createContributionObligation(params) {
299
+ const contribution = { type: params.type };
300
+ if (params.destination)
301
+ contribution.destination = params.destination;
302
+ if (params.min_amount !== undefined)
303
+ contribution.min_amount = params.min_amount;
304
+ if (params.currency)
305
+ contribution.currency = params.currency;
306
+ return { contribution };
307
+ }
308
+ /**
309
+ * Create a full obligations extension with both credit and contribution.
310
+ *
311
+ * @param credit - Credit obligation parameters
312
+ * @param contribution - Contribution obligation parameters
313
+ * @returns Full ObligationsExtension
314
+ */
315
+ function createObligationsExtension(credit, contribution) {
316
+ const result = {};
317
+ if (credit) {
318
+ result.credit = { required: credit.required };
319
+ if (credit.citation_url)
320
+ result.credit.citation_url = credit.citation_url;
321
+ if (credit.method)
322
+ result.credit.method = credit.method;
323
+ if (credit.credit_text)
324
+ result.credit.credit_text = credit.credit_text;
325
+ }
326
+ if (contribution) {
327
+ result.contribution = { type: contribution.type };
328
+ if (contribution.destination)
329
+ result.contribution.destination = contribution.destination;
330
+ if (contribution.min_amount !== undefined)
331
+ result.contribution.min_amount = contribution.min_amount;
332
+ if (contribution.currency)
333
+ result.contribution.currency = contribution.currency;
334
+ }
335
+ return result;
336
+ }
337
+ //# sourceMappingURL=obligations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obligations.js","sourceRoot":"","sources":["../src/obligations.ts"],"names":[],"mappings":";;;AAqNA,4DAQC;AAQD,wEAQC;AAkBD,oEAQC;AAQD,kEAYC;AAQD,4CAEC;AAQD,wDAGC;AAQD,wDAWC;AAQD,oEAWC;AASD,gEAgCC;AA/XD;;;;;;;;;;GAUG;AACH,6BAAwB;AAExB,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;GAMG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;AAGjF;;GAEG;AACU,QAAA,cAAc,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAU,CAAC;AAE9E,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF;;;;;;GAMG;AACU,QAAA,sBAAsB,GAAG,OAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;AAG9E;;GAEG;AACU,QAAA,kBAAkB,GAAG,CAAC,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAU,CAAC;AAE3E,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF;;;;;;;;;;;;;;GAcG;AACU,QAAA,sBAAsB,GAAG,OAAC;KACpC,MAAM,CAAC;IACN,4CAA4C;IAC5C,QAAQ,EAAE,OAAC,CAAC,OAAO,EAAE;IAErB,8CAA8C;IAC9C,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IAEnD,kFAAkF;IAClF,MAAM,EAAE,0BAAkB,CAAC,QAAQ,EAAE;IAErC,qDAAqD;IACrD,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;CAC7C,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACzB,gGAAgG;IAChG,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7E,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EACL,iGAAiG;YACnG,IAAI,EAAE,CAAC,UAAU,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAGL,gFAAgF;AAChF,qCAAqC;AACrC,gFAAgF;AAEhF;;;;;;;;;;;;;;;GAeG;AACU,QAAA,4BAA4B,GAAG,OAAC;KAC1C,MAAM,CAAC;IACN,sCAAsC;IACtC,IAAI,EAAE,8BAAsB;IAE5B,+EAA+E;IAC/E,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;IAE5C,4DAA4D;IAC5D,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAE9C,8EAA8E;IAC9E,QAAQ,EAAE,OAAC;SACR,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,KAAK,CAAC,iBAAiB,CAAC;SACxB,QAAQ,EAAE;CACd,CAAC;KACD,MAAM,EAAE;KACR,WAAW,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IACzB,8DAA8D;IAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/E,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,sDAAsD,IAAI,CAAC,IAAI,GAAG;YAC3E,IAAI,EAAE,CAAC,aAAa,CAAC;SACtB,CAAC,CAAC;IACL,CAAC;IACD,+BAA+B;IAC/B,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,OAAC,CAAC,YAAY,CAAC,MAAM;YAC3B,OAAO,EAAE,mDAAmD;YAC5D,IAAI,EAAE,CAAC,UAAU,CAAC;SACnB,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAGL,gFAAgF;AAChF,mCAAmC;AACnC,gFAAgF;AAEhF;;GAEG;AACU,QAAA,yBAAyB,GAAG,kBAA2B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACU,QAAA,0BAA0B,GAAG,OAAC;KACxC,MAAM,CAAC;IACN,gDAAgD;IAChD,MAAM,EAAE,8BAAsB,CAAC,QAAQ,EAAE;IAEzC,4CAA4C;IAC5C,YAAY,EAAE,oCAA4B,CAAC,QAAQ,EAAE;CACtD,CAAC;KACD,MAAM,EAAE,CAAC;AAGZ,gFAAgF;AAChF,gCAAgC;AAChC,gFAAgF;AAEhF;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,IAAa;IAEb,MAAM,MAAM,GAAG,8BAAsB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,8BAA8B,CAC5C,IAAa;IAEb,MAAM,MAAM,GAAG,oCAA4B,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,4BAA4B,CAC1C,IAAa;IAEb,MAAM,MAAM,GAAG,kCAA0B,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,2BAA2B,CACzC,UAA+C;IAE/C,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,iCAAyB,IAAI,UAAU,CAAC,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,4BAA4B,CAAC,UAAU,CAAC,iCAAyB,CAAC,CAAC,CAAC;IACnF,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,WAA6C;IAC5E,OAAO,WAAW,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;AAChD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,WAA6C;IAClF,MAAM,IAAI,GAAG,WAAW,EAAE,YAAY,EAAE,IAAI,CAAC;IAC7C,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,WAAW,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,MAKtC;IACC,MAAM,MAAM,GAAqB,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC/D,IAAI,MAAM,CAAC,YAAY;QAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IACnE,IAAI,MAAM,CAAC,MAAM;QAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACjD,IAAI,MAAM,CAAC,WAAW;QAAE,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAChE,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,4BAA4B,CAAC,MAK5C;IACC,MAAM,YAAY,GAA2B,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,MAAM,CAAC,WAAW;QAAE,YAAY,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACtE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;QAAE,YAAY,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACjF,IAAI,MAAM,CAAC,QAAQ;QAAE,YAAY,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7D,OAAO,EAAE,YAAY,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,0BAA0B,CACxC,MAKC,EACD,YAKC;IAED,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC9C,IAAI,MAAM,CAAC,YAAY;YAAE,MAAM,CAAC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QAC1E,IAAI,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACxD,IAAI,MAAM,CAAC,WAAW;YAAE,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACzE,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,YAAY,GAAG,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;QAClD,IAAI,YAAY,CAAC,WAAW;YAAE,MAAM,CAAC,YAAY,CAAC,WAAW,GAAG,YAAY,CAAC,WAAW,CAAC;QACzF,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS;YACvC,MAAM,CAAC,YAAY,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;QAC3D,IAAI,YAAY,CAAC,QAAQ;YAAE,MAAM,CAAC,YAAY,CAAC,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC;IAClF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,272 @@
1
+ /**
2
+ * PEAC Purpose Types (v0.9.24+)
3
+ *
4
+ * Purpose type hierarchy for forward-compatible purpose handling:
5
+ * - PurposeToken: Wire format (string) - preserves unknown tokens
6
+ * - CanonicalPurpose: PEAC's normative vocabulary - enforcement semantics
7
+ * - PurposeReason: Audit spine for enforcement decisions
8
+ *
9
+ * @see specs/kernel/constants.json for canonical values
10
+ */
11
+ /**
12
+ * PurposeToken - Wire format string with validation grammar
13
+ *
14
+ * Allows unknown tokens for forward compatibility. Any valid token
15
+ * that matches the grammar is accepted and preserved.
16
+ *
17
+ * Grammar: lowercase, max 64 chars, [a-z0-9_-] + optional vendor prefix (vendor:token)
18
+ * Hyphens allowed for interop with external systems (Cloudflare, IETF AIPREF, etc.)
19
+ *
20
+ * Examples: "train", "search", "user_action", "user-action", "cf:ai_crawler", "cf:ai-crawler"
21
+ */
22
+ export type PurposeToken = string;
23
+ /**
24
+ * CanonicalPurpose - PEAC's normative vocabulary
25
+ *
26
+ * These are the only tokens PEAC enforces semantics for.
27
+ * Matches specs/kernel/constants.json purpose.canonical_tokens.
28
+ *
29
+ * - train: Model training data collection
30
+ * - search: Traditional search indexing
31
+ * - user_action: Agent acting on user behalf (v0.9.24+)
32
+ * - inference: Runtime inference / RAG
33
+ * - index: Content indexing (store)
34
+ */
35
+ export type CanonicalPurpose = 'train' | 'search' | 'user_action' | 'inference' | 'index';
36
+ /**
37
+ * Internal-only purpose value (never valid on wire)
38
+ *
39
+ * Applied when PEAC-Purpose header is missing or empty.
40
+ * Explicit "undeclared" in request -> 400 Bad Request.
41
+ */
42
+ export type InternalPurpose = 'undeclared';
43
+ /**
44
+ * PurposeReason - Audit spine for enforcement decisions
45
+ *
46
+ * Captures WHY a purpose was enforced differently than declared.
47
+ * Matches specs/kernel/constants.json purpose.reason_values.
48
+ */
49
+ export type PurposeReason = 'allowed' | 'constrained' | 'denied' | 'downgraded' | 'undeclared_default' | 'unknown_preserved';
50
+ /**
51
+ * Legacy purpose tokens from pre-v0.9.24
52
+ *
53
+ * These are mapped to CanonicalPurpose via mapLegacyToCanonical().
54
+ * Retained for backward compatibility with existing ControlPurpose usage.
55
+ */
56
+ export type LegacyPurpose = 'crawl' | 'ai_input' | 'ai_index';
57
+ /**
58
+ * Grammar validation for PurposeToken
59
+ *
60
+ * Pattern: lowercase letter, optionally followed by alphanumeric/underscore/hyphen
61
+ * characters that MUST end with a letter or digit (no trailing separators).
62
+ * Optional vendor prefix separated by colon follows the same rules.
63
+ *
64
+ * Hyphens are allowed for interoperability with external systems (Cloudflare,
65
+ * IETF AIPREF, etc.) that use hyphenated tokens like "user-action" or "train-ai".
66
+ *
67
+ * Valid: "train", "user_action", "user-action", "cf:ai_crawler", "cf:ai-crawler", "a", "a1"
68
+ * Invalid: "Train", "123abc", "", "-train", "train-", "train_", "cf:ai-", "cf:-ai"
69
+ */
70
+ export declare const PURPOSE_TOKEN_REGEX: RegExp;
71
+ /** Maximum length for a purpose token */
72
+ export declare const MAX_PURPOSE_TOKEN_LENGTH = 64;
73
+ /** Maximum number of purpose tokens per request (RECOMMENDED, not MUST) */
74
+ export declare const MAX_PURPOSE_TOKENS_PER_REQUEST = 10;
75
+ /** Canonical purpose tokens (from constants.json) */
76
+ export declare const CANONICAL_PURPOSES: readonly CanonicalPurpose[];
77
+ /** Purpose reason values (from constants.json) */
78
+ export declare const PURPOSE_REASONS: readonly PurposeReason[];
79
+ /** Internal-only purpose value */
80
+ export declare const INTERNAL_PURPOSE_UNDECLARED: InternalPurpose;
81
+ /**
82
+ * Check if a string is a valid PurposeToken
83
+ *
84
+ * Validates against the purpose token grammar:
85
+ * - Lowercase letters, digits, underscores, hyphens
86
+ * - Optional vendor prefix with colon
87
+ * - Max 64 characters
88
+ * - Must start with lowercase letter
89
+ *
90
+ * @param token - String to validate
91
+ * @returns true if valid PurposeToken
92
+ */
93
+ export declare function isValidPurposeToken(token: string): token is PurposeToken;
94
+ /**
95
+ * Check if a PurposeToken is a CanonicalPurpose
96
+ *
97
+ * @param token - Token to check
98
+ * @returns true if token is in canonical vocabulary
99
+ */
100
+ export declare function isCanonicalPurpose(token: string): token is CanonicalPurpose;
101
+ /**
102
+ * Check if a PurposeToken is a LegacyPurpose
103
+ *
104
+ * @param token - Token to check
105
+ * @returns true if token is a legacy purpose
106
+ */
107
+ export declare function isLegacyPurpose(token: string): token is LegacyPurpose;
108
+ /**
109
+ * Check if a string is a valid PurposeReason
110
+ *
111
+ * @param reason - String to check
112
+ * @returns true if valid PurposeReason
113
+ */
114
+ export declare function isValidPurposeReason(reason: string): reason is PurposeReason;
115
+ /**
116
+ * Check if a purpose token is the internal-only "undeclared" value
117
+ *
118
+ * Used to reject explicit "undeclared" on wire (400 Bad Request).
119
+ *
120
+ * @param token - Token to check
121
+ * @returns true if token is "undeclared"
122
+ */
123
+ export declare function isUndeclaredPurpose(token: string): boolean;
124
+ /**
125
+ * Normalize a purpose token
126
+ *
127
+ * Applies normalization rules:
128
+ * - Trim whitespace
129
+ * - Lowercase
130
+ *
131
+ * @param token - Raw token from header
132
+ * @returns Normalized token
133
+ */
134
+ export declare function normalizePurposeToken(token: string): string;
135
+ /**
136
+ * Parse PEAC-Purpose header value into array of tokens
137
+ *
138
+ * Applies parsing rules:
139
+ * - Split on commas
140
+ * - Trim optional whitespace (OWS) around tokens
141
+ * - Lowercase all tokens
142
+ * - Drop empty tokens
143
+ * - Deduplicate
144
+ * - Preserve input order
145
+ *
146
+ * @param headerValue - Raw PEAC-Purpose header value
147
+ * @returns Array of normalized PurposeToken values
148
+ */
149
+ export declare function parsePurposeHeader(headerValue: string): PurposeToken[];
150
+ /**
151
+ * Validate parsed purpose tokens
152
+ *
153
+ * Returns validation result with:
154
+ * - valid: All tokens pass grammar validation
155
+ * - tokens: All normalized tokens (including invalid ones)
156
+ * - invalidTokens: Tokens that failed grammar validation
157
+ * - undeclaredPresent: true if explicit "undeclared" was found (should reject)
158
+ *
159
+ * @param tokens - Array of parsed tokens
160
+ * @returns Validation result
161
+ */
162
+ export interface PurposeValidationResult {
163
+ valid: boolean;
164
+ tokens: PurposeToken[];
165
+ invalidTokens: string[];
166
+ undeclaredPresent: boolean;
167
+ }
168
+ export declare function validatePurposeTokens(tokens: PurposeToken[]): PurposeValidationResult;
169
+ /**
170
+ * Derive known canonical purposes from declared tokens
171
+ *
172
+ * Filters purpose_declared to get only canonical purposes.
173
+ * This is a helper derivation, NOT stored on wire.
174
+ *
175
+ * @param declared - Array of declared PurposeTokens
176
+ * @returns Array of CanonicalPurpose tokens
177
+ */
178
+ export declare function deriveKnownPurposes(declared: PurposeToken[]): CanonicalPurpose[];
179
+ /**
180
+ * Map legacy purpose to canonical purpose
181
+ *
182
+ * Used for backward compatibility with pre-v0.9.24 ControlPurpose values.
183
+ *
184
+ * @param legacy - Legacy purpose token
185
+ * @returns Mapping result with canonical purpose and audit note
186
+ */
187
+ export interface LegacyMappingResult {
188
+ canonical: CanonicalPurpose;
189
+ mapping_note: string;
190
+ }
191
+ export declare function mapLegacyToCanonical(legacy: LegacyPurpose): LegacyMappingResult;
192
+ /**
193
+ * Normalize any purpose token (canonical, legacy, or unknown)
194
+ *
195
+ * Returns the canonical form if known, otherwise preserves the token.
196
+ *
197
+ * @param token - Any valid PurposeToken
198
+ * @returns Canonical purpose if mapped, otherwise original token
199
+ */
200
+ export declare function normalizeToCanonicalOrPreserve(token: PurposeToken): {
201
+ purpose: CanonicalPurpose;
202
+ mapped: false;
203
+ } | {
204
+ purpose: PurposeToken;
205
+ mapped: true;
206
+ from: LegacyPurpose;
207
+ } | {
208
+ purpose: PurposeToken;
209
+ mapped: false;
210
+ unknown: true;
211
+ };
212
+ /**
213
+ * Decision type for purpose reason determination
214
+ *
215
+ * Maps to policy decisions that affect purpose enforcement.
216
+ */
217
+ export type PurposeDecision = 'allowed' | 'constrained' | 'denied' | 'downgraded';
218
+ /**
219
+ * Context for determining purpose reason
220
+ */
221
+ export interface PurposeReasonContext {
222
+ /**
223
+ * Whether purposes were declared (PEAC-Purpose header present and non-empty).
224
+ * If false, reason will be 'undeclared_default'.
225
+ */
226
+ declared: boolean;
227
+ /**
228
+ * Whether any unknown (non-canonical) tokens are present in declared purposes.
229
+ * If true and declared is true, reason will be 'unknown_preserved'.
230
+ */
231
+ hasUnknownTokens: boolean;
232
+ /**
233
+ * The policy decision (only used if declared and no unknown tokens).
234
+ * Defaults to 'allowed' if not provided.
235
+ */
236
+ decision?: PurposeDecision;
237
+ }
238
+ /**
239
+ * Determine the appropriate PurposeReason based on context
240
+ *
241
+ * This helper implements the decision logic for the audit spine:
242
+ * 1. If no purposes declared -> 'undeclared_default'
243
+ * 2. If unknown tokens present -> 'unknown_preserved'
244
+ * 3. Otherwise -> maps to policy decision
245
+ *
246
+ * @param context - Context for determination
247
+ * @returns The appropriate PurposeReason for the audit spine
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * // Missing PEAC-Purpose header
252
+ * determinePurposeReason({ declared: false, hasUnknownTokens: false });
253
+ * // => 'undeclared_default'
254
+ *
255
+ * // Has vendor-prefixed tokens
256
+ * determinePurposeReason({ declared: true, hasUnknownTokens: true, decision: 'allowed' });
257
+ * // => 'unknown_preserved'
258
+ *
259
+ * // All canonical tokens, allowed by policy
260
+ * determinePurposeReason({ declared: true, hasUnknownTokens: false, decision: 'allowed' });
261
+ * // => 'allowed'
262
+ * ```
263
+ */
264
+ export declare function determinePurposeReason(context: PurposeReasonContext): PurposeReason;
265
+ /**
266
+ * Check if any tokens in an array are unknown (non-canonical)
267
+ *
268
+ * @param tokens - Array of purpose tokens
269
+ * @returns true if any token is not a canonical purpose
270
+ */
271
+ export declare function hasUnknownPurposeTokens(tokens: PurposeToken[]): boolean;
272
+ //# sourceMappingURL=purpose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purpose.d.ts","sourceRoot":"","sources":["../src/purpose.ts"],"names":[],"mappings":"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"}