@remnic/core 9.25.7 → 9.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-admin-ops-surface.d.ts +5 -5
- package/dist/access-admin-ops-surface.js +41 -41
- package/dist/access-audit.js +2 -2
- package/dist/access-authorization-probe.d.ts +5 -5
- package/dist/access-authorization-probe.js +42 -42
- package/dist/access-boundary.d.ts +5 -5
- package/dist/access-boundary.js +41 -41
- package/dist/access-cli.js +98 -97
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http-lcm-compaction.d.ts +130 -0
- package/dist/access-http-lcm-compaction.js +10 -0
- package/dist/access-http.d.ts +5 -5
- package/dist/access-http.js +53 -52
- package/dist/access-identity-continuity-surface.d.ts +4 -4
- package/dist/access-identity-continuity-surface.js +41 -41
- package/dist/access-lcm-surface.d.ts +5 -5
- package/dist/access-lcm-surface.js +41 -41
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +47 -47
- package/dist/access-namespace-preflight.js +41 -41
- package/dist/access-observe-write-surface.d.ts +5 -5
- package/dist/access-observe-write-surface.js +41 -41
- package/dist/access-operations-batch.js +43 -43
- package/dist/access-operations.d.ts +8 -8
- package/dist/access-operations.js +45 -45
- package/dist/access-recall-concurrency.d.ts +5 -5
- package/dist/access-recall-concurrency.js +41 -41
- package/dist/access-recall-response.d.ts +5 -5
- package/dist/access-recall-response.js +41 -41
- package/dist/access-recall-surface.d.ts +5 -5
- package/dist/access-recall-surface.js +41 -41
- package/dist/access-schema.d.ts +92 -77
- package/dist/access-schema.js +8 -8
- package/dist/{access-service-CIdWkP6J.d.ts → access-service-B4-Fu9x2.d.ts} +4 -4
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +41 -41
- package/dist/access-surface-catalog.d.ts +5 -5
- package/dist/access-wearables-meetings-surface.d.ts +2 -2
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-5OE5QOZB.js → auto-sync-UPTUVE4X.js} +3 -3
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +5 -5
- package/dist/buffer.d.ts +1 -1
- package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
- package/dist/capsule-crypto-YO5QJ6L3.js.map +1 -0
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.js +11 -11
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
- package/dist/{chunk-UMFLAACL.js → chunk-2RAC4JIG.js} +9 -9
- package/dist/{chunk-OIE242WM.js → chunk-4MJZTF42.js} +3 -3
- package/dist/chunk-4Z4XNEWZ.js +86 -0
- package/dist/chunk-4Z4XNEWZ.js.map +1 -0
- package/dist/{chunk-IR4LGIH6.js → chunk-5BRT4Z2I.js} +2 -2
- package/dist/{chunk-2PHX3I5C.js → chunk-6NNNURLK.js} +8 -8
- package/dist/{chunk-BLAKS3CP.js → chunk-77CNV7DY.js} +4 -4
- package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
- package/dist/{chunk-227UFSEQ.js → chunk-7RZJWZ46.js} +5 -5
- package/dist/{chunk-7CPOZH6Y.js → chunk-AJ7QCSIS.js} +2 -2
- package/dist/{chunk-TPYZ727G.js → chunk-BHLN7L7M.js} +6 -6
- package/dist/{chunk-WIGBTWXA.js → chunk-BNGPHGVZ.js} +2 -2
- package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
- package/dist/{chunk-PS5OG75R.js → chunk-CI26JDZA.js} +2 -2
- package/dist/{chunk-K4DP5KZA.js → chunk-CIQXI47W.js} +684 -22
- package/dist/chunk-CIQXI47W.js.map +1 -0
- package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
- package/dist/{chunk-W33DEUKR.js → chunk-EOLC6EXV.js} +2 -2
- package/dist/{chunk-UOURUMBN.js → chunk-EUSLKI4X.js} +2 -2
- package/dist/{chunk-ZPUFQGUF.js → chunk-EYJSW2RV.js} +5 -5
- package/dist/{chunk-3CHQZVAL.js → chunk-FRVTCCGD.js} +5 -5
- package/dist/{chunk-AQ2ZQYDI.js → chunk-HEXSNYJD.js} +6 -6
- package/dist/{chunk-E5A6C4A5.js → chunk-HORJVJ6K.js} +48 -48
- package/dist/{chunk-3UOSVTFR.js → chunk-JCVQV6QX.js} +11 -11
- package/dist/{chunk-37VPMR4E.js → chunk-JDOJZTFF.js} +6 -6
- package/dist/{chunk-P25IPRXP.js → chunk-KGTD2KZJ.js} +28 -8
- package/dist/chunk-KGTD2KZJ.js.map +1 -0
- package/dist/{chunk-WSEA52RI.js → chunk-MEBQFQ26.js} +2 -2
- package/dist/{chunk-G6MGAE36.js → chunk-MG6MNSP4.js} +5 -5
- package/dist/{chunk-BL4JHZSO.js → chunk-NUWMZIYZ.js} +40 -40
- package/dist/{chunk-ES36HTSC.js → chunk-PTN6UAUA.js} +4 -4
- package/dist/{chunk-KZVPTJNZ.js → chunk-RGJBM7Z3.js} +75 -75
- package/dist/{chunk-7IGWPXVC.js → chunk-RNY3BO35.js} +2 -2
- package/dist/{chunk-JA4HEXV7.js → chunk-RPA2RX5P.js} +2 -2
- package/dist/{chunk-32XTXKIA.js → chunk-RSYJV25N.js} +22 -14
- package/dist/chunk-RSYJV25N.js.map +1 -0
- package/dist/{chunk-S2BBISHU.js → chunk-RYHWZ52A.js} +4 -4
- package/dist/{chunk-ZN4UZWMT.js → chunk-SK3EYPKC.js} +2 -2
- package/dist/{chunk-BUK2FXOL.js → chunk-TKBDJTXG.js} +4 -4
- package/dist/{chunk-D7MAWMMK.js → chunk-U3TH5Q2Q.js} +2 -2
- package/dist/{chunk-SSYBI43M.js → chunk-UT3OQPFA.js} +6 -6
- package/dist/{chunk-4B77XSG5.js → chunk-UV72DEZD.js} +5 -5
- package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
- package/dist/{chunk-NRV4Y3PM.js → chunk-W4FBGYGK.js} +1 -1
- package/dist/{chunk-5J7HJ7RT.js → chunk-WEAO45M4.js} +2 -2
- package/dist/{chunk-MU7ZHSZE.js → chunk-WZFAPHIK.js} +2 -2
- package/dist/{chunk-NY6W6CJW.js → chunk-XKO7BM2C.js} +2 -2
- package/dist/{chunk-7KXQ44PA.js → chunk-XQ4EH6DI.js} +5 -5
- package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
- package/dist/{chunk-VPSAVXHM.js → chunk-YSGBD3QN.js} +7 -7
- package/dist/{cli-Da5kesWC.d.ts → cli-Bz7X7dGx.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +75 -74
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +5 -5
- package/dist/connectors/codex-materialize-runner.js +5 -5
- package/dist/connectors/index.js +5 -5
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- package/dist/corpus-watermark.js +16 -16
- package/dist/dashboard-runtime.js +2 -2
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +5 -5
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/extraction.js +3 -3
- package/dist/{first-start-migration-BKNGOFED.js → first-start-migration-LEXL3XYL.js} +4 -4
- package/dist/index.d.ts +398 -398
- package/dist/index.js +177 -176
- package/dist/lcm/engine.js +3 -3
- package/dist/lcm/index.js +9 -9
- package/dist/maintenance/memory-governance.js +6 -6
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.d.ts +1 -1
- package/dist/maintenance/rebuild-memory-projection.js +7 -7
- package/dist/{maintenance-DD22oIx9.d.ts → maintenance-DgnD2z8S.d.ts} +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +15 -15
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +5 -5
- package/dist/operator-doctor-corpus.js +17 -17
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +28 -28
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +11 -11
- package/dist/{orchestrator-CFJ_TG6D.d.ts → orchestrator-rIHmHpv1.d.ts} +3 -3
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +98 -97
- package/dist/resume-bundles.js +1 -1
- package/dist/schemas.d.ts +76 -76
- package/dist/search/factory.js +8 -8
- package/dist/search/index.js +13 -13
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/semantic-consolidation.js +7 -7
- package/dist/semantic-rule-promotion.js +5 -5
- package/dist/semantic-rule-verifier.js +6 -6
- package/dist/{service-Z8uzoAST.d.ts → service-cTvil7D_.d.ts} +1 -1
- package/dist/session-namespace-bindings.d.ts +27 -0
- package/dist/session-namespace-bindings.js +243 -0
- package/dist/session-namespace-bindings.js.map +1 -0
- package/dist/shared-context/manager.d.ts +8 -8
- package/dist/{storage-BZVMn8yJ.d.ts → storage-C9ibpTme.d.ts} +0 -3
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +4 -4
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/testing/lifecycle-matrix.d.ts +100 -0
- package/dist/testing/lifecycle-matrix.js +149 -0
- package/dist/testing/lifecycle-matrix.js.map +1 -0
- package/dist/tier-migration.d.ts +1 -1
- package/dist/transfer/backup.js +4 -4
- package/dist/transfer/capsule-export.js +4 -4
- package/dist/transfer/capsule-import.js +3 -3
- package/dist/transfer/types.d.ts +66 -66
- package/dist/verified-recall.js +6 -6
- package/package.json +22 -2
- package/src/access-http-lcm-compaction.ts +116 -0
- package/src/access-http.test.ts +218 -0
- package/src/access-http.ts +8 -8
- package/src/access-schema-pi.test.ts +9 -0
- package/src/access-schema.ts +29 -4
- package/src/access-surface-catalog.test.ts +1 -0
- package/src/session-namespace-bindings.test.ts +358 -0
- package/src/session-namespace-bindings.ts +301 -0
- package/src/storage/profile-header.ts +897 -0
- package/src/storage-profile-timestamp.test.ts +3290 -0
- package/src/storage.ts +5 -8
- package/src/testing/lifecycle-matrix.ts +17 -7
- package/src/testing/subjects/profile-header-write.test.ts +71 -0
- package/dist/chunk-32XTXKIA.js.map +0 -1
- package/dist/chunk-K4DP5KZA.js.map +0 -1
- package/dist/chunk-P25IPRXP.js.map +0 -1
- /package/dist/{capsule-crypto-7FJQINUR.js.map → access-http-lcm-compaction.js.map} +0 -0
- /package/dist/{auto-sync-5OE5QOZB.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
- /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
- /package/dist/{chunk-UMFLAACL.js.map → chunk-2RAC4JIG.js.map} +0 -0
- /package/dist/{chunk-OIE242WM.js.map → chunk-4MJZTF42.js.map} +0 -0
- /package/dist/{chunk-IR4LGIH6.js.map → chunk-5BRT4Z2I.js.map} +0 -0
- /package/dist/{chunk-2PHX3I5C.js.map → chunk-6NNNURLK.js.map} +0 -0
- /package/dist/{chunk-BLAKS3CP.js.map → chunk-77CNV7DY.js.map} +0 -0
- /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
- /package/dist/{chunk-227UFSEQ.js.map → chunk-7RZJWZ46.js.map} +0 -0
- /package/dist/{chunk-7CPOZH6Y.js.map → chunk-AJ7QCSIS.js.map} +0 -0
- /package/dist/{chunk-TPYZ727G.js.map → chunk-BHLN7L7M.js.map} +0 -0
- /package/dist/{chunk-WIGBTWXA.js.map → chunk-BNGPHGVZ.js.map} +0 -0
- /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
- /package/dist/{chunk-PS5OG75R.js.map → chunk-CI26JDZA.js.map} +0 -0
- /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
- /package/dist/{chunk-W33DEUKR.js.map → chunk-EOLC6EXV.js.map} +0 -0
- /package/dist/{chunk-UOURUMBN.js.map → chunk-EUSLKI4X.js.map} +0 -0
- /package/dist/{chunk-ZPUFQGUF.js.map → chunk-EYJSW2RV.js.map} +0 -0
- /package/dist/{chunk-3CHQZVAL.js.map → chunk-FRVTCCGD.js.map} +0 -0
- /package/dist/{chunk-AQ2ZQYDI.js.map → chunk-HEXSNYJD.js.map} +0 -0
- /package/dist/{chunk-E5A6C4A5.js.map → chunk-HORJVJ6K.js.map} +0 -0
- /package/dist/{chunk-3UOSVTFR.js.map → chunk-JCVQV6QX.js.map} +0 -0
- /package/dist/{chunk-37VPMR4E.js.map → chunk-JDOJZTFF.js.map} +0 -0
- /package/dist/{chunk-WSEA52RI.js.map → chunk-MEBQFQ26.js.map} +0 -0
- /package/dist/{chunk-G6MGAE36.js.map → chunk-MG6MNSP4.js.map} +0 -0
- /package/dist/{chunk-BL4JHZSO.js.map → chunk-NUWMZIYZ.js.map} +0 -0
- /package/dist/{chunk-ES36HTSC.js.map → chunk-PTN6UAUA.js.map} +0 -0
- /package/dist/{chunk-KZVPTJNZ.js.map → chunk-RGJBM7Z3.js.map} +0 -0
- /package/dist/{chunk-7IGWPXVC.js.map → chunk-RNY3BO35.js.map} +0 -0
- /package/dist/{chunk-JA4HEXV7.js.map → chunk-RPA2RX5P.js.map} +0 -0
- /package/dist/{chunk-S2BBISHU.js.map → chunk-RYHWZ52A.js.map} +0 -0
- /package/dist/{chunk-ZN4UZWMT.js.map → chunk-SK3EYPKC.js.map} +0 -0
- /package/dist/{chunk-BUK2FXOL.js.map → chunk-TKBDJTXG.js.map} +0 -0
- /package/dist/{chunk-D7MAWMMK.js.map → chunk-U3TH5Q2Q.js.map} +0 -0
- /package/dist/{chunk-SSYBI43M.js.map → chunk-UT3OQPFA.js.map} +0 -0
- /package/dist/{chunk-4B77XSG5.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
- /package/dist/{chunk-NRV4Y3PM.js.map → chunk-W4FBGYGK.js.map} +0 -0
- /package/dist/{chunk-5J7HJ7RT.js.map → chunk-WEAO45M4.js.map} +0 -0
- /package/dist/{chunk-MU7ZHSZE.js.map → chunk-WZFAPHIK.js.map} +0 -0
- /package/dist/{chunk-NY6W6CJW.js.map → chunk-XKO7BM2C.js.map} +0 -0
- /package/dist/{chunk-7KXQ44PA.js.map → chunk-XQ4EH6DI.js.map} +0 -0
- /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
- /package/dist/{chunk-VPSAVXHM.js.map → chunk-YSGBD3QN.js.map} +0 -0
- /package/dist/{first-start-migration-BKNGOFED.js.map → first-start-migration-LEXL3XYL.js.map} +0 -0
package/src/storage.ts
CHANGED
|
@@ -20,6 +20,7 @@ import path from "node:path";
|
|
|
20
20
|
import { log } from "./logger.js";
|
|
21
21
|
import { assertMemoryFrontmatterId, warnProjectionFallback } from "./storage-guards.js";
|
|
22
22
|
import { MemoryReadStore } from "./storage/memory-read-store.js";
|
|
23
|
+
import { renderProfileWithLastUpdated } from "./storage/profile-header.js";
|
|
23
24
|
import { readMaybeEncryptedLines, readMemoryActionEventRowsFromLines } from "./storage/secure-line-reader.js";
|
|
24
25
|
import {
|
|
25
26
|
appendLifecycleEventsSerialized,
|
|
@@ -4251,15 +4252,13 @@ export class StorageManager {
|
|
|
4251
4252
|
}
|
|
4252
4253
|
|
|
4253
4254
|
async writeProfile(content: string): Promise<void> {
|
|
4255
|
+
const stampedContent = renderProfileWithLastUpdated(content, new Date().toISOString());
|
|
4254
4256
|
await this.ensureDirectories();
|
|
4255
4257
|
await this.snapshotBeforeWrite(this.profilePath, "consolidation");
|
|
4256
|
-
await this.writeStorageSecureFile(this.profilePath,
|
|
4258
|
+
await this.writeStorageSecureFile(this.profilePath, stampedContent);
|
|
4257
4259
|
log.debug("updated profile.md");
|
|
4258
4260
|
}
|
|
4259
4261
|
|
|
4260
|
-
/**
|
|
4261
|
-
* Normalize a string for fuzzy profile dedup: lowercase, strip punctuation, collapse whitespace.
|
|
4262
|
-
*/
|
|
4263
4262
|
private static normalizeForDedup(s: string): string {
|
|
4264
4263
|
if (typeof s !== "string") return "";
|
|
4265
4264
|
return s
|
|
@@ -4308,15 +4307,13 @@ export class StorageManager {
|
|
|
4308
4307
|
const content = [
|
|
4309
4308
|
"# Behavioral Profile",
|
|
4310
4309
|
"",
|
|
4311
|
-
`*Last updated: ${new Date().toISOString()}*`,
|
|
4312
|
-
"",
|
|
4313
4310
|
...newBullets.map((b) => `- ${b}`),
|
|
4314
4311
|
"",
|
|
4315
4312
|
].join("\n");
|
|
4316
4313
|
await this.writeProfile(content);
|
|
4317
4314
|
} else {
|
|
4318
|
-
const
|
|
4319
|
-
|
|
4315
|
+
const withBullets =
|
|
4316
|
+
existing.trimEnd() + "\n" + newBullets.map((b) => `- ${b}`).join("\n") + "\n";
|
|
4320
4317
|
await this.writeProfile(withBullets);
|
|
4321
4318
|
}
|
|
4322
4319
|
}
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
* `MATRIX_ROWS` entry. Adding a row here is a one-file change that
|
|
16
16
|
* automatically extends every adopter — the whole point of the harness.
|
|
17
17
|
*
|
|
18
|
-
* Test-support only: this file lives under `src/testing/`
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* Test-support only: this file lives under `src/testing/` and is exported solely
|
|
19
|
+
* so adapter test subjects can share the canonical matrix across packages.
|
|
20
|
+
* The registrar loads `node:test` through `createRequire` so the built artifact
|
|
21
|
+
* keeps the builtin specifier, and runtime code must never import this module.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import
|
|
24
|
+
import { createRequire } from "node:module";
|
|
25
25
|
|
|
26
26
|
/** The nine canonical AGENTS.md session/retrieval/cache matrix rows. */
|
|
27
27
|
export type MatrixRowId =
|
|
@@ -215,13 +215,23 @@ export interface RunLifecycleMatrixOptions {
|
|
|
215
215
|
export function lifecycleTestName(subjectName: string, row: MatrixRow): string {
|
|
216
216
|
return `lifecycle-matrix[${subjectName}] :: ${row.id} — ${row.title}`;
|
|
217
217
|
}
|
|
218
|
+
type NodeTestRegistrar = {
|
|
219
|
+
(name: string, fn: () => void | Promise<void>): void;
|
|
220
|
+
(name: string, options: { skip: string }, fn: () => void): void;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const requiredNodeTest = createRequire(import.meta.url)("node:test") as
|
|
224
|
+
| NodeTestRegistrar
|
|
225
|
+
| { test: NodeTestRegistrar };
|
|
226
|
+
const nodeTest: NodeTestRegistrar =
|
|
227
|
+
typeof requiredNodeTest === "function" ? requiredNodeTest : requiredNodeTest.test;
|
|
218
228
|
|
|
219
229
|
const defaultRegister: MatrixTestRegistrar = (name, fn) => {
|
|
220
|
-
|
|
230
|
+
nodeTest(name, fn);
|
|
221
231
|
};
|
|
222
232
|
|
|
223
233
|
const defaultRegisterSkipped: MatrixSkipRegistrar = (name, reason) => {
|
|
224
|
-
|
|
234
|
+
nodeTest(name, { skip: reason }, () => {});
|
|
225
235
|
};
|
|
226
236
|
|
|
227
237
|
/**
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile-header write-boundary subject for the lifecycle scenario matrix.
|
|
3
|
+
* Profile content is not session state, so only the session-end mutation row
|
|
4
|
+
* applies; the remaining canonical rows are explicit skips rather than false
|
|
5
|
+
* extraction-lifecycle coverage.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
|
|
10
|
+
import { StorageManager } from "../../storage.js";
|
|
11
|
+
import { type LifecycleSubject, type MatrixRow, runLifecycleMatrix } from "../lifecycle-matrix.js";
|
|
12
|
+
import { cleanupDir, mkTempMemoryDir } from "../orchestrator-lite.js";
|
|
13
|
+
|
|
14
|
+
interface ProfileHeaderState {
|
|
15
|
+
dir: string;
|
|
16
|
+
storage: StorageManager;
|
|
17
|
+
writeStartedAt?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const STALE_PROFILE = [
|
|
21
|
+
"# Behavioral Profile",
|
|
22
|
+
"",
|
|
23
|
+
"*Last updated: 2024-01-02T03:04:05.000Z*",
|
|
24
|
+
"",
|
|
25
|
+
"- Profile content survives the write boundary.",
|
|
26
|
+
"",
|
|
27
|
+
].join("\n");
|
|
28
|
+
|
|
29
|
+
const subject: LifecycleSubject<ProfileHeaderState> = {
|
|
30
|
+
appliesTo(row: MatrixRow): boolean | string {
|
|
31
|
+
return row.id === "session-end"
|
|
32
|
+
? true
|
|
33
|
+
: "profile writes have no provider, restart, or replay variants; direct profile tests cover those boundaries";
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async setup(row: MatrixRow): Promise<ProfileHeaderState> {
|
|
37
|
+
const dir = await mkTempMemoryDir(`profile-header-${row.id}`);
|
|
38
|
+
try {
|
|
39
|
+
return { dir, storage: new StorageManager(dir) };
|
|
40
|
+
} catch (error) {
|
|
41
|
+
await cleanupDir(dir);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
async exercise(state: ProfileHeaderState): Promise<void> {
|
|
47
|
+
state.writeStartedAt = Date.now();
|
|
48
|
+
await state.storage.writeProfile(STALE_PROFILE);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async invariants(state: ProfileHeaderState): Promise<void> {
|
|
52
|
+
const profile = await state.storage.readProfile();
|
|
53
|
+
const headers = profile.match(/^\*Last updated: .*\*$/gm) ?? [];
|
|
54
|
+
assert.equal(headers.length, 1, "profile writes leave one canonical Last updated header");
|
|
55
|
+
assert.notEqual(headers[0], "*Last updated: 2024-01-02T03:04:05.000Z*");
|
|
56
|
+
assert.match(profile, /^# Behavioral Profile$/m);
|
|
57
|
+
|
|
58
|
+
const timestamp = headers[0]?.match(/^\*Last updated: ([^*]+)\*$/)?.[1];
|
|
59
|
+
assert.ok(timestamp, "the canonical header contains an ISO timestamp");
|
|
60
|
+
const updatedAt = Date.parse(timestamp);
|
|
61
|
+
assert.ok(Number.isFinite(updatedAt), "the profile header timestamp is parseable");
|
|
62
|
+
assert.ok(updatedAt >= (state.writeStartedAt ?? 0), "the header advances at the write boundary");
|
|
63
|
+
assert.ok(updatedAt <= Date.now(), "the header is not in the future");
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
async teardown(state: ProfileHeaderState): Promise<void> {
|
|
67
|
+
await cleanupDir(state.dir);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
runLifecycleMatrix("profile-header-write", subject);
|