@remnic/core 9.69.61 → 9.69.63

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 (94) hide show
  1. package/dist/access-admin-ops-surface.js +4 -4
  2. package/dist/access-authorization-probe.js +5 -5
  3. package/dist/access-boundary.js +4 -4
  4. package/dist/access-cli.js +20 -20
  5. package/dist/access-extraction-force-flush.js +4 -4
  6. package/dist/access-http-briefing.js +5 -5
  7. package/dist/access-http-query.js +4 -4
  8. package/dist/access-http.js +16 -16
  9. package/dist/access-identity-continuity-surface.js +4 -4
  10. package/dist/access-lcm-surface.js +4 -4
  11. package/dist/access-mcp.js +11 -11
  12. package/dist/access-namespace-preflight.js +4 -4
  13. package/dist/access-observe-write-surface.js +4 -4
  14. package/dist/access-operations-batch.js +5 -5
  15. package/dist/access-operations.js +10 -10
  16. package/dist/access-recall-concurrency.js +4 -4
  17. package/dist/access-recall-response.js +4 -4
  18. package/dist/access-recall-surface.js +4 -4
  19. package/dist/access-service.js +4 -4
  20. package/dist/access-surface-catalog.js +6 -6
  21. package/dist/{chunk-2C5Z7CWB.js → chunk-24TJ77TT.js} +2 -2
  22. package/dist/{chunk-LY3SDHMI.js → chunk-3MSMBVA3.js} +2 -2
  23. package/dist/{chunk-2L5DIVDU.js → chunk-4EEDRKRT.js} +2 -2
  24. package/dist/{chunk-WLZYGLJ4.js → chunk-5MA7ZLPD.js} +5 -7
  25. package/dist/chunk-5MA7ZLPD.js.map +1 -0
  26. package/dist/{chunk-XOLVM3AT.js → chunk-5WXJE5TV.js} +2 -2
  27. package/dist/{chunk-NLE6TSLG.js → chunk-BLVHDY2U.js} +5 -7
  28. package/dist/chunk-BLVHDY2U.js.map +1 -0
  29. package/dist/{chunk-4IFSMCRS.js → chunk-FEHVG4C4.js} +2 -2
  30. package/dist/{chunk-DC5CTLCZ.js → chunk-FTNV5476.js} +8 -8
  31. package/dist/{chunk-M4PHCEPU.js → chunk-LAEW4S43.js} +2 -2
  32. package/dist/{chunk-XN4CPSCN.js → chunk-LVGVXG22.js} +2 -2
  33. package/dist/{chunk-4P3ZBL5E.js → chunk-PZEXA6CM.js} +2 -2
  34. package/dist/{chunk-NORFVW2H.js → chunk-RA3C46VX.js} +2 -2
  35. package/dist/{chunk-YL2W6NUG.js → chunk-TPRBJF46.js} +3 -3
  36. package/dist/{chunk-TQAXUYUE.js → chunk-TQC6ELJO.js} +2 -2
  37. package/dist/{chunk-TM7S5UHD.js → chunk-U6HXB2OG.js} +2 -2
  38. package/dist/{chunk-WD32KTVI.js → chunk-VXGB766B.js} +3 -3
  39. package/dist/{chunk-ZNFHWNDM.js → chunk-W5UAB6EH.js} +3 -3
  40. package/dist/{chunk-ZJ6MEVTX.js → chunk-WAR75CRY.js} +8 -8
  41. package/dist/{chunk-KIOXEHWF.js → chunk-WKNWC46C.js} +2 -2
  42. package/dist/{chunk-K7S2IMGJ.js → chunk-ZDZJ2PG4.js} +309 -12
  43. package/dist/{chunk-K7S2IMGJ.js.map → chunk-ZDZJ2PG4.js.map} +1 -1
  44. package/dist/cli.js +17 -17
  45. package/dist/external-wiki-access.js +5 -5
  46. package/dist/extraction.js +3 -3
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +22 -20
  50. package/dist/memory-browse-operations.js +5 -5
  51. package/dist/model-registry.d.ts.map +1 -1
  52. package/dist/model-registry.js +1 -1
  53. package/dist/orchestrator.js +20 -20
  54. package/dist/profiling.d.ts.map +1 -1
  55. package/dist/profiling.js +1 -1
  56. package/dist/recall-navigation-operations.js +5 -5
  57. package/dist/recall-navigation.js +4 -4
  58. package/dist/security/audit-memory-cli.d.ts.map +1 -1
  59. package/dist/security/audit-memory.d.ts +10 -0
  60. package/dist/security/audit-memory.d.ts.map +1 -1
  61. package/dist/security/injection-screen.d.ts +1 -2
  62. package/dist/security/injection-screen.d.ts.map +1 -1
  63. package/dist/summarizer.js +2 -2
  64. package/dist/support-passport/index.js +7 -7
  65. package/package.json +12 -2
  66. package/src/index.ts +1 -1
  67. package/src/model-registry.test.ts +22 -1
  68. package/src/model-registry.ts +7 -6
  69. package/src/profiling.test.ts +20 -1
  70. package/src/profiling.ts +7 -7
  71. package/src/security/audit-memory-cli.test.ts +90 -0
  72. package/src/security/audit-memory-cli.ts +7 -0
  73. package/src/security/audit-memory.ts +14 -0
  74. package/src/security/injection-screen.test.ts +245 -0
  75. package/src/security/injection-screen.ts +341 -11
  76. package/dist/chunk-NLE6TSLG.js.map +0 -1
  77. package/dist/chunk-WLZYGLJ4.js.map +0 -1
  78. /package/dist/{chunk-2C5Z7CWB.js.map → chunk-24TJ77TT.js.map} +0 -0
  79. /package/dist/{chunk-LY3SDHMI.js.map → chunk-3MSMBVA3.js.map} +0 -0
  80. /package/dist/{chunk-2L5DIVDU.js.map → chunk-4EEDRKRT.js.map} +0 -0
  81. /package/dist/{chunk-XOLVM3AT.js.map → chunk-5WXJE5TV.js.map} +0 -0
  82. /package/dist/{chunk-4IFSMCRS.js.map → chunk-FEHVG4C4.js.map} +0 -0
  83. /package/dist/{chunk-DC5CTLCZ.js.map → chunk-FTNV5476.js.map} +0 -0
  84. /package/dist/{chunk-M4PHCEPU.js.map → chunk-LAEW4S43.js.map} +0 -0
  85. /package/dist/{chunk-XN4CPSCN.js.map → chunk-LVGVXG22.js.map} +0 -0
  86. /package/dist/{chunk-4P3ZBL5E.js.map → chunk-PZEXA6CM.js.map} +0 -0
  87. /package/dist/{chunk-NORFVW2H.js.map → chunk-RA3C46VX.js.map} +0 -0
  88. /package/dist/{chunk-YL2W6NUG.js.map → chunk-TPRBJF46.js.map} +0 -0
  89. /package/dist/{chunk-TQAXUYUE.js.map → chunk-TQC6ELJO.js.map} +0 -0
  90. /package/dist/{chunk-TM7S5UHD.js.map → chunk-U6HXB2OG.js.map} +0 -0
  91. /package/dist/{chunk-WD32KTVI.js.map → chunk-VXGB766B.js.map} +0 -0
  92. /package/dist/{chunk-ZNFHWNDM.js.map → chunk-W5UAB6EH.js.map} +0 -0
  93. /package/dist/{chunk-ZJ6MEVTX.js.map → chunk-WAR75CRY.js.map} +0 -0
  94. /package/dist/{chunk-KIOXEHWF.js.map → chunk-WKNWC46C.js.map} +0 -0
