instar 1.3.461 → 1.3.463

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.
Files changed (38) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +7 -24
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/feedback-factory/cutoverReadiness.d.ts +34 -0
  5. package/dist/feedback-factory/cutoverReadiness.d.ts.map +1 -1
  6. package/dist/feedback-factory/cutoverReadiness.js +37 -0
  7. package/dist/feedback-factory/cutoverReadiness.js.map +1 -1
  8. package/dist/feedback-factory/migration/PersistedShadowImportTarget.d.ts +54 -0
  9. package/dist/feedback-factory/migration/PersistedShadowImportTarget.d.ts.map +1 -0
  10. package/dist/feedback-factory/migration/PersistedShadowImportTarget.js +121 -0
  11. package/dist/feedback-factory/migration/PersistedShadowImportTarget.js.map +1 -0
  12. package/dist/feedback-factory/migration/integrityPassRunner.d.ts +26 -0
  13. package/dist/feedback-factory/migration/integrityPassRunner.d.ts.map +1 -0
  14. package/dist/feedback-factory/migration/integrityPassRunner.js +83 -0
  15. package/dist/feedback-factory/migration/integrityPassRunner.js.map +1 -0
  16. package/dist/monitoring/sentinelConsolidatedSend.d.ts +26 -0
  17. package/dist/monitoring/sentinelConsolidatedSend.d.ts.map +1 -0
  18. package/dist/monitoring/sentinelConsolidatedSend.js +80 -0
  19. package/dist/monitoring/sentinelConsolidatedSend.js.map +1 -0
  20. package/dist/server/AgentServer.d.ts.map +1 -1
  21. package/dist/server/AgentServer.js +49 -0
  22. package/dist/server/AgentServer.js.map +1 -1
  23. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  24. package/dist/server/CapabilityIndex.js +1 -0
  25. package/dist/server/CapabilityIndex.js.map +1 -1
  26. package/dist/server/middleware.d.ts.map +1 -1
  27. package/dist/server/middleware.js +3 -0
  28. package/dist/server/middleware.js.map +1 -1
  29. package/dist/server/routes.d.ts.map +1 -1
  30. package/dist/server/routes.js +28 -0
  31. package/dist/server/routes.js.map +1 -1
  32. package/package.json +1 -1
  33. package/src/data/builtin-manifest.json +47 -47
  34. package/upgrades/1.3.462.md +83 -0
  35. package/upgrades/1.3.463.md +27 -0
  36. package/upgrades/eli16/integrity-leg-shadow-import.md +27 -0
  37. package/upgrades/side-effects/integrity-leg-shadow-import.md +35 -0
  38. package/upgrades/side-effects/sentinel-escalation-selfheal.md +65 -0
@@ -97,6 +97,21 @@ export type ImportDryRunOutcome = {
97
97
  ok: false;
98
98
  reason: string;
99
99
  };
