@humanagencyp/hap-core 0.4.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.
package/src/types.ts ADDED
@@ -0,0 +1,333 @@
1
+ /**
2
+ * HAP Core Types — Agent Demo
3
+ *
4
+ * Types for agent-oriented profiles with bounded execution.
5
+ */
6
+
7
+ // ─── Attestation Types ───────────────────────────────────────────────────────
8
+
9
+ export interface AttestationHeader {
10
+ typ: 'HAP-attestation';
11
+ alg: 'EdDSA';
12
+ kid?: string;
13
+ }
14
+
15
+ export interface ResolvedDomain {
16
+ domain: string;
17
+ did: string;
18
+ }
19
+
20
+ export interface AttestationPayload {
21
+ attestation_id: string;
22
+ version: '0.3' | '0.4';
23
+ profile_id: string;
24
+ /** v0.3 (deprecated) — hash of the authorization frame */
25
+ frame_hash?: string;
26
+ /** v0.4 — hash of the bounds parameters */
27
+ bounds_hash?: string;
28
+ /** v0.4 — hash of the context parameters */
29
+ context_hash?: string;
30
+ execution_context_hash: string;
31
+ resolved_domains: ResolvedDomain[];
32
+ gate_content_hashes: Record<string, string>;
33
+ issued_at: number;
34
+ expires_at: number;
35
+ }
36
+
37
+ export interface Attestation {
38
+ header: AttestationHeader;
39
+ payload: AttestationPayload;
40
+ signature: string;
41
+ }
42
+
43
+ // ─── Profile Types ───────────────────────────────────────────────────────────
44
+
45
+ /**
46
+ * Field constraint type — what kind of bound a field supports.
47
+ * - max: numeric upper bound (actual <= bound)
48
+ * - enum: value must be in the allowed set
49
+ * - subset: every item in actual must appear in bound (comma-separated, case-insensitive)
50
+ */
51
+ export interface FieldConstraint {
52
+ type: 'number' | 'string';
53
+ enforceable: Array<'max' | 'enum' | 'subset'>;
54
+ }
55
+
56
+ /**
57
+ * Frame field definition within a profile.
58
+ */
59
+ export interface ProfileFrameField {
60
+ type: 'string' | 'number';
61
+ required: boolean;
62
+ description?: string;
63
+ constraint?: FieldConstraint;
64
+ enum?: string[];
65
+ }
66
+
67
+ /**
68
+ * Bounds field definition within a v0.4 profile.
69
+ */
70
+ export interface ProfileBoundsField {
71
+ type: 'string' | 'number';
72
+ required: boolean;
73
+ description?: string;
74
+ displayName?: string;
75
+ format?: 'email' | 'domain' | 'url' | 'currency';
76
+ constraint?: FieldConstraint;
77
+ enum?: string[];
78
+ }
79
+
80
+ /**
81
+ * Context field definition within a v0.4 profile.
82
+ */
83
+ export interface ProfileContextField {
84
+ type: 'string' | 'number';
85
+ required: boolean;
86
+ description?: string;
87
+ displayName?: string;
88
+ format?: 'email' | 'domain' | 'url' | 'currency';
89
+ constraint?: FieldConstraint;
90
+ enum?: string[];
91
+ }
92
+
93
+ /**
94
+ * Execution context field definition — declared source (value comes from the agent's tool call).
95
+ */
96
+ export interface DeclaredFieldDef {
97
+ source: 'declared';
98
+ description: string;
99
+ required: boolean;
100
+ constraint?: FieldConstraint;
101
+ }
102
+
103
+ /**
104
+ * Cumulative window types for stateful limit tracking.
105
+ */
106
+ export type CumulativeWindow = 'daily' | 'weekly' | 'monthly';
107
+
108
+ /**
109
+ * Execution context field definition — cumulative source (resolved from execution log).
110
+ *
111
+ * The gatekeeper resolves these by querying the execution log:
112
+ * - `cumulativeField`: which declared field to sum (use "_count" for plain counting)
113
+ * - `window`: time window for aggregation (daily, weekly, monthly)
114
+ *
115
+ * The resolved value = running total within window + current call value.
116
+ */
117
+ export interface CumulativeFieldDef {
118
+ source: 'cumulative';
119
+ cumulativeField: string;
120
+ window: CumulativeWindow;
121
+ description: string;
122
+ required: boolean;
123
+ constraint?: FieldConstraint;
124
+ }
125
+
126
+ /**
127
+ * Execution context field definition — either declared or cumulative.
128
+ */
129
+ export type ExecutionContextFieldDef = DeclaredFieldDef | CumulativeFieldDef;
130
+
131
+ /**
132
+ * Gate question definition.
133
+ */
134
+ export interface GateQuestion {
135
+ question: string;
136
+ required: boolean;
137
+ }
138
+
139
+ /**
140
+ * Execution path definition within a profile.
141
+ */
142
+ export interface ExecutionPath {
143
+ description: string;
144
+ requiredDomains?: string[]; // v0.3: defined in profile. v0.4: moved to SP group config.
145
+ ttl?: { default: number; max: number };
146
+ }
147
+
148
+ /**
149
+ * Agent Profile — defines constraint types, execution paths, gate questions,
150
+ * and the frame/bounds/context schemas for bounded execution.
151
+ *
152
+ * Supports both v0.3 (frameSchema) and v0.4 (boundsSchema + contextSchema).
153
+ */
154
+ export interface AgentProfile {
155
+ id: string;
156
+ name?: string;
157
+ version: string;
158
+ description: string;
159
+
160
+ /**
161
+ * v0.3 frame schema (deprecated, kept for backward compat).
162
+ * Used when boundsSchema is not present.
163
+ */
164
+ frameSchema?: {
165
+ keyOrder: string[];
166
+ fields: Record<string, ProfileFrameField>;
167
+ };
168
+
169
+ /**
170
+ * v0.4 bounds schema — defines the authorization bounds parameters.
171
+ */
172
+ boundsSchema?: {
173
+ keyOrder: string[];
174
+ fields: Record<string, ProfileBoundsField>;
175
+ };
176
+
177
+ /**
178
+ * v0.4 context schema — defines the execution context parameters (e.g., currency, action_type).
179
+ * May be absent or empty for profiles with no static context.
180
+ */
181
+ contextSchema?: {
182
+ keyOrder: string[];
183
+ fields: Record<string, ProfileContextField>;
184
+ };
185
+
186
+ executionContextSchema: {
187
+ fields: Record<string, ExecutionContextFieldDef>;
188
+ };
189
+
190
+ executionPaths: Record<string, ExecutionPath>;
191
+
192
+ requiredGates: string[];
193
+
194
+ gateQuestions: {
195
+ problem: GateQuestion;
196
+ objective: GateQuestion;
197
+ tradeoffs: GateQuestion;
198
+ };
199
+
200
+ ttl: { default: number; max: number };
201
+ retention_minimum: number;
202
+
203
+ /**
204
+ * Tool gating configuration — how MCP tools map to execution context.
205
+ * @deprecated Tool gating now lives in integration manifests (content/integrations/*.json).
206
+ * Kept for backward compatibility with profiles that still include it.
207
+ */
208
+ toolGating?: ProfileToolGating;
209
+ }
210
+
211
+ // ─── Tool Gating Types ───────────────────────────────────────────────────
212
+
213
+ /**
214
+ * Available transforms for array-aware execution mappings.
215
+ * - length: array length → number
216
+ * - join: array items joined by comma → string
217
+ * - join_domains: extract email domains, deduplicate, sort, join → string
218
+ */
219
+ export type ExecutionMappingTransform = 'join' | 'join_domains' | 'length';
220
+
221
+ /**
222
+ * Execution mapping value — how a tool argument maps to execution context field(s).
223
+ * - string: direct copy (argName → fieldName)
224
+ * - { field, divisor }: numeric division (e.g., cents ÷ 100 → EUR)
225
+ * - { field, transform }: array transform (e.g., join_domains)
226
+ * - Array form: one argument maps to multiple execution fields
227
+ */
228
+ export type ExecutionMappingValue =
229
+ | string
230
+ | { field: string; divisor: number }
231
+ | { field: string; transform: ExecutionMappingTransform }
232
+ | Array<{ field: string; divisor?: number; transform?: ExecutionMappingTransform }>;
233
+
234
+ /**
235
+ * Tool gating entry — how a tool's calls map to execution context fields.
236
+ * Read-only tools use { category: "read" } — they require authorization
237
+ * but skip execution context verification.
238
+ */
239
+ export interface ProfileToolGatingEntry {
240
+ executionMapping: Record<string, ExecutionMappingValue>;
241
+ staticExecution?: Record<string, string | number>;
242
+ /** Read-only tools: require authorization but no execution context checks */
243
+ category?: 'read';
244
+ }
245
+
246
+ /**
247
+ * Profile-level tool gating configuration.
248
+ * - default: applied to all tools not listed in overrides
249
+ * - overrides: per-tool configs keyed by original MCP tool name
250
+ * Use { category: "read" } for read-only tools (null is deprecated)
251
+ */
252
+ export interface ProfileToolGating {
253
+ default: ProfileToolGatingEntry;
254
+ overrides?: Record<string, ProfileToolGatingEntry | null>;
255
+ }
256
+
257
+ // ─── Execution Log Types ─────────────────────────────────────────────────────
258
+
259
+ /**
260
+ * A recorded execution — stored after gatekeeper approval for cumulative tracking.
261
+ */
262
+ export interface ExecutionLogEntry {
263
+ profileId: string;
264
+ path: string;
265
+ execution: Record<string, string | number>;
266
+ timestamp: number; // Unix seconds
267
+ }
268
+
269
+ /**
270
+ * Interface for querying cumulative execution data.
271
+ * Implementations live in the MCP server layer (not hap-core).
272
+ */
273
+ export interface ExecutionLogQuery {
274
+ /**
275
+ * Sum a field's values within a time window for a given profile.
276
+ * Use field="_count" to count executions instead of summing a field.
277
+ */
278
+ sumByWindow(profileId: string, path: string, field: string, window: CumulativeWindow, now?: number): number;
279
+ }
280
+
281
+ // ─── Frame Types ─────────────────────────────────────────────────────────────
282
+
283
+ /**
284
+ * Agent frame parameters — mixed types (strings and numbers).
285
+ * Keys and values come from the profile's frameSchema.
286
+ */
287
+ export type AgentFrameParams = Record<string, string | number>;
288
+
289
+ /**
290
+ * Agent bounds parameters — mixed types (strings and numbers).
291
+ * Keys and values come from the profile's boundsSchema (v0.4).
292
+ */
293
+ export type AgentBoundsParams = Record<string, string | number>;
294
+
295
+ /**
296
+ * Agent context parameters — mixed types (strings and numbers).
297
+ * Keys and values come from the profile's contextSchema (v0.4).
298
+ */
299
+ export type AgentContextParams = Record<string, string | number>;
300
+
301
+ // ─── Gatekeeper Types ────────────────────────────────────────────────────────
302
+
303
+ /**
304
+ * Request to the Gatekeeper for bounded execution verification.
305
+ */
306
+ export interface GatekeeperRequest {
307
+ /** The authorization frame (what was attested to) — v0.3 */
308
+ frame: AgentFrameParams;
309
+ /** Attestation blobs (base64url) for each domain */
310
+ attestations: string[];
311
+ /** The agent's execution values for this specific action */
312
+ execution: Record<string, string | number>;
313
+ /** v0.4: context parameters (currency, action_type, etc.) */
314
+ context?: AgentContextParams;
315
+ }
316
+
317
+ /**
318
+ * Structured error from Gatekeeper verification.
319
+ */
320
+ export interface GatekeeperError {
321
+ code: 'BOUND_EXCEEDED' | 'CUMULATIVE_LIMIT_EXCEEDED' | 'INVALID_SIGNATURE' | 'TTL_EXPIRED' | 'FRAME_MISMATCH' | 'BOUNDS_MISMATCH' | 'CONTEXT_MISMATCH' | 'DOMAIN_NOT_COVERED' | 'INVALID_PROFILE' | 'MALFORMED_ATTESTATION';
322
+ field?: string;
323
+ message: string;
324
+ bound?: string | number;
325
+ actual?: string | number;
326
+ }
327
+
328
+ /**
329
+ * Gatekeeper verification result.
330
+ */
331
+ export type GatekeeperResult =
332
+ | { approved: true }
333
+ | { approved: false; errors: GatekeeperError[] };