@@ -1,5 +1,6 @@
1
1
  import type { MemoryFile, MemoryFrontmatter } from "../types.js";
2
2
  import type { InjectionScreenProfile } from "./injection-screen.js";
3
+ import { type SecurityConfigProjection } from "../capabilities.js";
3
4
  export type AuditMemoryFindingCategory = "injection-signature" | "write-burst" | "authority-escalation";
4
5
  export interface AuditMemoryFinding {
5
6
  memoryId: string;
@@ -46,6 +47,15 @@ export interface AuditMemoryReport {
46
47
  }>;
47
48
  };
48
49
  }
50
+ /**
51
+ * The screen profile an audit sweep must use, resolved through the shared
52
+ * security capability plan (#1523) rather than read off config (#3078). The
53
+ * sweep matches the live write path, so a memory this deployment would
54
+ * quarantine on write does not survive once stored; a deployment with the
55
+ * screen DISABLED keeps the `default` weighting, because the sweep must
56
+ * never be stricter than the configured write path.
57
+ */
58
+ export declare function auditScreenProfile(config: SecurityConfigProjection): InjectionScreenProfile;
49
59
  export declare function auditMemoryStore(options: AuditMemoryStoreOptions): Promise<AuditMemoryReport>;
50
60
  export declare function formatAuditMemoryReport(report: AuditMemoryReport): string;
