@suveren/gateway 0.2.8 → 0.2.9
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/mcp-server/http.mjs +22 -3
- package/package.json +1 -1
- package/profiles/README.md +209 -0
- package/profiles/calendar/0.4.profile.json +183 -0
- package/profiles/charge/0.3.profile.json +173 -0
- package/profiles/charge/0.4.profile.json +200 -0
- package/profiles/customers/0.4.profile.json +111 -0
- package/profiles/email/0.3.profile.json +119 -0
- package/profiles/email/0.4.profile.json +174 -0
- package/profiles/index.json +12 -0
- package/profiles/publish/0.4.profile.json +174 -0
- package/profiles/purchase/0.4.profile.json +225 -0
- package/profiles/records/0.4.profile.json +105 -0
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -2244,7 +2244,7 @@ function loadProfiles(profilesDir) {
|
|
|
2244
2244
|
const dir = resolve(profilesDir ?? process.env.SUVEREN_PROFILES_DIR ?? join6(import.meta.dirname ?? __dirname, "..", "..", "..", "..", "..", "hap-profiles"));
|
|
2245
2245
|
const indexPath = join6(dir, "index.json");
|
|
2246
2246
|
if (!existsSync6(indexPath)) {
|
|
2247
|
-
|
|
2247
|
+
warnNoProfiles(`No index.json at ${indexPath}`);
|
|
2248
2248
|
return 0;
|
|
2249
2249
|
}
|
|
2250
2250
|
let index;
|
|
@@ -2269,9 +2269,26 @@ function loadProfiles(profilesDir) {
|
|
|
2269
2269
|
console.error(`[ProfileLoader] Failed to load profile ${profileId} from ${profilePath}:`, err);
|
|
2270
2270
|
}
|
|
2271
2271
|
}
|
|
2272
|
-
|
|
2272
|
+
if (loaded === 0) {
|
|
2273
|
+
warnNoProfiles(`index.json at ${indexPath} registered 0 profiles`);
|
|
2274
|
+
} else {
|
|
2275
|
+
console.error(`[ProfileLoader] Loaded ${loaded} profile(s) from ${dir}`);
|
|
2276
|
+
}
|
|
2273
2277
|
return loaded;
|
|
2274
2278
|
}
|
|
2279
|
+
function warnNoProfiles(reason) {
|
|
2280
|
+
console.error(
|
|
2281
|
+
`
|
|
2282
|
+
\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
2283
|
+
\u2551 \u26A0 NO PROFILES LOADED \u2014 every gated action will be REJECTED with \u2551
|
|
2284
|
+
\u2551 "Unknown profile". This gateway is misconfigured. \u2551
|
|
2285
|
+
\u2551 Reason: ${reason}
|
|
2286
|
+
\u2551 Fix: install a build that bundles profiles, or set \u2551
|
|
2287
|
+
\u2551 SUVEREN_PROFILES_DIR to a hap-profiles checkout, then restart. \u2551
|
|
2288
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
2289
|
+
`
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2275
2292
|
|
|
2276
2293
|
// src/lib/manifest-loader.ts
|
|
2277
2294
|
import { readFileSync as readFileSync6, existsSync as existsSync7 } from "fs";
|
|
@@ -2605,11 +2622,13 @@ app.all("/mcp", async (req, res) => {
|
|
|
2605
2622
|
res.status(405).json({ error: "Method not allowed" });
|
|
2606
2623
|
}
|
|
2607
2624
|
});
|
|
2625
|
+
var profilesLoaded = 0;
|
|
2608
2626
|
app.get("/health", (_req, res) => {
|
|
2609
2627
|
res.json({
|
|
2610
2628
|
status: "ok",
|
|
2611
2629
|
transports: ["sse", "streamable-http"],
|
|
2612
2630
|
sp: spUrl,
|
|
2631
|
+
profilesLoaded,
|
|
2613
2632
|
activeSessions: activeSessions.size,
|
|
2614
2633
|
storedGates: state.gateStore.getAll().length,
|
|
2615
2634
|
serviceCredentials: Array.from(serviceCredentials.keys()),
|
|
@@ -2699,7 +2718,7 @@ app.listen(port, "0.0.0.0", () => {
|
|
|
2699
2718
|
console.error(`[Suveren MCP] SSE: http://0.0.0.0:${port}/sse`);
|
|
2700
2719
|
console.error(`[Suveren MCP] Streamable: http://0.0.0.0:${port}/mcp`);
|
|
2701
2720
|
console.error(`[Suveren MCP] SP server: ${spUrl}`);
|
|
2702
|
-
loadProfiles();
|
|
2721
|
+
profilesLoaded = loadProfiles();
|
|
2703
2722
|
loadManifests();
|
|
2704
2723
|
if (integrationRegistry.getEnabled().length === 0) {
|
|
2705
2724
|
const personalManifests = getAllManifests().filter((m) => m.personalDefault);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suveren/gateway",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# HAP Authority Profiles
|
|
2
|
+
|
|
3
|
+
Authorization templates for the [Human Agency Protocol](https://humanagencyprotocol.org). Each profile defines what an AI agent is allowed to do within a specific domain — the bounds a human sets, and the Gatekeeper enforces.
|
|
4
|
+
|
|
5
|
+
> **Version 0.4** — March 2026
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What Profiles Define
|
|
10
|
+
|
|
11
|
+
A profile is a complete authorization schema. It specifies:
|
|
12
|
+
|
|
13
|
+
- **Bounds schema** — the limits a human commits to (e.g., max amount, allowed currencies)
|
|
14
|
+
- **Context schema** — local parameters that stay encrypted (e.g., allowed services, environment)
|
|
15
|
+
- **Execution context** — what the Gatekeeper checks at runtime, including cumulative limits
|
|
16
|
+
- **Execution paths** — governance tiers with required domain owners and TTLs
|
|
17
|
+
- **Gates** — the structured questions a human must answer before authorization
|
|
18
|
+
|
|
19
|
+
Profiles are referenced by ID (e.g., `charge@0.4`) and are immutable once published.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Profiles
|
|
24
|
+
|
|
25
|
+
### charge — Charge Authority
|
|
26
|
+
|
|
27
|
+
Governs charging customers: payments, refunds, subscriptions.
|
|
28
|
+
|
|
29
|
+
| Bound | Type | Purpose |
|
|
30
|
+
|-------|------|---------|
|
|
31
|
+
| `amount_max` | per-transaction | Maximum monetary amount |
|
|
32
|
+
| `amount_daily_max` | cumulative | Daily charge cap |
|
|
33
|
+
| `amount_monthly_max` | cumulative | Monthly charge cap |
|
|
34
|
+
| `transaction_count_daily_max` | cumulative | Daily transaction limit |
|
|
35
|
+
|
|
36
|
+
| Context | Type | Purpose |
|
|
37
|
+
|---------|------|---------|
|
|
38
|
+
| `currency` | enum | Permitted currencies |
|
|
39
|
+
| `action_type` | enum | charge, refund, subscribe |
|
|
40
|
+
|
|
41
|
+
| Path | Default TTL |
|
|
42
|
+
|------|-------------|
|
|
43
|
+
| `charge-routine` | 24h |
|
|
44
|
+
| `charge-reviewed` | 4h |
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### purchase — Purchase Authority
|
|
49
|
+
|
|
50
|
+
Governs spending company money: subscriptions, supplies, services, advertising.
|
|
51
|
+
|
|
52
|
+
| Bound | Type | Purpose |
|
|
53
|
+
|-------|------|---------|
|
|
54
|
+
| `spend_max` | per-transaction | Maximum spend amount |
|
|
55
|
+
| `spend_daily_max` | cumulative | Daily spend cap |
|
|
56
|
+
| `spend_monthly_max` | cumulative | Monthly spend cap |
|
|
57
|
+
| `transaction_count_daily_max` | cumulative | Daily transaction limit |
|
|
58
|
+
|
|
59
|
+
| Context | Type | Purpose |
|
|
60
|
+
|---------|------|---------|
|
|
61
|
+
| `currency` | enum | Permitted currencies |
|
|
62
|
+
| `category` | enum | subscription, supply, service, advertising |
|
|
63
|
+
| `allowed_vendors` | subset | Approved vendor names |
|
|
64
|
+
|
|
65
|
+
| Path | Default TTL |
|
|
66
|
+
|------|-------------|
|
|
67
|
+
| `purchase-routine` | 24h |
|
|
68
|
+
| `purchase-reviewed` | 4h |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### email — Email Authority
|
|
73
|
+
|
|
74
|
+
Governs sending, drafting, and reading email via Gmail.
|
|
75
|
+
|
|
76
|
+
| Bound | Type | Purpose |
|
|
77
|
+
|-------|------|---------|
|
|
78
|
+
| `recipient_max` | per-email | Maximum recipients |
|
|
79
|
+
| `send_daily_max` | cumulative | Daily send/draft limit |
|
|
80
|
+
| `read_max_age_days` | per-query | Max email age for search |
|
|
81
|
+
| `read_daily_max` | cumulative | Daily read limit |
|
|
82
|
+
|
|
83
|
+
| Context | Type | Purpose |
|
|
84
|
+
|---------|------|---------|
|
|
85
|
+
| `allowed_recipients` | subset | Permitted email addresses |
|
|
86
|
+
| `allowed_domains` | subset | Permitted recipient domains |
|
|
87
|
+
|
|
88
|
+
| Path | Default TTL |
|
|
89
|
+
|------|-------------|
|
|
90
|
+
| `email-draft` | 24h |
|
|
91
|
+
| `email-send` | 4h |
|
|
92
|
+
| `email-read` | 24h |
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### customers — Customer Management
|
|
97
|
+
|
|
98
|
+
Governs CRM operations: contacts, activities, deals, tasks.
|
|
99
|
+
|
|
100
|
+
| Bound | Type | Purpose |
|
|
101
|
+
|-------|------|---------|
|
|
102
|
+
| `write_daily_max` | cumulative | Daily write operations |
|
|
103
|
+
|
|
104
|
+
| Context | Type | Purpose |
|
|
105
|
+
|---------|------|---------|
|
|
106
|
+
| `contact_type` | subset | customer, lead, partner, vendor |
|
|
107
|
+
|
|
108
|
+
| Path | Default TTL |
|
|
109
|
+
|------|-------------|
|
|
110
|
+
| `customers-read` | 24h |
|
|
111
|
+
| `customers-write` | 8h |
|
|
112
|
+
| `customers-delete` | 2h |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### schedule — Scheduling Authority
|
|
117
|
+
|
|
118
|
+
Governs calendar access: reading, drafting, and booking events.
|
|
119
|
+
|
|
120
|
+
| Bound | Type | Purpose |
|
|
121
|
+
|-------|------|---------|
|
|
122
|
+
| `booking_daily_max` | cumulative | Daily new bookings |
|
|
123
|
+
| `booking_duration_max` | per-event | Max event duration (minutes) |
|
|
124
|
+
| `lookahead_days_max` | per-event | Max days into the future |
|
|
125
|
+
|
|
126
|
+
| Context | Type | Purpose |
|
|
127
|
+
|---------|------|---------|
|
|
128
|
+
| `allowed_calendars` | subset | Permitted calendar names |
|
|
129
|
+
| `allowed_attendees` | subset | Permitted attendee emails |
|
|
130
|
+
| `allowed_domains` | subset | Permitted attendee domains |
|
|
131
|
+
|
|
132
|
+
| Path | Default TTL |
|
|
133
|
+
|------|-------------|
|
|
134
|
+
| `schedule-read` | 24h |
|
|
135
|
+
| `schedule-draft` | 24h |
|
|
136
|
+
| `schedule-book` | 4h |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### publish — Content Publishing
|
|
141
|
+
|
|
142
|
+
Governs posting public content to social media, blogs, and other platforms.
|
|
143
|
+
|
|
144
|
+
| Bound | Type | Purpose |
|
|
145
|
+
|-------|------|---------|
|
|
146
|
+
| `post_daily_max` | cumulative | Daily post limit |
|
|
147
|
+
| `post_monthly_max` | cumulative | Monthly post limit |
|
|
148
|
+
|
|
149
|
+
| Context | Type | Purpose |
|
|
150
|
+
|---------|------|---------|
|
|
151
|
+
| `allowed_platforms` | subset | twitter, linkedin, instagram, blog, medium |
|
|
152
|
+
| `content_type` | enum | text, image, link, thread |
|
|
153
|
+
| `audience` | enum | public, followers, connections |
|
|
154
|
+
|
|
155
|
+
| Path | Default TTL |
|
|
156
|
+
|------|-------------|
|
|
157
|
+
| `publish-draft` | 24h |
|
|
158
|
+
| `publish-post` | 4h |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### records — Records Authority
|
|
163
|
+
|
|
164
|
+
Governs accessing and modifying personal structured data: queries, schema changes, exports. Renamed from `data` — for personal databases and spreadsheet replacements, not shared CRM data.
|
|
165
|
+
|
|
166
|
+
| Bound | Type | Purpose |
|
|
167
|
+
|-------|------|---------|
|
|
168
|
+
| `row_limit_max` | per-query | Maximum rows returned |
|
|
169
|
+
| `query_count_daily_max` | cumulative | Daily query limit |
|
|
170
|
+
| `export_row_count_daily_max` | cumulative | Daily exported row limit |
|
|
171
|
+
|
|
172
|
+
| Context | Type | Purpose |
|
|
173
|
+
|---------|------|---------|
|
|
174
|
+
| `access_level` | enum | read, write, admin |
|
|
175
|
+
| `data_scope` | enum | public, internal, pii |
|
|
176
|
+
| `scope` | enum | external (production), internal (sandbox) |
|
|
177
|
+
|
|
178
|
+
| Path | Default TTL |
|
|
179
|
+
|------|-------------|
|
|
180
|
+
| `records-read` | 8h |
|
|
181
|
+
| `records-write` | 2h |
|
|
182
|
+
| `records-export` | 1h |
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## How Profiles Work
|
|
187
|
+
|
|
188
|
+
A human creates an authorization by selecting a profile and execution path, setting the bounds, and answering the gate questions. Domain owners cryptographically attest to the bounds. The Gatekeeper then enforces those bounds on every tool call:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
Human sets bounds Agent requests execution Gatekeeper checks
|
|
192
|
+
amount_max: 80 EUR -> amount: 5 EUR -> 5 <= 80, approved
|
|
193
|
+
action_type: [charge] action_type: "charge" "charge" in [charge], approved
|
|
194
|
+
amount_daily_max: 500 amount_daily: 423 (from log) 423 + 5 <= 500, approved
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If any bound is exceeded, the Gatekeeper blocks execution.
|
|
198
|
+
|
|
199
|
+
All profiles require the same six gates: bounds, problem, objective, tradeoff, commitment, and decision owner.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Community Profiles
|
|
204
|
+
|
|
205
|
+
Anyone can create and publish profiles through the [HAP Service Provider](https://humanagencyprotocol.com). Published profiles are immutable and versioned. There is no approval process — trust decisions are local.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
See [humanagencyprotocol.org](https://humanagencyprotocol.org) for the full protocol specification.
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "github.com/humanagencyprotocol/hap-profiles/calendar@0.4",
|
|
3
|
+
"name": "Calendar",
|
|
4
|
+
"version": "0.4",
|
|
5
|
+
"description": "Calendar authority \u2014 governs calendar access: reading, drafting, and booking events",
|
|
6
|
+
"boundsSchema": {
|
|
7
|
+
"keyOrder": [
|
|
8
|
+
"profile",
|
|
9
|
+
"booking_daily_max",
|
|
10
|
+
"booking_duration_max",
|
|
11
|
+
"lookahead_days_max"
|
|
12
|
+
],
|
|
13
|
+
"fields": {
|
|
14
|
+
"profile": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"required": true
|
|
17
|
+
},
|
|
18
|
+
"booking_daily_max": {
|
|
19
|
+
"type": "number",
|
|
20
|
+
"required": true,
|
|
21
|
+
"displayName": "Daily booking limit",
|
|
22
|
+
"description": "Maximum new events booked per day",
|
|
23
|
+
"unit": "count",
|
|
24
|
+
"boundType": {
|
|
25
|
+
"kind": "cumulative_count",
|
|
26
|
+
"window": "daily"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"booking_duration_max": {
|
|
30
|
+
"type": "number",
|
|
31
|
+
"required": true,
|
|
32
|
+
"displayName": "Max event duration",
|
|
33
|
+
"description": "Maximum duration of a single event",
|
|
34
|
+
"unit": "minutes",
|
|
35
|
+
"boundType": {
|
|
36
|
+
"kind": "per_transaction",
|
|
37
|
+
"of": "duration"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"lookahead_days_max": {
|
|
41
|
+
"type": "number",
|
|
42
|
+
"required": true,
|
|
43
|
+
"displayName": "Max lookahead",
|
|
44
|
+
"description": "Maximum number of days into the future an event can be booked",
|
|
45
|
+
"unit": "days",
|
|
46
|
+
"boundType": {
|
|
47
|
+
"kind": "per_transaction",
|
|
48
|
+
"of": "lookahead"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"contextSchema": {
|
|
54
|
+
"keyOrder": [
|
|
55
|
+
"allowed_calendars",
|
|
56
|
+
"allowed_attendees",
|
|
57
|
+
"allowed_domains"
|
|
58
|
+
],
|
|
59
|
+
"fields": {
|
|
60
|
+
"allowed_calendars": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"required": false,
|
|
63
|
+
"displayName": "Allowed calendars",
|
|
64
|
+
"description": "Comma-separated list of calendar names the agent may access",
|
|
65
|
+
"constraint": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"enforceable": [
|
|
68
|
+
"subset"
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"allowed_attendees": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"required": false,
|
|
75
|
+
"displayName": "Allowed attendees",
|
|
76
|
+
"format": "email",
|
|
77
|
+
"description": "Comma-separated list of allowed attendee email addresses",
|
|
78
|
+
"constraint": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"enforceable": [
|
|
81
|
+
"subset"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"allowed_domains": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"required": false,
|
|
88
|
+
"displayName": "Allowed domains",
|
|
89
|
+
"format": "domain",
|
|
90
|
+
"description": "Comma-separated list of allowed attendee domains (e.g. acme.com,partner.org)",
|
|
91
|
+
"constraint": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"enforceable": [
|
|
94
|
+
"subset"
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"executionContextSchema": {
|
|
101
|
+
"fields": {
|
|
102
|
+
"duration": {
|
|
103
|
+
"source": "declared",
|
|
104
|
+
"description": "Duration of the event in minutes",
|
|
105
|
+
"required": true,
|
|
106
|
+
"constraint": {
|
|
107
|
+
"type": "number",
|
|
108
|
+
"enforceable": [
|
|
109
|
+
"max"
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"lookahead": {
|
|
114
|
+
"source": "declared",
|
|
115
|
+
"description": "Days from now the event is scheduled",
|
|
116
|
+
"required": true,
|
|
117
|
+
"constraint": {
|
|
118
|
+
"type": "number",
|
|
119
|
+
"enforceable": [
|
|
120
|
+
"max"
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"allowed_calendars": {
|
|
125
|
+
"source": "declared",
|
|
126
|
+
"description": "Calendar being used (checked against authorized calendars)",
|
|
127
|
+
"required": false,
|
|
128
|
+
"constraint": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"enforceable": [
|
|
131
|
+
"subset"
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"allowed_attendees": {
|
|
136
|
+
"source": "declared",
|
|
137
|
+
"description": "Attendee addresses from this event (checked against authorized attendees)",
|
|
138
|
+
"required": false,
|
|
139
|
+
"constraint": {
|
|
140
|
+
"type": "string",
|
|
141
|
+
"enforceable": [
|
|
142
|
+
"subset"
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"allowed_domains": {
|
|
147
|
+
"source": "declared",
|
|
148
|
+
"description": "Unique attendee domains from this event (checked against authorized domains)",
|
|
149
|
+
"required": false,
|
|
150
|
+
"constraint": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"enforceable": [
|
|
153
|
+
"subset"
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"booking_count_daily": {
|
|
158
|
+
"source": "cumulative",
|
|
159
|
+
"cumulativeField": "_count",
|
|
160
|
+
"window": "daily",
|
|
161
|
+
"description": "Running daily booking count (resolved from execution log)",
|
|
162
|
+
"required": true,
|
|
163
|
+
"constraint": {
|
|
164
|
+
"type": "number",
|
|
165
|
+
"enforceable": [
|
|
166
|
+
"max"
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"requiredGates": [
|
|
173
|
+
"bounds",
|
|
174
|
+
"intent",
|
|
175
|
+
"commitment",
|
|
176
|
+
"decision_owner"
|
|
177
|
+
],
|
|
178
|
+
"ttl": {
|
|
179
|
+
"default": 86400,
|
|
180
|
+
"max": 31536000
|
|
181
|
+
},
|
|
182
|
+
"retention_minimum": 7776000
|
|
183
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "github.com/humanagencyprotocol/hap-profiles/charge@0.3",
|
|
3
|
+
"version": "0.3",
|
|
4
|
+
"name": "Charge",
|
|
5
|
+
"description": "Charge authority — governs charging customers: payments, refunds, subscriptions",
|
|
6
|
+
|
|
7
|
+
"frameSchema": {
|
|
8
|
+
"keyOrder": ["profile", "path", "amount_max", "currency", "action_type"],
|
|
9
|
+
"fields": {
|
|
10
|
+
"profile": { "type": "string", "required": true },
|
|
11
|
+
"path": { "type": "string", "required": true },
|
|
12
|
+
"amount_max": {
|
|
13
|
+
"type": "number",
|
|
14
|
+
"required": true,
|
|
15
|
+
"description": "Maximum monetary amount per transaction in currency units",
|
|
16
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
17
|
+
},
|
|
18
|
+
"currency": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"required": true,
|
|
21
|
+
"description": "Permitted currency code",
|
|
22
|
+
"constraint": { "type": "string", "enforceable": ["enum"] }
|
|
23
|
+
},
|
|
24
|
+
"action_type": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"required": true,
|
|
27
|
+
"description": "Authorized financial operation (charge, refund, subscribe)",
|
|
28
|
+
"constraint": { "type": "string", "enforceable": ["enum"] }
|
|
29
|
+
},
|
|
30
|
+
"amount_daily_max": {
|
|
31
|
+
"type": "number",
|
|
32
|
+
"required": true,
|
|
33
|
+
"description": "Maximum cumulative charges per day in currency units",
|
|
34
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
35
|
+
},
|
|
36
|
+
"amount_monthly_max": {
|
|
37
|
+
"type": "number",
|
|
38
|
+
"required": true,
|
|
39
|
+
"description": "Maximum cumulative charges per month in currency units",
|
|
40
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
41
|
+
},
|
|
42
|
+
"transaction_count_daily_max": {
|
|
43
|
+
"type": "number",
|
|
44
|
+
"required": true,
|
|
45
|
+
"description": "Maximum number of transactions per day",
|
|
46
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
"executionContextSchema": {
|
|
52
|
+
"fields": {
|
|
53
|
+
"action_type": {
|
|
54
|
+
"source": "declared",
|
|
55
|
+
"description": "Financial operation being performed",
|
|
56
|
+
"required": true,
|
|
57
|
+
"constraint": { "type": "string", "enforceable": ["enum"] }
|
|
58
|
+
},
|
|
59
|
+
"amount": {
|
|
60
|
+
"source": "declared",
|
|
61
|
+
"description": "Monetary amount in currency units",
|
|
62
|
+
"required": true,
|
|
63
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
64
|
+
},
|
|
65
|
+
"currency": {
|
|
66
|
+
"source": "declared",
|
|
67
|
+
"description": "Currency code",
|
|
68
|
+
"required": true,
|
|
69
|
+
"constraint": { "type": "string", "enforceable": ["enum"] }
|
|
70
|
+
},
|
|
71
|
+
"amount_daily": {
|
|
72
|
+
"source": "cumulative",
|
|
73
|
+
"cumulativeField": "amount",
|
|
74
|
+
"window": "daily",
|
|
75
|
+
"description": "Running daily charge total (resolved from execution log)",
|
|
76
|
+
"required": true,
|
|
77
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
78
|
+
},
|
|
79
|
+
"amount_monthly": {
|
|
80
|
+
"source": "cumulative",
|
|
81
|
+
"cumulativeField": "amount",
|
|
82
|
+
"window": "monthly",
|
|
83
|
+
"description": "Running monthly charge total (resolved from execution log)",
|
|
84
|
+
"required": true,
|
|
85
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
86
|
+
},
|
|
87
|
+
"transaction_count_daily": {
|
|
88
|
+
"source": "cumulative",
|
|
89
|
+
"cumulativeField": "_count",
|
|
90
|
+
"window": "daily",
|
|
91
|
+
"description": "Running daily transaction count (resolved from execution log)",
|
|
92
|
+
"required": true,
|
|
93
|
+
"constraint": { "type": "number", "enforceable": ["max"] }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
"executionPaths": {
|
|
99
|
+
"charge-routine": {
|
|
100
|
+
"description": "Day-to-day financial transactions within authorized bounds",
|
|
101
|
+
"requiredDomains": ["finance"],
|
|
102
|
+
"ttl": { "default": 86400, "max": 86400 }
|
|
103
|
+
},
|
|
104
|
+
"charge-reviewed": {
|
|
105
|
+
"description": "Large or unusual transactions requiring dual authorization",
|
|
106
|
+
"requiredDomains": ["finance", "compliance"],
|
|
107
|
+
"ttl": { "default": 14400, "max": 86400 }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
"requiredGates": ["frame", "problem", "objective", "tradeoff", "commitment", "decision_owner"],
|
|
112
|
+
|
|
113
|
+
"gateQuestions": {
|
|
114
|
+
"problem": { "question": "What problem does this charge authority address?", "required": true },
|
|
115
|
+
"objective": { "question": "What outcome should this charge authority enable?", "required": true },
|
|
116
|
+
"tradeoffs": { "question": "What financial risks do you accept with this authority?", "required": true }
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
"ttl": { "default": 86400, "max": 86400 },
|
|
120
|
+
"retention_minimum": 7776000,
|
|
121
|
+
|
|
122
|
+
"toolGating": {
|
|
123
|
+
"default": {
|
|
124
|
+
"executionMapping": {},
|
|
125
|
+
"staticExecution": { "action_type": "read" }
|
|
126
|
+
},
|
|
127
|
+
"overrides": {
|
|
128
|
+
"create_payment_link": {
|
|
129
|
+
"executionMapping": {
|
|
130
|
+
"unit_amount": { "field": "amount", "divisor": 100 },
|
|
131
|
+
"currency": "currency"
|
|
132
|
+
},
|
|
133
|
+
"staticExecution": { "action_type": "charge" }
|
|
134
|
+
},
|
|
135
|
+
"create_price": {
|
|
136
|
+
"executionMapping": {
|
|
137
|
+
"unit_amount": { "field": "amount", "divisor": 100 },
|
|
138
|
+
"currency": "currency"
|
|
139
|
+
},
|
|
140
|
+
"staticExecution": { "action_type": "charge" }
|
|
141
|
+
},
|
|
142
|
+
"create_invoice_item": {
|
|
143
|
+
"executionMapping": {
|
|
144
|
+
"amount": { "field": "amount", "divisor": 100 },
|
|
145
|
+
"currency": "currency"
|
|
146
|
+
},
|
|
147
|
+
"staticExecution": { "action_type": "charge" }
|
|
148
|
+
},
|
|
149
|
+
"create_refund": {
|
|
150
|
+
"executionMapping": {
|
|
151
|
+
"amount": { "field": "amount", "divisor": 100 }
|
|
152
|
+
},
|
|
153
|
+
"staticExecution": { "action_type": "refund" }
|
|
154
|
+
},
|
|
155
|
+
"create_subscription": {
|
|
156
|
+
"executionMapping": {},
|
|
157
|
+
"staticExecution": { "action_type": "subscribe" }
|
|
158
|
+
},
|
|
159
|
+
"cancel_subscription": {
|
|
160
|
+
"executionMapping": {},
|
|
161
|
+
"staticExecution": { "action_type": "subscribe" }
|
|
162
|
+
},
|
|
163
|
+
"update_subscription": {
|
|
164
|
+
"executionMapping": {},
|
|
165
|
+
"staticExecution": { "action_type": "subscribe" }
|
|
166
|
+
},
|
|
167
|
+
"retrieve_balance": null,
|
|
168
|
+
"list_invoices": null,
|
|
169
|
+
"list_subscriptions": null,
|
|
170
|
+
"list_payment_methods": null
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|