instar 1.3.730 → 1.3.732
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 +161 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +26 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/CoherenceGate.d.ts +119 -0
- package/dist/core/CoherenceGate.d.ts.map +1 -1
- package/dist/core/CoherenceGate.js +342 -19
- package/dist/core/CoherenceGate.js.map +1 -1
- package/dist/core/CoherenceReviewer.d.ts +30 -0
- package/dist/core/CoherenceReviewer.d.ts.map +1 -1
- package/dist/core/CoherenceReviewer.js +14 -0
- package/dist/core/CoherenceReviewer.js.map +1 -1
- package/dist/core/ConversationRegistry.d.ts +260 -0
- package/dist/core/ConversationRegistry.d.ts.map +1 -0
- package/dist/core/ConversationRegistry.js +1151 -0
- package/dist/core/ConversationRegistry.js.map +1 -0
- package/dist/core/FileClassifier.d.ts.map +1 -1
- package/dist/core/FileClassifier.js +7 -0
- package/dist/core/FileClassifier.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +13 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +105 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ResponseReviewDecisionLog.d.ts +45 -0
- package/dist/core/ResponseReviewDecisionLog.d.ts.map +1 -0
- package/dist/core/ResponseReviewDecisionLog.js +85 -0
- package/dist/core/ResponseReviewDecisionLog.js.map +1 -0
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
- package/dist/core/WriteDomainRegistry.js +21 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -1
- package/dist/core/conversationContextWiring.d.ts +51 -0
- package/dist/core/conversationContextWiring.d.ts.map +1 -0
- package/dist/core/conversationContextWiring.js +78 -0
- package/dist/core/conversationContextWiring.js.map +1 -0
- package/dist/core/conversationIdentity.d.ts +112 -0
- package/dist/core/conversationIdentity.d.ts.map +1 -0
- package/dist/core/conversationIdentity.js +141 -0
- package/dist/core/conversationIdentity.js.map +1 -0
- package/dist/core/deliverToConversation.d.ts +62 -0
- package/dist/core/deliverToConversation.d.ts.map +1 -0
- package/dist/core/deliverToConversation.js +85 -0
- package/dist/core/deliverToConversation.js.map +1 -0
- package/dist/core/devGatedFeatures.d.ts.map +1 -1
- package/dist/core/devGatedFeatures.js +6 -0
- package/dist/core/devGatedFeatures.js.map +1 -1
- package/dist/core/reviewers/conversational-tone.d.ts.map +1 -1
- package/dist/core/reviewers/conversational-tone.js +15 -1
- package/dist/core/reviewers/conversational-tone.js.map +1 -1
- package/dist/core/types.d.ts +76 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/untrustedConversationContext.d.ts +77 -0
- package/dist/core/untrustedConversationContext.d.ts.map +1 -0
- package/dist/core/untrustedConversationContext.js +134 -0
- package/dist/core/untrustedConversationContext.js.map +1 -0
- package/dist/monitoring/ReviewCanaryBattery.d.ts +160 -0
- package/dist/monitoring/ReviewCanaryBattery.d.ts.map +1 -0
- package/dist/monitoring/ReviewCanaryBattery.js +416 -0
- package/dist/monitoring/ReviewCanaryBattery.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +15 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +7 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +13 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +15 -0
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +10 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +114 -1
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/scaffold/templates/jobs/instar/review-canary-battery.md +31 -0
- package/src/scaffold/templates.ts +15 -0
- package/upgrades/1.3.731.md +97 -0
- package/upgrades/1.3.732.md +107 -0
- package/upgrades/side-effects/context-aware-outbound-review.md +62 -0
- package/upgrades/side-effects/durable-conversation-identity-increment1.md +89 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResponseReviewDecisionLog — the durable would-block decision log
|
|
3
|
+
* (context-aware-outbound-review spec §D8, the flip-evidence store).
|
|
4
|
+
*
|
|
5
|
+
* The in-memory `CoherenceGate.reviewHistory` is pruned to 1000 entries and
|
|
6
|
+
* erased by every server restart — a data-gated enforcement-flip criterion
|
|
7
|
+
* ("a clean day on real traffic") cannot rest on a store any restart wipes.
|
|
8
|
+
* This append-only JSONL (`logs/response-review-decisions.jsonl`) is the
|
|
9
|
+
* restart-surviving record: one line per `_evaluate` verdict (ALL outcomes,
|
|
10
|
+
* not just would-blocks — the §D9.3 denominator matters), written at the same
|
|
11
|
+
* seam as `logAudit`, plus the two additive soak row types (counterfactual
|
|
12
|
+
* rows, §D9.4; canary/battery rows, §D9.4b — written through this SAME
|
|
13
|
+
* writer so there is exactly one file and one rotation policy).
|
|
14
|
+
*
|
|
15
|
+
* At-rest honesty (§D8): rows persist 200 credential-scrubbed chars of every
|
|
16
|
+
* reviewed turn plus topicId, as a plaintext machine-local file under
|
|
17
|
+
* filesystem permissions — the same posture as sibling JSONLs, NOT the
|
|
18
|
+
* encrypted vault. That is the trade for restart-surviving flip evidence.
|
|
19
|
+
*
|
|
20
|
+
* Failure direction: write failures are swallowed — telemetry must never
|
|
21
|
+
* affect a verdict or delivery (§D5: the D8 write is one of the individually
|
|
22
|
+
* contained context code paths; the HTTP seam above fails OPEN so nothing
|
|
23
|
+
* here may throw into `_evaluate`).
|
|
24
|
+
*/
|
|
25
|
+
export declare class ResponseReviewDecisionLog {
|
|
26
|
+
private readonly logPath;
|
|
27
|
+
private readonly maxBytes;
|
|
28
|
+
constructor(logPath: string, options?: {
|
|
29
|
+
maxBytes?: number;
|
|
30
|
+
});
|
|
31
|
+
/** The absolute path of the JSONL file (for tests + observability). */
|
|
32
|
+
getPath(): string;
|
|
33
|
+
/**
|
|
34
|
+
* Append one row. Swallows every failure — the decision log is telemetry;
|
|
35
|
+
* a full disk or unwritable path must never affect a review verdict.
|
|
36
|
+
*/
|
|
37
|
+
append(row: Record<string, unknown>): void;
|
|
38
|
+
/**
|
|
39
|
+
* Size rotation: when the file exceeds maxBytes, rename it to `<path>.1`
|
|
40
|
+
* (replacing the previous archive) and start fresh — the same bounded
|
|
41
|
+
* single-archive policy sibling JSONLs use. Contained; never throws.
|
|
42
|
+
*/
|
|
43
|
+
private rotateIfNeeded;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=ResponseReviewDecisionLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponseReviewDecisionLog.d.ts","sourceRoot":"","sources":["../../src/core/ResponseReviewDecisionLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAQH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAK5D,uEAAuE;IACvE,OAAO,IAAI,MAAM;IAIjB;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAW1C;;;;OAIG;IACH,OAAO,CAAC,cAAc;CAqBvB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResponseReviewDecisionLog — the durable would-block decision log
|
|
3
|
+
* (context-aware-outbound-review spec §D8, the flip-evidence store).
|
|
4
|
+
*
|
|
5
|
+
* The in-memory `CoherenceGate.reviewHistory` is pruned to 1000 entries and
|
|
6
|
+
* erased by every server restart — a data-gated enforcement-flip criterion
|
|
7
|
+
* ("a clean day on real traffic") cannot rest on a store any restart wipes.
|
|
8
|
+
* This append-only JSONL (`logs/response-review-decisions.jsonl`) is the
|
|
9
|
+
* restart-surviving record: one line per `_evaluate` verdict (ALL outcomes,
|
|
10
|
+
* not just would-blocks — the §D9.3 denominator matters), written at the same
|
|
11
|
+
* seam as `logAudit`, plus the two additive soak row types (counterfactual
|
|
12
|
+
* rows, §D9.4; canary/battery rows, §D9.4b — written through this SAME
|
|
13
|
+
* writer so there is exactly one file and one rotation policy).
|
|
14
|
+
*
|
|
15
|
+
* At-rest honesty (§D8): rows persist 200 credential-scrubbed chars of every
|
|
16
|
+
* reviewed turn plus topicId, as a plaintext machine-local file under
|
|
17
|
+
* filesystem permissions — the same posture as sibling JSONLs, NOT the
|
|
18
|
+
* encrypted vault. That is the trade for restart-surviving flip evidence.
|
|
19
|
+
*
|
|
20
|
+
* Failure direction: write failures are swallowed — telemetry must never
|
|
21
|
+
* affect a verdict or delivery (§D5: the D8 write is one of the individually
|
|
22
|
+
* contained context code paths; the HTTP seam above fails OPEN so nothing
|
|
23
|
+
* here may throw into `_evaluate`).
|
|
24
|
+
*/
|
|
25
|
+
import fs from 'node:fs';
|
|
26
|
+
import path from 'node:path';
|
|
27
|
+
import { SafeFsExecutor } from './SafeFsExecutor.js';
|
|
28
|
+
const DEFAULT_MAX_BYTES = 10 * 1024 * 1024; // 10MB, size-rotated like sibling JSONLs
|
|
29
|
+
export class ResponseReviewDecisionLog {
|
|
30
|
+
logPath;
|
|
31
|
+
maxBytes;
|
|
32
|
+
constructor(logPath, options) {
|
|
33
|
+
this.logPath = logPath;
|
|
34
|
+
this.maxBytes = options?.maxBytes ?? DEFAULT_MAX_BYTES;
|
|
35
|
+
}
|
|
36
|
+
/** The absolute path of the JSONL file (for tests + observability). */
|
|
37
|
+
getPath() {
|
|
38
|
+
return this.logPath;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Append one row. Swallows every failure — the decision log is telemetry;
|
|
42
|
+
* a full disk or unwritable path must never affect a review verdict.
|
|
43
|
+
*/
|
|
44
|
+
append(row) {
|
|
45
|
+
try {
|
|
46
|
+
fs.mkdirSync(path.dirname(this.logPath), { recursive: true });
|
|
47
|
+
this.rotateIfNeeded();
|
|
48
|
+
fs.appendFileSync(this.logPath, JSON.stringify(row) + '\n', 'utf8');
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// @silent-fallback-ok — §D8: decision-log write failures are swallowed;
|
|
52
|
+
// the verdict and delivery are unaffected (telemetry never gates).
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Size rotation: when the file exceeds maxBytes, rename it to `<path>.1`
|
|
57
|
+
* (replacing the previous archive) and start fresh — the same bounded
|
|
58
|
+
* single-archive policy sibling JSONLs use. Contained; never throws.
|
|
59
|
+
*/
|
|
60
|
+
rotateIfNeeded() {
|
|
61
|
+
try {
|
|
62
|
+
const stat = fs.statSync(this.logPath);
|
|
63
|
+
if (stat.size < this.maxBytes)
|
|
64
|
+
return;
|
|
65
|
+
const archive = `${this.logPath}.1`;
|
|
66
|
+
try {
|
|
67
|
+
SafeFsExecutor.safeRmSync(archive, {
|
|
68
|
+
force: true,
|
|
69
|
+
operation: 'ResponseReviewDecisionLog.rotate (drop the previous single archive)',
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// @silent-fallback-ok — a stale archive that cannot be removed only
|
|
74
|
+
// means renameSync below may fail; that failure is caught too.
|
|
75
|
+
}
|
|
76
|
+
fs.renameSync(this.logPath, archive);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// @silent-fallback-ok — a missing file (ENOENT on first write) or a
|
|
80
|
+
// failed rotation both degrade to "keep appending"; telemetry never
|
|
81
|
+
// gates and the append itself is separately contained.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=ResponseReviewDecisionLog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponseReviewDecisionLog.js","sourceRoot":"","sources":["../../src/core/ResponseReviewDecisionLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,yCAAyC;AAErF,MAAM,OAAO,yBAAyB;IACnB,OAAO,CAAS;IAChB,QAAQ,CAAS;IAElC,YAAY,OAAe,EAAE,OAA+B;QAC1D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,iBAAiB,CAAC;IACzD,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,GAA4B;QACjC,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QACtE,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;YACxE,mEAAmE;QACrE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,cAAc;QACpB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtC,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC;YACpC,IAAI,CAAC;gBACH,cAAc,CAAC,UAAU,CAAC,OAAO,EAAE;oBACjC,KAAK,EAAE,IAAI;oBACX,SAAS,EAAE,qEAAqE;iBACjF,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,oEAAoE;gBACpE,+DAA+D;YACjE,CAAC;YACD,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,oEAAoE;YACpE,uDAAuD;QACzD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WriteDomainRegistry.d.ts","sourceRoot":"","sources":["../../src/core/WriteDomainRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,MAAM,WAAW,GAAG,eAAe,GAAG,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAEjG,MAAM,MAAM,uBAAuB,GAC/B,iBAAiB,GACjB,uBAAuB,GACvB,kBAAkB,GAClB,mBAAmB,GACnB,uBAAuB,CAAC;AAE5B,MAAM,MAAM,YAAY,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAEpE,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,OAAO,EAAE,uBAAuB,CAAC;IACjC;iEAC6D;IAC7D,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gEAAgE;IAChE,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB;8EAC0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,IAAI,CAAC;IACX,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;mCAE+B;IAC/B,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;CACtC;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,cAAc,CAAC;IACvB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;CACtC;AAED,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,gBAAgB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gCAAgC,QAAQ,CAAC;AAatD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAGtF;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA8B;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,+EAA+E;IAC/E,QAAQ,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,CAAM;IAE9D;;2DAEuD;IACvD,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAsBlC;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI;IAO9D,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;KAAE;IAK/F;8BAC0B;IAC1B,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAQnE,qEAAqE;IACrE,YAAY,IAAI,SAAS,UAAU,EAAE;IAIrC,MAAM,IAAI,MAAM,EAAE;IAIlB,OAAO,IAAI,MAAM,EAAE;CAGpB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,mBAAmB,
|
|
1
|
+
{"version":3,"file":"WriteDomainRegistry.d.ts","sourceRoot":"","sources":["../../src/core/WriteDomainRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -181,6 +181,27 @@ export function buildWriteDomainRegistry(opts) {
|
|
|
181
181
|
reg.add({ kind: 'route', method: 'PATCH', pathPrefix: '/evolution/', domain: 'machine-local', story: evolutionStory });
|
|
182
182
|
reg.add({ kind: 'route', method: 'POST', pathPrefix: '/attention', domain: 'machine-local', story: attentionStory });
|
|
183
183
|
reg.add({ kind: 'route', method: 'PATCH', pathPrefix: '/attention', domain: 'machine-local', story: attentionStory });
|
|
184
|
+
// ── Review canary battery trigger (context-aware-outbound-review §D9.4b) ──
|
|
185
|
+
// Machine-local by construction: the Bearer-gated soak trigger runs THIS
|
|
186
|
+
// machine's review pipeline against booby-trapped fixtures. Its only writes
|
|
187
|
+
// are (a) transient fixture rows in the per-machine topic-memory SQLite,
|
|
188
|
+
// scoped to reserved NEGATIVE topic ids and removed in a finally (plus the
|
|
189
|
+
// next run's pre-clean, R4-m4), and (b) append-only batterySummary /
|
|
190
|
+
// decision rows in logs/response-review-decisions.jsonl — per-machine soak
|
|
191
|
+
// EVIDENCE, never authority, never converged across machines. Re-running
|
|
192
|
+
// the battery regenerates everything the route ever writes.
|
|
193
|
+
reg.add({
|
|
194
|
+
kind: 'route',
|
|
195
|
+
method: 'POST',
|
|
196
|
+
pathPrefix: '/review/canary-battery/run',
|
|
197
|
+
domain: 'machine-local',
|
|
198
|
+
story: {
|
|
199
|
+
logical: 'ephemeral-rebuildable',
|
|
200
|
+
onSharedGitSyncedPath: true,
|
|
201
|
+
fileLevel: 'git-sync-excluded',
|
|
202
|
+
note: 'canary fixtures are finally-cleaned rows in the per-machine topic-memory SQLite (reserved negative topic ids); the D8 decision log is per-machine soak evidence; file-level arm shipped in FileClassifier sync exclusions (.instar/topic-memory.db + logs/response-review-decisions.jsonl)',
|
|
203
|
+
},
|
|
204
|
+
});
|
|
184
205
|
return reg;
|
|
185
206
|
}
|
|
186
207
|
//# sourceMappingURL=WriteDomainRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WriteDomainRegistry.js","sourceRoot":"","sources":["../../src/core/WriteDomainRegistry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WriteDomainRegistry.js","sourceRoot":"","sources":["../../src/core/WriteDomainRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* conversationContextWiring — the WIRING-layer principal computation for the
|
|
3
|
+
* context-aware outbound review feature (spec §D1/§D4, Know Your Principal).
|
|
4
|
+
*
|
|
5
|
+
* The CoherenceGate stays decoupled from src/users/ and src/memory/: it sees
|
|
6
|
+
* only the injected `conversationContextProvider` function. THIS module is
|
|
7
|
+
* what the server wires that provider to — it converts raw TopicMemory rows
|
|
8
|
+
* plus the topic's verified-operator binding into the provider's return shape:
|
|
9
|
+
* role-labeled rows with per-row `verifiedOperator` tags AND the window's
|
|
10
|
+
* structural `askLicenseMode` (R4-m1: the provider RETURNS the wiring-computed
|
|
11
|
+
* values — the gate copies the mode into `conversationContextMeta` and NEVER
|
|
12
|
+
* computes or infers it).
|
|
13
|
+
*
|
|
14
|
+
* Principal rules (§D4, all computed from AUTHENTICATED uids — never content):
|
|
15
|
+
* - Role comes from the store's `fromUser` column, never message text.
|
|
16
|
+
* - BOUND topic (TopicOperatorStore binding present): mode =
|
|
17
|
+
* 'verified-operator'; each user row whose authenticated `telegramUserId`
|
|
18
|
+
* matches the binding uid is tagged `verifiedOperator: true` (rendered
|
|
19
|
+
* `USER(verified-operator):`); non-matching and uid-less rows render plain
|
|
20
|
+
* `USER:` (weak corroboration by the prompt contract).
|
|
21
|
+
* - UNBOUND topic: 'single-sender' ONLY when EVERY user-role row in the
|
|
22
|
+
* window carries an authenticated uid AND exactly ONE distinct uid appears
|
|
23
|
+
* (R4-L1: "at most one" would misread a zero-uid window as licensed).
|
|
24
|
+
* A window containing ANY uid-less user-role row — or 2+ distinct uids, or
|
|
25
|
+
* zero user rows — computes 'weak-corroboration-only' (R3-M2: an
|
|
26
|
+
* unverifiable sender can never help LICENSE; fail-closed).
|
|
27
|
+
*
|
|
28
|
+
* A throw anywhere in here is a PROVIDER throw, caught at acquisition inside
|
|
29
|
+
* CoherenceGate._evaluate per §D5 (degrades to no context section).
|
|
30
|
+
*/
|
|
31
|
+
import type { AskLicenseMode, ConversationContextMessage } from './untrustedConversationContext.js';
|
|
32
|
+
/** The subset of a TopicMemory row this computation reads. */
|
|
33
|
+
export interface ConversationSourceRow {
|
|
34
|
+
text: string;
|
|
35
|
+
fromUser: boolean;
|
|
36
|
+
/** Telegram numeric user ID — the authoritative authenticated identity. */
|
|
37
|
+
telegramUserId?: number | null;
|
|
38
|
+
}
|
|
39
|
+
/** The provider return shape (CoherenceGateOptions.conversationContextProvider). */
|
|
40
|
+
export interface ConversationContextProviderResult {
|
|
41
|
+
messages: ConversationContextMessage[];
|
|
42
|
+
askLicenseMode: AskLicenseMode;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compute the provider result from raw rows + the topic's verified-operator
|
|
46
|
+
* binding (null when the topic is unbound). Pure and synchronous.
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildConversationContext(rows: ConversationSourceRow[], operator: {
|
|
49
|
+
uid: string;
|
|
50
|
+
} | null): ConversationContextProviderResult;
|
|
51
|
+
//# sourceMappingURL=conversationContextWiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversationContextWiring.d.ts","sourceRoot":"","sources":["../../src/core/conversationContextWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,0BAA0B,EAC3B,MAAM,mCAAmC,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,oFAAoF;AACpF,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,qBAAqB,EAAE,EAC7B,QAAQ,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC/B,iCAAiC,CA6CnC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* conversationContextWiring — the WIRING-layer principal computation for the
|
|
3
|
+
* context-aware outbound review feature (spec §D1/§D4, Know Your Principal).
|
|
4
|
+
*
|
|
5
|
+
* The CoherenceGate stays decoupled from src/users/ and src/memory/: it sees
|
|
6
|
+
* only the injected `conversationContextProvider` function. THIS module is
|
|
7
|
+
* what the server wires that provider to — it converts raw TopicMemory rows
|
|
8
|
+
* plus the topic's verified-operator binding into the provider's return shape:
|
|
9
|
+
* role-labeled rows with per-row `verifiedOperator` tags AND the window's
|
|
10
|
+
* structural `askLicenseMode` (R4-m1: the provider RETURNS the wiring-computed
|
|
11
|
+
* values — the gate copies the mode into `conversationContextMeta` and NEVER
|
|
12
|
+
* computes or infers it).
|
|
13
|
+
*
|
|
14
|
+
* Principal rules (§D4, all computed from AUTHENTICATED uids — never content):
|
|
15
|
+
* - Role comes from the store's `fromUser` column, never message text.
|
|
16
|
+
* - BOUND topic (TopicOperatorStore binding present): mode =
|
|
17
|
+
* 'verified-operator'; each user row whose authenticated `telegramUserId`
|
|
18
|
+
* matches the binding uid is tagged `verifiedOperator: true` (rendered
|
|
19
|
+
* `USER(verified-operator):`); non-matching and uid-less rows render plain
|
|
20
|
+
* `USER:` (weak corroboration by the prompt contract).
|
|
21
|
+
* - UNBOUND topic: 'single-sender' ONLY when EVERY user-role row in the
|
|
22
|
+
* window carries an authenticated uid AND exactly ONE distinct uid appears
|
|
23
|
+
* (R4-L1: "at most one" would misread a zero-uid window as licensed).
|
|
24
|
+
* A window containing ANY uid-less user-role row — or 2+ distinct uids, or
|
|
25
|
+
* zero user rows — computes 'weak-corroboration-only' (R3-M2: an
|
|
26
|
+
* unverifiable sender can never help LICENSE; fail-closed).
|
|
27
|
+
*
|
|
28
|
+
* A throw anywhere in here is a PROVIDER throw, caught at acquisition inside
|
|
29
|
+
* CoherenceGate._evaluate per §D5 (degrades to no context section).
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Compute the provider result from raw rows + the topic's verified-operator
|
|
33
|
+
* binding (null when the topic is unbound). Pure and synchronous.
|
|
34
|
+
*/
|
|
35
|
+
export function buildConversationContext(rows, operator) {
|
|
36
|
+
const boundUid = operator && typeof operator.uid === 'string' && operator.uid.length > 0
|
|
37
|
+
? operator.uid
|
|
38
|
+
: null;
|
|
39
|
+
const messages = rows.map((r) => {
|
|
40
|
+
const role = r.fromUser ? 'user' : 'agent';
|
|
41
|
+
const msg = {
|
|
42
|
+
role,
|
|
43
|
+
text: typeof r.text === 'string' ? r.text : String(r.text ?? ''),
|
|
44
|
+
};
|
|
45
|
+
if (boundUid !== null &&
|
|
46
|
+
role === 'user' &&
|
|
47
|
+
r.telegramUserId !== null &&
|
|
48
|
+
r.telegramUserId !== undefined &&
|
|
49
|
+
String(r.telegramUserId) === boundUid) {
|
|
50
|
+
msg.verifiedOperator = true;
|
|
51
|
+
}
|
|
52
|
+
return msg;
|
|
53
|
+
});
|
|
54
|
+
let askLicenseMode;
|
|
55
|
+
if (boundUid !== null) {
|
|
56
|
+
// Bound topic: the binding IS the license authority. Uid-less rows are
|
|
57
|
+
// already rendered plain USER: (weak corroboration) by the tag rule above.
|
|
58
|
+
askLicenseMode = 'verified-operator';
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const userRows = rows.filter((r) => r.fromUser);
|
|
62
|
+
const uids = new Set();
|
|
63
|
+
let anyUidless = userRows.length === 0; // zero user rows can never license
|
|
64
|
+
for (const r of userRows) {
|
|
65
|
+
if (r.telegramUserId === null || r.telegramUserId === undefined) {
|
|
66
|
+
anyUidless = true;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
uids.add(String(r.telegramUserId));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
askLicenseMode = !anyUidless && uids.size === 1
|
|
73
|
+
? 'single-sender'
|
|
74
|
+
: 'weak-corroboration-only';
|
|
75
|
+
}
|
|
76
|
+
return { messages, askLicenseMode };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=conversationContextWiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversationContextWiring.js","sourceRoot":"","sources":["../../src/core/conversationContextWiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAqBH;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA6B,EAC7B,QAAgC;IAEhC,MAAM,QAAQ,GAAG,QAAQ,IAAI,OAAO,QAAQ,CAAC,GAAG,KAAK,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;QACtF,CAAC,CAAC,QAAQ,CAAC,GAAG;QACd,CAAC,CAAC,IAAI,CAAC;IAET,MAAM,QAAQ,GAAiC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5D,MAAM,IAAI,GAAqB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAC7D,MAAM,GAAG,GAA+B;YACtC,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;SACjE,CAAC;QACF,IACE,QAAQ,KAAK,IAAI;YACjB,IAAI,KAAK,MAAM;YACf,CAAC,CAAC,cAAc,KAAK,IAAI;YACzB,CAAC,CAAC,cAAc,KAAK,SAAS;YAC9B,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,QAAQ,EACrC,CAAC;YACD,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,IAAI,cAA8B,CAAC;IACnC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,uEAAuE;QACvE,2EAA2E;QAC3E,cAAc,GAAG,mBAAmB,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,IAAI,UAAU,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,mCAAmC;QAC3E,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,CAAC,cAAc,KAAK,IAAI,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAChE,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,cAAc,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;YAC7C,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,yBAAyB,CAAC;IAChC,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* conversationIdentity.ts — the SINGLE hash + identity surface for durable,
|
|
3
|
+
* channel-agnostic conversation identity (docs/specs/durable-conversation-identity.md §4).
|
|
4
|
+
*
|
|
5
|
+
* This module absorbs `slackRefreshBinding`'s key helpers and is the ONE place
|
|
6
|
+
* the legacy 32-bit sum-shift hash + mint-candidate formula live going forward.
|
|
7
|
+
* The three legacy copies (`server.ts slackChannelToSyntheticId`, the
|
|
8
|
+
* `routes.ts` build-heartbeat inline copy, `slackRefreshBinding.ts
|
|
9
|
+
* slackRoutingKeySyntheticId`) consolidate onto these exports in the §4
|
|
10
|
+
* foundation increment; a FOURTH copy of the mint idiom is a CI failure
|
|
11
|
+
* (tests/unit/conversation-identity-mint-idiom-ratchet.test.ts).
|
|
12
|
+
*
|
|
13
|
+
* Spec §3.1: the PRIMARY identity of a conversation is the structured tuple
|
|
14
|
+
* `(platform, channelId, threadTs?)` bound to a stable minted NEGATIVE id; the
|
|
15
|
+
* canonical key string (`slack:<teamId>:<channelId>[:<threadTs>]`) is its
|
|
16
|
+
* normalized LOOKUP form, and `workspaceId` is identity-adjacent metadata
|
|
17
|
+
* (upgradable in place, `_` placeholder when unknown). Telegram positive ids
|
|
18
|
+
* pass through unregistered, forever.
|
|
19
|
+
*/
|
|
20
|
+
/** Tuple schema version (§Glossary). v1 is SINGLE-WORKSPACE: the tuple carries
|
|
21
|
+
* no workspaceId — correct only because exactly one workspace is enforced
|
|
22
|
+
* (§3.1). Phase 7.1 introduces schema-version 2 with workspaceId in the core. */
|
|
23
|
+
export declare const TUPLE_SCHEMA_VERSION = 1;
|
|
24
|
+
/**
|
|
25
|
+
* §3.3/§3.5 frozen constants — schema-v1, changed ONLY by a versioned
|
|
26
|
+
* migration (a mixed fleet comparing different bounds/windows would pick
|
|
27
|
+
* divergent accept/quarantine verdicts). Pinned by the §10 golden-parity test.
|
|
28
|
+
*/
|
|
29
|
+
export declare const MAX_PROBE_DISTANCE = 64;
|
|
30
|
+
/** Probe direction is DOWN (`id -= 1`) and FROZEN FOREVER (frontloaded decision 2). */
|
|
31
|
+
export declare const PROBE_DIRECTION = -1;
|
|
32
|
+
/** HLC `physical` unit: MILLISECONDS since the Unix epoch (frozen, schema-v1 — R3-M10). */
|
|
33
|
+
export declare const HLC_ABS_MIN = 1767225600000;
|
|
34
|
+
export declare const HLC_ABS_MAX = 4102444800000;
|
|
35
|
+
/** §3.5 ingest shape clamps (also applied at the §6.3 mint site — security-M1c). */
|
|
36
|
+
export declare const SLACK_CHANNEL_ID_RE: RegExp;
|
|
37
|
+
export declare const SLACK_THREAD_TS_RE: RegExp;
|
|
38
|
+
export declare const SLACK_WORKSPACE_ID_RE: RegExp;
|
|
39
|
+
/** The unknown-workspace placeholder (§3.1) — upgrades in place to a concrete teamId. */
|
|
40
|
+
export declare const WORKSPACE_PLACEHOLDER = "_";
|
|
41
|
+
/** The Phase-1 structured tuple (§3.1). `threadTs: null` = channel-level. */
|
|
42
|
+
export interface ConversationTuple {
|
|
43
|
+
platform: 'slack';
|
|
44
|
+
channelId: string;
|
|
45
|
+
threadTs: string | null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The frozen 32-bit sum-shift hash over a routing key — byte-identical to the
|
|
49
|
+
* three legacy copies (golden-parity pinned in §10). NEVER change this: mixed-
|
|
50
|
+
* fleet convergence and zero-loss adoption both depend on it (§3.3 properties 1/2).
|
|
51
|
+
*/
|
|
52
|
+
export declare function sumShiftHash(input: string): number;
|
|
53
|
+
/**
|
|
54
|
+
* The deterministic mint CANDIDATE for a routing key (§3.3):
|
|
55
|
+
* `-(abs(hash) + 1)` — always negative, never 0, value-identical to
|
|
56
|
+
* `slackRoutingKeySyntheticId` (thread-aware: hashes `channelId[:threadTs]`).
|
|
57
|
+
* This is the mint candidate, no longer an identity authority — the registry
|
|
58
|
+
* is the collision authority.
|
|
59
|
+
*/
|
|
60
|
+
export declare function candidateIdForRoutingKey(routingKey: string): number;
|
|
61
|
+
/** Adapter routing-key tail for a tuple: `<channelId>[:<threadTs>]` (§3.1). */
|
|
62
|
+
export declare function routingKeyForTuple(tuple: ConversationTuple): string;
|
|
63
|
+
/**
|
|
64
|
+
* Parse a Slack routing key (`C…` or `C…:<thread_ts>`) into a v1 tuple.
|
|
65
|
+
* Returns null when the shape is invalid (§3.6: callers treat as "no durable
|
|
66
|
+
* id" and keep legacy behavior — a typed refusal, never a throw).
|
|
67
|
+
* Shape validation here is the §7 mesh-forward guard (security-M1c): a
|
|
68
|
+
* forwarded/replayed inbound cannot supply a crafted key to force a target
|
|
69
|
+
* candidate.
|
|
70
|
+
*/
|
|
71
|
+
export declare function tupleForRoutingKey(routingKey: string): ConversationTuple | null;
|
|
72
|
+
/**
|
|
73
|
+
* The §3.4 tupleKey — the IMMUTABLE byte-form used for the tuple index AND the
|
|
74
|
+
* `≺` tiebreak (§3.5.1: null `threadTs` compares as the EMPTY string, so a
|
|
75
|
+
* channel-level tuple deterministically precedes its own threads).
|
|
76
|
+
*/
|
|
77
|
+
export declare function tupleKeyFor(tuple: ConversationTuple): string;
|
|
78
|
+
/**
|
|
79
|
+
* Canonical key (§3.1): `slack:<teamId>:<channelId>[:<threadTs>]` with `_`
|
|
80
|
+
* for an unknown teamId. The normalized lookup/display string — NOT the
|
|
81
|
+
* primary identity (the tuple is).
|
|
82
|
+
*/
|
|
83
|
+
export declare function canonicalKeyFor(tuple: ConversationTuple, workspaceId: string | undefined): string;
|
|
84
|
+
/** Parse a canonical key back to `{ tuple, workspaceId }`, or null when malformed. */
|
|
85
|
+
export declare function parseCanonicalKey(key: string): {
|
|
86
|
+
tuple: ConversationTuple;
|
|
87
|
+
workspaceId: string;
|
|
88
|
+
} | null;
|
|
89
|
+
/** Result of a displacement walk (§3.3 probe / §3.5.1 step 2). */
|
|
90
|
+
export type DisplacementResult = {
|
|
91
|
+
ok: true;
|
|
92
|
+
id: number;
|
|
93
|
+
probes: number;
|
|
94
|
+
} | {
|
|
95
|
+
ok: false;
|
|
96
|
+
overflow: true;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* The ONE shared displacement implementation (§3.3 = §3.5.1 step 2 — pinned by
|
|
100
|
+
* the §10 shared-implementation equivalence test; R2-adversarial-2). Walks the
|
|
101
|
+
* FROZEN down-sequence `candidate, candidate-1, candidate-2, …` and returns
|
|
102
|
+
* the first offset for which `collides(id)` is false, bounded by
|
|
103
|
+
* `MAX_PROBE_DISTANCE` (= the ingest coherence bound, so a local mint can
|
|
104
|
+
* never produce an id a peer's ingest would quarantine as a pre-squat).
|
|
105
|
+
*
|
|
106
|
+
* `collides` MUST be the pure §3.3 `candidateCollides` predicate — reserved
|
|
107
|
+
* canonicals (a), the alias table (b), and the GLOBAL displaced-assignment set
|
|
108
|
+
* (c) — each an O(1) lookup, NEVER a live-tuple scan (R2-scalability-1). A
|
|
109
|
+
* walk exceeding the bound degrades to the §3.6 pending-mint path.
|
|
110
|
+
*/
|
|
111
|
+
export declare function walkDisplacement(candidate: number, collides: (id: number) => boolean): DisplacementResult;
|
|
112
|
+
//# sourceMappingURL=conversationIdentity.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* conversationIdentity.ts — the SINGLE hash + identity surface for durable,
|
|
3
|
+
* channel-agnostic conversation identity (docs/specs/durable-conversation-identity.md §4).
|
|
4
|
+
*
|
|
5
|
+
* This module absorbs `slackRefreshBinding`'s key helpers and is the ONE place
|
|
6
|
+
* the legacy 32-bit sum-shift hash + mint-candidate formula live going forward.
|
|
7
|
+
* The three legacy copies (`server.ts slackChannelToSyntheticId`, the
|
|
8
|
+
* `routes.ts` build-heartbeat inline copy, `slackRefreshBinding.ts
|
|
9
|
+
* slackRoutingKeySyntheticId`) consolidate onto these exports in the §4
|
|
10
|
+
* foundation increment; a FOURTH copy of the mint idiom is a CI failure
|
|
11
|
+
* (tests/unit/conversation-identity-mint-idiom-ratchet.test.ts).
|
|
12
|
+
*
|
|
13
|
+
* Spec §3.1: the PRIMARY identity of a conversation is the structured tuple
|
|
14
|
+
* `(platform, channelId, threadTs?)` bound to a stable minted NEGATIVE id; the
|
|
15
|
+
* canonical key string (`slack:<teamId>:<channelId>[:<threadTs>]`) is its
|
|
16
|
+
* normalized LOOKUP form, and `workspaceId` is identity-adjacent metadata
|
|
17
|
+
* (upgradable in place, `_` placeholder when unknown). Telegram positive ids
|
|
18
|
+
* pass through unregistered, forever.
|
|
19
|
+
*/
|
|
20
|
+
/** Tuple schema version (§Glossary). v1 is SINGLE-WORKSPACE: the tuple carries
|
|
21
|
+
* no workspaceId — correct only because exactly one workspace is enforced
|
|
22
|
+
* (§3.1). Phase 7.1 introduces schema-version 2 with workspaceId in the core. */
|
|
23
|
+
export const TUPLE_SCHEMA_VERSION = 1;
|
|
24
|
+
/**
|
|
25
|
+
* §3.3/§3.5 frozen constants — schema-v1, changed ONLY by a versioned
|
|
26
|
+
* migration (a mixed fleet comparing different bounds/windows would pick
|
|
27
|
+
* divergent accept/quarantine verdicts). Pinned by the §10 golden-parity test.
|
|
28
|
+
*/
|
|
29
|
+
export const MAX_PROBE_DISTANCE = 64;
|
|
30
|
+
/** Probe direction is DOWN (`id -= 1`) and FROZEN FOREVER (frontloaded decision 2). */
|
|
31
|
+
export const PROBE_DIRECTION = -1;
|
|
32
|
+
/** HLC `physical` unit: MILLISECONDS since the Unix epoch (frozen, schema-v1 — R3-M10). */
|
|
33
|
+
export const HLC_ABS_MIN = 1767225600000; // 2026-01-01T00:00:00Z
|
|
34
|
+
export const HLC_ABS_MAX = 4102444800000; // 2100-01-01T00:00:00Z — documented horizon; re-pin via versioned migration WELL before
|
|
35
|
+
/** §3.5 ingest shape clamps (also applied at the §6.3 mint site — security-M1c). */
|
|
36
|
+
export const SLACK_CHANNEL_ID_RE = /^[CDG][A-Z0-9]+$/;
|
|
37
|
+
export const SLACK_THREAD_TS_RE = /^\d{10}\.\d{6}$/;
|
|
38
|
+
export const SLACK_WORKSPACE_ID_RE = /^T[A-Z0-9]+$/;
|
|
39
|
+
/** The unknown-workspace placeholder (§3.1) — upgrades in place to a concrete teamId. */
|
|
40
|
+
export const WORKSPACE_PLACEHOLDER = '_';
|
|
41
|
+
/**
|
|
42
|
+
* The frozen 32-bit sum-shift hash over a routing key — byte-identical to the
|
|
43
|
+
* three legacy copies (golden-parity pinned in §10). NEVER change this: mixed-
|
|
44
|
+
* fleet convergence and zero-loss adoption both depend on it (§3.3 properties 1/2).
|
|
45
|
+
*/
|
|
46
|
+
export function sumShiftHash(input) {
|
|
47
|
+
let hash = 0;
|
|
48
|
+
for (let i = 0; i < input.length; i++) {
|
|
49
|
+
hash = ((hash << 5) - hash + input.charCodeAt(i)) | 0;
|
|
50
|
+
}
|
|
51
|
+
return hash;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The deterministic mint CANDIDATE for a routing key (§3.3):
|
|
55
|
+
* `-(abs(hash) + 1)` — always negative, never 0, value-identical to
|
|
56
|
+
* `slackRoutingKeySyntheticId` (thread-aware: hashes `channelId[:threadTs]`).
|
|
57
|
+
* This is the mint candidate, no longer an identity authority — the registry
|
|
58
|
+
* is the collision authority.
|
|
59
|
+
*/
|
|
60
|
+
export function candidateIdForRoutingKey(routingKey) {
|
|
61
|
+
return -(Math.abs(sumShiftHash(routingKey)) + 1);
|
|
62
|
+
}
|
|
63
|
+
/** Adapter routing-key tail for a tuple: `<channelId>[:<threadTs>]` (§3.1). */
|
|
64
|
+
export function routingKeyForTuple(tuple) {
|
|
65
|
+
return tuple.threadTs ? `${tuple.channelId}:${tuple.threadTs}` : tuple.channelId;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse a Slack routing key (`C…` or `C…:<thread_ts>`) into a v1 tuple.
|
|
69
|
+
* Returns null when the shape is invalid (§3.6: callers treat as "no durable
|
|
70
|
+
* id" and keep legacy behavior — a typed refusal, never a throw).
|
|
71
|
+
* Shape validation here is the §7 mesh-forward guard (security-M1c): a
|
|
72
|
+
* forwarded/replayed inbound cannot supply a crafted key to force a target
|
|
73
|
+
* candidate.
|
|
74
|
+
*/
|
|
75
|
+
export function tupleForRoutingKey(routingKey) {
|
|
76
|
+
const idx = routingKey.indexOf(':');
|
|
77
|
+
const channelId = idx === -1 ? routingKey : routingKey.slice(0, idx);
|
|
78
|
+
const threadTs = idx === -1 ? null : routingKey.slice(idx + 1);
|
|
79
|
+
if (!SLACK_CHANNEL_ID_RE.test(channelId))
|
|
80
|
+
return null;
|
|
81
|
+
if (threadTs !== null && !SLACK_THREAD_TS_RE.test(threadTs))
|
|
82
|
+
return null;
|
|
83
|
+
return { platform: 'slack', channelId, threadTs };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The §3.4 tupleKey — the IMMUTABLE byte-form used for the tuple index AND the
|
|
87
|
+
* `≺` tiebreak (§3.5.1: null `threadTs` compares as the EMPTY string, so a
|
|
88
|
+
* channel-level tuple deterministically precedes its own threads).
|
|
89
|
+
*/
|
|
90
|
+
export function tupleKeyFor(tuple) {
|
|
91
|
+
return `${tuple.platform}\x1f${tuple.channelId}\x1f${tuple.threadTs ?? ''}`;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Canonical key (§3.1): `slack:<teamId>:<channelId>[:<threadTs>]` with `_`
|
|
95
|
+
* for an unknown teamId. The normalized lookup/display string — NOT the
|
|
96
|
+
* primary identity (the tuple is).
|
|
97
|
+
*/
|
|
98
|
+
export function canonicalKeyFor(tuple, workspaceId) {
|
|
99
|
+
const team = workspaceId && SLACK_WORKSPACE_ID_RE.test(workspaceId) ? workspaceId : WORKSPACE_PLACEHOLDER;
|
|
100
|
+
const base = `${tuple.platform}:${team}:${tuple.channelId}`;
|
|
101
|
+
return tuple.threadTs ? `${base}:${tuple.threadTs}` : base;
|
|
102
|
+
}
|
|
103
|
+
/** Parse a canonical key back to `{ tuple, workspaceId }`, or null when malformed. */
|
|
104
|
+
export function parseCanonicalKey(key) {
|
|
105
|
+
const parts = key.split(':');
|
|
106
|
+
if (parts.length < 3 || parts.length > 4 || parts[0] !== 'slack')
|
|
107
|
+
return null;
|
|
108
|
+
const [, workspaceId, channelId, threadTs] = parts;
|
|
109
|
+
if (workspaceId !== WORKSPACE_PLACEHOLDER && !SLACK_WORKSPACE_ID_RE.test(workspaceId))
|
|
110
|
+
return null;
|
|
111
|
+
if (!SLACK_CHANNEL_ID_RE.test(channelId))
|
|
112
|
+
return null;
|
|
113
|
+
if (threadTs !== undefined && !SLACK_THREAD_TS_RE.test(threadTs))
|
|
114
|
+
return null;
|
|
115
|
+
return { tuple: { platform: 'slack', channelId, threadTs: threadTs ?? null }, workspaceId };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The ONE shared displacement implementation (§3.3 = §3.5.1 step 2 — pinned by
|
|
119
|
+
* the §10 shared-implementation equivalence test; R2-adversarial-2). Walks the
|
|
120
|
+
* FROZEN down-sequence `candidate, candidate-1, candidate-2, …` and returns
|
|
121
|
+
* the first offset for which `collides(id)` is false, bounded by
|
|
122
|
+
* `MAX_PROBE_DISTANCE` (= the ingest coherence bound, so a local mint can
|
|
123
|
+
* never produce an id a peer's ingest would quarantine as a pre-squat).
|
|
124
|
+
*
|
|
125
|
+
* `collides` MUST be the pure §3.3 `candidateCollides` predicate — reserved
|
|
126
|
+
* canonicals (a), the alias table (b), and the GLOBAL displaced-assignment set
|
|
127
|
+
* (c) — each an O(1) lookup, NEVER a live-tuple scan (R2-scalability-1). A
|
|
128
|
+
* walk exceeding the bound degrades to the §3.6 pending-mint path.
|
|
129
|
+
*/
|
|
130
|
+
export function walkDisplacement(candidate, collides) {
|
|
131
|
+
let id = candidate;
|
|
132
|
+
let probes = 0;
|
|
133
|
+
while (collides(id)) {
|
|
134
|
+
id += PROBE_DIRECTION;
|
|
135
|
+
probes++;
|
|
136
|
+
if (probes > MAX_PROBE_DISTANCE)
|
|
137
|
+
return { ok: false, overflow: true };
|
|
138
|
+
}
|
|
139
|
+
return { ok: true, id, probes };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=conversationIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversationIdentity.js","sourceRoot":"","sources":["../../src/core/conversationIdentity.ts"],"names":[],"mappings":"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"}
|