51
61
  //# sourceMappingURL=audit-memory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit-memory.d.ts","sourceRoot":"","sources":["../../src/security/audit-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAIpE,MAAM,MAAM,0BAA0B,GAClC,qBAAqB,GACrB,aAAa,GACb,sBAAsB,CAAC;AAE3B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACzC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAClD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC/D,iCAAiC,CAC/B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACjC,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,EAAE,CAAC,EAAE,IAAI,CAAC;KACX,GACA,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,KAAK,CAAC;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChE,CAAC;CACH;AAqJD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwFnG;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuBzE"}
1
+ {"version":3,"file":"audit-memory.d.ts","sourceRoot":"","sources":["../../src/security/audit-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAA+B,KAAK,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAIhG,MAAM,MAAM,0BAA0B,GAClC,qBAAqB,GACrB,aAAa,GACb,sBAAsB,CAAC;AAE3B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IACzC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAClD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC/D,iCAAiC,CAC/B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,OAAO,CAAC,iBAAiB,CAAC,EACjC,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,EAAE,CAAC,EAAE,IAAI,CAAC;KACX,GACA,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mFAAmF;IACnF,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,iBAAiB,EAAE,MAAM,CAAC;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,KAAK,CAAC;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAChE,CAAC;CACH;AAqJD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,GAAG,sBAAsB,CAG3F;AAED,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwFnG;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuBzE"}
@@ -15,6 +15,5 @@ export interface InjectionScreenResult {
15
15
  }
16
16
  export type InjectionScreenProfile = "default" | "hardened";
17
17
  export declare const INJECTION_SCREEN_THRESHOLD = 4;
18
- /** Screen a candidate fact without model calls, I/O, or mutable state. */
19
- export declare function screenCandidateFact(content: string, profile?: InjectionScreenProfile): InjectionScreenResult;
18
+ export declare function screenCandidateFact(rawContent: string, profile?: InjectionScreenProfile): InjectionScreenResult;
20
19
  //# sourceMappingURL=injection-screen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"injection-screen.d.ts","sourceRoot":"","sources":["../../src/security/injection-screen.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,UAAU,CAAC;AAwC5D,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAyJ5C,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,sBAAkC,GAAG,qBAAqB,CAkBvH"}
1
+ {"version":3,"file":"injection-screen.d.ts","sourceRoot":"","sources":["../../src/security/injection-screen.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,UAAU,CAAC;AAwC5D,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAud5C,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,sBAAkC,GAC1C,qBAAqB,CA4BvB"}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  HourlySummarizer,
3
3
  summarizeHourlyStatus
4
- } from "./chunk-XOLVM3AT.js";
4
+ } from "./chunk-5WXJE5TV.js";
5
5
  import "./chunk-6DNMUYEE.js";
6
6
  import "./chunk-S4DDLTPX.js";
7
- import "./chunk-WLZYGLJ4.js";
7
+ import "./chunk-5MA7ZLPD.js";
8
8
  import "./chunk-62JTOLEX.js";
9
9
  import "./chunk-QM2SPLKQ.js";
10
10
  import "./chunk-JUXOTY6J.js";
@@ -4,7 +4,7 @@ import {
4
4
  SUPPORT_PASSPORT_MODEL_RESULT_PATH,
5
5
  SupportPassportModelBridge,
6
6
  parseSupportPassportModelJob
7
- } from "../chunk-M4PHCEPU.js";
7
+ } from "../chunk-LAEW4S43.js";
8
8
  import {
9
9
  DEFAULT_SUPPORT_PASSPORT_CONFIG,
10
10
  parseSupportPassportConfig
@@ -14,8 +14,8 @@ import {
14
14
  buildSupportPassportPublicRequestHandler,
15
15
  composeSupportPassportExternalRequestHandlers,
16
16
  normalizeSupportPassportNetworkAddress
17
- } from "../chunk-XN4CPSCN.js";
18
- import "../chunk-2C5Z7CWB.js";
17
+ } from "../chunk-LVGVXG22.js";
18
+ import "../chunk-24TJ77TT.js";
19
19
  import {
20
20
  SUPPORT_PASSPORT_DRAFT_MAX_CONTENT_CHARACTERS,
21
21
  SUPPORT_PASSPORT_DRAFT_MAX_MEMORIES,
@@ -56,7 +56,7 @@ import {
56
56
  notifySupportPassportCommitted,
57
57
  resolveSupportPassportModelRoutePlan,
58
58
  syncDirectoryForDurability
59
- } from "../chunk-WD32KTVI.js";
59
+ } from "../chunk-VXGB766B.js";
60
60
  import "../chunk-W4F3C7N7.js";
