@humanagencyp/hap-core 0.12.0 → 0.12.1

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.
package/dist/index.d.mts CHANGED
@@ -384,7 +384,23 @@ interface ContentBinding {
384
384
  * Absent → the binding applies to every gated action under the profile.
385
385
  */
386
386
  appliesTo?: string[];
387
+ /**
388
+ * v2 only — what kind of value each bound field holds, so a verifier (or any
389
+ * view) can collect and show it without guessing from the field's name:
390
+ * - `text` — one string (an email body);
391
+ * - `list` — an array of strings (recipients);
392
+ * - `files` — the sealed fingerprints of documents sent by reference:
393
+ * `[{ filename, sha256 }]` — never the bytes. A verifier asks for the
394
+ * files themselves and computes each SHA-256 locally.
395
+ *
396
+ * A hint only: it never changes what is hashed. Keys MUST be a subset of
397
+ * {@link fields}; a field without an entry is unspecified (a verifier may
398
+ * offer a choice, as before).
399
+ */
400
+ field_kinds?: Record<string, ContentFieldKind>;
387
401
  }
402
+ /** See {@link ContentBinding.field_kinds}. */
403
+ type ContentFieldKind = 'text' | 'list' | 'files';
388
404
  /**
389
405
  * Scope field definition within a profile (renamed from `ProfileContextField`
390
406
  * in v0.7 — protocol.md → *Migration from v0.6*, `contextSchema` → `scopeSchema`).
@@ -831,6 +847,14 @@ declare function selectBoundFields(binding: ContentBinding, args: Record<string,
831
847
  * {@link selectBoundFields} + {@link computeContentHash} for the common path.
832
848
  */
833
849
  declare function computeFieldsContentHash(binding: ContentBinding, args: Record<string, unknown>): string;
850
+ /**
851
+ * Why a binding's `field_kinds` is malformed, or null when it is fine (or
852
+ * absent). For profile validation — a malformed hint is a profile error, not
853
+ * a call-time refusal, because it never changes what is hashed.
854
+ */
855
+ declare function invalidFieldKindsReason(binding: ContentBinding): string | null;
856
+ /** The bound fields declared as `files` — sealed document fingerprints. */
857
+ declare function filesFields(binding: ContentBinding): string[];
834
858
 
835
859
  /**
836
860
  * Intent hashing + intent-disclosure binding (HAP v0.5).
@@ -1477,4 +1501,4 @@ declare function decodeDidKey(did: string): Uint8Array;
1477
1501
  /** True iff the DID decodes as a key-bearing Ed25519 did:key. Never throws. */
1478
1502
  declare function isKeyBearingDid(did: string): boolean;
1479
1503
 
1480
- export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, HapError, type HapErrorCode, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROTOCOL_VERSION, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, TICKET_ERROR_CODES, type TicketPayload, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, checkDiscloseSubset, checkMandateExpiry, checkOwnerSignatureRequirement, clearProfiles, computeBoundsHash, computeContentHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, deriveIdentityLine, encodeDidKey, encodeMandateBlob, fromBase64Url, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, listProfiles, mandateBlobId, negotiateVersion, projectionSigningBytes, publicTicketView, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, toBase64Url, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyTicketSignature };
1504
+ export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type ContentFieldKind, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, HapError, type HapErrorCode, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROTOCOL_VERSION, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, TICKET_ERROR_CODES, type TicketPayload, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, checkDiscloseSubset, checkMandateExpiry, checkOwnerSignatureRequirement, clearProfiles, computeBoundsHash, computeContentHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, deriveIdentityLine, encodeDidKey, encodeMandateBlob, filesFields, fromBase64Url, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, invalidFieldKindsReason, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, listProfiles, mandateBlobId, negotiateVersion, projectionSigningBytes, publicTicketView, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, toBase64Url, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyTicketSignature };
package/dist/index.d.ts CHANGED
@@ -384,7 +384,23 @@ interface ContentBinding {
384
384
  * Absent → the binding applies to every gated action under the profile.
385
385
  */
386
386
  appliesTo?: string[];
387
+ /**
388
+ * v2 only — what kind of value each bound field holds, so a verifier (or any
389
+ * view) can collect and show it without guessing from the field's name:
390
+ * - `text` — one string (an email body);
391
+ * - `list` — an array of strings (recipients);
392
+ * - `files` — the sealed fingerprints of documents sent by reference:
393
+ * `[{ filename, sha256 }]` — never the bytes. A verifier asks for the
394
+ * files themselves and computes each SHA-256 locally.
395
+ *
396
+ * A hint only: it never changes what is hashed. Keys MUST be a subset of
397
+ * {@link fields}; a field without an entry is unspecified (a verifier may
398
+ * offer a choice, as before).
399
+ */
400
+ field_kinds?: Record<string, ContentFieldKind>;
387
401
  }
