@remnic/core 10.0.39 → 10.0.41
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/access-admin-ops-surface.js +14 -14
- package/dist/access-authorization-probe.js +15 -15
- package/dist/access-boundary.js +14 -14
- package/dist/access-cli.js +53 -53
- package/dist/access-extraction-force-flush.js +14 -14
- package/dist/access-http-briefing.js +15 -15
- package/dist/access-http-query.js +16 -16
- package/dist/access-http.js +30 -30
- package/dist/access-identity-continuity-surface.js +14 -14
- package/dist/access-lcm-surface.js +14 -14
- package/dist/access-mcp.js +23 -23
- package/dist/access-namespace-preflight.js +14 -14
- package/dist/access-observe-write-surface.js +14 -14
- package/dist/access-operations-batch.js +15 -15
- package/dist/access-operations.js +22 -22
- package/dist/access-recall-concurrency.js +14 -14
- package/dist/access-recall-response.js +14 -14
- package/dist/access-recall-surface.js +14 -14
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.d.ts.map +1 -1
- package/dist/access-service.js +14 -14
- package/dist/access-surface-catalog.js +16 -16
- package/dist/active-recall.js +2 -2
- package/dist/briefing.js +3 -3
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-M7KGIW5F.js → chunk-4KS4IHKH.js} +2 -2
- package/dist/{chunk-JORSMFL6.js → chunk-574N53FL.js} +5 -5
- package/dist/{chunk-BUKZ7MTN.js → chunk-5TRU6QQC.js} +2 -2
- package/dist/{chunk-SRPGA6WN.js → chunk-7BCYAJKP.js} +2 -2
- package/dist/{chunk-MD3W2H3G.js → chunk-7G4O5EQT.js} +31 -31
- package/dist/{chunk-MD3W2H3G.js.map → chunk-7G4O5EQT.js.map} +1 -1
- package/dist/{chunk-F2IU6A2L.js → chunk-7XGWW3LQ.js} +16 -16
- package/dist/{chunk-ZXFKG7VZ.js → chunk-AOBDA3VC.js} +2 -2
- package/dist/{chunk-JRTKYFFY.js → chunk-AY6LO7GD.js} +2 -2
- package/dist/{chunk-5KZNWERU.js → chunk-BIYVUPC6.js} +19 -3
- package/dist/{chunk-5KZNWERU.js.map → chunk-BIYVUPC6.js.map} +1 -1
- package/dist/{chunk-V2XMG7GM.js → chunk-CHNZPOWX.js} +3 -2
- package/dist/{chunk-V2XMG7GM.js.map → chunk-CHNZPOWX.js.map} +1 -1
- package/dist/{chunk-GPVGAHXL.js → chunk-CNAL35D5.js} +2 -2
- package/dist/{chunk-NJ2DZYEK.js → chunk-DBM2NQBG.js} +2 -2
- package/dist/{chunk-U66CTIF5.js → chunk-F2RDRE7M.js} +2 -2
- package/dist/{chunk-VIS23B6O.js → chunk-F7MP76CB.js} +15 -13
- package/dist/chunk-F7MP76CB.js.map +1 -0
- package/dist/{chunk-B7VKRCAG.js → chunk-FNEYSTB6.js} +2 -2
- package/dist/{chunk-GSBSGT43.js → chunk-FPHU6KVI.js} +2 -2
- package/dist/{chunk-RO2NNWR5.js → chunk-GAUS4XGN.js} +3 -3
- package/dist/{chunk-4UT2NUAC.js → chunk-GCDIHTWF.js} +2 -2
- package/dist/{chunk-4HJ2QK32.js → chunk-GDOI4U4D.js} +2 -2
- package/dist/{chunk-VCOCOBUS.js → chunk-GZMHBRIR.js} +3 -3
- package/dist/{chunk-LJXBFVI2.js → chunk-ICTJOOWZ.js} +2 -2
- package/dist/{chunk-6Z2ZWBOV.js → chunk-IWDFHVPJ.js} +2 -2
- package/dist/{chunk-TTQYX7VU.js → chunk-J3FPMHQG.js} +2 -2
- package/dist/{chunk-GCW7UT5I.js → chunk-JJSMSS45.js} +2 -2
- package/dist/{chunk-O2O4FDAH.js → chunk-JXQTECMU.js} +2 -2
- package/dist/{chunk-ANV373S5.js → chunk-KYYN2FK4.js} +2 -2
- package/dist/{chunk-PJRKLB4Z.js → chunk-L5PM7B3I.js} +16 -2
- package/dist/{chunk-PJRKLB4Z.js.map → chunk-L5PM7B3I.js.map} +1 -1
- package/dist/{chunk-5TJEOU6Y.js → chunk-LKRXGOQW.js} +18 -8
- package/dist/{chunk-5TJEOU6Y.js.map → chunk-LKRXGOQW.js.map} +1 -1
- package/dist/{chunk-B3I2QQU7.js → chunk-LWIU5BMA.js} +3 -3
- package/dist/{chunk-WQYS47G4.js → chunk-N3PUGD7E.js} +2 -2
- package/dist/{chunk-EKR6OO4P.js → chunk-NTD3VWJ2.js} +2 -2
- package/dist/{chunk-JQCP5QW3.js → chunk-O67H7OXJ.js} +2 -2
- package/dist/{chunk-4LLV2N3R.js → chunk-ONIVKGNC.js} +2 -2
- package/dist/{chunk-GLB6VV3J.js → chunk-OUYYEPXD.js} +3 -3
- package/dist/{chunk-RWW5KPIY.js → chunk-PCZZMMBL.js} +12 -12
- package/dist/chunk-PCZZMMBL.js.map +1 -0
- package/dist/{chunk-WT2VVYBM.js → chunk-PJXSBXEC.js} +2 -2
- package/dist/{chunk-P3YUEPSQ.js → chunk-PUMP554C.js} +2 -2
- package/dist/{chunk-SJHFU52W.js → chunk-Q47WGGKI.js} +5 -5
- package/dist/chunk-Q47WGGKI.js.map +1 -0
- package/dist/{chunk-RIAKNXZB.js → chunk-Q77SLBWT.js} +3 -3
- package/dist/{chunk-22YJQTPN.js → chunk-QGNZ5QPV.js} +2 -2
- package/dist/{chunk-GE5ZNDLE.js → chunk-R42VUN5V.js} +3 -3
- package/dist/{chunk-7IANFJ24.js → chunk-RWMLDC2F.js} +17 -17
- package/dist/chunk-RWMLDC2F.js.map +1 -0
- package/dist/{chunk-LPD6I2U6.js → chunk-SLVR3U4E.js} +2 -2
- package/dist/{chunk-IAOW2L6K.js → chunk-TNTYAH7T.js} +2 -2
- package/dist/{chunk-CR72WZ3M.js → chunk-UBGFPD62.js} +4 -4
- package/dist/{chunk-CR72WZ3M.js.map → chunk-UBGFPD62.js.map} +1 -1
- package/dist/{chunk-JZFJZLJY.js → chunk-UGV256H3.js} +2 -2
- package/dist/{chunk-L74NWAD4.js → chunk-UKIIAEJF.js} +2 -2
- package/dist/{chunk-5Q6CR65T.js → chunk-VTZSIG6O.js} +2 -2
- package/dist/{chunk-IZRNMXZC.js → chunk-WCUYCTTG.js} +2 -2
- package/dist/{chunk-JT3IXJIL.js → chunk-XBHUMPIQ.js} +7 -7
- package/dist/{chunk-JM6U3SAE.js → chunk-XJ77IOAD.js} +2 -2
- package/dist/{chunk-ODJ2HRFW.js → chunk-XXBCUIYQ.js} +7 -7
- package/dist/{chunk-JOOGPZJE.js → chunk-XXW3P3RX.js} +2 -2
- package/dist/cli.js +40 -40
- package/dist/coding/export-okf-codegraph.js +2 -2
- package/dist/compounding/engine.js +4 -4
- package/dist/config.js +2 -2
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +4 -4
- package/dist/convergence-refresh.js +5 -5
- package/dist/corpus-watermark.js +5 -5
- package/dist/entity-retrieval.js +3 -3
- package/dist/external-wiki-access.js +15 -15
- package/dist/extraction-error-classification.d.ts +15 -0
- package/dist/extraction-error-classification.d.ts.map +1 -1
- package/dist/extraction-error-classification.js +7 -3
- package/dist/extraction.js +8 -8
- package/dist/harmonic-retrieval.js +3 -3
- package/dist/index.js +53 -53
- package/dist/location/index.js +5 -5
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/memory-browse-operations.js +15 -15
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/search.d.ts +1 -0
- package/dist/namespaces/search.d.ts.map +1 -1
- package/dist/namespaces/search.js +5 -3
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-doctor-corpus.js +6 -6
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/maintenance.js +13 -13
- package/dist/orchestration/qmd-result-resolver.d.ts +5 -0
- package/dist/orchestration/qmd-result-resolver.d.ts.map +1 -1
- package/dist/orchestration/recall-search-pipeline.d.ts.map +1 -1
- package/dist/orchestrator.js +53 -53
- package/dist/recall-navigation-operations.js +15 -15
- package/dist/recall-navigation.js +14 -14
- package/dist/resume-bundles.js +2 -2
- package/dist/runtime/daemon-health.d.ts.map +1 -1
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/source-agent-qualifier.js +6 -6
- package/dist/standup/build.js +3 -3
- package/dist/storage.js +2 -2
- package/dist/support-passport/index.js +17 -17
- package/dist/transfer/export-okf.js +3 -3
- package/dist/verified-recall.js +3 -3
- package/dist/who-knows-cli.js +4 -4
- package/dist/who-knows.js +3 -3
- package/package.json +3 -3
- package/src/access-entity-principal.test.ts +190 -0
- package/src/access-http.ts +2 -2
- package/src/access-operations-batch.ts +2 -2
- package/src/access-service.ts +7 -6
- package/src/chat/chat-executor.ts +1 -1
- package/src/extraction-error-classification.ts +23 -0
- package/src/extraction-local-failure-class.test.ts +55 -0
- package/src/extraction.ts +9 -9
- package/src/namespaces/search.ts +1 -1
- package/src/orchestration/extraction-run.test.ts +83 -2
- package/src/orchestration/qmd-result-resolver.ts +26 -1
- package/src/orchestration/recall-search-pipeline.ts +11 -12
- package/src/runtime/daemon-health.test.ts +85 -0
- package/src/runtime/daemon-health.ts +20 -7
- package/dist/chunk-7IANFJ24.js.map +0 -1
- package/dist/chunk-RWW5KPIY.js.map +0 -1
- package/dist/chunk-SJHFU52W.js.map +0 -1
- package/dist/chunk-VIS23B6O.js.map +0 -1
- /package/dist/{chunk-M7KGIW5F.js.map → chunk-4KS4IHKH.js.map} +0 -0
- /package/dist/{chunk-JORSMFL6.js.map → chunk-574N53FL.js.map} +0 -0
- /package/dist/{chunk-BUKZ7MTN.js.map → chunk-5TRU6QQC.js.map} +0 -0
- /package/dist/{chunk-SRPGA6WN.js.map → chunk-7BCYAJKP.js.map} +0 -0
- /package/dist/{chunk-F2IU6A2L.js.map → chunk-7XGWW3LQ.js.map} +0 -0
- /package/dist/{chunk-ZXFKG7VZ.js.map → chunk-AOBDA3VC.js.map} +0 -0
- /package/dist/{chunk-JRTKYFFY.js.map → chunk-AY6LO7GD.js.map} +0 -0
- /package/dist/{chunk-GPVGAHXL.js.map → chunk-CNAL35D5.js.map} +0 -0
- /package/dist/{chunk-NJ2DZYEK.js.map → chunk-DBM2NQBG.js.map} +0 -0
- /package/dist/{chunk-U66CTIF5.js.map → chunk-F2RDRE7M.js.map} +0 -0
- /package/dist/{chunk-B7VKRCAG.js.map → chunk-FNEYSTB6.js.map} +0 -0
- /package/dist/{chunk-GSBSGT43.js.map → chunk-FPHU6KVI.js.map} +0 -0
- /package/dist/{chunk-RO2NNWR5.js.map → chunk-GAUS4XGN.js.map} +0 -0
- /package/dist/{chunk-4UT2NUAC.js.map → chunk-GCDIHTWF.js.map} +0 -0
- /package/dist/{chunk-4HJ2QK32.js.map → chunk-GDOI4U4D.js.map} +0 -0
- /package/dist/{chunk-VCOCOBUS.js.map → chunk-GZMHBRIR.js.map} +0 -0
- /package/dist/{chunk-LJXBFVI2.js.map → chunk-ICTJOOWZ.js.map} +0 -0
- /package/dist/{chunk-6Z2ZWBOV.js.map → chunk-IWDFHVPJ.js.map} +0 -0
- /package/dist/{chunk-TTQYX7VU.js.map → chunk-J3FPMHQG.js.map} +0 -0
- /package/dist/{chunk-GCW7UT5I.js.map → chunk-JJSMSS45.js.map} +0 -0
- /package/dist/{chunk-O2O4FDAH.js.map → chunk-JXQTECMU.js.map} +0 -0
- /package/dist/{chunk-ANV373S5.js.map → chunk-KYYN2FK4.js.map} +0 -0
- /package/dist/{chunk-B3I2QQU7.js.map → chunk-LWIU5BMA.js.map} +0 -0
- /package/dist/{chunk-WQYS47G4.js.map → chunk-N3PUGD7E.js.map} +0 -0
- /package/dist/{chunk-EKR6OO4P.js.map → chunk-NTD3VWJ2.js.map} +0 -0
- /package/dist/{chunk-JQCP5QW3.js.map → chunk-O67H7OXJ.js.map} +0 -0
- /package/dist/{chunk-4LLV2N3R.js.map → chunk-ONIVKGNC.js.map} +0 -0
- /package/dist/{chunk-GLB6VV3J.js.map → chunk-OUYYEPXD.js.map} +0 -0
- /package/dist/{chunk-WT2VVYBM.js.map → chunk-PJXSBXEC.js.map} +0 -0
- /package/dist/{chunk-P3YUEPSQ.js.map → chunk-PUMP554C.js.map} +0 -0
- /package/dist/{chunk-RIAKNXZB.js.map → chunk-Q77SLBWT.js.map} +0 -0
- /package/dist/{chunk-22YJQTPN.js.map → chunk-QGNZ5QPV.js.map} +0 -0
- /package/dist/{chunk-GE5ZNDLE.js.map → chunk-R42VUN5V.js.map} +0 -0
- /package/dist/{chunk-LPD6I2U6.js.map → chunk-SLVR3U4E.js.map} +0 -0
- /package/dist/{chunk-IAOW2L6K.js.map → chunk-TNTYAH7T.js.map} +0 -0
- /package/dist/{chunk-JZFJZLJY.js.map → chunk-UGV256H3.js.map} +0 -0
- /package/dist/{chunk-L74NWAD4.js.map → chunk-UKIIAEJF.js.map} +0 -0
- /package/dist/{chunk-5Q6CR65T.js.map → chunk-VTZSIG6O.js.map} +0 -0
- /package/dist/{chunk-IZRNMXZC.js.map → chunk-WCUYCTTG.js.map} +0 -0
- /package/dist/{chunk-JT3IXJIL.js.map → chunk-XBHUMPIQ.js.map} +0 -0
- /package/dist/{chunk-JM6U3SAE.js.map → chunk-XJ77IOAD.js.map} +0 -0
- /package/dist/{chunk-ODJ2HRFW.js.map → chunk-XXBCUIYQ.js.map} +0 -0
- /package/dist/{chunk-JOOGPZJE.js.map → chunk-XXW3P3RX.js.map} +0 -0
|
@@ -27,7 +27,7 @@ import { inferIntentFromText, intentCompatibilityScore } from "../intent.js";
|
|
|
27
27
|
import { log } from "../logger.js";
|
|
28
28
|
import { NamespaceStorageRouter } from "../namespaces/storage.js";
|
|
29
29
|
import { NegativeExampleStore } from "../negative.js";
|
|
30
|
-
import { qmdCollectionPathParts } from "./qmd-result-resolver.js";
|
|
30
|
+
import { normalizeFlatQmdResults, qmdCollectionPathParts } from "./qmd-result-resolver.js";
|
|
31
31
|
import type { RecallRerankCoordinator, RecallResultPartitionSink } from "./recall-rerank-coordinator.js";
|
|
32
32
|
import type { GraphRecallExpansionOptions, GraphRecallExpansionResult } from "./graph-recall-coordinator.js";
|
|
33
33
|
import { RelevanceStore } from "../relevance.js";
|
|
@@ -394,7 +394,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
394
394
|
break;
|
|
395
395
|
}
|
|
396
396
|
|
|
397
|
-
|
|
397
|
+
let primaryResults = options.collection
|
|
398
398
|
? options.abortSignal
|
|
399
399
|
? await this.deps.qmd.search(
|
|
400
400
|
prompt,
|
|
@@ -426,6 +426,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
426
426
|
onDegradation: options.onDegradation,
|
|
427
427
|
},
|
|
428
428
|
});
|
|
429
|
+
primaryResults = normalizeFlatQmdResults(primaryResults, this.deps.config, options.collection);
|
|
429
430
|
lastPrimaryResultCount = primaryResults.length;
|
|
430
431
|
lastHybridResultCount = 0;
|
|
431
432
|
lastHybridTopUpUsed = false;
|
|
@@ -452,7 +453,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
452
453
|
// uniform across primary + top-up (gotcha #39). Issue #1335 (codex review #1422).
|
|
453
454
|
lastHybridTopUpSkippedReason = "lex_strategy";
|
|
454
455
|
} else {
|
|
455
|
-
|
|
456
|
+
let hybridResults = options.collection
|
|
456
457
|
? await this.deps.qmd.hybridSearch(
|
|
457
458
|
prompt,
|
|
458
459
|
options.collection,
|
|
@@ -474,6 +475,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
474
475
|
onDegradation: options.onDegradation,
|
|
475
476
|
},
|
|
476
477
|
});
|
|
478
|
+
hybridResults = normalizeFlatQmdResults(hybridResults, this.deps.config, options.collection);
|
|
477
479
|
lastHybridResultCount = hybridResults.length;
|
|
478
480
|
lastHybridTopUpUsed = hybridResults.length > 0;
|
|
479
481
|
if (hybridResults.length > 0) {
|
|
@@ -740,9 +742,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
740
742
|
// limps home later cannot mutate a recorded recall's collector.
|
|
741
743
|
coldQmdObserverActive = false;
|
|
742
744
|
if (longTerm.length > 0) {
|
|
743
|
-
log.debug(
|
|
744
|
-
`cold-tier recall source=cold-qmd collection=${coldCollection} hits=${longTerm.length}`,
|
|
745
|
-
);
|
|
745
|
+
log.debug(`cold-tier recall source=cold-qmd collection=${coldCollection} hits=${longTerm.length}`);
|
|
746
746
|
}
|
|
747
747
|
}
|
|
748
748
|
}
|
|
@@ -940,9 +940,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
940
940
|
}
|
|
941
941
|
}
|
|
942
942
|
if (caps.rerank && this.deps.config.rerankProvider === "cloud") {
|
|
943
|
-
log.debug(
|
|
944
|
-
"rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank",
|
|
945
|
-
);
|
|
943
|
+
log.debug("rerankProvider=cloud is reserved/experimental in v2.2.0; skipping rerank");
|
|
946
944
|
}
|
|
947
945
|
|
|
948
946
|
if (caps.recallTrustScore && results.length > 0) {
|
|
@@ -1149,6 +1147,9 @@ export class RecallSearchPipelineCoordinator {
|
|
|
1149
1147
|
: null;
|
|
1150
1148
|
const buildRecallRow = (r: QmdSearchResult, memory: MemoryFile | undefined): QmdSearchResult => ({
|
|
1151
1149
|
...r,
|
|
1150
|
+
// Render loaded flat memories, not QMD's front-matter/chunk preview (#3194).
|
|
1151
|
+
snippet: memory && !resolveNamespaceCapabilities(this.deps.config).namespaces ? memory.content : r.snippet,
|
|
1152
|
+
line: memory && !resolveNamespaceCapabilities(this.deps.config).namespaces ? undefined : r.line,
|
|
1152
1153
|
sourceConnector: memory ? memory.frontmatter.sourceConnector : undefined,
|
|
1153
1154
|
origin: memory ? memory.frontmatter.origin : undefined,
|
|
1154
1155
|
// #1952: an active state view carries the chain fields the inject
|
|
@@ -1358,9 +1359,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
1358
1359
|
}
|
|
1359
1360
|
}
|
|
1360
1361
|
if (connectorPartitionFilteredCount > 0) {
|
|
1361
|
-
log.debug(
|
|
1362
|
-
`connector partition filter removed ${connectorPartitionFilteredCount} tool-scoped candidates from recall`,
|
|
1363
|
-
);
|
|
1362
|
+
log.debug(`connector partition filter removed ${connectorPartitionFilteredCount} tool-scoped candidates from recall`);
|
|
1364
1363
|
}
|
|
1365
1364
|
if (supportPassportFilteredCount > 0) {
|
|
1366
1365
|
log.debug(
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { once } from "node:events";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
import { Worker } from "node:worker_threads";
|
|
5
|
+
import { checkDaemonHealth } from "./daemon-health.js";
|
|
6
|
+
|
|
7
|
+
test("checkDaemonHealth probes /live without waiting on diagnostic /health", { timeout: 30_000 }, async (t) => {
|
|
8
|
+
// The synchronous probe blocks this thread, so HTTP must run on a worker.
|
|
9
|
+
const worker = new Worker(`
|
|
10
|
+
const { parentPort } = require("node:worker_threads");
|
|
11
|
+
const { createServer } = require("node:http");
|
|
12
|
+
const paths = [];
|
|
13
|
+
const server = createServer((request, response) => {
|
|
14
|
+
paths.push(request.url);
|
|
15
|
+
if (request.url === "/engram/v1/health") return;
|
|
16
|
+
response.writeHead(request.headers.authorization === "Bearer test-token" ? 200 : 401).end();
|
|
17
|
+
});
|
|
18
|
+
server.listen(0, "127.0.0.1", () => parentPort.postMessage(server.address().port));
|
|
19
|
+
parentPort.on("message", () => parentPort.postMessage(paths));
|
|
20
|
+
`, { eval: true });
|
|
21
|
+
t.after(() => worker.terminate());
|
|
22
|
+
let port = 0;
|
|
23
|
+
[port] = await once(worker, "message");
|
|
24
|
+
assert.ok(Number.isInteger(port) && port > 0 && port <= 65535);
|
|
25
|
+
assert.equal(checkDaemonHealth("127.0.0.1", port, "test-token"), true);
|
|
26
|
+
assert.equal(checkDaemonHealth("127.0.0.1", port, "wrong-token"), false);
|
|
27
|
+
const paths = once(worker, "message");
|
|
28
|
+
worker.postMessage("paths");
|
|
29
|
+
assert.deepEqual((await paths)[0], [
|
|
30
|
+
"/engram/v1/live",
|
|
31
|
+
"/engram/v1/live",
|
|
32
|
+
"/engram/v1/live",
|
|
33
|
+
]);
|
|
34
|
+
await worker.terminate();
|
|
35
|
+
assert.equal(checkDaemonHealth("127.0.0.1", port, "test-token"), false);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("checkDaemonHealth retries legacy /health only on 404 (#3257)", { timeout: 30_000 }, async (t) => {
|
|
39
|
+
const worker = new Worker(`
|
|
40
|
+
const { parentPort } = require("node:worker_threads");
|
|
41
|
+
const { createServer } = require("node:http");
|
|
42
|
+
const paths = [];
|
|
43
|
+
const server = createServer((request, response) => {
|
|
44
|
+
paths.push(request.url);
|
|
45
|
+
if (request.url === "/engram/v1/live") return response.writeHead(404).end();
|
|
46
|
+
response.writeHead(200).end();
|
|
47
|
+
});
|
|
48
|
+
server.listen(0, "127.0.0.1", () => parentPort.postMessage(server.address().port));
|
|
49
|
+
parentPort.on("message", () => parentPort.postMessage(paths));
|
|
50
|
+
`, { eval: true });
|
|
51
|
+
t.after(() => worker.terminate());
|
|
52
|
+
let port = 0;
|
|
53
|
+
[port] = await once(worker, "message");
|
|
54
|
+
assert.equal(checkDaemonHealth("127.0.0.1", port, "test-token"), true);
|
|
55
|
+
const paths = once(worker, "message");
|
|
56
|
+
worker.postMessage("paths");
|
|
57
|
+
assert.deepEqual((await paths)[0], [
|
|
58
|
+
"/engram/v1/live",
|
|
59
|
+
"/engram/v1/health",
|
|
60
|
+
]);
|
|
61
|
+
await worker.terminate();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("checkDaemonHealth treats 503 as final with no legacy retry (#3257)", { timeout: 30_000 }, async (t) => {
|
|
65
|
+
const worker = new Worker(`
|
|
66
|
+
const { parentPort } = require("node:worker_threads");
|
|
67
|
+
const { createServer } = require("node:http");
|
|
68
|
+
const paths = [];
|
|
69
|
+
const server = createServer((request, response) => {
|
|
70
|
+
paths.push(request.url);
|
|
71
|
+
if (request.url === "/engram/v1/live") return response.writeHead(503).end();
|
|
72
|
+
response.writeHead(200).end();
|
|
73
|
+
});
|
|
74
|
+
server.listen(0, "127.0.0.1", () => parentPort.postMessage(server.address().port));
|
|
75
|
+
parentPort.on("message", () => parentPort.postMessage(paths));
|
|
76
|
+
`, { eval: true });
|
|
77
|
+
t.after(() => worker.terminate());
|
|
78
|
+
let port = 0;
|
|
79
|
+
[port] = await once(worker, "message");
|
|
80
|
+
assert.equal(checkDaemonHealth("127.0.0.1", port, "test-token"), false);
|
|
81
|
+
const paths = once(worker, "message");
|
|
82
|
+
worker.postMessage("paths");
|
|
83
|
+
assert.deepEqual((await paths)[0], ["/engram/v1/live"]);
|
|
84
|
+
await worker.terminate();
|
|
85
|
+
});
|
|
@@ -16,6 +16,9 @@ export function checkDaemonHealth(
|
|
|
16
16
|
if (!Number.isFinite(safePort) || safePort < 1 || safePort > 65535) return false;
|
|
17
17
|
|
|
18
18
|
const bareHost = host.startsWith("[") && host.endsWith("]") ? host.slice(1, -1) : host;
|
|
19
|
+
// One 3 s aggregate budget: /engram/v1/live, and only a 404 (daemon older
|
|
20
|
+
// than the live route) retries the legacy diagnostic path with the
|
|
21
|
+
// remaining time. 401/503/other statuses are final answers, never re-probed.
|
|
19
22
|
const script = [
|
|
20
23
|
"const env = process['env'];",
|
|
21
24
|
"const protocol = env.REMNIC_HEALTH_PROTOCOL;",
|
|
@@ -23,13 +26,23 @@ export function checkDaemonHealth(
|
|
|
23
26
|
"const transport = require(protocol);",
|
|
24
27
|
"const headers = {};",
|
|
25
28
|
"if (env.REMNIC_HEALTH_TOKEN) headers['authorization'] = 'Bearer ' + env.REMNIC_HEALTH_TOKEN;",
|
|
26
|
-
"const
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
29
|
+
"const exitFor = (status) => process.exit(status === 200 ? 0 : status === 401 ? 2 : 1);",
|
|
30
|
+
"const attempt = (path, timeoutMs, onStatus) => {",
|
|
31
|
+
" const req = transport.get({",
|
|
32
|
+
" host: env.REMNIC_HEALTH_HOST,",
|
|
33
|
+
" port: parseInt(env.REMNIC_HEALTH_PORT, 10),",
|
|
34
|
+
" path, headers, timeout: timeoutMs,",
|
|
35
|
+
" }, (res) => { res.resume(); onStatus(res.statusCode); });",
|
|
36
|
+
" req.on('error', () => process.exit(1));",
|
|
37
|
+
" req.on('timeout', () => { req.destroy(); process.exit(1); });",
|
|
38
|
+
"};",
|
|
39
|
+
"const deadline = Date.now() + 3000;",
|
|
40
|
+
"attempt('/engram/v1/live', 3000, (status) => {",
|
|
41
|
+
" if (status !== 404) exitFor(status);",
|
|
42
|
+
" const remaining = deadline - Date.now();",
|
|
43
|
+
" if (remaining <= 0) process.exit(1);",
|
|
44
|
+
" attempt('/engram/v1/health', remaining, exitFor);",
|
|
45
|
+
"});",
|
|
33
46
|
].join("\n");
|
|
34
47
|
const env: NodeJS.ProcessEnv = mergeEnv({
|
|
35
48
|
REMNIC_HEALTH_HOST: bareHost,
|