100
+ /**
101
+ * Outcome of the REAL pre-click integrity pass. Unlike the dry-run, a passing (or
102
+ * failing) report is recorded to the CANONICAL integrity path via recordIntegrityReport
103
+ * — so this outcome IS load-bearing on `ready`. `recorded` says whether a report landed
104
+ * (false only on a pre-import abort, where there is no report to record).
105
+ */
106
+ export type ImportIntegrityPassOutcome = {
107
+ ok: true;
108
+ result: ImportRunResult;
109
+ generatedAt: string;
110
+ recorded: boolean;
111
+ } | {
112
+ ok: false;
113
+ reason: string;
114
+ };
100
115
  export interface CutoverReadinessDeps {
101
116
  parityMonitor: DurableParityMonitor;
102
117
  /** Where the import tooling's IntegrityReport persists (JSON envelope). */
@@ -113,6 +128,13 @@ export interface CutoverReadinessDeps {
113
128
  /** SERVER-SIDE import rehearsal (live source fetch → in-memory AS-IS import →
114
129
  * integrity gate over readback). Null/absent when no source is configured. */
115
130
  runImportDryRun?: (() => Promise<ImportRunResult>) | null;
131
+ /** SERVER-SIDE REAL pre-click integrity pass (live source fetch → AS-IS import into
132
+ * a PERSISTED shadow → integrity gate over readback). Distinct from the dry-run:
133
+ * its passing report greens the canonical integrity condition via
134
+ * recordIntegrityReport. Run OFF the event loop (AgentServer spawns a child process)
135
+ * because the full-corpus fetch+import cannot settle in-process (#948). Null/absent
136
+ * when no source is configured. */
137
+ runIntegrityImport?: (() => Promise<ImportRunResult>) | null;
116
138
  /** Freshness bound for the parity window (default 6h). */
117
139
  maxPassStalenessMs?: number;
118
140
  /**
@@ -175,6 +197,18 @@ export declare class CutoverReadiness {
175
197
  * integrity report is structurally out of reach of this method.
176
198
  */
177
199
  runImportDryRunPass(): Promise<ImportDryRunOutcome>;
200
+ /**
201
+ * TRIGGER the REAL pre-click integrity pass (T7: the agent may ask; the server
202
+ * computes — live source fetch → AS-IS import into a PERSISTED shadow → integrity
203
+ * gate over the readback). UNLIKE the dry-run, the resulting report is recorded to
204
+ * the CANONICAL integrity path via recordIntegrityReport: a PASSING report greens
205
+ * `ready`, a FAILING report flips it closed (the door always reflects the LATEST
206
+ * real verdict — never a stale green). A pre-import abort (fingerprint collision →
207
+ * null report) records nothing and leaves prior state; the abort is returned for the
208
+ * operator to resolve. A FAILED fetch records nothing (absence of evidence, not a
209
+ * verdict). Shares the single-flight live-fetch guard + the max-hold backstop.
210
+ */
211
+ runIntegrityPass(): Promise<ImportIntegrityPassOutcome>;
178
212
  importDryRunStatus(): ImportDryRunStatus;
179
213
  /** The everything-up-to-the-door readiness signal. Read-only; never fires anything. */
180
214
  status(): CutoverReadinessStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"cutoverReadiness.d.ts","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,GAAG,EAAE,OAAO,CAAC;IACb,2EAA2E;IAC3E,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,uDAAuD;IACvD,OAAO,EAAE;QACP,qBAAqB,EAAE,MAAM,CAAC;QAC9B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;KACtB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;iGAC6F;IAC7F,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACxD,0FAA0F;IAC1F,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC;kFAC8E;IAC9E,KAAK,EAAE,OAAO,CAAC;IACf,mFAAmF;IACnF,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,eAAe,CAAC;IACxB;;;;;OAKG;IACH,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC9H;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,oBAAoB,CAAC;IACpC,2EAA2E;IAC3E,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;gEAE4D;IAC5D,cAAc,EAAE,CAAC,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,IAAI,CAAC;IACrD;;;kCAG8B;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;mFAC+E;IAC/E,eAAe,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,IAAI,CAAC;IAC1D,0DAA0D;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;;;8EAW0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAkBD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB,CAA4E;gBAEzF,IAAI,EAAE,oBAAoB;IAWtC,OAAO,CAAC,KAAK;IAIb;;;;;;;+DAO2D;YAC7C,WAAW;IAiBzB,2EAA2E;IAC3E,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAS1E,eAAe,IAAI,eAAe;IAuBlC,YAAY,IAAI,eAAe;IAW/B;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA0BjD;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAuBzD,kBAAkB,IAAI,kBAAkB;IAmBxC,uFAAuF;IACvF,MAAM,IAAI,sBAAsB;CAYjC"}
1
+ {"version":3,"file":"cutoverReadiness.d.ts","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"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"}
@@ -186,6 +186,43 @@ export class CutoverReadiness {
186
186
  fs.writeFileSync(this.d.importDryRunReportPath, JSON.stringify(envelope, null, 2));
187
187
  return { ok: true, result, generatedAt };
188
188
  }
189
+ /**
190
+ * TRIGGER the REAL pre-click integrity pass (T7: the agent may ask; the server
191
+ * computes — live source fetch → AS-IS import into a PERSISTED shadow → integrity
192
+ * gate over the readback). UNLIKE the dry-run, the resulting report is recorded to
193
+ * the CANONICAL integrity path via recordIntegrityReport: a PASSING report greens
194
+ * `ready`, a FAILING report flips it closed (the door always reflects the LATEST
195
+ * real verdict — never a stale green). A pre-import abort (fingerprint collision →
196
+ * null report) records nothing and leaves prior state; the abort is returned for the
197
+ * operator to resolve. A FAILED fetch records nothing (absence of evidence, not a
198
+ * verdict). Shares the single-flight live-fetch guard + the max-hold backstop.
199
+ */
200
+ async runIntegrityPass() {
201
+ if (!this.d.runIntegrityImport) {
202
+ return { ok: false, reason: 'no import source configured (feedbackMigration.paritySource) — cannot run a real integrity pass' };
203
+ }
204
+ if (this.liveFetchInFlight) {
205
+ return { ok: false, reason: `live source fetch already in flight (${this.liveFetchInFlight.op} started ${this.liveFetchInFlight.startedAt}) — one at a time; retry after it completes` };
206
+ }
207
+ this.liveFetchInFlight = { op: 'integrity-pass', startedAt: new Date(this.nowMs()).toISOString() };
208
+ let result;
209
+ try {
210
+ result = await this.withMaxHold(this.d.runIntegrityImport(), 'integrity-pass');
211
+ }
212
+ catch (err) {
213
+ return { ok: false, reason: `integrity pass failed: ${err instanceof Error ? err.message : String(err)}` };
214
+ }
215
+ finally {
216
+ this.liveFetchInFlight = null;
217
+ }
218
+ const generatedAt = new Date(this.nowMs()).toISOString();
219
+ let recorded = false;
220
+ if (result.report) {
221
+ this.recordIntegrityReport(result.report, generatedAt);
222
+ recorded = true;
223
+ }
224
+ return { ok: true, result, generatedAt, recorded };
225
+ }
189
226
  importDryRunStatus() {
190
227
  const empty = { ran: false, passed: false, generatedAt: null, imported: null, abortedPreImport: null };
191
228
  if (!this.d.importDryRunReportPath)
@@ -1 +1 @@
1
- {"version":3,"file":"cutoverReadiness.js","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cutoverReadiness.js","sourceRoot":"","sources":["../../src/feedback-factory/cutoverReadiness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * PersistedShadowImportTarget.ts — a DURABLE, on-disk AS-IS import sink for the
3
+ * pre-click cutover integrity gate (spec §2.4; feedback-factory-migration.md §2.5).
4
+ *
5
+ * Why this exists (and why it is NOT `InMemoryImportTarget`):
6
+ *
7
+ * `cutoverReadiness.ts` hard-gates the operator's IRREVERSIBLE cutover click on
8
+ * `ready = integrity.passed && parity.cleared && !parity.stale`. The integrity leg
9
+ * greens ONLY when `recordIntegrityReport(passingReport)` is called. The existing
10
+ * import-DRYRUN route is deliberately walled off from that path (its report goes to
11
+ * `importDryRunReportPath`, never `integrityReportPath`) precisely so an EPHEMERAL,
12
+ * in-memory rehearsal can never quietly green an irreversible gate.
13
+ *
14
+ * The pre-click integrity gate therefore needs a target that is a step more real than
15
+ * the in-memory dry-run: a **persisted** shadow the import physically lands in and is
16
+ * read back FROM DISK, so the recorded integrity report corresponds to a durable,
17
+ * inspectable artifact — not an in-process Map that vanishes with the process. The
18
+ * shadow is a VERIFICATION target, never canonical: the canonical production import
19
+ * (Portal's apply-clusters / the real Prisma write) happens AFTER the click. This
20
+ * mirrors `InMemoryImportTarget`'s contract exactly (same `ImportTarget` interface,
21
+ * same dup-PK refusal, same `schemaDescriptor() === null` → the runner derives the
22
+ * dry-run schema), differing ONLY in where the rows live.
23
+ *
24
+ * Backing store: two newline-delimited JSON files (`clusters.jsonl`, `feedback.jsonl`)
25
+ * under a caller-supplied directory. JSONL (not SQLite) keeps the target dependency-free
26
+ * so the out-of-process integrity-pass runner bundles cleanly (no native module). Each
27
+ * AS-IS import APPENDS one row; `readBack*` parses the file. Duplicate PKs are refused
28
+ * before the append (mirrors the DB @id constraint the real adapter would hit). The
29
+ * shadow directory is disposable — `dispose()` removes it after the gate has run.
30
+ */
31
+ import { type ImportTarget, type RawRow } from './importRunner.js';
32
+ import type { SchemaDescriptor } from './importIntegrity.js';
33
+ export declare class PersistedShadowImportTarget implements ImportTarget {
34
+ private readonly dir;
35
+ private readonly clustersPath;
36
+ private readonly feedbackPath;
37
+ private readonly clusterIds;
38
+ private readonly feedbackIds;
39
+ constructor(dir: string);
40
+ private readJsonl;
41
+ importClusterAsIs(row: RawRow): void;
42
+ importFeedbackAsIs(row: RawRow): void;
43
+ readBackClusters(): RawRow[];
44
+ readBackFeedback(): RawRow[];
45
+ /**
46
+ * No real schema descriptor — like the in-memory dry-run target, the runner derives
47
+ * the target schema from readback + the canonical accepted-status contract. (A future
48
+ * real Prisma adapter would return its actual descriptor here.)
49
+ */
50
+ schemaDescriptor(): SchemaDescriptor | null;
51
+ /** Remove the on-disk shadow. Call after the integrity gate has run + the report is recorded. */
52
+ dispose(): void;
53
+ }
54
+ //# sourceMappingURL=PersistedShadowImportTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedShadowImportTarget.d.ts","sourceRoot":"","sources":["../../../src/feedback-factory/migration/PersistedShadowImportTarget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,MAAM,EAEZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAa7D,qBAAa,2BAA4B,YAAW,YAAY;IASlD,OAAO,CAAC,QAAQ,CAAC,GAAG;IARhC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAItC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;gBAEpB,GAAG,EAAE,MAAM;IAexC,OAAO,CAAC,SAAS;IAWjB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQpC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQrC,gBAAgB,IAAI,MAAM,EAAE;IAI5B,gBAAgB,IAAI,MAAM,EAAE;IAI5B;;;;OAIG;IACH,gBAAgB,IAAI,gBAAgB,GAAG,IAAI;IAI3C,iGAAiG;IACjG,OAAO,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * PersistedShadowImportTarget.ts — a DURABLE, on-disk AS-IS import sink for the
3
+ * pre-click cutover integrity gate (spec §2.4; feedback-factory-migration.md §2.5).
4
+ *
5
+ * Why this exists (and why it is NOT `InMemoryImportTarget`):
6
+ *
7
+ * `cutoverReadiness.ts` hard-gates the operator's IRREVERSIBLE cutover click on
8
+ * `ready = integrity.passed && parity.cleared && !parity.stale`. The integrity leg
9
+ * greens ONLY when `recordIntegrityReport(passingReport)` is called. The existing
10
+ * import-DRYRUN route is deliberately walled off from that path (its report goes to
11
+ * `importDryRunReportPath`, never `integrityReportPath`) precisely so an EPHEMERAL,
12
+ * in-memory rehearsal can never quietly green an irreversible gate.
13
+ *
14
+ * The pre-click integrity gate therefore needs a target that is a step more real than
15
+ * the in-memory dry-run: a **persisted** shadow the import physically lands in and is
16
+ * read back FROM DISK, so the recorded integrity report corresponds to a durable,
17
+ * inspectable artifact — not an in-process Map that vanishes with the process. The
18
+ * shadow is a VERIFICATION target, never canonical: the canonical production import
19
+ * (Portal's apply-clusters / the real Prisma write) happens AFTER the click. This
20
+ * mirrors `InMemoryImportTarget`'s contract exactly (same `ImportTarget` interface,
21
+ * same dup-PK refusal, same `schemaDescriptor() === null` → the runner derives the
22
+ * dry-run schema), differing ONLY in where the rows live.
23
+ *
24
+ * Backing store: two newline-delimited JSON files (`clusters.jsonl`, `feedback.jsonl`)
25
+ * under a caller-supplied directory. JSONL (not SQLite) keeps the target dependency-free
26
+ * so the out-of-process integrity-pass runner bundles cleanly (no native module). Each
27
+ * AS-IS import APPENDS one row; `readBack*` parses the file. Duplicate PKs are refused
28
+ * before the append (mirrors the DB @id constraint the real adapter would hit). The
29
+ * shadow directory is disposable — `dispose()` removes it after the gate has run.
30
+ */
31
+ import { appendFileSync, mkdirSync, readFileSync, existsSync } from 'node:fs';
32
+ import { join } from 'node:path';
33
+ import { DuplicateImportIdError, } from './importRunner.js';
34
+ import { SafeFsExecutor } from '../../core/SafeFsExecutor.js';
35
+ /** Resolve a row's primary-key id from the AS-IS field aliases (mirrors importRunner's pickId). */
36
+ function pickId(row, ...keys) {
37
+ for (const k of keys) {
38
+ const v = row[k];
39
+ if (typeof v === 'string' && v.length > 0)
40
+ return v;
41
+ if (typeof v === 'number')
42
+ return String(v);
43
+ }
44
+ return '';
45
+ }
46
+ export class PersistedShadowImportTarget {
47
+ dir;
48
+ clustersPath;
49
+ feedbackPath;
50
+ // In-memory PK sets enforce the @id constraint at import time (the durable readback
51
+ // is still the file). Sets are rebuilt from disk on construction so a reused dir is
52
+ // duplicate-safe across processes.
53
+ clusterIds = new Set();
54
+ feedbackIds = new Set();
55
+ constructor(dir) {
56
+ this.dir = dir;
57
+ mkdirSync(dir, { recursive: true });
58
+ this.clustersPath = join(dir, 'clusters.jsonl');
59
+ this.feedbackPath = join(dir, 'feedback.jsonl');
60
+ // Rebuild PK sets from any rows already on disk (idempotent reuse / crash recovery).
61
+ for (const r of this.readJsonl(this.clustersPath)) {
62
+ const id = pickId(r, 'clusterId', 'cluster_id', 'id');
63
+ if (id)
64
+ this.clusterIds.add(id);
65
+ }
66
+ for (const r of this.readJsonl(this.feedbackPath)) {
67
+ const id = pickId(r, 'feedbackId', 'feedback_id', 'id');
68
+ if (id)
69
+ this.feedbackIds.add(id);
70
+ }
71
+ }
72
+ readJsonl(path) {
73
+ if (!existsSync(path))
74
+ return [];
75
+ const txt = readFileSync(path, 'utf8');
76
+ const out = [];
77
+ for (const line of txt.split('\n')) {
78
+ if (!line)
79
+ continue;
80
+ out.push(JSON.parse(line));
81
+ }
82
+ return out;
83
+ }
84
+ importClusterAsIs(row) {
85
+ const id = pickId(row, 'clusterId', 'cluster_id', 'id');
86
+ if (!id)
87
+ throw new Error('cluster row has no resolvable id (clusterId/cluster_id/id) — cannot import');
88
+ if (this.clusterIds.has(id))
89
+ throw new DuplicateImportIdError('cluster', id);
90
+ this.clusterIds.add(id);
91
+ appendFileSync(this.clustersPath, JSON.stringify(row) + '\n');
92
+ }
93
+ importFeedbackAsIs(row) {
94
+ const id = pickId(row, 'feedbackId', 'feedback_id', 'id');
95
+ if (!id)
96
+ throw new Error('feedback row has no resolvable id (feedbackId/feedback_id/id) — cannot import');
97
+ if (this.feedbackIds.has(id))
98
+ throw new DuplicateImportIdError('feedback', id);
99
+ this.feedbackIds.add(id);
100
+ appendFileSync(this.feedbackPath, JSON.stringify(row) + '\n');
101
+ }
102
+ readBackClusters() {
103
+ return this.readJsonl(this.clustersPath);
104
+ }
105
+ readBackFeedback() {
106
+ return this.readJsonl(this.feedbackPath);
107
+ }
108
+ /**
109
+ * No real schema descriptor — like the in-memory dry-run target, the runner derives
110
+ * the target schema from readback + the canonical accepted-status contract. (A future
111
+ * real Prisma adapter would return its actual descriptor here.)
112
+ */
113
+ schemaDescriptor() {
114
+ return null;
115
+ }
116
+ /** Remove the on-disk shadow. Call after the integrity gate has run + the report is recorded. */
117
+ dispose() {
118
+ SafeFsExecutor.safeRmSync(this.dir, { recursive: true, force: true, operation: 'PersistedShadowImportTarget.dispose' });
119
+ }
120
+ }
121
+ //# sourceMappingURL=PersistedShadowImportTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersistedShadowImportTarget.js","sourceRoot":"","sources":["../../../src/feedback-factory/migration/PersistedShadowImportTarget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type ImportRunResult } from './importRunner.js';
2
+ /** What the pass returns (and prints as stdout JSON in CLI mode). */
3
+ export interface IntegrityPassResult {
4
+ passed: boolean;
5
+ imported: ImportRunResult['imported'];
6
+ abortedPreImport: ImportRunResult['abortedPreImport'];
7
+ report: ImportRunResult['report'];
8
+ fetchSeconds: number;
9
+ importSeconds: number;
10
+ }
11
+ /** The minimal source contract the pass consumes — lets tests inject a fake. */
12
+ export interface RawCorpusSource {
13
+ prepare(): Promise<void>;
14
+ readRawClusters(): Record<string, unknown>[];
15
+ readRawFeedback(): Record<string, unknown>[];
16
+ }
17
+ /**
18
+ * Run the AS-IS import of `source`'s corpus into a persisted shadow under `shadowDir`,
19
+ * then the integrity gate over the readback. The shadow dir is removed afterward unless
20
+ * `keepShadow`. Pure w.r.t. canonical state — the shadow is a verification target only.
21
+ */
22
+ export declare function runIntegrityPass(source: RawCorpusSource, shadowDir: string, opts?: {
23
+ keepShadow?: boolean;
24
+ now?: () => number;
25
+ }): Promise<IntegrityPassResult>;
26
+ //# sourceMappingURL=integrityPassRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrityPassRunner.d.ts","sourceRoot":"","sources":["../../../src/feedback-factory/migration/integrityPassRunner.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpE,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACtC,gBAAgB,EAAE,eAAe,CAAC,kBAAkB,CAAC,CAAC;IACtD,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC7C,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAAO,GACtD,OAAO,CAAC,mBAAmB,CAAC,CAsB9B"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * integrityPassRunner.ts — the REAL pre-click import-integrity pass that greens the
3
+ * cutover door's INTEGRITY leg (spec §2.4; feedback-factory-migration.md §2.5).
4
+ *
5
+ * Runs the canonical pipeline — HttpParitySource captureRaw (read-only GET
6
+ * /api/instar/read) → runImport into a PERSISTED shadow target → the pure integrity
7
+ * gate over the readback — and returns the IntegrityReport verdict. The caller
8
+ * (AgentServer) feeds a PASSING report to `CutoverReadiness.recordIntegrityReport()`.
9
+ *
10
+ * Why this is a standalone module with a CLI entry (not an in-process closure like
11
+ * runParityCheck): the full 145K-row captureRaw fetch + import cannot settle inside
12
+ * the server's single-flight budget when run IN the event loop — that is exactly why
13
+ * the in-process import-dryrun budget-fails at 720s (#948), and why the parity-pass
14
+ * had to drop to clustersOnly (#1007). The heavy pass belongs OFF the event loop, so
15
+ * AgentServer spawns this module as a child `node` process. Exporting the logic as a
16
+ * function ALSO keeps it unit-testable against an injected source.
17
+ */
18
+ import { tmpdir } from 'node:os';
19
+ import { join, resolve } from 'node:path';
20
+ import { fileURLToPath } from 'node:url';
21
+ import { runImport } from './importRunner.js';
22
+ import { PersistedShadowImportTarget } from './PersistedShadowImportTarget.js';
23
+ import { HttpParitySource } from '../dryrun/HttpParitySource.js';
24
+ /**
25
+ * Run the AS-IS import of `source`'s corpus into a persisted shadow under `shadowDir`,
26
+ * then the integrity gate over the readback. The shadow dir is removed afterward unless
27
+ * `keepShadow`. Pure w.r.t. canonical state — the shadow is a verification target only.
28
+ */
29
+ export async function runIntegrityPass(source, shadowDir, opts = {}) {
30
+ const now = opts.now ?? (() => Date.now());
31
+ const t0 = now();
32
+ const target = new PersistedShadowImportTarget(shadowDir);
33
+ try {
34
+ await source.prepare();
35
+ const clusters = source.readRawClusters();
36
+ const feedback = source.readRawFeedback();
37
+ const tFetch = now();
38
+ const result = runImport({ clusters, feedback }, target);
39
+ const tDone = now();
40
+ return {
41
+ passed: result.passed,
42
+ imported: result.imported,
43
+ abortedPreImport: result.abortedPreImport,
44
+ report: result.report,
45
+ fetchSeconds: Number(((tFetch - t0) / 1000).toFixed(1)),
46
+ importSeconds: Number(((tDone - tFetch) / 1000).toFixed(1)),
47
+ };
48
+ }
49
+ finally {
50
+ if (!opts.keepShadow)
51
+ target.dispose();
52
+ }
53
+ }
54
+ /** CLI entry: env-driven, prints the verdict JSON to stdout. Used by AgentServer's child spawn. */
55
+ async function main() {
56
+ const token = process.env.TOKEN;
57
+ if (!token) {
58
+ console.error('FATAL: TOKEN env required (instar:read scope)');
59
+ process.exit(2);
60
+ }
61
+ const baseUrl = process.env.BASE_URL || 'https://dawn.bot-me.ai';
62
+ const shadowDir = process.env.SHADOW_DIR || join(tmpdir(), `cutover-integrity-shadow-${process.pid}`);
63
+ const keepShadow = process.env.KEEP_SHADOW === '1';
64
+ const source = new HttpParitySource({
65
+ baseUrl,
66
+ token,
67
+ captureRaw: true,
68
+ pageTimeoutMs: 120_000,
69
+ // Stay UNDER CutoverReadiness's 12-min single-flight max-hold backstop so the
70
+ // child self-exits before the in-process guard fires (measured pass ~2.7min).
71
+ totalTimeoutMs: 600_000,
72
+ });
73
+ console.error(`[integrity-pass] fetching corpus from ${baseUrl}/api/instar/read (captureRaw) → shadow ${shadowDir} ...`);
74
+ const out = await runIntegrityPass(source, shadowDir, { keepShadow });
75
+ console.error(`[integrity-pass] fetch ${out.fetchSeconds}s + import/integrity ${out.importSeconds}s → passed=${out.passed}`);
76
+ console.log(JSON.stringify(out));
77
+ process.exit(out.passed ? 0 : 1);
78
+ }
79
+ // Direct-run detection (ESM): run main() only when invoked as a script, not when imported.
80
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
81
+ void main();
82
+ }
83
+ //# sourceMappingURL=integrityPassRunner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrityPassRunner.js","sourceRoot":"","sources":["../../../src/feedback-factory/migration/integrityPassRunner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Robust consolidated-escalation send for SentinelNotifier.
3
+ *
4
+ * Background (incident 2026-06-09): the sentinel's `sendConsolidated` closures
5
+ * did `try { sendToTopic(lifelineTopicId) } catch { return false }`. The
6
+ * configured lifeline/system topic had been DELETED on the Telegram side, so
7
+ * every send returned `400: message thread not found` — and the bare `catch`
8
+ * black-holed it. 41 stall escalations in one day failed silently; the user got
9
+ * pure silence and could not tell a stalled session from a working one.
10
+ *
11
+ * `TelegramAdapter.ensureLifelineTopic()` already knows how to recreate a
12
+ * deleted lifeline topic and persist the new id — the send path just never
13
+ * invoked it. This helper closes that gap: send to the lifeline topic; on
14
+ * failure, self-heal via ensureLifelineTopic() and retry once; and NEVER
15
+ * swallow the error silently (it is always logged).
16
+ *
17
+ * Pure + adapter-injected so it is unit-testable without a live Telegram.
18
+ */
19
+ export interface ConsolidatedSendTelegram {
20
+ getLifelineTopicId(): number | undefined | null;
21
+ sendToTopic(topicId: number, text: string): Promise<unknown>;
22
+ /** Recreates the lifeline/system topic if deleted, persists the new id, returns it (or null). */
23
+ ensureLifelineTopic(): Promise<number | null>;
24
+ }
25
+ export declare function sendConsolidatedWithSelfHeal(tg: ConsolidatedSendTelegram, text: string, log: (line: string) => void): Promise<boolean>;
26
+ //# sourceMappingURL=sentinelConsolidatedSend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentinelConsolidatedSend.d.ts","sourceRoot":"","sources":["../../src/monitoring/sentinelConsolidatedSend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,IAAI,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAChD,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7D,iGAAiG;IACjG,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAkBD,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,wBAAwB,EAC5B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC1B,OAAO,CAAC,OAAO,CAAC,CA6ClB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Robust consolidated-escalation send for SentinelNotifier.
3
+ *
4
+ * Background (incident 2026-06-09): the sentinel's `sendConsolidated` closures
5
+ * did `try { sendToTopic(lifelineTopicId) } catch { return false }`. The
6
+ * configured lifeline/system topic had been DELETED on the Telegram side, so
7
+ * every send returned `400: message thread not found` — and the bare `catch`
8
+ * black-holed it. 41 stall escalations in one day failed silently; the user got
9
+ * pure silence and could not tell a stalled session from a working one.
10
+ *
11
+ * `TelegramAdapter.ensureLifelineTopic()` already knows how to recreate a
12
+ * deleted lifeline topic and persist the new id — the send path just never
13
+ * invoked it. This helper closes that gap: send to the lifeline topic; on
14
+ * failure, self-heal via ensureLifelineTopic() and retry once; and NEVER
15
+ * swallow the error silently (it is always logged).
16
+ *
17
+ * Pure + adapter-injected so it is unit-testable without a live Telegram.
18
+ */
19
+ function errMsg(err) {
20
+ return err instanceof Error ? err.message : String(err);
21
+ }
22
+ /**
23
+ * True when the send error means the target topic is GONE (deleted/closed) — the
24
+ * only case where the message definitely did NOT land, so recreating + retrying
25
+ * is safe. We deliberately do NOT retry other (transient/network) errors: those
26
+ * may have landed at Telegram before the response was lost, and a blind retry
27
+ * would double-post the escalation (this path bypasses the /telegram/reply
28
+ * content-dedup). A transient failure is recovered by the sentinel's next sweep.
29
+ */
30
+ function isTopicGone(msg) {
31
+ return /message thread not found|thread not found|topic[ _-]?deleted|topic[ _-]?closed|chat not found/i.test(msg);
32
+ }
33
+ export async function sendConsolidatedWithSelfHeal(tg, text, log) {
34
+ const topicId = tg.getLifelineTopicId();
35
+ // Fast path: send to the currently-configured lifeline topic.
36
+ if (topicId) {
37
+ try {
38
+ await tg.sendToTopic(topicId, text);
39
+ return true;
40
+ }
41
+ catch (err) {
42
+ // De-swallow (the original `catch { return false }` black-holed this).
43
+ const msg = errMsg(err);
44
+ if (!isTopicGone(msg)) {
45
+ // Not a deleted-topic error — could be transient and may have partially
46
+ // landed. Do NOT retry (avoid a duplicate escalation); the sentinel
47
+ // re-escalates on its next sweep if the condition persists.
48
+ log(`escalation send to lifeline topic ${topicId} failed (${msg}) — transient/non-topic-gone, not retrying`);
49
+ return false;
50
+ }
51
+ log(`escalation send to lifeline topic ${topicId} failed (${msg}: topic gone) — self-healing`);
52
+ }
53
+ }
54
+ else {
55
+ log('escalation has no lifeline topic configured — establishing one');
56
+ }
57
+ // Self-heal: (re)establish the lifeline/system topic (recreates if deleted,
58
+ // persists the new id) and retry the send once.
59
+ let healed;
60
+ try {
61
+ healed = await tg.ensureLifelineTopic();
62
+ }
63
+ catch (err) {
64
+ log(`escalation self-heal (ensureLifelineTopic) threw (${errMsg(err)}) — alert NOT delivered`);
65
+ return false;
66
+ }
67
+ if (!healed) {
68
+ log('escalation self-heal could not establish a lifeline topic — alert NOT delivered');
69
+ return false;
70
+ }
71
+ try {
72
+ await tg.sendToTopic(healed, text);
73
+ return true;
74
+ }
75
+ catch (err) {
76
+ log(`escalation retry to healed lifeline topic ${healed} failed (${errMsg(err)}) — alert NOT delivered`);
77
+ return false;
78
+ }
79
+ }
80
+ //# sourceMappingURL=sentinelConsolidatedSend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentinelConsolidatedSend.js","sourceRoot":"","sources":["../../src/monitoring/sentinelConsolidatedSend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AASH,SAAS,MAAM,CAAC,GAAY;IAC1B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,gGAAgG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,EAA4B,EAC5B,IAAY,EACZ,GAA2B;IAE3B,MAAM,OAAO,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC;IAExC,8DAA8D;IAC9D,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uEAAuE;YACvE,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,wEAAwE;gBACxE,oEAAoE;gBACpE,4DAA4D;gBAC5D,GAAG,CAAC,qCAAqC,OAAO,YAAY,GAAG,4CAA4C,CAAC,CAAC;gBAC7G,OAAO,KAAK,CAAC;YACf,CAAC;YACD,GAAG,CAAC,qCAAqC,OAAO,YAAY,GAAG,8BAA8B,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,gEAAgE,CAAC,CAAC;IACxE,CAAC;IAED,4EAA4E;IAC5E,gDAAgD;IAChD,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,mBAAmB,EAAE,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,qDAAqD,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAC/F,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,iFAAiF,CAAC,CAAC;QACvF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,6CAA6C,MAAM,YAAY,MAAM,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACzG,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}