402
+ /** See {@link ContentBinding.field_kinds}. */
403
+ type ContentFieldKind = 'text' | 'list' | 'files';
388
404
  /**
389
405
  * Scope field definition within a profile (renamed from `ProfileContextField`
390
406
  * in v0.7 — protocol.md → *Migration from v0.6*, `contextSchema` → `scopeSchema`).
@@ -831,6 +847,14 @@ declare function selectBoundFields(binding: ContentBinding, args: Record<string,
831
847
  * {@link selectBoundFields} + {@link computeContentHash} for the common path.
832
848
  */
833
849
  declare function computeFieldsContentHash(binding: ContentBinding, args: Record<string, unknown>): string;
850
+ /**
851
+ * Why a binding's `field_kinds` is malformed, or null when it is fine (or
852
+ * absent). For profile validation — a malformed hint is a profile error, not
853
+ * a call-time refusal, because it never changes what is hashed.
854
+ */
855
+ declare function invalidFieldKindsReason(binding: ContentBinding): string | null;
856
+ /** The bound fields declared as `files` — sealed document fingerprints. */
857
+ declare function filesFields(binding: ContentBinding): string[];
834
858
 
835
859
  /**
836
860
  * Intent hashing + intent-disclosure binding (HAP v0.5).
@@ -1477,4 +1501,4 @@ declare function decodeDidKey(did: string): Uint8Array;
1477
1501
  /** True iff the DID decodes as a key-bearing Ed25519 did:key. Never throws. */
1478
1502
  declare function isKeyBearingDid(did: string): boolean;
1479
1503
 