61
61
  import "../chunk-MPC7TYTZ.js";
62
62
  import "../chunk-ZHXSOMYH.js";
@@ -69,7 +69,7 @@ import "../chunk-PJSK6OJM.js";
69
69
  import "../chunk-GNVZQ5JN.js";
70
70
  import "../chunk-YN2UN7N3.js";
71
71
  import "../chunk-ROBHL3GL.js";
72
- import "../chunk-XOLVM3AT.js";
72
+ import "../chunk-5WXJE5TV.js";
73
73
  import "../chunk-6DNMUYEE.js";
74
74
  import "../chunk-P5FPO2BR.js";
75
75
  import "../chunk-6ET2VII7.js";
@@ -103,8 +103,8 @@ import "../chunk-EI6V5UXY.js";
103
103
  import "../chunk-KKNZ7PUZ.js";
104
104
  import "../chunk-AERXJCOG.js";
105
105
  import "../chunk-754XN6LX.js";
106
- import "../chunk-NLE6TSLG.js";
107
- import "../chunk-WLZYGLJ4.js";
106
+ import "../chunk-BLVHDY2U.js";
107
+ import "../chunk-5MA7ZLPD.js";
108
108
  import "../chunk-62JTOLEX.js";
109
109
  import "../chunk-QM2SPLKQ.js";
110
110
  import "../chunk-JUXOTY6J.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remnic/core",
3
- "version": "9.69.61",
3
+ "version": "9.69.63",
4
4
  "description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2620,6 +2620,16 @@
2620
2620
  "remnic-source": "./src/session-integrity.ts",
2621
2621
  "import": "./dist/session-integrity.js"
2622
2622
  },
2623
+ "./recall-handles": {
2624
+ "types": "./dist/recall-handles.d.ts",
2625
+ "remnic-source": "./src/recall-handles.ts",
2626
+ "import": "./dist/recall-handles.js"
2627
+ },
2628
+ "./recall-handles.js": {
2629
+ "types": "./dist/recall-handles.d.ts",
2630
+ "remnic-source": "./src/recall-handles.ts",
2631
+ "import": "./dist/recall-handles.js"
2632
+ },
2623
2633
  "./session-namespace-bindings": {
2624
2634
  "types": "./dist/session-namespace-bindings.d.ts",
2625
2635
  "remnic-source": "./src/session-namespace-bindings.ts",
@@ -3307,7 +3317,7 @@
3307
3317
  "core"
3308
3318
  ],
3309
3319
  "peerDependencies": {
3310
- "@remnic/coding-graph": "^9.69.61"
3320
+ "@remnic/coding-graph": "^9.69.63"
3311
3321
  },
3312
3322
  "peerDependenciesMeta": {
3313
3323
  "@remnic/coding-graph": {
package/src/index.ts CHANGED
@@ -389,7 +389,7 @@ export {
389
389
  } from "./trust-zones.js";
390
390
  export { DEFAULT_UNTRUSTED_ORIGINS, HARDENED_UNTRUSTED_ORIGINS, classifyOrigin, isUntrustedOrigin, parseOriginClass, renderAuthorityFence, type MemoryInjectionDefenseMode, type OriginClass } from "./security/origin-authority.js";
391
391
  export { INJECTION_SCREEN_THRESHOLD, screenCandidateFact, type InjectionScreenFinding, type InjectionScreenProfile, type InjectionScreenResult } from "./security/injection-screen.js";
392
- export { auditMemoryStore, formatAuditMemoryReport, type AuditMemoryReport } from "./security/audit-memory.js";
392
+ export { auditMemoryStore, auditScreenProfile, formatAuditMemoryReport, type AuditMemoryReport } from "./security/audit-memory.js";
393
393
  // Access layer (HTTP + MCP + schema validation)
394
394
  // ---------------------------------------------------------------------------
395
395
 
@@ -1,5 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtempSync, rmSync } from "node:fs";
2
+ import { existsSync, mkdtempSync, rmSync } from "node:fs";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import test from "node:test";
@@ -36,3 +36,24 @@ test("calculateContextSizes ignores invalid or tiny override values before budge
36
36
  rmSync(dir, { recursive: true, force: true });
37
37
  }
38
38
  });
