@cotal-ai/core 0.17.0 → 0.19.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 +0 -7
- package/dist/acls.d.ts.map +1 -1
- package/dist/acls.js +10 -7
- package/dist/acls.js.map +1 -1
- package/dist/agui-kind.d.ts +71 -0
- package/dist/agui-kind.d.ts.map +1 -0
- package/dist/agui-kind.js +95 -0
- package/dist/agui-kind.js.map +1 -0
- package/dist/endpoint-action.d.ts +3 -3
- package/dist/endpoint-action.js +4 -4
- package/dist/endpoint-action.js.map +1 -1
- package/dist/endpoint-binding.d.ts +48 -5
- package/dist/endpoint-binding.d.ts.map +1 -1
- package/dist/endpoint-binding.js +82 -6
- package/dist/endpoint-binding.js.map +1 -1
- package/dist/endpoint-cluster.d.ts +20 -0
- package/dist/endpoint-cluster.d.ts.map +1 -1
- package/dist/endpoint-cluster.js +47 -0
- package/dist/endpoint-cluster.js.map +1 -1
- package/dist/endpoint-contract-store.d.ts +6 -0
- package/dist/endpoint-contract-store.d.ts.map +1 -1
- package/dist/endpoint-contract-store.js +21 -2
- package/dist/endpoint-contract-store.js.map +1 -1
- package/dist/endpoint-effects.d.ts +73 -0
- package/dist/endpoint-effects.d.ts.map +1 -0
- package/dist/endpoint-effects.js +46 -0
- package/dist/endpoint-effects.js.map +1 -0
- package/dist/endpoint-envelope.d.ts +32 -1
- package/dist/endpoint-envelope.d.ts.map +1 -1
- package/dist/endpoint-envelope.js +56 -2
- package/dist/endpoint-envelope.js.map +1 -1
- package/dist/endpoint-epname.d.ts +62 -0
- package/dist/endpoint-epname.d.ts.map +1 -0
- package/dist/endpoint-epname.js +273 -0
- package/dist/endpoint-epname.js.map +1 -0
- package/dist/endpoint-error.d.ts +155 -1
- package/dist/endpoint-error.d.ts.map +1 -1
- package/dist/endpoint-error.js +114 -2
- package/dist/endpoint-error.js.map +1 -1
- package/dist/endpoint-goaleff.d.ts +56 -0
- package/dist/endpoint-goaleff.d.ts.map +1 -0
- package/dist/endpoint-goaleff.js +212 -0
- package/dist/endpoint-goaleff.js.map +1 -0
- package/dist/endpoint-grants.d.ts +46 -0
- package/dist/endpoint-grants.d.ts.map +1 -1
- package/dist/endpoint-grants.js +68 -0
- package/dist/endpoint-grants.js.map +1 -1
- package/dist/endpoint-invoke.d.ts +1 -1
- package/dist/endpoint-invoke.d.ts.map +1 -1
- package/dist/endpoint-invoke.js +162 -27
- package/dist/endpoint-invoke.js.map +1 -1
- package/dist/endpoint-journal.d.ts +103 -0
- package/dist/endpoint-journal.d.ts.map +1 -1
- package/dist/endpoint-journal.js +290 -0
- package/dist/endpoint-journal.js.map +1 -1
- package/dist/endpoint-records.d.ts.map +1 -1
- package/dist/endpoint-records.js +37 -0
- package/dist/endpoint-records.js.map +1 -1
- package/dist/endpoint-serve.d.ts.map +1 -1
- package/dist/endpoint-serve.js +45 -1
- package/dist/endpoint-serve.js.map +1 -1
- package/dist/endpoint-subjects.d.ts +10 -0
- package/dist/endpoint-subjects.d.ts.map +1 -1
- package/dist/endpoint-subjects.js +10 -0
- package/dist/endpoint-subjects.js.map +1 -1
- package/dist/endpoint-verbs.d.ts +12 -3
- package/dist/endpoint-verbs.d.ts.map +1 -1
- package/dist/endpoint-verbs.js +113 -19
- package/dist/endpoint-verbs.js.map +1 -1
- package/dist/endpoint.d.ts +170 -6
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +472 -37
- package/dist/endpoint.js.map +1 -1
- package/dist/event-channel.d.ts +107 -0
- package/dist/event-channel.d.ts.map +1 -0
- package/dist/event-channel.js +139 -0
- package/dist/event-channel.js.map +1 -0
- package/dist/evict.d.ts +47 -0
- package/dist/evict.d.ts.map +1 -1
- package/dist/evict.js +191 -59
- package/dist/evict.js.map +1 -1
- package/dist/identity.d.ts +15 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +34 -0
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/membership-feed.d.ts.map +1 -1
- package/dist/membership-feed.js +35 -12
- package/dist/membership-feed.js.map +1 -1
- package/dist/parts.d.ts +29 -5
- package/dist/parts.d.ts.map +1 -1
- package/dist/parts.js +46 -3
- package/dist/parts.js.map +1 -1
- package/dist/provision.d.ts +19 -7
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +75 -14
- package/dist/provision.js.map +1 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +38 -0
- package/dist/resolve.js.map +1 -1
- package/dist/streams.d.ts +142 -3
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +192 -17
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +49 -15
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +130 -15
- package/dist/subjects.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place the `events.` convention is spelled.
|
|
3
|
+
*
|
|
4
|
+
* {@link eventChannel} and {@link eventChannelPrincipal} both read it, which is the only reason the
|
|
5
|
+
* constructor and the classifier are allowed to be two functions.
|
|
6
|
+
*/
|
|
7
|
+
export declare const EVENT_CHANNEL_PREFIX = "events.";
|
|
8
|
+
/**
|
|
9
|
+
* The event channel for a principal: `events.<owner>.<actor>`.
|
|
10
|
+
*
|
|
11
|
+
* THE KEY IS THE PRINCIPAL BECAUSE THE DISPLAY NAME IS NOT AN IDENTITY. An earlier version took a
|
|
12
|
+
* name and reduced it to `[a-z0-9_-]`, which FUSED distinct principals onto one channel:
|
|
13
|
+
* `assertValidName` deliberately permits internal spaces and dots (human display names like
|
|
14
|
+
* "Ada Lovelace"), so `Alice Bob`, `Alice.Bob`, `alice bob` and `alice-bob` all collapsed to
|
|
15
|
+
* `events.alice-bob`, and case-folding collapsed `Alice` onto `alice` besides. Eight valid distinct
|
|
16
|
+
* names measured onto three channels. That was an ISOLATION defect rather than a cosmetic one: the
|
|
17
|
+
* publish grant is minted FROM this value, so two distinct principals received the same grant and
|
|
18
|
+
* published to the same subject.
|
|
19
|
+
*
|
|
20
|
+
* The name-keyed version answered that with a sanitiser plus a truncated digest, and could therefore
|
|
21
|
+
* only ever claim COLLISION RESISTANCE, a defence that itself shipped two constructible collisions.
|
|
22
|
+
* Keyed on the principal there is no lossy transform to defend: {@link assertValidOwnerToken} is
|
|
23
|
+
* `[A-Za-z0-9_]+` and FAILS LOUD rather than rewriting, and `.` separates two tokens that cannot
|
|
24
|
+
* contain one. Distinct principals give distinct channels, injective by construction rather than by
|
|
25
|
+
* digest length.
|
|
26
|
+
*
|
|
27
|
+
* THE DOT FORM COSTS TWO SEGMENTS, deliberately. `principalKey().key` is `<owner>.<actor>`, so a
|
|
28
|
+
* channel is three tokens and `events.<owner>.>` is expressible and means OWNER-WIDE: every actor
|
|
29
|
+
* under one owner, not one agent's sessions. The single-token name form (`<owner>-<actor>`) would
|
|
30
|
+
* avoid that, but the dot form is the canonical serialization every authority enforcing per-agent
|
|
31
|
+
* grants already checks against, and a second encoding of a principal is the drift this design
|
|
32
|
+
* refuses everywhere else.
|
|
33
|
+
*
|
|
34
|
+
* Validation is `principalKey`'s own, reused rather than re-implemented: this function derives an
|
|
35
|
+
* AUTHORIZATION value and must not depend on a caller having validated first.
|
|
36
|
+
*
|
|
37
|
+
* @throws via {@link assertValidOwnerToken} on a token outside `[A-Za-z0-9_]+`. A caller holding
|
|
38
|
+
* untrusted input wants {@link eventChannelPrincipal}, which answers with `null`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function eventChannel(principal: {
|
|
41
|
+
owner: string;
|
|
42
|
+
actor: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/**
|
|
45
|
+
* The principal an event channel names, or `null` if the string does not name one.
|
|
46
|
+
*
|
|
47
|
+
* THIS IS A FULL DERIVATION, NOT A PREFIX TEST, AND THAT IS THE WHOLE POINT OF THE FUNCTION. The
|
|
48
|
+
* classifier it replaces asked `channel.startsWith("events.")` and documented the gap as a known
|
|
49
|
+
* limit: any string beginning with those seven characters classified as an event channel. The limit
|
|
50
|
+
* was not harmless in the direction the comment argued. It reasoned that a MALFORMED publisher
|
|
51
|
+
* should stay visible to a filter, but the cost lands on the other side: `assertValidName` permits a
|
|
52
|
+
* dot inside a display name and nothing anywhere reserves the `events.` prefix, so an ordinary chat
|
|
53
|
+
* channel a human called `events.standup` was classified as machine traffic and swept out of the
|
|
54
|
+
* chat pane. A person's messages disappearing from the view they were sent to is a silent loss, and
|
|
55
|
+
* it is exactly the failure this lane exists to remove.
|
|
56
|
+
*
|
|
57
|
+
* The derivation fails the other way, which is the correct direction: a string that does not resolve
|
|
58
|
+
* to a principal is NOT an event channel, so a malformed `events.` name stays in the chat view where
|
|
59
|
+
* a reader can see that something is publishing nonsense. A wrong answer that is visible beats a
|
|
60
|
+
* wrong answer that is quiet.
|
|
61
|
+
*
|
|
62
|
+
* WHAT IT STILL CANNOT SEPARATE, STATED RATHER THAN LEFT FOR A READER TO DISCOVER. Nothing reserves
|
|
63
|
+
* the `events.` prefix, so a human chat channel whose remainder happens to BE principal-shaped is
|
|
64
|
+
* indistinguishable from an agent's stream: `events.team.standup` classifies as an event channel and
|
|
65
|
+
* always will, because `team.standup` is a well-formed principal key and this function has no other
|
|
66
|
+
* evidence to weigh. The derivation narrows the collision rather than closing it. Measured, the
|
|
67
|
+
* narrowing is real and one-directional: `assertValidChannel` admits `-` in a segment and
|
|
68
|
+
* {@link assertValidOwnerToken} does not, and a principal key is exactly two segments, so
|
|
69
|
+
* `events.standup`, `events.my-team.standup` and `events.a.b.c` all return to the chat pane where
|
|
70
|
+
* the prefix test had taken them. Only the exactly-two-underscore-or-alphanumeric-segment case
|
|
71
|
+
* remains. Closing it entirely means reserving the prefix on the wire, which is a change to the
|
|
72
|
+
* normative contract and is deliberately not made here.
|
|
73
|
+
*
|
|
74
|
+
* IT IS THE CONSTRUCTOR'S INVERSE, EXECUTED, not a second expression that resembles it. The parse is
|
|
75
|
+
* checked by rebuilding the name with {@link eventChannel} and comparing. That comparison is
|
|
76
|
+
* currently always true, and it is not decoration: it is the assertion that the two functions still
|
|
77
|
+
* agree, evaluated on every classification rather than argued for in a comment. A change to how the
|
|
78
|
+
* name is formed that forgot this file would be caught by it.
|
|
79
|
+
*
|
|
80
|
+
* IT CANNOT THROW, and that is a property of the order rather than a promise. {@link parsePrincipalKey}
|
|
81
|
+
* admits exactly `[A-Za-z0-9_]+` on both sides of the first dot, which is character for character
|
|
82
|
+
* what {@link assertValidOwnerToken} admits, so by the time {@link eventChannel} is called its
|
|
83
|
+
* refusal is unreachable. The equivalence of those two alphabets is asserted at the boundary
|
|
84
|
+
* characters by the suite rather than assumed here, because it is the load-bearing step and it is
|
|
85
|
+
* one narrowing edit away from being false. No `try` swallows the refusal: a throw arriving here
|
|
86
|
+
* would mean the constructor and the parser had diverged, and hiding that would turn a loud
|
|
87
|
+
* contradiction into a channel silently reclassified as chat.
|
|
88
|
+
*
|
|
89
|
+
* THE SESSION-SCOPED FORM IS DELIBERATELY NOT RECOGNISED. `events.<owner>.<actor>.<session>` is a
|
|
90
|
+
* planned later step, and nothing mints a grant for it or emits on one today. It parses to `null`
|
|
91
|
+
* here, because a classifier that accepts a shape no producer writes is a claim no test can hold up.
|
|
92
|
+
* The commit that starts emitting on a sub-channel is the commit that widens this, and until then
|
|
93
|
+
* the failure if someone forgets is event traffic appearing in the chat pane, which is visible.
|
|
94
|
+
*/
|
|
95
|
+
export declare function eventChannelPrincipal(channel: unknown): {
|
|
96
|
+
owner: string;
|
|
97
|
+
actor: string;
|
|
98
|
+
} | null;
|
|
99
|
+
/**
|
|
100
|
+
* Whether a channel name is an agent's structured-event channel rather than ordinary chat.
|
|
101
|
+
*
|
|
102
|
+
* The predicate a display filter wants, over {@link eventChannelPrincipal}'s derivation. It takes
|
|
103
|
+
* `unknown` and means it: a surface classifies whatever its message carried, and a `channel` field
|
|
104
|
+
* is absent on a direct message and on an anycast.
|
|
105
|
+
*/
|
|
106
|
+
export declare function isEventChannel(channel: unknown): boolean;
|
|
107
|
+
//# sourceMappingURL=event-channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-channel.d.ts","sourceRoot":"","sources":["../src/event-channel.ts"],"names":[],"mappings":"AA4BA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAEhF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAK/F;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAExD"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-agent EVENT channel: how its name is FORMED, and how one is RECOGNISED.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS IS IN CORE, beside `agui-kind.ts`, and not in the connector that emits on it. The same
|
|
5
|
+
* test `agui-kind.ts` applies to the frame's identity applies here: could one adapter change this
|
|
6
|
+
* while the others are unaffected? It could not. Every connector publishes to this name, a grant is
|
|
7
|
+
* minted from the same value, and a reader on the other side of the wire has to recognise it without
|
|
8
|
+
* knowing which adapter produced it. A shape all adapters must agree on is a protocol shape.
|
|
9
|
+
*
|
|
10
|
+
* The direct evidence is the READER. `cotal console`'s mesh view and the dashboard classify live
|
|
11
|
+
* traffic to keep an agent's event stream out of the chat pane, and neither one imports a connector:
|
|
12
|
+
* `bin/run.ts` loads connectors as removable, lazily-materialized `cotal ext` plugins, so a
|
|
13
|
+
* classifier living in `connector-core` is not merely inconvenient for a console, it is ABSENT from
|
|
14
|
+
* the process that needs it. The alternative every consumer reached for instead was re-spelling
|
|
15
|
+
* `events.` locally, which is one more copy of a convention with nothing recomputing that the copies
|
|
16
|
+
* agree.
|
|
17
|
+
*
|
|
18
|
+
* NAMING AND CLASSIFICATION ONLY, AND THAT LINE IS DELIBERATE. What an event channel CARRIES, when
|
|
19
|
+
* it is written, and who may write it all stay in `connector-core`: the emitter, the write-ahead
|
|
20
|
+
* log, the durable source, the ephemeral-identity refusal, and the display-name resolver, which
|
|
21
|
+
* needs presence records core has no business reading. Core learns the name and the predicate,
|
|
22
|
+
* because those are what a reader needs, and nothing beyond them.
|
|
23
|
+
*
|
|
24
|
+
* CORE GAINS NO DEPENDENCY FOR THIS. Both halves are built out of `subjects.ts`, which is already
|
|
25
|
+
* here: {@link principalKey} forms the name and {@link parsePrincipalKey} takes it apart.
|
|
26
|
+
*/
|
|
27
|
+
import { principalKey, parsePrincipalKey } from "./subjects.js";
|
|
28
|
+
/**
|
|
29
|
+
* The one place the `events.` convention is spelled.
|
|
30
|
+
*
|
|
31
|
+
* {@link eventChannel} and {@link eventChannelPrincipal} both read it, which is the only reason the
|
|
32
|
+
* constructor and the classifier are allowed to be two functions.
|
|
33
|
+
*/
|
|
34
|
+
export const EVENT_CHANNEL_PREFIX = "events.";
|
|
35
|
+
/**
|
|
36
|
+
* The event channel for a principal: `events.<owner>.<actor>`.
|
|
37
|
+
*
|
|
38
|
+
* THE KEY IS THE PRINCIPAL BECAUSE THE DISPLAY NAME IS NOT AN IDENTITY. An earlier version took a
|
|
39
|
+
* name and reduced it to `[a-z0-9_-]`, which FUSED distinct principals onto one channel:
|
|
40
|
+
* `assertValidName` deliberately permits internal spaces and dots (human display names like
|
|
41
|
+
* "Ada Lovelace"), so `Alice Bob`, `Alice.Bob`, `alice bob` and `alice-bob` all collapsed to
|
|
42
|
+
* `events.alice-bob`, and case-folding collapsed `Alice` onto `alice` besides. Eight valid distinct
|
|
43
|
+
* names measured onto three channels. That was an ISOLATION defect rather than a cosmetic one: the
|
|
44
|
+
* publish grant is minted FROM this value, so two distinct principals received the same grant and
|
|
45
|
+
* published to the same subject.
|
|
46
|
+
*
|
|
47
|
+
* The name-keyed version answered that with a sanitiser plus a truncated digest, and could therefore
|
|
48
|
+
* only ever claim COLLISION RESISTANCE, a defence that itself shipped two constructible collisions.
|
|
49
|
+
* Keyed on the principal there is no lossy transform to defend: {@link assertValidOwnerToken} is
|
|
50
|
+
* `[A-Za-z0-9_]+` and FAILS LOUD rather than rewriting, and `.` separates two tokens that cannot
|
|
51
|
+
* contain one. Distinct principals give distinct channels, injective by construction rather than by
|
|
52
|
+
* digest length.
|
|
53
|
+
*
|
|
54
|
+
* THE DOT FORM COSTS TWO SEGMENTS, deliberately. `principalKey().key` is `<owner>.<actor>`, so a
|
|
55
|
+
* channel is three tokens and `events.<owner>.>` is expressible and means OWNER-WIDE: every actor
|
|
56
|
+
* under one owner, not one agent's sessions. The single-token name form (`<owner>-<actor>`) would
|
|
57
|
+
* avoid that, but the dot form is the canonical serialization every authority enforcing per-agent
|
|
58
|
+
* grants already checks against, and a second encoding of a principal is the drift this design
|
|
59
|
+
* refuses everywhere else.
|
|
60
|
+
*
|
|
61
|
+
* Validation is `principalKey`'s own, reused rather than re-implemented: this function derives an
|
|
62
|
+
* AUTHORIZATION value and must not depend on a caller having validated first.
|
|
63
|
+
*
|
|
64
|
+
* @throws via {@link assertValidOwnerToken} on a token outside `[A-Za-z0-9_]+`. A caller holding
|
|
65
|
+
* untrusted input wants {@link eventChannelPrincipal}, which answers with `null`.
|
|
66
|
+
*/
|
|
67
|
+
export function eventChannel(principal) {
|
|
68
|
+
return `${EVENT_CHANNEL_PREFIX}${principalKey(principal.owner, principal.actor).key}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The principal an event channel names, or `null` if the string does not name one.
|
|
72
|
+
*
|
|
73
|
+
* THIS IS A FULL DERIVATION, NOT A PREFIX TEST, AND THAT IS THE WHOLE POINT OF THE FUNCTION. The
|
|
74
|
+
* classifier it replaces asked `channel.startsWith("events.")` and documented the gap as a known
|
|
75
|
+
* limit: any string beginning with those seven characters classified as an event channel. The limit
|
|
76
|
+
* was not harmless in the direction the comment argued. It reasoned that a MALFORMED publisher
|
|
77
|
+
* should stay visible to a filter, but the cost lands on the other side: `assertValidName` permits a
|
|
78
|
+
* dot inside a display name and nothing anywhere reserves the `events.` prefix, so an ordinary chat
|
|
79
|
+
* channel a human called `events.standup` was classified as machine traffic and swept out of the
|
|
80
|
+
* chat pane. A person's messages disappearing from the view they were sent to is a silent loss, and
|
|
81
|
+
* it is exactly the failure this lane exists to remove.
|
|
82
|
+
*
|
|
83
|
+
* The derivation fails the other way, which is the correct direction: a string that does not resolve
|
|
84
|
+
* to a principal is NOT an event channel, so a malformed `events.` name stays in the chat view where
|
|
85
|
+
* a reader can see that something is publishing nonsense. A wrong answer that is visible beats a
|
|
86
|
+
* wrong answer that is quiet.
|
|
87
|
+
*
|
|
88
|
+
* WHAT IT STILL CANNOT SEPARATE, STATED RATHER THAN LEFT FOR A READER TO DISCOVER. Nothing reserves
|
|
89
|
+
* the `events.` prefix, so a human chat channel whose remainder happens to BE principal-shaped is
|
|
90
|
+
* indistinguishable from an agent's stream: `events.team.standup` classifies as an event channel and
|
|
91
|
+
* always will, because `team.standup` is a well-formed principal key and this function has no other
|
|
92
|
+
* evidence to weigh. The derivation narrows the collision rather than closing it. Measured, the
|
|
93
|
+
* narrowing is real and one-directional: `assertValidChannel` admits `-` in a segment and
|
|
94
|
+
* {@link assertValidOwnerToken} does not, and a principal key is exactly two segments, so
|
|
95
|
+
* `events.standup`, `events.my-team.standup` and `events.a.b.c` all return to the chat pane where
|
|
96
|
+
* the prefix test had taken them. Only the exactly-two-underscore-or-alphanumeric-segment case
|
|
97
|
+
* remains. Closing it entirely means reserving the prefix on the wire, which is a change to the
|
|
98
|
+
* normative contract and is deliberately not made here.
|
|
99
|
+
*
|
|
100
|
+
* IT IS THE CONSTRUCTOR'S INVERSE, EXECUTED, not a second expression that resembles it. The parse is
|
|
101
|
+
* checked by rebuilding the name with {@link eventChannel} and comparing. That comparison is
|
|
102
|
+
* currently always true, and it is not decoration: it is the assertion that the two functions still
|
|
103
|
+
* agree, evaluated on every classification rather than argued for in a comment. A change to how the
|
|
104
|
+
* name is formed that forgot this file would be caught by it.
|
|
105
|
+
*
|
|
106
|
+
* IT CANNOT THROW, and that is a property of the order rather than a promise. {@link parsePrincipalKey}
|
|
107
|
+
* admits exactly `[A-Za-z0-9_]+` on both sides of the first dot, which is character for character
|
|
108
|
+
* what {@link assertValidOwnerToken} admits, so by the time {@link eventChannel} is called its
|
|
109
|
+
* refusal is unreachable. The equivalence of those two alphabets is asserted at the boundary
|
|
110
|
+
* characters by the suite rather than assumed here, because it is the load-bearing step and it is
|
|
111
|
+
* one narrowing edit away from being false. No `try` swallows the refusal: a throw arriving here
|
|
112
|
+
* would mean the constructor and the parser had diverged, and hiding that would turn a loud
|
|
113
|
+
* contradiction into a channel silently reclassified as chat.
|
|
114
|
+
*
|
|
115
|
+
* THE SESSION-SCOPED FORM IS DELIBERATELY NOT RECOGNISED. `events.<owner>.<actor>.<session>` is a
|
|
116
|
+
* planned later step, and nothing mints a grant for it or emits on one today. It parses to `null`
|
|
117
|
+
* here, because a classifier that accepts a shape no producer writes is a claim no test can hold up.
|
|
118
|
+
* The commit that starts emitting on a sub-channel is the commit that widens this, and until then
|
|
119
|
+
* the failure if someone forgets is event traffic appearing in the chat pane, which is visible.
|
|
120
|
+
*/
|
|
121
|
+
export function eventChannelPrincipal(channel) {
|
|
122
|
+
if (typeof channel !== "string" || !channel.startsWith(EVENT_CHANNEL_PREFIX))
|
|
123
|
+
return null;
|
|
124
|
+
const principal = parsePrincipalKey(channel.slice(EVENT_CHANNEL_PREFIX.length));
|
|
125
|
+
if (principal === null)
|
|
126
|
+
return null;
|
|
127
|
+
return eventChannel(principal) === channel ? principal : null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Whether a channel name is an agent's structured-event channel rather than ordinary chat.
|
|
131
|
+
*
|
|
132
|
+
* The predicate a display filter wants, over {@link eventChannelPrincipal}'s derivation. It takes
|
|
133
|
+
* `unknown` and means it: a surface classifies whatever its message carried, and a `channel` field
|
|
134
|
+
* is absent on a direct message and on an anycast.
|
|
135
|
+
*/
|
|
136
|
+
export function isEventChannel(channel) {
|
|
137
|
+
return eventChannelPrincipal(channel) !== null;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=event-channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-channel.js","sourceRoot":"","sources":["../src/event-channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,YAAY,CAAC,SAA2C;IACtE,OAAO,GAAG,oBAAoB,GAAG,YAAY,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC;AACxF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1F,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,YAAY,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO,qBAAqB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AACjD,CAAC"}
|
package/dist/evict.d.ts
CHANGED
|
@@ -134,6 +134,53 @@ export declare function observePlaneLivenessWithCreds(opts: {
|
|
|
134
134
|
query: PlaneLivenessQuery;
|
|
135
135
|
options?: EvictOptions;
|
|
136
136
|
}): Promise<PlaneLivenessResult>;
|
|
137
|
+
/** A principal's liveness verdict. `live` = a connection attributed to it exists NOW; `gone` = a
|
|
138
|
+
* COMPLETE, single-server-proven sweep proves none does; `unknown` = the observation cannot decide.
|
|
139
|
+
* A caller MUST treat `unknown` as "may still be live" — never as gone. */
|
|
140
|
+
export type PrincipalLiveness = "live" | "gone" | "unknown";
|
|
141
|
+
/** The probe's bound reply: the principal ECHOED back with its verdict (a reply that does not echo
|
|
142
|
+
* the exact principal asked about never authorizes), plus `sweepComplete` — CONNZ observation
|
|
143
|
+
* completeness, kept as its own field and NEVER folded into the verdict. */
|
|
144
|
+
export interface PrincipalLivenessResult {
|
|
145
|
+
principal: string;
|
|
146
|
+
state: PrincipalLiveness;
|
|
147
|
+
sweepComplete: boolean;
|
|
148
|
+
note?: string;
|
|
149
|
+
}
|
|
150
|
+
/** Closed, ECHO-BOUND parse of a wire-crossing {@link PrincipalLivenessResult} — the caller
|
|
151
|
+
* validates the delivery-admin rail's reply BEFORE reasoning over it. Exactly the v1 keys, the
|
|
152
|
+
* state in the enum, and the echoed principal EQUAL to the one queried. Undefined on ANY
|
|
153
|
+
* violation; the caller maps that to `unknown` (a garbled or foreign oracle must block the repair,
|
|
154
|
+
* never authorize it). `expected` is required precisely so the echo cannot be forgotten. */
|
|
155
|
+
export declare function parsePrincipalLivenessResult(v: unknown, expected: string): PrincipalLivenessResult | undefined;
|
|
156
|
+
/**
|
|
157
|
+
* Answer whether ONE principal holds any live connection — the read-only half of principal
|
|
158
|
+
* eviction, drawn from the SAME {@link livenessSweep} the plane oracle uses, so an observation good
|
|
159
|
+
* enough to authorize a repair is validated identically wherever it is read.
|
|
160
|
+
*
|
|
161
|
+
* - `live`: a complete sweep attributed at least one connection to the principal.
|
|
162
|
+
* - `gone`: the sweep is COMPLETE, the single-server mode is PROVEN (SPEC 13.13), and no connection
|
|
163
|
+
* attributes to the principal. The single-server proof is required for the same reason the plane
|
|
164
|
+
* reclaim requires it: in a clustered account, CONNZ absence cannot distinguish a genuinely dead
|
|
165
|
+
* holder from a live one behind a partition, and reading the second as "gone" is exactly the
|
|
166
|
+
* unsafe direction for a repair that revokes and evicts a credential family.
|
|
167
|
+
* - `unknown`: the sweep under-reported, or the single-server mode is unproven.
|
|
168
|
+
*
|
|
169
|
+
* Refuses a non-principal loudly: CONNZ attribution only ever surfaces `local`/`u_…` owners, so a
|
|
170
|
+
* syntactically-valid non-principal would sweep clean and return a HEALTHY `gone` — false
|
|
171
|
+
* confidence for a typo'd target. Same boundary `executeEviction` applies to its filter.
|
|
172
|
+
*/
|
|
173
|
+
export declare function observePrincipalLiveness(observerConn: NatsConnection, accountId: string, principal: string, options?: EvictOptions): Promise<PrincipalLivenessResult>;
|
|
174
|
+
/** Creds-level wrapper for the delivery daemon's admin-rail principal-liveness verb: open the $SYS
|
|
175
|
+
* observer PER CALL (the eviction seam's rule — never a standing $SYS connection), run
|
|
176
|
+
* {@link observePrincipalLiveness}, drain. Read-only: no evictor cred enters this path. */
|
|
177
|
+
export declare function observePrincipalLivenessWithCreds(opts: {
|
|
178
|
+
servers: string;
|
|
179
|
+
observerCreds: string;
|
|
180
|
+
accountId: string;
|
|
181
|
+
principal: string;
|
|
182
|
+
options?: EvictOptions;
|
|
183
|
+
}): Promise<PrincipalLivenessResult>;
|
|
137
184
|
/** Creds-level wrapper for composition roots that hold the two $SYS creds as FILES/strings (the
|
|
138
185
|
* delivery daemon's admin-rail executor): open the observer (under its granted inbox prefix) and
|
|
139
186
|
* the kick-only evictor PER CALL, run {@link evictDeniedPrincipal}, and drain both — eviction is a
|
package/dist/evict.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evict.d.ts","sourceRoot":"","sources":["../src/evict.ts"],"names":[],"mappings":"AAiCA,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAgC3F;;sDAEsD;AACtD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,qGAAqG;IACrG,SAAS,EAAE,MAAM,CAAC;IAClB;0FACsF;IACtF,YAAY,EAAE,OAAO,CAAC;IACtB;sDACkD;IAClD,YAAY,EAAE,OAAO,CAAC;IACtB,+FAA+F;IAC/F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;6CAC6C;AAC7C,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"evict.d.ts","sourceRoot":"","sources":["../src/evict.ts"],"names":[],"mappings":"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"}
|