1480
- export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, HapError, type HapErrorCode, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROTOCOL_VERSION, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, TICKET_ERROR_CODES, type TicketPayload, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, checkDiscloseSubset, checkMandateExpiry, checkOwnerSignatureRequirement, clearProfiles, computeBoundsHash, computeContentHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, deriveIdentityLine, encodeDidKey, encodeMandateBlob, fromBase64Url, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, listProfiles, mandateBlobId, negotiateVersion, projectionSigningBytes, publicTicketView, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, toBase64Url, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyTicketSignature };
1504
+ export { type AgentBoundsParams, type AgentProfile, type AgentScopeParams, type ApprovalObject, type BoundType, CanonicalValueError, type ContentBinding, ContentBindingError, type ContentBindingErrorCode, type ContentFieldKind, type CumulativeFieldDef, type CumulativeWindow, type DeclaredFieldDef, type ExecutionContextFieldDef, type ExecutionLogEntry, type ExecutionLogQuery, type FieldConstraint, type FieldUnit, type GatekeeperError, type GatekeeperRequest, type GatekeeperResult, HapError, type HapErrorCode, MANDATE_ERROR_CODES, type Mandate, type MandateHeader, type MandateOwnerEntry, type MandatePayload, type MandateProjection, type OwnerSignatureBinding, OwnerSignatureError, PROTOCOL_VERSION, type ProfileBoundsField, type ProfileOwnerSignatureFloor, type ProfileScopeField, type ProfileValidationError, SIGNABLE_COMMITMENT_MODES, SUPPORTED_VERSIONS, type SignableCommitmentMode, type SigningSurface, type Subject, type SubjectValidation, TICKET_ERROR_CODES, type TicketPayload, type VerifyOptions, allowedCommitmentModes, approvalSigningBytes, bindingAppliesTo, boundActionTypes, buildMandateProjection, canonicalBounds, canonicalScope, canonicalize, canonicalizeText, checkDiscloseSubset, checkMandateExpiry, checkOwnerSignatureRequirement, clearProfiles, computeBoundsHash, computeContentHash, computeFieldsContentHash, computeIntentDisclosureHash, computeIntentHash, computeProfileHash, computeScopeHash, contentCanonicalBytes, decodeDidKey, decodeMandateBlob, deriveIdentityLine, encodeDidKey, encodeMandateBlob, filesFields, fromBase64Url, getAllProfiles, getProfile, intentDisclosureCanonicalBytes, invalidFieldKindsReason, isCommitmentModeAllowed, isFieldBinding, isKeyBearingDid, listProfiles, mandateBlobId, negotiateVersion, projectionSigningBytes, publicTicketView, registerProfile, selectBoundFields, signApproval, signMandate, signMandateProjection, signTicket, toBase64Url, validateBoundsParams, validateMandateOwners, validateProfile, validateScopeParams, validateSubject, verify, verifyApproval, verifyMandate, verifyMandateSignature, verifyOwnerSignature, verifyOwnerSignatures, verifyTicketSignature };
package/dist/index.js CHANGED
@@ -65,10 +65,12 @@ __export(index_exports, {
65
65
  deriveIdentityLine: () => deriveIdentityLine,
66
66
  encodeDidKey: () => encodeDidKey,
67
67
  encodeMandateBlob: () => encodeMandateBlob,
68
+ filesFields: () => filesFields,
68
69
  fromBase64Url: () => fromBase64Url,
69
70
  getAllProfiles: () => getAllProfiles,
70
71
  getProfile: () => getProfile,
71
72
  intentDisclosureCanonicalBytes: () => intentDisclosureCanonicalBytes,
73
+ invalidFieldKindsReason: () => invalidFieldKindsReason,
72
74
  isCommitmentModeAllowed: () => isCommitmentModeAllowed,
73
75
  isFieldBinding: () => isFieldBinding,
74
76
  isKeyBearingDid: () => isKeyBearingDid,
@@ -315,6 +317,20 @@ function selectBoundFields(binding, args) {
315
317
  function computeFieldsContentHash(binding, args) {
316
318
  return computeContentHash(binding, selectBoundFields(binding, args));
317
319
  }
320
+ var FIELD_KINDS = /* @__PURE__ */ new Set(["text", "list", "files"]);
321
+ function invalidFieldKindsReason(binding) {
322
+ const kinds = binding.field_kinds;
323
+ if (kinds === void 0) return null;
324
+ if (!kinds || typeof kinds !== "object" || Array.isArray(kinds)) return "field_kinds must be an object";
325
+ for (const [field, kind] of Object.entries(kinds)) {
326
+ if (!(binding.fields ?? []).includes(field)) return `field_kinds names "${field}", which is not in fields`;
327
+ if (!FIELD_KINDS.has(kind)) return `field_kinds.${field} must be one of text, list, files`;
328
+ }
329
+ return null;
330
+ }
331
+ function filesFields(binding) {
332
+ return Object.entries(binding.field_kinds ?? {}).filter(([, k]) => k === "files").map(([f]) => f);
333
+ }
318
334
 
319
335
  // src/intent-disclosure.ts
320
336
  var import_crypto2 = require("crypto");
@@ -1359,10 +1375,12 @@ function checkScopeConstraints(scope, execution, profile) {
1359
1375
  deriveIdentityLine,
1360
1376
  encodeDidKey,
1361
1377
  encodeMandateBlob,
1378
+ filesFields,
1362
1379
  fromBase64Url,
1363
1380
  getAllProfiles,
1364
1381
  getProfile,
1365
1382
  intentDisclosureCanonicalBytes,
1383
+ invalidFieldKindsReason,
1366
1384
  isCommitmentModeAllowed,
1367
1385
  isFieldBinding,
1368
1386
  isKeyBearingDid,
package/dist/index.mjs CHANGED
@@ -214,6 +214,20 @@ function selectBoundFields(binding, args) {
214
214
  function computeFieldsContentHash(binding, args) {
215
215
  return computeContentHash(binding, selectBoundFields(binding, args));
216
216
  }
217
+ var FIELD_KINDS = /* @__PURE__ */ new Set(["text", "list", "files"]);
218
+ function invalidFieldKindsReason(binding) {
219
+ const kinds = binding.field_kinds;
220
+ if (kinds === void 0) return null;
221
+ if (!kinds || typeof kinds !== "object" || Array.isArray(kinds)) return "field_kinds must be an object";
222
+ for (const [field, kind] of Object.entries(kinds)) {
223
+ if (!(binding.fields ?? []).includes(field)) return `field_kinds names "${field}", which is not in fields`;
224
+ if (!FIELD_KINDS.has(kind)) return `field_kinds.${field} must be one of text, list, files`;
225
+ }
226
+ return null;
227
+ }
228
+ function filesFields(binding) {
229
+ return Object.entries(binding.field_kinds ?? {}).filter(([, k]) => k === "files").map(([f]) => f);
230
+ }
217
231
 
218
232
  // src/intent-disclosure.ts
219
233
  import { createHash as createHash2 } from "crypto";
@@ -1257,10 +1271,12 @@ export {
1257
1271
  deriveIdentityLine,
1258
1272
  encodeDidKey,
1259
1273
  encodeMandateBlob,
1274
+ filesFields,
1260
1275
  fromBase64Url,
1261
1276
  getAllProfiles,
1262
1277
  getProfile,
1263
1278
  intentDisclosureCanonicalBytes,
1279
+ invalidFieldKindsReason,
1264
1280
  isCommitmentModeAllowed,
1265
1281
  isFieldBinding,
1266
1282
  isKeyBearingDid,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanagencyp/hap-core",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Core types, cryptographic primitives, and verification logic for the Human Agency Protocol",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
 
32
32
  import { createHash } from 'crypto';
33
33
  import { canonicalize } from './canonicalize';
34
- import type { ContentBinding } from './types';
34
+ import type { ContentBinding, ContentFieldKind } from './types';
35
35
 
36
36
  /**
37
37
  * Canonicalize free text per the v0.5 'text' rule. Idempotent.
@@ -249,3 +249,28 @@ export function computeFieldsContentHash(
249
249
  ): string {
250
250
  return computeContentHash(binding, selectBoundFields(binding, args));
251
251
  }
252
+
253
+ // ─── Field kinds (display / verification hint) ───────────────────────────────
254
+
255
+ const FIELD_KINDS = new Set<ContentFieldKind>(['text', 'list', 'files']);
256
+
257
+ /**
258
+ * Why a binding's `field_kinds` is malformed, or null when it is fine (or
259
+ * absent). For profile validation — a malformed hint is a profile error, not
260
+ * a call-time refusal, because it never changes what is hashed.
261
+ */
262
+ export function invalidFieldKindsReason(binding: ContentBinding): string | null {
263
+ const kinds = binding.field_kinds;
264
+ if (kinds === undefined) return null;
265
+ if (!kinds || typeof kinds !== 'object' || Array.isArray(kinds)) return 'field_kinds must be an object';
266
+ for (const [field, kind] of Object.entries(kinds)) {
267
+ if (!(binding.fields ?? []).includes(field)) return `field_kinds names "${field}", which is not in fields`;
268
+ if (!FIELD_KINDS.has(kind)) return `field_kinds.${field} must be one of text, list, files`;
269
+ }
270
+ return null;
271
+ }
272
+
273
+ /** The bound fields declared as `files` — sealed document fingerprints. */
274
+ export function filesFields(binding: ContentBinding): string[] {
275
+ return Object.entries(binding.field_kinds ?? {}).filter(([, k]) => k === 'files').map(([f]) => f);
276
+ }
package/src/types.ts CHANGED
@@ -359,8 +359,25 @@ export interface ContentBinding {
359
359
  * Absent → the binding applies to every gated action under the profile.
360
360
  */
361
361
  appliesTo?: string[];
362
+ /**
363
+ * v2 only — what kind of value each bound field holds, so a verifier (or any
364
+ * view) can collect and show it without guessing from the field's name:
365
+ * - `text` — one string (an email body);
366
+ * - `list` — an array of strings (recipients);
367
+ * - `files` — the sealed fingerprints of documents sent by reference:
368
+ * `[{ filename, sha256 }]` — never the bytes. A verifier asks for the
369
+ * files themselves and computes each SHA-256 locally.
370
+ *
371
+ * A hint only: it never changes what is hashed. Keys MUST be a subset of
372
+ * {@link fields}; a field without an entry is unspecified (a verifier may
373
+ * offer a choice, as before).
374
+ */
375
+ field_kinds?: Record<string, ContentFieldKind>;
362
376
  }
363
377
 
378
+ /** See {@link ContentBinding.field_kinds}. */
379
+ export type ContentFieldKind = 'text' | 'list' | 'files';
380
+
364
381
  /**
365
382
  * Scope field definition within a profile (renamed from `ProfileContextField`
366
383
  * in v0.7 — protocol.md → *Migration from v0.6*, `contextSchema` → `scopeSchema`).