39
+
40
+ test("construction never creates the registry dir; the first save does", () => {
41
+ const dir = mkdtempSync(join(tmpdir(), "remnic-model-registry-"));
42
+ const registryDir = join(dir, ".registry");
43
+ try {
44
+ const registry = new ModelRegistry(dir);
45
+ // Constructing a registry happens on every plugin registration, including
46
+ // read-only discovery passes, so it must not touch the memory dir.
47
+ assert.equal(existsSync(registryDir), false, "no dir before anything is cached");
48
+ registry.setCapabilities("local-model", {
49
+ maxPositionEmbeddings: 32_768,
50
+ contextWindow: 32_768,
51
+ supportsExtendedContext: false,
52
+ typicalOutputTokens: 2_048,
53
+ source: "manual",
54
+ });
55
+ assert.equal(existsSync(registryDir), true, "the first cached model creates it");
56
+ } finally {
57
+ rmSync(dir, { recursive: true, force: true });
58
+ }
59
+ });
@@ -5,7 +5,7 @@
5
5
 
6
6
  import { log } from "./logger.js";
7
7
  import fs from "node:fs";
8
- import { join } from "node:path";
8
+ import { dirname, join } from "node:path";
9
9
 
10
10
  export interface ModelCapabilities {
11
11
  modelId: string;
@@ -116,11 +116,7 @@ export class ModelRegistry {
116
116
  private readonly CACHE_TTL_DAYS = 7;
117
117
 
118
118
  constructor(memoryDir: string) {
119
- const registryDir = join(memoryDir, ".registry");
120
- if (!fs.existsSync(registryDir)) {
121
- fs.mkdirSync(registryDir, { recursive: true });
122
- }
123
- this.registryPath = join(registryDir, "model-capabilities.json");
119
+ this.registryPath = join(memoryDir, ".registry", "model-capabilities.json");
124
120
  this.data = this.loadRegistry();
125
121
  }
126
122
 
@@ -140,6 +136,11 @@ export class ModelRegistry {
140
136
 
141
137
  private saveRegistry(): void {
142
138
  try {
139
+ // Created on first save, never at construction: building a registry
140
+ // happens on every plugin registration, including read-only discovery
141
+ // passes, and must not touch the operator's memory dir.
142
+ const registryDir = dirname(this.registryPath);
143
+ if (!fs.existsSync(registryDir)) fs.mkdirSync(registryDir, { recursive: true });
143
144
  fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
144
145
  } catch (err) {
145
146
  log.warn(`ModelRegistry: failed to save registry: ${err}`);
@@ -1,5 +1,5 @@
1
1
  import assert from "node:assert/strict";
2
- import { mkdtempSync, readdirSync, rmSync } from "node:fs";
2
+ import { existsSync, mkdtempSync, readdirSync, rmSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { tmpdir } from "node:os";
5
5
  import test, { describe } from "node:test";
@@ -283,4 +283,23 @@ describe("ProfilingCollector", () => {
283
283
  cleanup(dir);
284
284
  }
285
285
  });
286
+
287
+ test("construction never creates the storage dir; the first persist does", () => {
288
+ const dir = tempDir();
289
+ const storageDir = join(dir, "profiling");
290
+ try {
291
+ const collector = new ProfilingCollector({ enabled: true, storageDir, maxTraces: 10 });
292
+ // Constructing a collector happens on every plugin registration, including
293
+ // read-only discovery passes, so it must not touch the memory dir.
294
+ assert.equal(existsSync(storageDir), false, "no dir before a trace is written");
295
+ collector.startTrace("recall", "test-session");
296
+ collector.startSpan("qmd-search");
297
+ collector.endSpan("qmd-search");
298
+ collector.endTrace();
299
+ assert.equal(existsSync(storageDir), true, "the first persisted trace creates it");
300
+ assert.equal(readdirSync(storageDir).length, 1);
301
+ } finally {
302
+ cleanup(dir);
303
+ }
304
+ });
286
305
  });
package/src/profiling.ts CHANGED
@@ -118,13 +118,6 @@ export class ProfilingCollector {
118
118
  this.enabled = config.enabled;
119
119
  this.storageDir = config.storageDir;
120
120
  this.maxTraces = Math.max(0, config.maxTraces);
121
-
122
- if (this.enabled) {
123
- if (!existsSync(this.storageDir)) {
124
- mkdirSync(this.storageDir, { recursive: true });
125
- log.debug(`profiling: created storage dir ${this.storageDir}`);
126
- }
127
- }
128
121
  }
129
122
 
130
123
  get isEnabled(): boolean {
@@ -347,6 +340,13 @@ export class ProfilingCollector {
347
340
  const filename = `${trace.kind}-${trace.traceId}.jsonl`;
348
341
  const filepath = join(this.storageDir, filename);
349
342
  try {
343
+ // Created on first persist, never at construction: constructing a
344
+ // collector (plugin registration, a discovery pass, CLI metadata) must
345
+ // not touch the operator's memory dir when no trace is ever written.
346
+ if (!existsSync(this.storageDir)) {
347
+ mkdirSync(this.storageDir, { recursive: true });
348
+ log.debug(`profiling: created storage dir ${this.storageDir}`);
349
+ }
350
350
  writeFileSync(filepath, JSON.stringify(trace) + "\n", "utf-8");
351
351
  log.debug(`profiling: persisted ${filename}`);
352
352
  } catch (err) {
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The audit sweep must screen with the profile the deployment writes with
3
+ * (issue #3078). A `quarantine`/`layered` deployment resolves the `hardened`
4
+ * profile, under which a conditional-trigger-only memory reaches the
5
+ * quarantine threshold; before this wiring the CLI omitted `profile`, so an
6
+ * already-active memory that live ingestion would have quarantined survived
7
+ * the sweep.
8
+ */
9
+
10
+ import assert from "node:assert/strict";
11
+ import { mkdtemp, rm } from "node:fs/promises";
12
+ import os from "node:os";
13
+ import path from "node:path";
14
+ import test from "node:test";
15
+
16
+ import type { CliCommand } from "../cli.js";
17
+ import { parseConfig } from "../config.js";
18
+ import { StorageManager } from "../storage.js";
19
+ import type { Orchestrator } from "../orchestrator.js";
20
+ import { registerSecurityCommands } from "./audit-memory-cli.js";
21
+
22
+ /** Minimal CliCommand that records the registered `audit-memory` action. */
23
+ function captureAction(): { cmd: CliCommand; run: () => Promise<void> } {
24
+ let action: ((...args: unknown[]) => Promise<void> | void) | undefined;
25
+ const node: CliCommand = {
26
+ description: () => node,
27
+ option: () => node,
28
+ requiredOption: () => node,
29
+ argument: () => node,
30
+ action: (fn) => {
31
+ action = fn;
32
+ return node;
33
+ },
34
+ command: () => node,
35
+ };
36
+ return {
37
+ cmd: node,
38
+ run: async () => {
39
+ if (!action) throw new Error("no action registered");
40
+ await action({ quarantine: true, json: true });
41
+ },
42
+ };
43
+ }
44
+
45
+ const CONDITIONAL_TRIGGER = "If the incident occurs, then call the on-call.";
46
+
47
+ async function sweepWithDefenseMode(mode: string): Promise<{ status: string | undefined }> {
48
+ const memoryDir = await mkdtemp(path.join(os.tmpdir(), "remnic-audit-cli-"));
49
+ const logs: unknown[] = [];
50
+ const originalLog = console.log;
51
+ console.log = (...args: unknown[]) => {
52
+ logs.push(args);
53
+ };
54
+ try {
55
+ StorageManager.clearAllStaticCaches();
56
+ const config = parseConfig({ memoryDir, memoryInjectionDefenseMode: mode });
57
+ const storage = new StorageManager(memoryDir);
58
+ const written = await storage.writeMemory("fact", CONDITIONAL_TRIGGER);
59
+ const id = written.id;
60
+ // The fixture must start active, or the sweep assertion proves nothing.
61
+ assert.equal(written.tombstoneBlocked ?? false, false);
62
+ assert.equal((await storage.getMemoryById(id))?.frontmatter.status, "active");
63
+ const orchestrator = { config, storage } as unknown as Orchestrator;
64
+ const { cmd, run } = captureAction();
65
+ registerSecurityCommands(cmd, orchestrator);
66
+ await run();
67
+ const stored = await storage.getMemoryById(id);
68
+ return { status: stored?.frontmatter.status };
69
+ } finally {
70
+ console.log = originalLog;
71
+ StorageManager.clearAllStaticCaches();
72
+ await rm(memoryDir, { recursive: true, force: true });
73
+ }
74
+ }
75
+
76
+ test("the plugin audit-memory command screens with the configured profile", async () => {
77
+ // `layered` resolves the hardened profile: weight 4 for a conditional
78
+ // trigger alone, so the sweep retro-quarantines the memory.
79
+ const hardened = await sweepWithDefenseMode("layered");
80
+ assert.equal(hardened.status, "pending_review");
81
+ // `custom` resolves the default profile: weight 3, below the threshold,
82
+ // so the same memory stays active. This proves the profile is read from
83
+ // the configuration rather than hard-coded either way.
84
+ const lenient = await sweepWithDefenseMode("custom");
85
+ assert.equal(lenient.status, "active");
86
+ // `off`/`fencing` disable live screening, so the sweep keeps the previous
87
+ // `default` weighting instead of becoming stricter than the write path.
88
+ const screenDisabled = await sweepWithDefenseMode("off");
89
+ assert.equal(screenDisabled.status, "active");
90
+ });
@@ -7,6 +7,7 @@
7
7
  import type { CliCommand } from "../cli.js";
8
8
  import { runAuditMemoryCliCommand } from "../cli.js";
9
9
  import type { Orchestrator } from "../orchestrator.js";
10
+ import { auditScreenProfile } from "./audit-memory.js";
10
11
  import { formatAuditMemoryReport } from "./audit-memory.js";
11
12
 
12
13
  export function registerSecurityCommands(
@@ -32,6 +33,12 @@ export function registerSecurityCommands(
32
33
  ? options.since.trim()
33
34
  : undefined,
34
35
  quarantine: options.quarantine === true,
36
+ // Screen with the profile live ingestion uses, or a memory this
37
+ // deployment would quarantine on write stays active once stored
38
+ // (#3078). A deployment with the screen DISABLED keeps the previous
39
+ // `default` weighting: the sweep must not be stricter than the
40
+ // write path the operator configured.
41
+ profile: auditScreenProfile(orchestrator.config),
35
42
  });
36
43
  if (options.json === true) {
37
44
  console.log(JSON.stringify(report, null, 2));
@@ -1,6 +1,7 @@
1
1
  import type { MemoryFile, MemoryFrontmatter } from "../types.js";
2
2
  import { screenCandidateFact } from "./injection-screen.js";
3
3
  import type { InjectionScreenProfile } from "./injection-screen.js";
4
+ import { resolveSecurityCapabilities, type SecurityConfigProjection } from "../capabilities.js";
4
5
  import { inferMemoryStatus, isArchivedMemoryPath, toMemoryPathRel } from "../memory-lifecycle-ledger-utils.js";
5
6
  import { parseStrictCliDate } from "../training-export/date-parse.js";
6
7
 
@@ -206,6 +207,19 @@ function writeBurstStats(groups: Map<string, MemoryFile[]>): AuditMemoryReport["
206
207
  };
207
208
  }
208
209
 
210
+ /**
211
+ * The screen profile an audit sweep must use, resolved through the shared
212
+ * security capability plan (#1523) rather than read off config (#3078). The
213
+ * sweep matches the live write path, so a memory this deployment would
214
+ * quarantine on write does not survive once stored; a deployment with the
215
+ * screen DISABLED keeps the `default` weighting, because the sweep must
216
+ * never be stricter than the configured write path.
217
+ */
218
+ export function auditScreenProfile(config: SecurityConfigProjection): InjectionScreenProfile {
219
+ const capabilities = resolveSecurityCapabilities(config);
220
+ return capabilities.injectionScreen ? capabilities.injectionScreenProfile : "default";
221
+ }
222
+
209
223
  export async function auditMemoryStore(options: AuditMemoryStoreOptions): Promise<AuditMemoryReport> {
210
224
  const since = parseSince(options.since);
211
225
  const storage = options.storage;