@remnic/core 9.3.680 → 9.3.682

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 (167) hide show
  1. package/dist/access-boundary.d.ts +178 -0
  2. package/dist/access-boundary.js +121 -0
  3. package/dist/access-cli.js +115 -101
  4. package/dist/access-cli.js.map +1 -1
  5. package/dist/access-http.d.ts +1 -1
  6. package/dist/access-http.js +48 -46
  7. package/dist/access-mcp.d.ts +1 -1
  8. package/dist/access-mcp.js +44 -42
  9. package/dist/access-operations.d.ts +127 -0
  10. package/dist/access-operations.js +115 -0
  11. package/dist/access-operations.js.map +1 -0
  12. package/dist/access-schema.d.ts +34 -34
  13. package/dist/access-schema.js +6 -6
  14. package/dist/{access-service-S9oGKPZc.d.ts → access-service-DvA6jyHL.d.ts} +1 -1
  15. package/dist/access-service.d.ts +1 -1
  16. package/dist/access-service.js +40 -40
  17. package/dist/access-surface-catalog.d.ts +125 -0
  18. package/dist/access-surface-catalog.js +162 -0
  19. package/dist/access-surface-catalog.js.map +1 -0
  20. package/dist/adapters/index.js +7 -7
  21. package/dist/adapters/registry.js +3 -3
  22. package/dist/auto-sync-5CJBJMPZ.js +1 -1
  23. package/dist/briefing.js +8 -8
  24. package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
  25. package/dist/capsule-crypto-7FJQINUR.js.map +1 -0
  26. package/dist/causal-behavior.js +5 -5
  27. package/dist/causal-chain.js +3 -3
  28. package/dist/causal-consolidation.js +16 -16
  29. package/dist/causal-retrieval.js +3 -3
  30. package/dist/causal-trajectory.js +1 -1
  31. package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
  32. package/dist/{chunk-JBPKEARU.js → chunk-2QSZNTDO.js} +7 -7
  33. package/dist/{chunk-3OKWZT7F.js → chunk-3IND7N4X.js} +2 -2
  34. package/dist/{chunk-GYSYLGNE.js → chunk-7MOTEVAA.js} +2 -2
  35. package/dist/{chunk-6T4LTI2F.js → chunk-7XH7VJN4.js} +4 -4
  36. package/dist/{chunk-AGNBY3VG.js → chunk-APJQ6UEA.js} +4 -4
  37. package/dist/{chunk-LZSMQHXC.js → chunk-ARLRTZZZ.js} +5 -5
  38. package/dist/{chunk-DL6H3D7S.js → chunk-ARV3AUOM.js} +2 -2
  39. package/dist/{chunk-Q2H5U37U.js → chunk-B2B2IHUH.js} +2 -2
  40. package/dist/{chunk-SECQS4G4.js → chunk-BTVX7ZXZ.js} +5 -5
  41. package/dist/{chunk-DGEZKYVI.js → chunk-DOCTITOP.js} +4 -4
  42. package/dist/{chunk-EQYP3HA6.js → chunk-EG4TCVMU.js} +2 -2
  43. package/dist/{chunk-SLTKP5WJ.js → chunk-EW5KFXHL.js} +4 -4
  44. package/dist/{chunk-5TEYIXMP.js → chunk-FDSOMA6M.js} +28 -41
  45. package/dist/chunk-FDSOMA6M.js.map +1 -0
  46. package/dist/{chunk-CTCPB57O.js → chunk-G7Z3C2X6.js} +2 -2
  47. package/dist/{chunk-OBM7EVFU.js → chunk-H4BDNIKQ.js} +53 -53
  48. package/dist/{chunk-MTJ2LFAJ.js → chunk-H6PMGMNP.js} +2 -2
  49. package/dist/{chunk-7AAKSHDG.js → chunk-I3HSKQT7.js} +136 -136
  50. package/dist/{chunk-NXBXM7Q6.js → chunk-I75DF4FZ.js} +2 -2
  51. package/dist/{chunk-RC3AFF6Z.js → chunk-JD4SCARD.js} +1 -1
  52. package/dist/{chunk-LVTTO3VC.js → chunk-KACIOX42.js} +2 -2
  53. package/dist/{chunk-VDX2J7OX.js → chunk-KQAFEZQX.js} +2 -2
  54. package/dist/{chunk-ATRB6Q25.js → chunk-KV6CX4ON.js} +2 -2
  55. package/dist/{chunk-VL5JJOOY.js → chunk-L5MUA6Q7.js} +5 -5
  56. package/dist/{chunk-W67ZZDHO.js → chunk-M4I3TREG.js} +75 -75
  57. package/dist/chunk-NHFXF4ZO.js +107 -0
  58. package/dist/chunk-NHFXF4ZO.js.map +1 -0
  59. package/dist/{chunk-MNUPGYIV.js → chunk-NQMBSSWW.js} +2 -2
  60. package/dist/{chunk-V4ZHKCGA.js → chunk-O2WELT5C.js} +5 -5
  61. package/dist/{chunk-Z6SEG36L.js → chunk-OUWAQVDJ.js} +4 -4
  62. package/dist/{chunk-57ME5VSI.js → chunk-Q5ZU3RNY.js} +4 -4
  63. package/dist/{chunk-ACYX37IM.js → chunk-QUA2JPH2.js} +6 -6
  64. package/dist/{chunk-DWQPM67F.js → chunk-QVWM4C24.js} +37 -32
  65. package/dist/chunk-QVWM4C24.js.map +1 -0
  66. package/dist/{chunk-2AP4QJX5.js → chunk-TOQEZ63C.js} +8 -8
  67. package/dist/{chunk-EUM7CZFM.js → chunk-TY5NT3T3.js} +17 -17
  68. package/dist/{chunk-ZCVPFDHB.js → chunk-UAODC6GJ.js} +14 -14
  69. package/dist/{chunk-JI6HWBYL.js → chunk-UDJLF3BO.js} +2 -2
  70. package/dist/{chunk-YJ4J2JJ2.js → chunk-UJDV2NLT.js} +9 -9
  71. package/dist/chunk-V254FAT5.js +85 -0
  72. package/dist/chunk-V254FAT5.js.map +1 -0
  73. package/dist/{chunk-3IE22DJ2.js → chunk-WEPMT6SC.js} +10 -10
  74. package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
  75. package/dist/{chunk-EZ25VE3G.js → chunk-YNDLCWXS.js} +4 -4
  76. package/dist/{cli-B2Ve7R22.d.ts → cli-feUe-x3I.d.ts} +1 -1
  77. package/dist/cli.d.ts +2 -2
  78. package/dist/cli.js +75 -73
  79. package/dist/compounding/engine.js +9 -9
  80. package/dist/connectors/codex-materialize-runner.js +9 -9
  81. package/dist/connectors/index.js +9 -9
  82. package/dist/consolidation-provenance-check.js +2 -2
  83. package/dist/dashboard-runtime.js +2 -2
  84. package/dist/entity-retrieval.js +7 -7
  85. package/dist/extraction.js +2 -2
  86. package/dist/{first-start-migration-PG5HBC3K.js → first-start-migration-FF7YFGRP.js} +4 -4
  87. package/dist/index.d.ts +2 -2
  88. package/dist/index.js +209 -207
  89. package/dist/index.js.map +1 -1
  90. package/dist/lcm/engine.js +4 -4
  91. package/dist/lcm/index.js +12 -12
  92. package/dist/maintenance/memory-governance.js +8 -8
  93. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +7 -7
  94. package/dist/maintenance/rebuild-memory-projection.js +9 -9
  95. package/dist/mcp-memory-inspector-app.d.ts +1 -1
  96. package/dist/namespaces/migrate.js +17 -17
  97. package/dist/namespaces/search.js +8 -8
  98. package/dist/namespaces/storage.js +8 -8
  99. package/dist/operator-toolkit.js +22 -22
  100. package/dist/orchestrator.js +70 -70
  101. package/dist/resume-bundles.js +1 -1
  102. package/dist/schemas.d.ts +28 -28
  103. package/dist/search/factory.js +7 -7
  104. package/dist/search/index.js +11 -11
  105. package/dist/search/lancedb-backend.js +3 -3
  106. package/dist/search/meilisearch-backend.js +3 -3
  107. package/dist/search/orama-backend.js +3 -3
  108. package/dist/semantic-consolidation.js +11 -11
  109. package/dist/semantic-rule-promotion.js +7 -7
  110. package/dist/semantic-rule-verifier.js +8 -8
  111. package/dist/storage.js +6 -6
  112. package/dist/transfer/backup.js +4 -4
  113. package/dist/transfer/capsule-export.js +4 -4
  114. package/dist/transfer/capsule-import.js +3 -3
  115. package/dist/transfer/import-sqlite.js +2 -2
  116. package/dist/transfer/types.d.ts +20 -20
  117. package/dist/verified-recall.js +8 -8
  118. package/package.json +2 -2
  119. package/src/access-boundary.test.ts +212 -0
  120. package/src/access-boundary.ts +235 -0
  121. package/src/access-cli.ts +32 -15
  122. package/src/access-http.ts +38 -28
  123. package/src/access-mcp.ts +41 -35
  124. package/src/access-operations.ts +157 -0
  125. package/src/access-surface-catalog.test.ts +772 -0
  126. package/src/access-surface-catalog.ts +218 -0
  127. package/dist/chunk-5TEYIXMP.js.map +0 -1
  128. package/dist/chunk-DWQPM67F.js.map +0 -1
  129. /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-boundary.js.map} +0 -0
  130. /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
  131. /package/dist/{chunk-JBPKEARU.js.map → chunk-2QSZNTDO.js.map} +0 -0
  132. /package/dist/{chunk-3OKWZT7F.js.map → chunk-3IND7N4X.js.map} +0 -0
  133. /package/dist/{chunk-GYSYLGNE.js.map → chunk-7MOTEVAA.js.map} +0 -0
  134. /package/dist/{chunk-6T4LTI2F.js.map → chunk-7XH7VJN4.js.map} +0 -0
  135. /package/dist/{chunk-AGNBY3VG.js.map → chunk-APJQ6UEA.js.map} +0 -0
  136. /package/dist/{chunk-LZSMQHXC.js.map → chunk-ARLRTZZZ.js.map} +0 -0
  137. /package/dist/{chunk-DL6H3D7S.js.map → chunk-ARV3AUOM.js.map} +0 -0
  138. /package/dist/{chunk-Q2H5U37U.js.map → chunk-B2B2IHUH.js.map} +0 -0
  139. /package/dist/{chunk-SECQS4G4.js.map → chunk-BTVX7ZXZ.js.map} +0 -0
  140. /package/dist/{chunk-DGEZKYVI.js.map → chunk-DOCTITOP.js.map} +0 -0
  141. /package/dist/{chunk-EQYP3HA6.js.map → chunk-EG4TCVMU.js.map} +0 -0
  142. /package/dist/{chunk-SLTKP5WJ.js.map → chunk-EW5KFXHL.js.map} +0 -0
  143. /package/dist/{chunk-CTCPB57O.js.map → chunk-G7Z3C2X6.js.map} +0 -0
  144. /package/dist/{chunk-OBM7EVFU.js.map → chunk-H4BDNIKQ.js.map} +0 -0
  145. /package/dist/{chunk-MTJ2LFAJ.js.map → chunk-H6PMGMNP.js.map} +0 -0
  146. /package/dist/{chunk-7AAKSHDG.js.map → chunk-I3HSKQT7.js.map} +0 -0
  147. /package/dist/{chunk-NXBXM7Q6.js.map → chunk-I75DF4FZ.js.map} +0 -0
  148. /package/dist/{chunk-RC3AFF6Z.js.map → chunk-JD4SCARD.js.map} +0 -0
  149. /package/dist/{chunk-LVTTO3VC.js.map → chunk-KACIOX42.js.map} +0 -0
  150. /package/dist/{chunk-VDX2J7OX.js.map → chunk-KQAFEZQX.js.map} +0 -0
  151. /package/dist/{chunk-ATRB6Q25.js.map → chunk-KV6CX4ON.js.map} +0 -0
  152. /package/dist/{chunk-VL5JJOOY.js.map → chunk-L5MUA6Q7.js.map} +0 -0
  153. /package/dist/{chunk-W67ZZDHO.js.map → chunk-M4I3TREG.js.map} +0 -0
  154. /package/dist/{chunk-MNUPGYIV.js.map → chunk-NQMBSSWW.js.map} +0 -0
  155. /package/dist/{chunk-V4ZHKCGA.js.map → chunk-O2WELT5C.js.map} +0 -0
  156. /package/dist/{chunk-Z6SEG36L.js.map → chunk-OUWAQVDJ.js.map} +0 -0
  157. /package/dist/{chunk-57ME5VSI.js.map → chunk-Q5ZU3RNY.js.map} +0 -0
  158. /package/dist/{chunk-ACYX37IM.js.map → chunk-QUA2JPH2.js.map} +0 -0
  159. /package/dist/{chunk-2AP4QJX5.js.map → chunk-TOQEZ63C.js.map} +0 -0
  160. /package/dist/{chunk-EUM7CZFM.js.map → chunk-TY5NT3T3.js.map} +0 -0
  161. /package/dist/{chunk-ZCVPFDHB.js.map → chunk-UAODC6GJ.js.map} +0 -0
  162. /package/dist/{chunk-JI6HWBYL.js.map → chunk-UDJLF3BO.js.map} +0 -0
  163. /package/dist/{chunk-YJ4J2JJ2.js.map → chunk-UJDV2NLT.js.map} +0 -0
  164. /package/dist/{chunk-3IE22DJ2.js.map → chunk-WEPMT6SC.js.map} +0 -0
  165. /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
  166. /package/dist/{chunk-EZ25VE3G.js.map → chunk-YNDLCWXS.js.map} +0 -0
  167. /package/dist/{first-start-migration-PG5HBC3K.js.map → first-start-migration-FF7YFGRP.js.map} +0 -0
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Static inventory of every handler on the MCP and HTTP access surfaces, with
3
+ * its migration status against the access boundary (issue #1525).
4
+ *
5
+ * The fitness test (`access-surface-catalog.test.ts`) walks this catalog,
6
+ * checks each entry against the live registry, and counts unmigrated handlers.
7
+ * The ratchet (`scripts/check-ratchets.mjs`) reads this file and counts
8
+ * `operation: null` entries so the unmigrated count can only decrease.
9
+ *
10
+ * WHEN MIGRATING A HANDLER (follow-up PRs):
11
+ * 1. Add the operation to `access-operations.ts` via `defineOperation`.
12
+ * 2. Flip its entry here from `operation: null` to `operation: "<name>"`.
13
+ * 3. Delete the surface-local validation the handler used to do.
14
+ * 4. Run `node scripts/check-ratchets.mjs --update` to ratchet the count
15
+ * down — the improvement is recorded in `scripts/ratchet-baseline.json`.
16
+ *
17
+ * WHEN ADDING A NEW HANDLER:
18
+ * 1. Add the entry here with `operation: null` (the fitness test will fail
19
+ * until you either migrate it or acknowledge it as unmigrated).
20
+ * 2. Migrate it in the same PR if it carries user input — the boundary's
21
+ * whole point is that no new handler bypasses it.
22
+ */
23
+
24
+ import type { OperationName } from "./access-boundary.js";
25
+
26
+ /**
27
+ * One row per MCP tool, keyed by the canonical SHORT name (no `engram.`/
28
+ * `remnic.` prefix — both aliases dispatch to the same operation). The name
29
+ * MUST match the tool's short suffix as advertised by `tools/list`.
30
+ */
31
+ export interface McpToolEntry {
32
+ readonly tool: string;
33
+ readonly operation: OperationName | null;
34
+ }
35
+
36
+ /**
37
+ * One row per HTTP route that invokes an access-service method. Routes that
38
+ * only serve static assets, SSE streams, or admin console HTML are excluded —
39
+ * they don't carry user-validated request envelopes into the facade.
40
+ */
41
+ export interface HttpRouteEntry {
42
+ readonly method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
43
+ readonly pathname: string;
44
+ readonly operation: OperationName | null;
45
+ }
46
+
47
+ // Each tool below corresponds 1:1 to an `engram.*` definition in
48
+ // `EngramMcpServer.tools` (access-mcp.ts). The fitness test asserts the live
49
+ // `tools/list` response matches this list by short name, so a new tool cannot
50
+ // land without either migrating it or acknowledging the unmigrated count.
51
+ export const MCP_TOOLS: readonly McpToolEntry[] = [
52
+ { tool: "recall", operation: null },
53
+ { tool: "recall_explain", operation: null },
54
+ { tool: "set_coding_context", operation: null },
55
+ { tool: "recall_tier_explain", operation: null },
56
+ { tool: "recall_xray", operation: null },
57
+ { tool: "wearables_status", operation: null },
58
+ { tool: "wearables_sync", operation: null },
59
+ { tool: "transcript_day", operation: null },
60
+ { tool: "transcript_search", operation: null },
61
+ { tool: "transcript_memories", operation: null },
62
+ { tool: "action_confidence", operation: null },
63
+ { tool: "chatgpt_memory_inspector", operation: null },
64
+ { tool: "day_summary", operation: null },
65
+ { tool: "capsule_export", operation: null },
66
+ { tool: "capsule_import", operation: null },
67
+ { tool: "capsule_list", operation: null },
68
+ { tool: "memory_governance_run", operation: null },
69
+ { tool: "procedure_mining_run", operation: null },
70
+ { tool: "pattern_reinforcement_run", operation: null },
71
+ { tool: "procedural_stats", operation: null },
72
+ { tool: "memory_get", operation: "memory_get" },
73
+ { tool: "memory_timeline", operation: null },
74
+ { tool: "memory_store", operation: "memory_store" },
75
+ { tool: "suggestion_submit", operation: null },
76
+ { tool: "entity_get", operation: null },
77
+ { tool: "review_queue_list", operation: null },
78
+ { tool: "observe", operation: null },
79
+ { tool: "lcm_search", operation: null },
80
+ { tool: "lcm_compaction_flush", operation: null },
81
+ { tool: "lcm_compaction_record", operation: null },
82
+ { tool: "continuity_audit_generate", operation: null },
83
+ { tool: "continuity_incident_open", operation: null },
84
+ { tool: "continuity_incident_close", operation: null },
85
+ { tool: "continuity_incident_list", operation: null },
86
+ { tool: "continuity_loop_add_or_update", operation: null },
87
+ { tool: "continuity_loop_review", operation: null },
88
+ { tool: "identity_anchor_get", operation: null },
89
+ { tool: "identity_anchor_update", operation: null },
90
+ { tool: "memory_identity", operation: null },
91
+ { tool: "work_task", operation: null },
92
+ { tool: "work_project", operation: null },
93
+ { tool: "work_board", operation: null },
94
+ { tool: "shared_context_write_output", operation: null },
95
+ { tool: "shared_feedback_record", operation: null },
96
+ { tool: "shared_priorities_append", operation: null },
97
+ { tool: "shared_context_cross_signals_run", operation: null },
98
+ { tool: "shared_context_curate_daily", operation: null },
99
+ { tool: "compounding_weekly_synthesize", operation: null },
100
+ { tool: "compounding_promote_candidate", operation: null },
101
+ { tool: "compression_guidelines_optimize", operation: null },
102
+ { tool: "compression_guidelines_activate", operation: null },
103
+ { tool: "memory_search", operation: "memory_search" },
104
+ { tool: "memory_profile", operation: null },
105
+ { tool: "memory_entities_list", operation: null },
106
+ { tool: "memory_questions", operation: null },
107
+ { tool: "memory_last_recall", operation: null },
108
+ { tool: "memory_intent_debug", operation: null },
109
+ { tool: "memory_qmd_debug", operation: null },
110
+ { tool: "memory_graph_explain", operation: null },
111
+ { tool: "graph_snapshot", operation: null },
112
+ { tool: "memory_feedback", operation: null },
113
+ { tool: "memory_promote", operation: null },
114
+ { tool: "memory_outcome", operation: null },
115
+ { tool: "memory_action_apply", operation: null },
116
+ { tool: "context_checkpoint", operation: null },
117
+ { tool: "briefing", operation: null },
118
+ { tool: "review_list", operation: null },
119
+ { tool: "review_resolve", operation: null },
120
+ { tool: "contradiction_scan_run", operation: null },
121
+ { tool: "memory_summarize_hourly", operation: null },
122
+ { tool: "conversation_index_update", operation: null },
123
+ { tool: "profiling_report", operation: null },
124
+ { tool: "graph_edge_decay_run", operation: null },
125
+ { tool: "live_connectors_run", operation: null },
126
+ { tool: "peer_list", operation: null },
127
+ { tool: "peer_get", operation: null },
128
+ { tool: "peer_set", operation: null },
129
+ { tool: "peer_delete", operation: null },
130
+ { tool: "peer_profile_get", operation: null },
131
+ { tool: "peer_forget", operation: null },
132
+ { tool: "console_state", operation: null },
133
+ { tool: "dreams_status", operation: null },
134
+ { tool: "dreams_run", operation: null },
135
+ ];
136
+
137
+ // Each route below corresponds 1:1 to a service-invoking route branch in
138
+ // `EngramAccessHttpServer.handle` (access-http.ts). Pathname patterns use
139
+ // `:param` for path segments. The fitness test asserts each entry resolves
140
+ // against the catalog so a new service route cannot land without either
141
+ // migrating it or acknowledging the unmigrated count. Infrastructure probes
142
+ // (health, adapters, the /mcp delegate, admin console, SSE-only endpoints)
143
+ // carry no user request envelope and are intentionally excluded.
144
+ export const HTTP_ROUTES: readonly HttpRouteEntry[] = [
145
+ { method: "POST", pathname: "/engram/v1/recall", operation: null },
146
+ { method: "POST", pathname: "/engram/v1/coding-context", operation: null },
147
+ { method: "POST", pathname: "/engram/v1/capsules/export", operation: null },
148
+ { method: "POST", pathname: "/engram/v1/capsules/import", operation: null },
149
+ { method: "GET", pathname: "/engram/v1/offline-sync/snapshot", operation: null },
150
+ { method: "GET", pathname: "/engram/v1/offline-sync/snapshot-stream", operation: null },
151
+ { method: "POST", pathname: "/engram/v1/offline-sync/snapshot", operation: null },
152
+ { method: "POST", pathname: "/engram/v1/offline-sync/files", operation: null },
153
+ { method: "POST", pathname: "/engram/v1/offline-sync/file-content", operation: null },
154
+ { method: "POST", pathname: "/engram/v1/offline-sync/apply-file-content", operation: null },
155
+ { method: "POST", pathname: "/engram/v1/offline-sync/apply", operation: null },
156
+ { method: "POST", pathname: "/engram/v1/recall/explain", operation: null },
157
+ { method: "POST", pathname: "/engram/v1/action-confidence", operation: null },
158
+ { method: "GET", pathname: "/engram/v1/recall/tier-explain", operation: null },
159
+ { method: "GET", pathname: "/engram/v1/recall/xray", operation: null },
160
+ { method: "GET", pathname: "/engram/v1/wearables/status", operation: null },
161
+ { method: "POST", pathname: "/engram/v1/wearables/sync", operation: null },
162
+ { method: "GET", pathname: "/engram/v1/wearables/transcript", operation: null },
163
+ { method: "GET", pathname: "/engram/v1/wearables/transcripts/search", operation: null },
164
+ { method: "GET", pathname: "/engram/v1/wearables/memories", operation: null },
165
+ { method: "POST", pathname: "/engram/v1/observe", operation: null },
166
+ { method: "POST", pathname: "/engram/v1/lcm/search", operation: null },
167
+ { method: "POST", pathname: "/engram/v1/lcm/compaction/flush", operation: null },
168
+ { method: "POST", pathname: "/engram/v1/lcm/compaction/record", operation: null },
169
+ { method: "GET", pathname: "/engram/v1/lcm/status", operation: null },
170
+ { method: "POST", pathname: "/engram/v1/memories", operation: "memory_store" },
171
+ { method: "POST", pathname: "/engram/v1/suggestions", operation: null },
172
+ { method: "GET", pathname: "/engram/v1/memories", operation: null },
173
+ { method: "GET", pathname: "/engram/v1/memories/:id", operation: "memory_get" },
174
+ { method: "GET", pathname: "/engram/v1/memories/:id/timeline", operation: null },
175
+ { method: "GET", pathname: "/engram/v1/entities", operation: null },
176
+ { method: "GET", pathname: "/engram/v1/entities/:id", operation: null },
177
+ { method: "GET", pathname: "/engram/v1/review-queue", operation: null },
178
+ { method: "GET", pathname: "/engram/v1/maintenance", operation: null },
179
+ { method: "GET", pathname: "/engram/v1/quality", operation: null },
180
+ { method: "GET", pathname: "/engram/v1/trust-zones/status", operation: null },
181
+ { method: "GET", pathname: "/engram/v1/procedural/stats", operation: null },
182
+ { method: "GET", pathname: "/engram/v1/trust-zones/records", operation: null },
183
+ { method: "POST", pathname: "/engram/v1/review-disposition", operation: null },
184
+ { method: "POST", pathname: "/engram/v1/trust-zones/promote", operation: null },
185
+ { method: "POST", pathname: "/engram/v1/trust-zones/demo-seed", operation: null },
186
+ { method: "POST", pathname: "/v1/citations/observed", operation: null },
187
+ { method: "GET", pathname: "/engram/v1/review/contradictions", operation: null },
188
+ { method: "GET", pathname: "/engram/v1/review/contradictions/:id", operation: null },
189
+ { method: "POST", pathname: "/engram/v1/review/resolve", operation: null },
190
+ { method: "GET", pathname: "/engram/v1/graph/snapshot", operation: null },
191
+ { method: "POST", pathname: "/engram/v1/contradiction-scan", operation: null },
192
+ { method: "GET", pathname: "/engram/v1/graph/events", operation: null },
193
+ { method: "GET", pathname: "/engram/v1/console/state", operation: null },
194
+ { method: "GET", pathname: "/engram/v1/peers", operation: null },
195
+ { method: "GET", pathname: "/engram/v1/peers/:id/profile", operation: null },
196
+ { method: "GET", pathname: "/engram/v1/peers/:id", operation: null },
197
+ { method: "PUT", pathname: "/engram/v1/peers/:id", operation: null },
198
+ { method: "DELETE", pathname: "/engram/v1/peers/:id", operation: null },
199
+ { method: "GET", pathname: "/engram/v1/dreams/status", operation: null },
200
+ { method: "POST", pathname: "/engram/v1/dreams/run", operation: null },
201
+ ];
202
+
203
+ /**
204
+ * Total unmigrated-handler count across both surfaces. The ratchet baseline
205
+ * tracks this number; it may only decrease. `access-surface-catalog.test.ts`
206
+ * recomputes it from the live catalog and asserts equality, so a catalog edit
207
+ * without a baseline bump (or, ideally, a migration) fails the gate.
208
+ */
209
+ export function countUnmigratedHandlers(): number {
210
+ let count = 0;
211
+ for (const entry of MCP_TOOLS) {
212
+ if (entry.operation === null) count += 1;
213
+ }
214
+ for (const entry of HTTP_ROUTES) {
215
+ if (entry.operation === null) count += 1;
216
+ }
217
+ return count;
218
+ }