instar 1.3.732 → 1.3.733
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/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +127 -2
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ConversationRegistry.d.ts +95 -0
- package/dist/core/ConversationRegistry.d.ts.map +1 -1
- package/dist/core/ConversationRegistry.js +292 -5
- package/dist/core/ConversationRegistry.js.map +1 -1
- package/dist/core/SessionManager.d.ts +15 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +28 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/conversationBindToken.d.ts +36 -0
- package/dist/core/conversationBindToken.d.ts.map +1 -0
- package/dist/core/conversationBindToken.js +144 -0
- package/dist/core/conversationBindToken.js.map +1 -0
- package/dist/core/conversationIdentity.d.ts +14 -0
- package/dist/core/conversationIdentity.d.ts.map +1 -1
- package/dist/core/conversationIdentity.js +19 -0
- package/dist/core/conversationIdentity.js.map +1 -1
- package/dist/core/deliverToConversation.d.ts +68 -25
- package/dist/core/deliverToConversation.d.ts.map +1 -1
- package/dist/core/deliverToConversation.js +300 -11
- package/dist/core/deliverToConversation.js.map +1 -1
- package/dist/core/slackRefreshBinding.d.ts +8 -10
- package/dist/core/slackRefreshBinding.d.ts.map +1 -1
- package/dist/core/slackRefreshBinding.js +8 -16
- package/dist/core/slackRefreshBinding.js.map +1 -1
- package/dist/core/types.d.ts +9 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/CommitmentTracker.d.ts +64 -0
- package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
- package/dist/monitoring/CommitmentTracker.js +58 -0
- package/dist/monitoring/CommitmentTracker.js.map +1 -1
- package/dist/monitoring/PromiseBeacon.d.ts +70 -0
- package/dist/monitoring/PromiseBeacon.d.ts.map +1 -1
- package/dist/monitoring/PromiseBeacon.js +221 -24
- package/dist/monitoring/PromiseBeacon.js.map +1 -1
- package/dist/server/AgentServer.d.ts +9 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +8 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +12 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +128 -10
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +48 -48
- package/upgrades/1.3.733.md +108 -0
- package/upgrades/side-effects/durable-conversation-identity-increment2.md +88 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface BindTokenPayload {
|
|
2
|
+
sessionName: string;
|
|
3
|
+
bootstrapConversationIds: number[];
|
|
4
|
+
mintedAt: string;
|
|
5
|
+
}
|
|
6
|
+
/** §7 R7-minor-2: the token-less positive-id straggler backstop window. */
|
|
7
|
+
export declare const TOKENLESS_BIND_GRACE_DAYS = 14;
|
|
8
|
+
/** Read-or-create the 32-byte bind-token secret (first-boot generation). */
|
|
9
|
+
export declare function ensureBindTokenSecret(stateDir: string): Buffer;
|
|
10
|
+
export declare function mintBindToken(secret: Buffer, payload: BindTokenPayload): string;
|
|
11
|
+
/**
|
|
12
|
+
* Verify a token. Returns the CLAMPED payload on a valid MAC, null otherwise
|
|
13
|
+
* (missing/tampered/undecodable — the caller maps null to the typed
|
|
14
|
+
* `conversation-bind-not-authorized` refusal, fail-closed on minted-id binds).
|
|
15
|
+
*/
|
|
16
|
+
export declare function verifyBindToken(secret: Buffer, token: string): BindTokenPayload | null;
|
|
17
|
+
/**
|
|
18
|
+
* Write the per-feature deploy stamp on first boot (idempotent — the house
|
|
19
|
+
* per-feature deploy-stamp shape, R8-low-3). The stamp anchors the
|
|
20
|
+
* `tokenlessBindGraceDays` clock for the R7-minor-2 straggler backstop.
|
|
21
|
+
*/
|
|
22
|
+
export declare function ensureBindDeployStamp(stateDir: string, version: string): void;
|
|
23
|
+
/** Age of the deploy stamp in whole days, or null when unstamped/unreadable. */
|
|
24
|
+
export declare function bindDeployStampAgeDays(stateDir: string, now?: () => number): number | null;
|
|
25
|
+
/** The ctx surface the routes-layer bind gate consumes (wired at bootstrap;
|
|
26
|
+
* AgentServer default-constructs it so the gate is alive on every init path).
|
|
27
|
+
* `mint` is the SessionManager spawn-env side (INSTAR_BIND_TOKEN); `verify` +
|
|
28
|
+
* `deployStampAgeDays` are the POST /commitments gate side — one shared
|
|
29
|
+
* secret backs both. */
|
|
30
|
+
export interface ConversationBindAuth {
|
|
31
|
+
mint: (sessionName: string, bootstrapConversationIds: number[]) => string;
|
|
32
|
+
verify: (token: string) => BindTokenPayload | null;
|
|
33
|
+
deployStampAgeDays: () => number | null;
|
|
34
|
+
}
|
|
35
|
+
export declare function createConversationBindAuth(stateDir: string): ConversationBindAuth;
|
|
36
|
+
//# sourceMappingURL=conversationBindToken.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversationBindToken.d.ts","sourceRoot":"","sources":["../../src/core/conversationBindToken.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,2EAA2E;AAC3E,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAK5C,4EAA4E;AAC5E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAY9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAI/E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAqCtF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAW7E;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,MAAiB,GAAG,MAAM,GAAG,IAAI,CAYpG;AAED;;;;yBAIyB;AACzB,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,KAAK,MAAM,CAAC;IAC1E,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IACnD,kBAAkB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACzC;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,CAQjF"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* conversationBindToken — the §7 bind-time authority primitive (B7 / R3-M5 /
|
|
3
|
+
* R4-M3, docs/specs/durable-conversation-identity.md).
|
|
4
|
+
*
|
|
5
|
+
* A durable-state BIND (`POST /commitments`, working-set carry) on a minted
|
|
6
|
+
* conversation id must be scoped to the session's OWN authenticated bootstrap
|
|
7
|
+
* context. The enforcement primitive is a per-session bind token minted at
|
|
8
|
+
* session spawn and delivered ONLY through the spawned session's environment
|
|
9
|
+
* (`INSTAR_BIND_TOKEN` in the tmux -e block) — never over a route.
|
|
10
|
+
*
|
|
11
|
+
* The token is SELF-AUTHENTICATING and validation is STATELESS (R4-M3):
|
|
12
|
+
* sessions are tmux processes that OUTLIVE the server process, and the server
|
|
13
|
+
* restarts on every auto-update — so the server stores nothing per-session.
|
|
14
|
+
* It verifies the HMAC and reads the bootstrap set FROM the token; a live
|
|
15
|
+
* session's token remains valid across any number of server restarts.
|
|
16
|
+
*
|
|
17
|
+
* Shape: `base64url(payload) + "." + base64url(HMAC-SHA256(secret, payload))`
|
|
18
|
+
* where payload = { sessionName, bootstrapConversationIds, mintedAt }.
|
|
19
|
+
*
|
|
20
|
+
* The secret is a random 32-byte value generated once at first boot and
|
|
21
|
+
* persisted in the stateDir (same at-rest posture as authToken — plaintext
|
|
22
|
+
* machine-local; it authorizes only bind-scoping, never delivery or message
|
|
23
|
+
* content). It is deliberately EXCLUDED from the backup manifest (R5-minor-4):
|
|
24
|
+
* a disaster restore regenerates it, so all outstanding tokens invalidate —
|
|
25
|
+
* live sessions then hit the loud typed refusal until respawned, never a
|
|
26
|
+
* silent failure. Rotating it (delete the file, restart) is the revocation
|
|
27
|
+
* story — a LOUD deliberate trade.
|
|
28
|
+
*/
|
|
29
|
+
import crypto from 'node:crypto';
|
|
30
|
+
import fs from 'node:fs';
|
|
31
|
+
import path from 'node:path';
|
|
32
|
+
/** §7 R7-minor-2: the token-less positive-id straggler backstop window. */
|
|
33
|
+
export const TOKENLESS_BIND_GRACE_DAYS = 14;
|
|
34
|
+
const SECRET_RELATIVE_PATH = path.join('state', 'conversation-bind-token.secret');
|
|
35
|
+
const DEPLOY_STAMP_RELATIVE_PATH = path.join('state', 'conversation-registry-deploy.json');
|
|
36
|
+
/** Read-or-create the 32-byte bind-token secret (first-boot generation). */
|
|
37
|
+
export function ensureBindTokenSecret(stateDir) {
|
|
38
|
+
const p = path.join(stateDir, SECRET_RELATIVE_PATH);
|
|
39
|
+
try {
|
|
40
|
+
const existing = fs.readFileSync(p);
|
|
41
|
+
if (existing.length >= 32)
|
|
42
|
+
return existing;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* falls through to generation */
|
|
46
|
+
}
|
|
47
|
+
const secret = crypto.randomBytes(32);
|
|
48
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
49
|
+
fs.writeFileSync(p, secret, { mode: 0o600 });
|
|
50
|
+
return secret;
|
|
51
|
+
}
|
|
52
|
+
export function mintBindToken(secret, payload) {
|
|
53
|
+
const body = Buffer.from(JSON.stringify(payload), 'utf-8').toString('base64url');
|
|
54
|
+
const mac = crypto.createHmac('sha256', secret).update(body).digest('base64url');
|
|
55
|
+
return `${body}.${mac}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Verify a token. Returns the CLAMPED payload on a valid MAC, null otherwise
|
|
59
|
+
* (missing/tampered/undecodable — the caller maps null to the typed
|
|
60
|
+
* `conversation-bind-not-authorized` refusal, fail-closed on minted-id binds).
|
|
61
|
+
*/
|
|
62
|
+
export function verifyBindToken(secret, token) {
|
|
63
|
+
if (typeof token !== 'string' || token.length > 4096)
|
|
64
|
+
return null;
|
|
65
|
+
const idx = token.indexOf('.');
|
|
66
|
+
if (idx <= 0 || idx === token.length - 1)
|
|
67
|
+
return null;
|
|
68
|
+
const body = token.slice(0, idx);
|
|
69
|
+
const givenMac = token.slice(idx + 1);
|
|
70
|
+
const expected = crypto.createHmac('sha256', secret).update(body).digest();
|
|
71
|
+
let given;
|
|
72
|
+
try {
|
|
73
|
+
given = Buffer.from(givenMac, 'base64url');
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// @silent-fallback-ok — a non-decodable MAC is an INVALID token; returning
|
|
77
|
+
// null is the fail-CLOSED security contract (the caller refuses the bind),
|
|
78
|
+
// not a degraded-service fallback.
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (given.length !== expected.length || !crypto.timingSafeEqual(given, expected))
|
|
82
|
+
return null;
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(Buffer.from(body, 'base64url').toString('utf-8'));
|
|
85
|
+
if (!parsed ||
|
|
86
|
+
typeof parsed.sessionName !== 'string' ||
|
|
87
|
+
!Array.isArray(parsed.bootstrapConversationIds) ||
|
|
88
|
+
typeof parsed.mintedAt !== 'string') {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
sessionName: parsed.sessionName.slice(0, 128),
|
|
93
|
+
bootstrapConversationIds: parsed.bootstrapConversationIds.filter((n) => typeof n === 'number' && Number.isSafeInteger(n)),
|
|
94
|
+
mintedAt: parsed.mintedAt.slice(0, 64),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Write the per-feature deploy stamp on first boot (idempotent — the house
|
|
103
|
+
* per-feature deploy-stamp shape, R8-low-3). The stamp anchors the
|
|
104
|
+
* `tokenlessBindGraceDays` clock for the R7-minor-2 straggler backstop.
|
|
105
|
+
*/
|
|
106
|
+
export function ensureBindDeployStamp(stateDir, version) {
|
|
107
|
+
const p = path.join(stateDir, DEPLOY_STAMP_RELATIVE_PATH);
|
|
108
|
+
if (fs.existsSync(p))
|
|
109
|
+
return;
|
|
110
|
+
try {
|
|
111
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
112
|
+
fs.writeFileSync(p, JSON.stringify({ firstBootVersion: version, at: new Date().toISOString() }, null, 2));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
/* @silent-fallback-ok — the stamp only arms the fail-OPEN straggler
|
|
116
|
+
attention backstop; a missed write means the backstop stays unarmed
|
|
117
|
+
(today's behavior), never a refused bind. */
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** Age of the deploy stamp in whole days, or null when unstamped/unreadable. */
|
|
121
|
+
export function bindDeployStampAgeDays(stateDir, now = Date.now) {
|
|
122
|
+
try {
|
|
123
|
+
const raw = JSON.parse(fs.readFileSync(path.join(stateDir, DEPLOY_STAMP_RELATIVE_PATH), 'utf-8'));
|
|
124
|
+
const at = raw?.at ? Date.parse(raw.at) : NaN;
|
|
125
|
+
if (!Number.isFinite(at))
|
|
126
|
+
return null;
|
|
127
|
+
return Math.floor((now() - at) / 86400000);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// @silent-fallback-ok — an unreadable/absent deploy stamp reads as "no age"
|
|
131
|
+
// (null), so the R7-minor-2 straggler backstop simply stays UNARMED (today's
|
|
132
|
+
// fail-open behavior) — never a refused bind, never a degraded service path.
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function createConversationBindAuth(stateDir) {
|
|
137
|
+
const secret = ensureBindTokenSecret(stateDir);
|
|
138
|
+
return {
|
|
139
|
+
mint: (sessionName, bootstrapConversationIds) => mintBindToken(secret, { sessionName, bootstrapConversationIds, mintedAt: new Date().toISOString() }),
|
|
140
|
+
verify: (token) => verifyBindToken(secret, token),
|
|
141
|
+
deployStampAgeDays: () => bindDeployStampAgeDays(stateDir),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=conversationBindToken.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversationBindToken.js","sourceRoot":"","sources":["../../src/core/conversationBindToken.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,6 +86,20 @@ export declare function parseCanonicalKey(key: string): {
|
|
|
86
86
|
tuple: ConversationTuple;
|
|
87
87
|
workspaceId: string;
|
|
88
88
|
} | null;
|
|
89
|
+
/**
|
|
90
|
+
* The SHARED id↔tuple coherence predicate (§3.5 ingest check ≡ §3.5.2 R5-M2
|
|
91
|
+
* delivery-time check — ONE implementation, never a second copy; a second
|
|
92
|
+
* implementation is a CI failure per §10). An id is coherent with a tuple iff
|
|
93
|
+
* it is the tuple's recomputed candidate or a within-`MAX_PROBE_DISTANCE`
|
|
94
|
+
* displacement offset of it (probe direction DOWN):
|
|
95
|
+
*
|
|
96
|
+
* cand(routingKey(tuple)) − MAX_PROBE_DISTANCE ≤ id ≤ cand(routingKey(tuple))
|
|
97
|
+
*
|
|
98
|
+
* Used at delivery time to validate a binding's stored `topicId` against its
|
|
99
|
+
* record-carried `boundTuple` (increment 2); the §6.1-step-9 replication
|
|
100
|
+
* ingest check MUST reuse this export.
|
|
101
|
+
*/
|
|
102
|
+
export declare function idWithinCoherenceBound(id: number, tuple: ConversationTuple): boolean;
|
|
89
103
|
/** Result of a displacement walk (§3.3 probe / §3.5.1 step 2). */
|
|
90
104
|
export type DisplacementResult = {
|
|
91
105
|
ok: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversationIdentity.d.ts","sourceRoot":"","sources":["../../src/core/conversationIdentity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;kFAEkF;AAClF,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,uFAAuF;AACvF,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,2FAA2F;AAC3F,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AACtD,eAAO,MAAM,kBAAkB,QAAoB,CAAC;AACpD,eAAO,MAAM,qBAAqB,QAAiB,CAAC;AACpD,yFAAyF;AACzF,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAEnE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAO/E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIjG;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,iBAAiB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQvG;AAED,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,kBAAkB,CASzG"}
|
|
1
|
+
{"version":3,"file":"conversationIdentity.d.ts","sourceRoot":"","sources":["../../src/core/conversationIdentity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;kFAEkF;AAClF,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,uFAAuF;AACvF,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,2FAA2F;AAC3F,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,QAAqB,CAAC;AACtD,eAAO,MAAM,kBAAkB,QAAoB,CAAC;AACpD,eAAO,MAAM,qBAAqB,QAAiB,CAAC;AACpD,yFAAyF;AACzF,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAEnE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAO/E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAE5D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAIjG;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,iBAAiB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQvG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAIpF;AAED,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,kBAAkB,CASzG"}
|
|
@@ -114,6 +114,25 @@ export function parseCanonicalKey(key) {
|
|
|
114
114
|
return null;
|
|
115
115
|
return { tuple: { platform: 'slack', channelId, threadTs: threadTs ?? null }, workspaceId };
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The SHARED id↔tuple coherence predicate (§3.5 ingest check ≡ §3.5.2 R5-M2
|
|
119
|
+
* delivery-time check — ONE implementation, never a second copy; a second
|
|
120
|
+
* implementation is a CI failure per §10). An id is coherent with a tuple iff
|
|
121
|
+
* it is the tuple's recomputed candidate or a within-`MAX_PROBE_DISTANCE`
|
|
122
|
+
* displacement offset of it (probe direction DOWN):
|
|
123
|
+
*
|
|
124
|
+
* cand(routingKey(tuple)) − MAX_PROBE_DISTANCE ≤ id ≤ cand(routingKey(tuple))
|
|
125
|
+
*
|
|
126
|
+
* Used at delivery time to validate a binding's stored `topicId` against its
|
|
127
|
+
* record-carried `boundTuple` (increment 2); the §6.1-step-9 replication
|
|
128
|
+
* ingest check MUST reuse this export.
|
|
129
|
+
*/
|
|
130
|
+
export function idWithinCoherenceBound(id, tuple) {
|
|
131
|
+
if (!Number.isSafeInteger(id) || id >= 0)
|
|
132
|
+
return false;
|
|
133
|
+
const cand = candidateIdForRoutingKey(routingKeyForTuple(tuple));
|
|
134
|
+
return id <= cand && id >= cand - MAX_PROBE_DISTANCE;
|
|
135
|
+
}
|
|
117
136
|
/**
|
|
118
137
|
* The ONE shared displacement implementation (§3.3 = §3.5.1 step 2 — pinned by
|
|
119
138
|
* the §10 shared-implementation equivalence test; R2-adversarial-2). Walks the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversationIdentity.js","sourceRoot":"","sources":["../../src/core/conversationIdentity.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conversationIdentity.js","sourceRoot":"","sources":["../../src/core/conversationIdentity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* deliverToConversation — the outbound funnel SKELETON
|
|
3
|
-
* (docs/specs/durable-conversation-identity.md §5; §6.1 increment 1).
|
|
4
|
-
*
|
|
5
|
-
* A single delivery helper every follow-through consumer MIGRATES onto in the
|
|
6
|
-
* later §6.1 increments. In increment 1 it ships with ZERO consumers and the
|
|
7
|
-
* `id<0` arm dark-gated behind `conversationIdentity.followThrough` (§9:
|
|
8
|
-
* `enabled` OMITTED → the developmentAgent gate resolves it — live-on-dev,
|
|
9
|
-
* dark-fleet; `dryRun: true` FIRST because delivery is externally visible).
|
|
10
|
-
*
|
|
11
|
-
* §5.1 failure/dryRun contract: a funnel non-delivery is a TYPED,
|
|
12
|
-
* NON-EXCEPTIONAL return the caller inspects — never a thrown exception, and
|
|
13
|
-
* NEVER success-shaped. dryRun (and fleet-dark) return the SAME
|
|
14
|
-
* `not-delivered` typed result the unresolvable path uses, plus a
|
|
15
|
-
* `would-deliver` audit line — caller-visible as a non-delivery so beacon
|
|
16
|
-
* retry / attention escalation keep engaging (A Refusal Stays a Refusal / P18).
|
|
17
|
-
*
|
|
18
|
-
* NOT in this skeleton (they land WITH their §6.1 increments, before any
|
|
19
|
-
* consumer migrates onto the funnel): the §5.0(a) E1 ambiguous-outcome
|
|
20
|
-
* idempotency guard + durable send-intent ops (increment 2, the proof
|
|
21
|
-
* consumer), the §5 `deterministicKind` gate-exempt arm (increment 3), the
|
|
22
|
-
* §5.2 P17 budgets (increment 5's attention migration), and the §5.1
|
|
23
|
-
* permanent-error classification (increment 2).
|
|
24
|
-
*/
|
|
25
1
|
import type { ConversationRegistry } from './ConversationRegistry.js';
|
|
26
2
|
export interface DeliverOpts {
|
|
27
3
|
isProxy?: boolean;
|
|
@@ -29,16 +5,78 @@ export interface DeliverOpts {
|
|
|
29
5
|
tier?: string;
|
|
30
6
|
allowDuplicate?: boolean;
|
|
31
7
|
messageKind?: string;
|
|
8
|
+
/**
|
|
9
|
+
* §5.0(a) STABLE logical send identity (`<commitmentId>:<sendSeq>` for
|
|
10
|
+
* beacon sends — the §3.4 pinned encoding). A caller supplying its own
|
|
11
|
+
* logicalSendId MUST also define its retirement events (R8-low-2); a caller
|
|
12
|
+
* that cannot name them belongs on the content-hash window lane (omit this).
|
|
13
|
+
*/
|
|
14
|
+
logicalSendId?: string;
|
|
15
|
+
/**
|
|
16
|
+
* §3.5.2 property 5: the binding record's denormalized bind-time tuple.
|
|
17
|
+
* Delivery targets `resolve(boundTuple)` when present AND coherent with the
|
|
18
|
+
* binding's stored id — the uniform every-machine delivery rule.
|
|
19
|
+
*/
|
|
20
|
+
boundTuple?: {
|
|
21
|
+
platform: string;
|
|
22
|
+
channelId: string;
|
|
23
|
+
threadTs: string | null;
|
|
24
|
+
};
|
|
32
25
|
}
|
|
33
26
|
export type DeliveryOutcome = {
|
|
34
27
|
delivered: true;
|
|
35
28
|
outcome: 'delivered';
|
|
29
|
+
}
|
|
30
|
+
/** §5.0(a): DELIVERED-EQUIVALENT for sequencing (R7-M1) — the caller treats
|
|
31
|
+
* it as delivered (no re-escalation, seq advances) so suppression can never
|
|
32
|
+
* mute the beacon. */
|
|
33
|
+
| {
|
|
34
|
+
delivered: false;
|
|
35
|
+
outcome: 'already-delivered-recently';
|
|
36
36
|
} | {
|
|
37
37
|
delivered: false;
|
|
38
38
|
outcome: 'not-delivered';
|
|
39
|
-
reason: 'follow-through-dark' | 'follow-through-dry-run' | 'unresolvable' | 'replicated-only-origin' | 'system-channel-suppressed' | 'no-slack-adapter' | 'send-failed' | 'telegram-send-failed';
|
|
39
|
+
reason: 'follow-through-dark' | 'follow-through-dry-run' | 'unresolvable' | 'replicated-only-origin' | 'system-channel-suppressed' | 'no-slack-adapter' | 'send-failed' | 'telegram-send-failed' | 'conversation-unreachable' | 'conversation-binding-incoherent' | 'binding-target-unresolved';
|
|
40
40
|
detail?: string;
|
|
41
|
+
/** §5.1: true ONLY for the pinned permanent error set — the beacon
|
|
42
|
+
* treats it as TERMINAL (dead-letter), never an infinite retry. */
|
|
43
|
+
permanent?: boolean;
|
|
44
|
+
/** §5/I1 dead-letter scoping: a by-design non-owning/unresolvable
|
|
45
|
+
* refusal — the beacon STANDS DOWN (bounded ownership recheck), and this
|
|
46
|
+
* NEVER increments the dead-letter counter. */
|
|
47
|
+
standDown?: boolean;
|
|
41
48
|
};
|
|
49
|
+
/** §5.1 pinned PERMANENT `chat.postMessage` error codes — the code is
|
|
50
|
+
* `is_archived`, NOT `channel_archived` (adversarial-A2/codex-X4). DISTINCT
|
|
51
|
+
* from the adapter's token-scoped `SlackApiError.permanent` set. */
|
|
52
|
+
export declare const CONVERSATION_UNREACHABLE_ERRORS: Set<string>;
|
|
53
|
+
/** Content-hash lane length gate — mirrors the Telegram exact-duplicate
|
|
54
|
+
* dedup's `minLength` (brief acks are never suppressed). */
|
|
55
|
+
export declare const CONTENT_HASH_MIN_LENGTH = 40;
|
|
56
|
+
/** §5.1 R2-lessons-2/P17 pinned emitter coalescing window (mass-unreachable). */
|
|
57
|
+
export declare const UNREACHABLE_COALESCING_WINDOW_MS = 60000;
|
|
58
|
+
export type SlackSendErrorClass = {
|
|
59
|
+
kind: 'permanent';
|
|
60
|
+
code: string;
|
|
61
|
+
} | {
|
|
62
|
+
kind: 'permanent-shaped-unknown';
|
|
63
|
+
code: string;
|
|
64
|
+
} | {
|
|
65
|
+
kind: 'clean-transient';
|
|
66
|
+
detail: string;
|
|
67
|
+
} | {
|
|
68
|
+
kind: 'ambiguous';
|
|
69
|
+
detail: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Classify a Slack-arm send failure (§5.1 + §5.0(a) R2-security-NEW-3).
|
|
73
|
+
* A `SlackApiError` means Slack ANSWERED `ok:false` — positive evidence the
|
|
74
|
+
* message did NOT post (clean), further split permanent/canary/transient.
|
|
75
|
+
* A pre-accept network refusal is clean. Everything else (timeout, reset,
|
|
76
|
+
* unknown) is AMBIGUOUS — the message may actually have posted, so the E1
|
|
77
|
+
* suppressor IS recorded (only a CLEAN failure forbids recording).
|
|
78
|
+
*/
|
|
79
|
+
export declare function classifySlackSendError(err: unknown): SlackSendErrorClass;
|
|
42
80
|
export interface ConversationDeliveryDeps {
|
|
43
81
|
registry: ConversationRegistry;
|
|
44
82
|
/** §9 followThrough gate state, resolved through resolveDevAgentGate at wiring. */
|
|
@@ -55,7 +93,12 @@ export interface ConversationDeliveryDeps {
|
|
|
55
93
|
isSystemChannel?: (channelId: string) => boolean;
|
|
56
94
|
/** `would-deliver` audit sink for dark/dry non-deliveries (§5.1). */
|
|
57
95
|
auditWouldDeliver?: (line: string) => void;
|
|
96
|
+
/** ONE deduped attention item per episode (incoherent binding, pin redirect,
|
|
97
|
+
* drift canary, mass-unreachable summary, non-owning heal paths). */
|
|
98
|
+
onAttention?: (dedupeKey: string, title: string, body: string) => void;
|
|
58
99
|
log?: (line: string) => void;
|
|
100
|
+
/** Test override for the mass-unreachable coalescing window. */
|
|
101
|
+
coalescingWindowMs?: number;
|
|
59
102
|
}
|
|
60
103
|
export type DeliverToConversation = (id: number, text: string, opts?: DeliverOpts) => Promise<DeliveryOutcome>;
|
|
61
104
|
export declare function createConversationDelivery(deps: ConversationDeliveryDeps): DeliverToConversation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliverToConversation.d.ts","sourceRoot":"","sources":["../../src/core/deliverToConversation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deliverToConversation.d.ts","sourceRoot":"","sources":["../../src/core/deliverToConversation.ts"],"names":[],"mappings":"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"}
|