@cotal-ai/core 0.12.0 → 0.13.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/dist/acls.d.ts +31 -7
- package/dist/acls.d.ts.map +1 -1
- package/dist/acls.js +105 -17
- package/dist/acls.js.map +1 -1
- package/dist/agent-file.js +1 -1
- package/dist/agent-file.js.map +1 -1
- package/dist/auth-provider.d.ts +8 -0
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/auth-provider.js.map +1 -1
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +6 -4
- package/dist/backup.js.map +1 -1
- package/dist/broker-floor.d.ts +34 -0
- package/dist/broker-floor.d.ts.map +1 -0
- package/dist/broker-floor.js +39 -0
- package/dist/broker-floor.js.map +1 -0
- package/dist/canonical.d.ts +24 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +159 -0
- package/dist/canonical.js.map +1 -0
- package/dist/connector.d.ts +4 -0
- package/dist/connector.d.ts.map +1 -1
- package/dist/endpoint-action.d.ts +424 -0
- package/dist/endpoint-action.d.ts.map +1 -0
- package/dist/endpoint-action.js +910 -0
- package/dist/endpoint-action.js.map +1 -0
- package/dist/endpoint-binding.d.ts +344 -0
- package/dist/endpoint-binding.d.ts.map +1 -0
- package/dist/endpoint-binding.js +753 -0
- package/dist/endpoint-binding.js.map +1 -0
- package/dist/endpoint-checkpoint.d.ts +292 -0
- package/dist/endpoint-checkpoint.d.ts.map +1 -0
- package/dist/endpoint-checkpoint.js +818 -0
- package/dist/endpoint-checkpoint.js.map +1 -0
- package/dist/endpoint-cluster.d.ts +95 -0
- package/dist/endpoint-cluster.d.ts.map +1 -0
- package/dist/endpoint-cluster.js +194 -0
- package/dist/endpoint-cluster.js.map +1 -0
- package/dist/endpoint-contract-store.d.ts +90 -0
- package/dist/endpoint-contract-store.d.ts.map +1 -0
- package/dist/endpoint-contract-store.js +348 -0
- package/dist/endpoint-contract-store.js.map +1 -0
- package/dist/endpoint-envelope.d.ts +165 -0
- package/dist/endpoint-envelope.d.ts.map +1 -0
- package/dist/endpoint-envelope.js +346 -0
- package/dist/endpoint-envelope.js.map +1 -0
- package/dist/endpoint-grants.d.ts +123 -0
- package/dist/endpoint-grants.d.ts.map +1 -0
- package/dist/endpoint-grants.js +215 -0
- package/dist/endpoint-grants.js.map +1 -0
- package/dist/endpoint-guard.d.ts +222 -0
- package/dist/endpoint-guard.d.ts.map +1 -0
- package/dist/endpoint-guard.js +468 -0
- package/dist/endpoint-guard.js.map +1 -0
- package/dist/endpoint-handle.d.ts +176 -0
- package/dist/endpoint-handle.d.ts.map +1 -0
- package/dist/endpoint-handle.js +608 -0
- package/dist/endpoint-handle.js.map +1 -0
- package/dist/endpoint-journal.d.ts +225 -0
- package/dist/endpoint-journal.d.ts.map +1 -0
- package/dist/endpoint-journal.js +431 -0
- package/dist/endpoint-journal.js.map +1 -0
- package/dist/endpoint-receipt.d.ts +225 -0
- package/dist/endpoint-receipt.d.ts.map +1 -0
- package/dist/endpoint-receipt.js +417 -0
- package/dist/endpoint-receipt.js.map +1 -0
- package/dist/endpoint-records.d.ts +243 -0
- package/dist/endpoint-records.d.ts.map +1 -0
- package/dist/endpoint-records.js +591 -0
- package/dist/endpoint-records.js.map +1 -0
- package/dist/endpoint-serve.d.ts +176 -0
- package/dist/endpoint-serve.d.ts.map +1 -0
- package/dist/endpoint-serve.js +446 -0
- package/dist/endpoint-serve.js.map +1 -0
- package/dist/endpoint-service.d.ts +518 -0
- package/dist/endpoint-service.d.ts.map +1 -0
- package/dist/endpoint-service.js +973 -0
- package/dist/endpoint-service.js.map +1 -0
- package/dist/endpoint-session.d.ts +398 -0
- package/dist/endpoint-session.d.ts.map +1 -0
- package/dist/endpoint-session.js +834 -0
- package/dist/endpoint-session.js.map +1 -0
- package/dist/endpoint-signing.d.ts +105 -0
- package/dist/endpoint-signing.d.ts.map +1 -0
- package/dist/endpoint-signing.js +190 -0
- package/dist/endpoint-signing.js.map +1 -0
- package/dist/endpoint-subjects.d.ts +222 -0
- package/dist/endpoint-subjects.d.ts.map +1 -0
- package/dist/endpoint-subjects.js +381 -0
- package/dist/endpoint-subjects.js.map +1 -0
- package/dist/endpoint-supervisor.d.ts +19 -0
- package/dist/endpoint-supervisor.d.ts.map +1 -0
- package/dist/endpoint-supervisor.js +12 -0
- package/dist/endpoint-supervisor.js.map +1 -0
- package/dist/endpoint-traits.d.ts +225 -0
- package/dist/endpoint-traits.d.ts.map +1 -0
- package/dist/endpoint-traits.js +469 -0
- package/dist/endpoint-traits.js.map +1 -0
- package/dist/endpoint-verbs.d.ts +277 -0
- package/dist/endpoint-verbs.d.ts.map +1 -0
- package/dist/endpoint-verbs.js +576 -0
- package/dist/endpoint-verbs.js.map +1 -0
- package/dist/endpoint-virtual.d.ts +308 -0
- package/dist/endpoint-virtual.d.ts.map +1 -0
- package/dist/endpoint-virtual.js +440 -0
- package/dist/endpoint-virtual.js.map +1 -0
- package/dist/endpoint-work.d.ts +304 -0
- package/dist/endpoint-work.d.ts.map +1 -0
- package/dist/endpoint-work.js +728 -0
- package/dist/endpoint-work.js.map +1 -0
- package/dist/endpoint.d.ts +66 -22
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +289 -89
- package/dist/endpoint.js.map +1 -1
- package/dist/evict.d.ts +95 -32
- package/dist/evict.d.ts.map +1 -1
- package/dist/evict.js +193 -3
- package/dist/evict.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/lease.d.ts +4 -0
- package/dist/lease.d.ts.map +1 -1
- package/dist/lease.js.map +1 -1
- package/dist/members.d.ts +4 -4
- package/dist/members.d.ts.map +1 -1
- package/dist/members.js +12 -12
- package/dist/members.js.map +1 -1
- package/dist/provision.d.ts +70 -18
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +194 -33
- package/dist/provision.js.map +1 -1
- package/dist/safe-pattern.d.ts +33 -0
- package/dist/safe-pattern.d.ts.map +1 -0
- package/dist/safe-pattern.js +486 -0
- package/dist/safe-pattern.js.map +1 -0
- package/dist/schema-profile.d.ts +93 -0
- package/dist/schema-profile.d.ts.map +1 -0
- package/dist/schema-profile.js +284 -0
- package/dist/schema-profile.js.map +1 -0
- package/dist/streams.d.ts +13 -8
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +35 -18
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +100 -40
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +136 -60
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.4 endpoint control-surface grant grammar (SPEC §13.9 matrix, caller + serve rows) — the
|
|
3
|
+
* capability → exact allow-list builders `permissionsFor` mints from. Default-deny throughout:
|
|
4
|
+
* every row is an exact-arity literal form from the §13.9 matrix; no builder emits a wildcard
|
|
5
|
+
* that admits subjects outside the §13.2 grammar.
|
|
6
|
+
*
|
|
7
|
+
* SCOPE: the SUBJECT-space rows (core publish/subscribe grants). The `$JS.API` rows of the
|
|
8
|
+
* matrix (canonicalizer/effects/pool/reader durables) bind to the §13.12 stream names and land
|
|
9
|
+
* with that binding; the serve PROFILE that carries these rows to an endpoint daemon lands with
|
|
10
|
+
* the service registry machinery.
|
|
11
|
+
*/
|
|
12
|
+
import { spacePrefix } from "./subjects.js";
|
|
13
|
+
import { endpointToken, assertCommandToken, assertLifecycleToken, assertBoundedOwner, epCallerReplyFilter, epResponderReplyPattern, epClassQueueGroup, } from "./endpoint-subjects.js";
|
|
14
|
+
/** Grant-row token block for a capability's authz/target segment, enforcing the §13.2 minting
|
|
15
|
+
* rules per mode: `owner`/`child` standing mints pin `<tOwner>` to the caller's own owner
|
|
16
|
+
* (never a wildcard, never a foreign owner); `any`/`ledger` accept a literal `"*"` (mintable
|
|
17
|
+
* only under operator/admin policy — enforced by the minting authority, not here) or a
|
|
18
|
+
* validated owner token; `handle` validates the full redemption triple. Every concrete token
|
|
19
|
+
* routes through the same validator the subject builders use, so a grant row can never carry
|
|
20
|
+
* a smuggled `.`/`*`/`>` that widens the minted permission beyond the grammar. */
|
|
21
|
+
function targetGrantTokens(target, caller) {
|
|
22
|
+
if (target.mode === "self")
|
|
23
|
+
return ["self"];
|
|
24
|
+
if (target.mode === "handle")
|
|
25
|
+
return ["handle", assertBoundedOwner(target.tOwner, "target owner"), assertBoundedOwner(target.tActor, "target actor"), assertLifecycleToken(target.tUid, "target lifecycleUid")];
|
|
26
|
+
if (target.mode === "any" || target.mode === "ledger")
|
|
27
|
+
return [target.mode, target.tOwner === "*" ? "*" : assertBoundedOwner(target.tOwner, "target owner")];
|
|
28
|
+
if (target.tOwner !== caller.owner)
|
|
29
|
+
throw new Error(`an "${target.mode}"-mode grant pins the target owner to the caller's own owner (SPEC 13.2); got "${target.tOwner}" for caller owner "${caller.owner}"`);
|
|
30
|
+
return [target.mode, assertBoundedOwner(target.tOwner, "target owner")];
|
|
31
|
+
}
|
|
32
|
+
function callerBlock(caller) {
|
|
33
|
+
return `${assertBoundedOwner(caller.owner, "caller owner")}.${assertBoundedOwner(caller.actor, "caller actor")}.${assertLifecycleToken(caller.uid, "caller lifecycleUid")}`;
|
|
34
|
+
}
|
|
35
|
+
/** Request-publish rows for one capability (§13.9 "Request publish"): per route,
|
|
36
|
+
* `ep.{one,all}.<endpoint>.<command>[.<mode>[.<target…>]].<cO>.<cA>.<cUid>.*` and the
|
|
37
|
+
* instance-pinned form when `instanceId` is set. The nonce is the only wildcard token. */
|
|
38
|
+
export function epRequestGrantRows(space, cap, caller) {
|
|
39
|
+
const e = endpointToken(cap.endpoint);
|
|
40
|
+
const cmd = assertCommandToken(cap.command);
|
|
41
|
+
const mid = cap.target ? `.${targetGrantTokens(cap.target, caller).join(".")}` : "";
|
|
42
|
+
const tail = `${mid}.${callerBlock(caller)}.*`;
|
|
43
|
+
const rows = (cap.routes ?? ["one"]).map((r) => `${spacePrefix(space)}.ep.${r}.${e}.${cmd}${tail}`);
|
|
44
|
+
if (cap.instanceId)
|
|
45
|
+
rows.push(`${spacePrefix(space)}.ep.inst.${e}.${assertLifecycleToken(cap.instanceId, "instanceId")}.${cmd}${tail}`);
|
|
46
|
+
return rows;
|
|
47
|
+
}
|
|
48
|
+
/** Journal-submission append row (§13.9 "Journal submission append"): the same authz/target
|
|
49
|
+
* block as the request forms, caller-pinned, no nonce. Explicitly untrusted input (§13.4). */
|
|
50
|
+
export function epJournalGrantRow(space, cap, caller) {
|
|
51
|
+
const mid = cap.target ? `.${targetGrantTokens(cap.target, caller).join(".")}` : "";
|
|
52
|
+
return `${spacePrefix(space)}.epj.${endpointToken(cap.endpoint)}.${assertCommandToken(cap.command)}${mid}.${callerBlock(caller)}`;
|
|
53
|
+
}
|
|
54
|
+
/** The caller's reply-rail read row (§13.9 "Reply subscribe"): its own rail only, exact arity. */
|
|
55
|
+
export function epCallerReplyGrantRow(space, caller) {
|
|
56
|
+
return epCallerReplyFilter(space, caller);
|
|
57
|
+
}
|
|
58
|
+
/** Per-goal live progress read row (§13.9 "Live event progress", reserved `goal` topic):
|
|
59
|
+
* `epe.<endpoint>.*.*.goal.<cO>.<cA>.<cUid>.>` — the caller identity in the subject gives
|
|
60
|
+
* mint-time read containment; delivered on the caller's own core subscription only. */
|
|
61
|
+
export function epGoalProgressGrantRow(space, endpoint, caller) {
|
|
62
|
+
return `${spacePrefix(space)}.epe.${endpointToken(endpoint)}.*.*.goal.${callerBlock(caller)}.>`;
|
|
63
|
+
}
|
|
64
|
+
/** All caller-side rows for a capability set: request-publish (+ optional journal) into
|
|
65
|
+
* `pub.allow`, the reply rail into `sub.allow`. This is the STANDING rollup (`permissionsFor`
|
|
66
|
+
* mints long-lived credentials from it), so a `handle`-mode capability is refused here:
|
|
67
|
+
* handle rows are redemption-minted only (§13.2/§13.6), built by the redemption path through
|
|
68
|
+
* {@link epRequestGrantRows} directly. Deliberately NOT included: `epe` event
|
|
69
|
+
* subtrees beyond the per-goal row — read grants are minted per read capability by the
|
|
70
|
+
* granting authority (Appendix B), not implied by an invoke capability. */
|
|
71
|
+
export function epCallerGrantRows(space, caps, caller) {
|
|
72
|
+
const pub = [];
|
|
73
|
+
for (const cap of caps) {
|
|
74
|
+
if (cap.target?.mode === "handle")
|
|
75
|
+
throw new Error(`a "handle"-mode capability on "${cap.endpoint}.${cap.command}" is redemption-minted only (SPEC 13.2), never a standing capability`);
|
|
76
|
+
pub.push(...epRequestGrantRows(space, cap, caller));
|
|
77
|
+
if (cap.journal)
|
|
78
|
+
pub.push(epJournalGrantRow(space, cap, caller));
|
|
79
|
+
}
|
|
80
|
+
return { pub, sub: caps.length ? [epCallerReplyGrantRow(space, caller)] : [] };
|
|
81
|
+
}
|
|
82
|
+
// ---- the Appendix-B BASELINE capability set (SPEC Appendix B "Agent", §13.9 agent row) ------------
|
|
83
|
+
// "every agent gets the baseline set (`describe` on all endpoints; the delivery endpoint's durable
|
|
84
|
+
// join/leave/list commands; self-targeted lifecycle commands with authz-mode `self`); the `spawn`
|
|
85
|
+
// capability adds the manager endpoint's lifecycle commands with authz-mode `owner`". The v0.4
|
|
86
|
+
// command NAMES map the served v0.3 ops 1:1: ctl.delivery durableJoin/durableLeave/listMemberships
|
|
87
|
+
// → delivery `join`/`leave`/`list` (untargeted: they act on the caller's own memberships, carried
|
|
88
|
+
// by the pinned caller triple, no target block); the self-service control tier serves exactly
|
|
89
|
+
// no-name self `stop` → manager `stop` with mode `self`; the privileged tier's spawn/stop/despawn/
|
|
90
|
+
// attach → the owner-mode spawn set. These names become the served v0.4 endpoint surfaces when the
|
|
91
|
+
// daemons register them; minting them ahead of serving is default-deny-safe (an unserved request
|
|
92
|
+
// form is a no-responder, never authority).
|
|
93
|
+
/** The delivery endpoint's baseline command names (Appendix B: "durable join/leave/list").
|
|
94
|
+
* All four command vocabularies below are RUNTIME-frozen (TS `as const` is type-level only)
|
|
95
|
+
* and the capability builders consult PRIVATE module-load snapshots, never these live
|
|
96
|
+
* exports: a post-import `push("attach")` here would otherwise widen every subsequently
|
|
97
|
+
* minted agent grant (the afa715b identity-vs-integrity class, executed repro). */
|
|
98
|
+
export const BASELINE_DELIVERY_ENDPOINT = "delivery";
|
|
99
|
+
export const BASELINE_DELIVERY_COMMANDS = Object.freeze(["join", "leave", "list"]);
|
|
100
|
+
/** The manager endpoint's self-lifecycle baseline (the v0.3 self-service tier serves exactly
|
|
101
|
+
* no-name self stop) and the spawn-capability owner-mode lifecycle set. */
|
|
102
|
+
export const BASELINE_LIFECYCLE_ENDPOINT = "manager";
|
|
103
|
+
export const BASELINE_SELF_LIFECYCLE_COMMANDS = Object.freeze(["stop"]);
|
|
104
|
+
/** `spawn` is CREATION: a virgin spawn has no target lifecycle UID or current mapping yet, so it
|
|
105
|
+
* CANNOT ride owner mode (§13.2 owner mode resolves a body `{owner, actor, lifecycleUid}` against
|
|
106
|
+
* the CURRENT mapping — there is nothing to resolve for a not-yet-existing child). It is minted
|
|
107
|
+
* UNTARGETED; the child-owner ceiling is the authenticated caller's own owner, carried by the
|
|
108
|
+
* pinned caller triple. `despawn` (terminal) and `attach` (interactive) act on an EXISTING agent,
|
|
109
|
+
* so they ride owner mode. Owner-mode `stop` is DELIBERATELY ABSENT: on the v0.3 surface a named
|
|
110
|
+
* stop and a despawn both free-slot + deprovision, so an owner-mode `stop` would be a wire synonym
|
|
111
|
+
* of `despawn` (distsys) — one owner-mode terminal command keeps the vocabulary single. Self-`stop`
|
|
112
|
+
* stays in the BASELINE (the v0.3 self-service tier's only op); it is the lighter self-halt. */
|
|
113
|
+
export const SPAWN_CREATE_COMMANDS = Object.freeze(["spawn"]);
|
|
114
|
+
export const SPAWN_OWNER_LIFECYCLE_COMMANDS = Object.freeze(["despawn", "attach"]);
|
|
115
|
+
// PRIVATE module-load snapshots of the command vocabularies: the builders below map over THESE,
|
|
116
|
+
// never the live exports, so the minted surface survives even a hypothetical defeat of the
|
|
117
|
+
// freezes above (the seam-snapshot half of the afa715b closure pattern).
|
|
118
|
+
const DELIVERY_COMMANDS_SNAP = Object.freeze([...BASELINE_DELIVERY_COMMANDS]);
|
|
119
|
+
const SELF_LIFECYCLE_SNAP = Object.freeze([...BASELINE_SELF_LIFECYCLE_COMMANDS]);
|
|
120
|
+
const SPAWN_CREATE_SNAP = Object.freeze([...SPAWN_CREATE_COMMANDS]);
|
|
121
|
+
const SPAWN_OWNER_SNAP = Object.freeze([...SPAWN_OWNER_LIFECYCLE_COMMANDS]);
|
|
122
|
+
/** `describe` on ALL endpoints (Appendix B / §13.9 "describe by default"): the ONE
|
|
123
|
+
* subject-wildcard request form in the caller grammar,
|
|
124
|
+
* `ep.one.*.describe.<cO>.<cA>.<cUid>.*` — the endpoint token is the wildcard, the command is
|
|
125
|
+
* the literal reserved `describe`, and the caller triple stays pinned. DELIBERATELY not an
|
|
126
|
+
* {@link EpCapability} (whose endpoint is a validated literal): a wildcard-endpoint capability
|
|
127
|
+
* would generalize to arbitrary commands, and the baseline is the only place the wildcard form
|
|
128
|
+
* is normative. Untargeted only — describe is constructed untargeted on every serve
|
|
129
|
+
* (§13.7), so no authz/target block ever appears in the row. */
|
|
130
|
+
export function epDescribeAllGrantRow(space, caller) {
|
|
131
|
+
return `${spacePrefix(space)}.ep.one.*.describe.${callerBlock(caller)}.*`;
|
|
132
|
+
}
|
|
133
|
+
/** The baseline {@link EpCapability} set every agent holds (Appendix B) beyond the wildcard
|
|
134
|
+
* describe row: delivery join/leave/list (untargeted) + self-mode lifecycle. */
|
|
135
|
+
export function baselineCallerCapabilities() {
|
|
136
|
+
return [
|
|
137
|
+
...DELIVERY_COMMANDS_SNAP.map((command) => ({ endpoint: BASELINE_DELIVERY_ENDPOINT, command })),
|
|
138
|
+
...SELF_LIFECYCLE_SNAP.map((command) => ({ endpoint: BASELINE_LIFECYCLE_ENDPOINT, command, target: { mode: "self" } })),
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
/** The `spawn` capability's addition (Appendix B): the manager endpoint's lifecycle commands.
|
|
142
|
+
* `spawn` (creation) is UNTARGETED — a virgin child has no lifecycle UID to resolve against the
|
|
143
|
+
* current mapping, so an owner-mode row would be un-invokable under the verb grammar (§13.2). The
|
|
144
|
+
* three that act on an existing agent ride owner mode, target owner pinned to the CALLER's own
|
|
145
|
+
* (§13.2: an owner-mode standing mint never names a foreign owner). */
|
|
146
|
+
export function spawnCallerCapabilities(callerOwner) {
|
|
147
|
+
return [
|
|
148
|
+
...SPAWN_CREATE_SNAP.map((command) => ({ endpoint: BASELINE_LIFECYCLE_ENDPOINT, command })),
|
|
149
|
+
...SPAWN_OWNER_SNAP.map((command) => ({
|
|
150
|
+
endpoint: BASELINE_LIFECYCLE_ENDPOINT, command,
|
|
151
|
+
target: { mode: "owner", tOwner: callerOwner },
|
|
152
|
+
})),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
/** All BASELINE caller rows (Appendix B): the wildcard describe form + the baseline capability
|
|
156
|
+
* rollup into `pub.allow`, and the caller's reply rail into `sub.allow` — ALWAYS present (the
|
|
157
|
+
* baseline implies the reply read even when no per-capability rows are minted). */
|
|
158
|
+
export function epBaselineGrantRows(space, caller) {
|
|
159
|
+
const base = epCallerGrantRows(space, baselineCallerCapabilities(), caller);
|
|
160
|
+
return { pub: [epDescribeAllGrantRow(space, caller), ...base.pub], sub: [epCallerReplyGrantRow(space, caller)] };
|
|
161
|
+
}
|
|
162
|
+
/** One registered command's serve-subscribe rows (§13.9 "Serve subscribe"), per registered
|
|
163
|
+
* command and never a cross-command `>`:
|
|
164
|
+
* - class rail: `"ep.one.<endpoint>.<command>.> <queue>"` — QUEUE-QUALIFIED ONLY (the NATS
|
|
165
|
+
* `subject queue` grant form): no credential can plain-subscribe the class rail, which is
|
|
166
|
+
* what keeps per-request nonces visible only to the queue-selected instance;
|
|
167
|
+
* - scatter rail: `ep.all.<endpoint>.<command>.>` plain;
|
|
168
|
+
* - instance rail: `ep.inst.<endpoint>.<instanceId>.<command>.>` exact.
|
|
169
|
+
* The epoch is deliberately absent from serve subscriptions (§13.1's barrier is the fence). */
|
|
170
|
+
export function epServeSubscribeRows(space, endpoint, instanceId, command) {
|
|
171
|
+
const e = endpointToken(endpoint);
|
|
172
|
+
const cmd = assertCommandToken(command);
|
|
173
|
+
return [
|
|
174
|
+
`${spacePrefix(space)}.ep.one.${e}.${cmd}.> ${epClassQueueGroup(endpoint)}`,
|
|
175
|
+
`${spacePrefix(space)}.ep.all.${e}.${cmd}.>`,
|
|
176
|
+
`${spacePrefix(space)}.ep.inst.${e}.${assertLifecycleToken(instanceId, "instanceId")}.${cmd}.>`,
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
/** A serving instance's egress rows (§13.9 matrix): reply publish (attribution-pinned instance
|
|
180
|
+
* triple + epoch), events, timer SCHEDULE requests (never `.armed`/`.fire`), and the epoch-pinned
|
|
181
|
+
* record-write ingress. Every row pins the instance's own identity and epoch. */
|
|
182
|
+
export function epServePublishRows(space, endpoint, instanceId, epoch) {
|
|
183
|
+
const e = endpointToken(endpoint);
|
|
184
|
+
const iId = assertLifecycleToken(instanceId, "instanceId");
|
|
185
|
+
if (!Number.isSafeInteger(epoch) || epoch < 0)
|
|
186
|
+
throw new Error(`epoch ${epoch} is not an unsigned integer`);
|
|
187
|
+
return [
|
|
188
|
+
epResponderReplyPattern(space, endpoint, instanceId, epoch),
|
|
189
|
+
`${spacePrefix(space)}.epe.${e}.${iId}.${epoch}.>`,
|
|
190
|
+
`${spacePrefix(space)}.ept.${e}.${iId}.${epoch}.*.schedule`,
|
|
191
|
+
`${spacePrefix(space)}.epr.${e}.${iId}.${epoch}.>`,
|
|
192
|
+
];
|
|
193
|
+
}
|
|
194
|
+
/** All serve-credential subject-space rows for an instance. `ephemeralCommands` is the
|
|
195
|
+
* RAIL-SERVED (ephemeral) subset only — journal commands stay in the credential's descriptor
|
|
196
|
+
* surface but ride `epj` submissions, never the §13.2 request rails, so they take no rail
|
|
197
|
+
* subscribe row here (their effects/pool durable binds ride the §13.12 stream binding). The
|
|
198
|
+
* reserved `describe` is DERIVED here — every endpoint serves it (§13.7), so this ONE assembly
|
|
199
|
+
* seam emits its rails for every serve credential (even a journal-only endpoint, whose
|
|
200
|
+
* `ephemeralCommands` is empty) and an explicit `describe` refuses (mirroring
|
|
201
|
+
* {@link import("./endpoint-serve.js").serveEndpoint}'s construction rule: there is no custom
|
|
202
|
+
* describe). The subscribe side also carries the instance's OWN epoch-pinned timer FIRE row
|
|
203
|
+
* (§13.9 "Timer fire consume": `ept.<e>.<i>.<epoch>.*.fire` — consume only; the publish side
|
|
204
|
+
* stays `.schedule`-only, no credential publishes `.armed`/`.fire`). */
|
|
205
|
+
export function epServeGrantRows(space, serve) {
|
|
206
|
+
if (serve.ephemeralCommands.includes("describe"))
|
|
207
|
+
throw new Error(`"describe" is not a mintable serve command: it is reserved and derived here for every serve credential (SPEC 13.7/13.9)`);
|
|
208
|
+
const sub = [];
|
|
209
|
+
for (const cmd of [...serve.ephemeralCommands, "describe"])
|
|
210
|
+
sub.push(...epServeSubscribeRows(space, serve.endpoint, serve.instanceId, cmd));
|
|
211
|
+
const pub = epServePublishRows(space, serve.endpoint, serve.instanceId, serve.epoch); // validates the tuple's tokens + epoch
|
|
212
|
+
sub.push(`${spacePrefix(space)}.ept.${endpointToken(serve.endpoint)}.${assertLifecycleToken(serve.instanceId, "instanceId")}.${serve.epoch}.*.fire`);
|
|
213
|
+
return { pub, sub };
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=endpoint-grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-grants.js","sourceRoot":"","sources":["../src/endpoint-grants.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { EpCaller } from "./endpoint-subjects.js";
|
|
2
|
+
import { type AnchorResolver } from "./endpoint-signing.js";
|
|
3
|
+
import { type CheckpointSettleFact } from "./endpoint-checkpoint.js";
|
|
4
|
+
import { type ActionContext, type GoalRef, type GoalStatusValue, type GoalResultFact } from "./endpoint-action.js";
|
|
5
|
+
/** A signed guard OBLIGATION (§13.6/§13.10): attenuations the effecting endpoint MUST apply,
|
|
6
|
+
* bound to its goal/request id, reusable within it. Verified against the anchor registry
|
|
7
|
+
* (role `obligations`, scope = the endpoints the key may attest for). */
|
|
8
|
+
export interface GuardObligation {
|
|
9
|
+
v: 1;
|
|
10
|
+
space: string;
|
|
11
|
+
/** The guarded goal/request id this obligation binds to (§13.10: bound to its goal/request). */
|
|
12
|
+
requestId: string;
|
|
13
|
+
signer: {
|
|
14
|
+
keyId: string;
|
|
15
|
+
};
|
|
16
|
+
/** The monotonic attenuations the endpoint MUST apply; opaque to this wiring (the effecting
|
|
17
|
+
* handler interprets them), validated as non-empty structured entries and signed. */
|
|
18
|
+
attenuations: unknown[];
|
|
19
|
+
iat: number;
|
|
20
|
+
exp: number;
|
|
21
|
+
sig: string;
|
|
22
|
+
}
|
|
23
|
+
/** The guard endpoint's parsed answer (closed per decision): `hold` carries the checkpoint
|
|
24
|
+
* coordinates; `deny` carries an optional reason; obligations ride `allow`/`hold` only. */
|
|
25
|
+
export type GuardAnswer = {
|
|
26
|
+
decision: "allow";
|
|
27
|
+
obligations: GuardObligation[];
|
|
28
|
+
} | {
|
|
29
|
+
decision: "deny";
|
|
30
|
+
reason?: string;
|
|
31
|
+
} | {
|
|
32
|
+
decision: "hold";
|
|
33
|
+
token: string;
|
|
34
|
+
holdDeadlineMs: number;
|
|
35
|
+
obligations: GuardObligation[];
|
|
36
|
+
};
|
|
37
|
+
/** The injected class-call seam: invoke the guard endpoint's decision command and return its
|
|
38
|
+
* raw answer body PLUS the broker-authenticated responder identity (derived from the reply
|
|
39
|
+
* subject by the caller's transport layer, never from the body). The seam receives the
|
|
40
|
+
* guarded request's coordinates so the guard knows WHAT it is deciding; the GATE owns all
|
|
41
|
+
* parsing and verification of the answer, so no wiring can surface an unverified obligation. */
|
|
42
|
+
export type GuardCallSeam = (q: {
|
|
43
|
+
/** The guard endpoint the VERIFIED trait value names. */
|
|
44
|
+
guardEndpoint: string;
|
|
45
|
+
/** The guarded request's broker-authenticated coordinates. */
|
|
46
|
+
endpoint: string;
|
|
47
|
+
command?: string;
|
|
48
|
+
requestId: string;
|
|
49
|
+
caller: EpCaller;
|
|
50
|
+
}) => Promise<{
|
|
51
|
+
answer: unknown;
|
|
52
|
+
responder: {
|
|
53
|
+
id: string;
|
|
54
|
+
lifecycleUid: string;
|
|
55
|
+
};
|
|
56
|
+
}>;
|
|
57
|
+
/** The gate's verdict for the effecting handler. */
|
|
58
|
+
export type GuardVerdict = {
|
|
59
|
+
decision: "allow";
|
|
60
|
+
obligations: GuardObligation[];
|
|
61
|
+
} | {
|
|
62
|
+
decision: "hold";
|
|
63
|
+
token: string;
|
|
64
|
+
holdDeadlineMs: number;
|
|
65
|
+
obligations: GuardObligation[];
|
|
66
|
+
responder: {
|
|
67
|
+
id: string;
|
|
68
|
+
lifecycleUid: string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
/** Run the §13.6 guard gate for one guarded request: call the guard endpoint (via the injected
|
|
72
|
+
* seam) within `deadlineMs`, and classify FAIL-CLOSED — the ONLY outcomes are a verified
|
|
73
|
+
* ALLOW, a verified HOLD (the caller then wires the pause via {@link holdGuardedGoal}), or a
|
|
74
|
+
* `permission-denied` throw. A timeout, transport failure, garbled answer, cross-variant
|
|
75
|
+
* fields, or an obligation that does not verify (signature, scope, window, request binding)
|
|
76
|
+
* all DENY. Ordering is guard-then-effect: call this BEFORE any effect. */
|
|
77
|
+
export declare function runGuardGate(opts: {
|
|
78
|
+
/** The guard endpoint named by the VERIFIED `ai.cotal.guarded` trait value (the D6 governed
|
|
79
|
+
* attachment verification is the caller's step; this seam trusts its output only). */
|
|
80
|
+
guardEndpoint: string;
|
|
81
|
+
/** The guarded request's coordinates (broker-authenticated at the serve boundary). */
|
|
82
|
+
request: {
|
|
83
|
+
endpoint: string;
|
|
84
|
+
command?: string;
|
|
85
|
+
id: string;
|
|
86
|
+
caller: EpCaller;
|
|
87
|
+
};
|
|
88
|
+
callGuard: GuardCallSeam;
|
|
89
|
+
/** The guard budget: past it the gate DENIES (never hangs, never allows). */
|
|
90
|
+
deadlineMs: number;
|
|
91
|
+
now: number;
|
|
92
|
+
space: string;
|
|
93
|
+
resolveAnchor: AnchorResolver;
|
|
94
|
+
}): Promise<GuardVerdict>;
|
|
95
|
+
/** The ACTION composite's guard gate (§13.6): run by the OWNING instance for a guarded goal
|
|
96
|
+
* BEFORE any execution effect — the counterpart of the ephemeral rail's
|
|
97
|
+
* `assertGovernedPreEffect`, with hold ROUTED instead of refused. {@link runGuardGate} does
|
|
98
|
+
* the calling, parsing, and obligation verification; this seam projects the verdict onto the
|
|
99
|
+
* goal:
|
|
100
|
+
* - ALLOW: the goal transitions accepted → running under the owner's construction-bound
|
|
101
|
+
* proof (this projection is the owner's admission to execute) and the VERIFIED
|
|
102
|
+
* obligations return for the executor, which MUST apply them;
|
|
103
|
+
* - HOLD: {@link holdGuardedGoal} mints the guard-holder-bound checkpoint and projects
|
|
104
|
+
* `waiting`;
|
|
105
|
+
* - DENY (or ANY fail-closed gate refusal: timeout, garble, unverifiable obligation): the
|
|
106
|
+
* goal commits terminal `failed` at the shared commit point under the OWNER's
|
|
107
|
+
* construction-bound proof — the owner runs this gate, so the deny predicate is the
|
|
108
|
+
* owner's own refusal to execute, carrying the gate's reason in the terminal payload.
|
|
109
|
+
* Obligations bind to the GOAL id (§13.10: bound to its goal/request, reusable within it). */
|
|
110
|
+
export declare function gateGoalExecution(ctx: ActionContext, args: {
|
|
111
|
+
goal: GoalRef;
|
|
112
|
+
/** The guard endpoint named by the goal's VERIFIED `ai.cotal.guarded` trait value. */
|
|
113
|
+
guardEndpoint: string;
|
|
114
|
+
callGuard: GuardCallSeam;
|
|
115
|
+
resolveAnchor: AnchorResolver;
|
|
116
|
+
deadlineMs: number;
|
|
117
|
+
now: number;
|
|
118
|
+
/** The OWNING instance arming a hold's timer (its identity/epoch subject, §13.12). */
|
|
119
|
+
instanceId: string;
|
|
120
|
+
epoch: number;
|
|
121
|
+
}): Promise<{
|
|
122
|
+
outcome: "running";
|
|
123
|
+
obligations: GuardObligation[];
|
|
124
|
+
status: GoalStatusValue;
|
|
125
|
+
} | {
|
|
126
|
+
outcome: "waiting";
|
|
127
|
+
hold: {
|
|
128
|
+
token: string;
|
|
129
|
+
holdDeadlineMs: number;
|
|
130
|
+
};
|
|
131
|
+
obligations: GuardObligation[];
|
|
132
|
+
status: GoalStatusValue;
|
|
133
|
+
} | {
|
|
134
|
+
outcome: "denied";
|
|
135
|
+
won: boolean;
|
|
136
|
+
fact: GoalResultFact;
|
|
137
|
+
status: GoalStatusValue;
|
|
138
|
+
}>;
|
|
139
|
+
/** The durable HOLD reconciler (§13.6): converge a goal whose guard-hold checkpoint SETTLED
|
|
140
|
+
* while the goal projection lags (a release or expiry crashed mid-flight, or the timer fire
|
|
141
|
+
* settled the checkpoint and the owner's projection is still owed). For a goal `waiting` on
|
|
142
|
+
* checkpoint T whose spec binds THIS goal:
|
|
143
|
+
* - settle RESUMED: finish the projection to `running` (idempotent);
|
|
144
|
+
* - settle EXPIRED: drive the terminal deny via {@link expireGuardHold} (idempotent);
|
|
145
|
+
* - still live: nothing to do — the timer plane owns the deadline.
|
|
146
|
+
* A goal not waiting, or waiting on a token whose checkpoint does not bind it, is left
|
|
147
|
+
* untouched: this reconciler converges exactly the holds this module minted. (The
|
|
148
|
+
* mint-then-no-wait partial state is recovered by RETRYING the gate — the mint is
|
|
149
|
+
* idempotent-if-identical and the transition completes; a dedicated repair arm was
|
|
150
|
+
* panel-adjudicated as insurance ahead of composition and deliberately not built.)
|
|
151
|
+
* A converged `running` carries the hold's RECORDED verified obligations (§13.6/§13.10:
|
|
152
|
+
* MUST-apply, reusable within the goal — the pause never launders them away). */
|
|
153
|
+
export declare function reconcileGuardHold(ctx: ActionContext, args: {
|
|
154
|
+
goal: GoalRef;
|
|
155
|
+
now: number;
|
|
156
|
+
}): Promise<{
|
|
157
|
+
converged: "running" | "denied" | "none";
|
|
158
|
+
obligations?: GuardObligation[];
|
|
159
|
+
}>;
|
|
160
|
+
/** Convert a HELD action to `waiting` on a checkpoint OWNED BY THE GUARD DECISION (§13.6): the
|
|
161
|
+
* checkpoint's holder is the guard's authenticated responder (only IT may resume), the
|
|
162
|
+
* deadline is the hold's (mandatory), and the goal's status projects `waiting` carrying the
|
|
163
|
+
* checkpoint coordinate. The mint is idempotent and the timer is armed through the mediated
|
|
164
|
+
* plane by the checkpoint module. */
|
|
165
|
+
export declare function holdGuardedGoal(ctx: ActionContext, args: {
|
|
166
|
+
goal: GoalRef;
|
|
167
|
+
hold: {
|
|
168
|
+
token: string;
|
|
169
|
+
holdDeadlineMs: number;
|
|
170
|
+
responder: {
|
|
171
|
+
id: string;
|
|
172
|
+
lifecycleUid: string;
|
|
173
|
+
};
|
|
174
|
+
obligations?: GuardObligation[];
|
|
175
|
+
};
|
|
176
|
+
/** The OWNING instance arming the hold's timer (its identity/epoch subject, §13.12). */
|
|
177
|
+
instanceId: string;
|
|
178
|
+
epoch: number;
|
|
179
|
+
now: number;
|
|
180
|
+
}): Promise<GoalStatusValue>;
|
|
181
|
+
/** Release a guard hold: the GUARD (the checkpoint's holder, presenting as itself) resumes the
|
|
182
|
+
* one-use checkpoint, and the goal leaves `waiting` back to `running`. The token is first bound
|
|
183
|
+
* to THIS goal (a valid token for another goal never releases it), THEN the resume seam
|
|
184
|
+
* enforces holder binding, one-use, and the deadline fence (a hold past its deadline drives
|
|
185
|
+
* the EXPIRED settlement there and refuses; an expired hold never releases).
|
|
186
|
+
*
|
|
187
|
+
* CRASH CONVERGENCE (the checkpoint settlement is the arbiter; the goal transition is its
|
|
188
|
+
* derived projection): a crash between the one-use resume and the goal transition leaves the
|
|
189
|
+
* checkpoint `resumed` and the goal `waiting` — the RETRY's resume loses `conflict`, so it
|
|
190
|
+
* OBSERVES the recorded settlement, requires it to be THIS presenter's own `resumed` (a
|
|
191
|
+
* foreign or expired settlement rethrows), and finishes the projection idempotently (a goal
|
|
192
|
+
* already `running` is the converged state, not an error). */
|
|
193
|
+
export declare function releaseGuardHold(ctx: ActionContext, args: {
|
|
194
|
+
goal: GoalRef;
|
|
195
|
+
token: string;
|
|
196
|
+
presenter: {
|
|
197
|
+
id: string;
|
|
198
|
+
lifecycleUid: string;
|
|
199
|
+
};
|
|
200
|
+
now: number;
|
|
201
|
+
}): Promise<{
|
|
202
|
+
settle: CheckpointSettleFact;
|
|
203
|
+
status: GoalStatusValue;
|
|
204
|
+
obligations: GuardObligation[];
|
|
205
|
+
}>;
|
|
206
|
+
/** Settle an EXPIRED guard hold onto the goal: an expired hold is DENY (fail closed). The token
|
|
207
|
+
* is first bound to THIS goal (an arbitrary token never terminal-fails an unrelated goal), then
|
|
208
|
+
* the CHECKPOINT is owner-expired (settling its status and stopping its timers, so no orphaned
|
|
209
|
+
* schedule lingers until the checkpoint's own deadline), and finally the goal commits terminal
|
|
210
|
+
* `failed` (permission-denied) at the shared commit point — where a racing completion or cancel
|
|
211
|
+
* may lawfully have won first (the caller observes the winner; the projection converges either
|
|
212
|
+
* way). Idempotent: an already-terminal goal returns its winner. */
|
|
213
|
+
export declare function expireGuardHold(ctx: ActionContext, args: {
|
|
214
|
+
goal: GoalRef;
|
|
215
|
+
token: string;
|
|
216
|
+
now: number;
|
|
217
|
+
}): Promise<{
|
|
218
|
+
won: boolean;
|
|
219
|
+
fact: GoalResultFact;
|
|
220
|
+
status: GoalStatusValue;
|
|
221
|
+
}>;
|
|
222
|
+
//# sourceMappingURL=endpoint-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-guard.d.ts","sourceRoot":"","sources":["../src/endpoint-guard.ts"],"names":[],"mappings":"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"}
|