instar 0.28.102 → 0.28.103

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 (247) hide show
  1. package/.claude/hooks/instar/before-prompt-recall.js +90 -0
  2. package/dist/cli.js +28 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +1 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +14 -1
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/jobMigrate.d.ts +46 -0
  9. package/dist/commands/jobMigrate.d.ts.map +1 -0
  10. package/dist/commands/jobMigrate.js +292 -0
  11. package/dist/commands/jobMigrate.js.map +1 -0
  12. package/dist/commands/server.d.ts.map +1 -1
  13. package/dist/commands/server.js +88 -42
  14. package/dist/commands/server.js.map +1 -1
  15. package/dist/core/BackupManager.d.ts +27 -1
  16. package/dist/core/BackupManager.d.ts.map +1 -1
  17. package/dist/core/BackupManager.js +56 -1
  18. package/dist/core/BackupManager.js.map +1 -1
  19. package/dist/core/GitStateManager.d.ts +8 -0
  20. package/dist/core/GitStateManager.d.ts.map +1 -1
  21. package/dist/core/GitStateManager.js +31 -1
  22. package/dist/core/GitStateManager.js.map +1 -1
  23. package/dist/core/MigratorStepEngine.d.ts +170 -0
  24. package/dist/core/MigratorStepEngine.d.ts.map +1 -0
  25. package/dist/core/MigratorStepEngine.js +352 -0
  26. package/dist/core/MigratorStepEngine.js.map +1 -0
  27. package/dist/core/PostUpdateMigrator.d.ts +76 -0
  28. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  29. package/dist/core/PostUpdateMigrator.js +252 -1
  30. package/dist/core/PostUpdateMigrator.js.map +1 -1
  31. package/dist/core/PreCompactionFlush.d.ts +101 -0
  32. package/dist/core/PreCompactionFlush.d.ts.map +1 -0
  33. package/dist/core/PreCompactionFlush.js +282 -0
  34. package/dist/core/PreCompactionFlush.js.map +1 -0
  35. package/dist/core/PromptBuildRecall.d.ts +97 -0
  36. package/dist/core/PromptBuildRecall.d.ts.map +1 -0
  37. package/dist/core/PromptBuildRecall.js +152 -0
  38. package/dist/core/PromptBuildRecall.js.map +1 -0
  39. package/dist/core/selectIntelligenceProvider.d.ts +41 -0
  40. package/dist/core/selectIntelligenceProvider.d.ts.map +1 -0
  41. package/dist/core/selectIntelligenceProvider.js +89 -0
  42. package/dist/core/selectIntelligenceProvider.js.map +1 -0
  43. package/dist/lifeline/ServerSupervisor.d.ts +183 -0
  44. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  45. package/dist/lifeline/ServerSupervisor.js +443 -0
  46. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  47. package/dist/memory/NativeModuleHealer.d.ts +89 -0
  48. package/dist/memory/NativeModuleHealer.d.ts.map +1 -1
  49. package/dist/memory/NativeModuleHealer.js +371 -1
  50. package/dist/memory/NativeModuleHealer.js.map +1 -1
  51. package/dist/memory/SemanticMemory.d.ts +131 -0
  52. package/dist/memory/SemanticMemory.d.ts.map +1 -1
  53. package/dist/memory/SemanticMemory.js +315 -0
  54. package/dist/memory/SemanticMemory.js.map +1 -1
  55. package/dist/messaging/DeliveryRetryManager.d.ts +60 -0
  56. package/dist/messaging/DeliveryRetryManager.d.ts.map +1 -1
  57. package/dist/messaging/DeliveryRetryManager.js +104 -0
  58. package/dist/messaging/DeliveryRetryManager.js.map +1 -1
  59. package/dist/monitoring/DegradationReporter.d.ts +164 -0
  60. package/dist/monitoring/DegradationReporter.d.ts.map +1 -1
  61. package/dist/monitoring/DegradationReporter.js +309 -1
  62. package/dist/monitoring/DegradationReporter.js.map +1 -1
  63. package/dist/monitoring/ErrorCodeExtractor.d.ts +69 -0
  64. package/dist/monitoring/ErrorCodeExtractor.d.ts.map +1 -0
  65. package/dist/monitoring/ErrorCodeExtractor.js +131 -0
  66. package/dist/monitoring/ErrorCodeExtractor.js.map +1 -0
  67. package/dist/monitoring/PromptGate.d.ts +34 -0
  68. package/dist/monitoring/PromptGate.d.ts.map +1 -1
  69. package/dist/monitoring/PromptGate.js +81 -1
  70. package/dist/monitoring/PromptGate.js.map +1 -1
  71. package/dist/monitoring/Redactor.d.ts +58 -0
  72. package/dist/monitoring/Redactor.d.ts.map +1 -0
  73. package/dist/monitoring/Redactor.js +143 -0
  74. package/dist/monitoring/Redactor.js.map +1 -0
  75. package/dist/monitoring/probes/LifelineProbe.d.ts +7 -0
  76. package/dist/monitoring/probes/LifelineProbe.d.ts.map +1 -1
  77. package/dist/monitoring/probes/LifelineProbe.js +7 -0
  78. package/dist/monitoring/probes/LifelineProbe.js.map +1 -1
  79. package/dist/monitoring/probes/__shared.d.ts +50 -0
  80. package/dist/monitoring/probes/__shared.d.ts.map +1 -0
  81. package/dist/monitoring/probes/__shared.js +51 -0
  82. package/dist/monitoring/probes/__shared.js.map +1 -0
  83. package/dist/remediation/IntentJournal.d.ts +64 -0
  84. package/dist/remediation/IntentJournal.d.ts.map +1 -0
  85. package/dist/remediation/IntentJournal.js +118 -0
  86. package/dist/remediation/IntentJournal.js.map +1 -0
  87. package/dist/remediation/MachineLock.d.ts +137 -0
  88. package/dist/remediation/MachineLock.d.ts.map +1 -0
  89. package/dist/remediation/MachineLock.js +314 -0
  90. package/dist/remediation/MachineLock.js.map +1 -0
  91. package/dist/remediation/PrimaryAggregatorLease.d.ts +205 -0
  92. package/dist/remediation/PrimaryAggregatorLease.d.ts.map +1 -0
  93. package/dist/remediation/PrimaryAggregatorLease.js +450 -0
  94. package/dist/remediation/PrimaryAggregatorLease.js.map +1 -0
  95. package/dist/remediation/RemediationContext.d.ts +63 -0
  96. package/dist/remediation/RemediationContext.d.ts.map +1 -0
  97. package/dist/remediation/RemediationContext.js +109 -0
  98. package/dist/remediation/RemediationContext.js.map +1 -0
  99. package/dist/remediation/RemediationKeyVault.d.ts +123 -0
  100. package/dist/remediation/RemediationKeyVault.d.ts.map +1 -0
  101. package/dist/remediation/RemediationKeyVault.js +564 -0
  102. package/dist/remediation/RemediationKeyVault.js.map +1 -0
  103. package/dist/remediation/Remediator.d.ts +288 -0
  104. package/dist/remediation/Remediator.d.ts.map +1 -0
  105. package/dist/remediation/Remediator.js +520 -0
  106. package/dist/remediation/Remediator.js.map +1 -0
  107. package/dist/remediation/RemediatorBootstrap.d.ts +141 -0
  108. package/dist/remediation/RemediatorBootstrap.d.ts.map +1 -0
  109. package/dist/remediation/RemediatorBootstrap.js +255 -0
  110. package/dist/remediation/RemediatorBootstrap.js.map +1 -0
  111. package/dist/remediation/TrustElevationSource.d.ts +153 -0
  112. package/dist/remediation/TrustElevationSource.d.ts.map +1 -0
  113. package/dist/remediation/TrustElevationSource.js +208 -0
  114. package/dist/remediation/TrustElevationSource.js.map +1 -0
  115. package/dist/remediation/audit/AuditProjection.d.ts +37 -0
  116. package/dist/remediation/audit/AuditProjection.d.ts.map +1 -0
  117. package/dist/remediation/audit/AuditProjection.js +118 -0
  118. package/dist/remediation/audit/AuditProjection.js.map +1 -0
  119. package/dist/remediation/audit/AuditWriter.d.ts +79 -0
  120. package/dist/remediation/audit/AuditWriter.d.ts.map +1 -0
  121. package/dist/remediation/audit/AuditWriter.js +132 -0
  122. package/dist/remediation/audit/AuditWriter.js.map +1 -0
  123. package/dist/remediation/channels/CliApprovalChannel.d.ts +37 -0
  124. package/dist/remediation/channels/CliApprovalChannel.d.ts.map +1 -0
  125. package/dist/remediation/channels/CliApprovalChannel.js +45 -0
  126. package/dist/remediation/channels/CliApprovalChannel.js.map +1 -0
  127. package/dist/remediation/channels/TelegramApprovalChannel.d.ts +37 -0
  128. package/dist/remediation/channels/TelegramApprovalChannel.d.ts.map +1 -0
  129. package/dist/remediation/channels/TelegramApprovalChannel.js +45 -0
  130. package/dist/remediation/channels/TelegramApprovalChannel.js.map +1 -0
  131. package/dist/remediation/runbooks/db-corruption.d.ts +86 -0
  132. package/dist/remediation/runbooks/db-corruption.d.ts.map +1 -0
  133. package/dist/remediation/runbooks/db-corruption.js +190 -0
  134. package/dist/remediation/runbooks/db-corruption.js.map +1 -0
  135. package/dist/remediation/runbooks/messaging-delivery-failed.d.ts +108 -0
  136. package/dist/remediation/runbooks/messaging-delivery-failed.d.ts.map +1 -0
  137. package/dist/remediation/runbooks/messaging-delivery-failed.js +172 -0
  138. package/dist/remediation/runbooks/messaging-delivery-failed.js.map +1 -0
  139. package/dist/remediation/runbooks/node-abi-mismatch.d.ts +70 -0
  140. package/dist/remediation/runbooks/node-abi-mismatch.d.ts.map +1 -0
  141. package/dist/remediation/runbooks/node-abi-mismatch.js +216 -0
  142. package/dist/remediation/runbooks/node-abi-mismatch.js.map +1 -0
  143. package/dist/remediation/runbooks/supervisor-preflight.d.ts +114 -0
  144. package/dist/remediation/runbooks/supervisor-preflight.d.ts.map +1 -0
  145. package/dist/remediation/runbooks/supervisor-preflight.js +299 -0
  146. package/dist/remediation/runbooks/supervisor-preflight.js.map +1 -0
  147. package/dist/scheduler/AgentMdAtomicSave.d.ts +85 -0
  148. package/dist/scheduler/AgentMdAtomicSave.d.ts.map +1 -0
  149. package/dist/scheduler/AgentMdAtomicSave.js +169 -0
  150. package/dist/scheduler/AgentMdAtomicSave.js.map +1 -0
  151. package/dist/scheduler/AgentMdReconcile.d.ts +62 -0
  152. package/dist/scheduler/AgentMdReconcile.d.ts.map +1 -0
  153. package/dist/scheduler/AgentMdReconcile.js +212 -0
  154. package/dist/scheduler/AgentMdReconcile.js.map +1 -0
  155. package/dist/scheduler/DisabledBodyDrift.d.ts +70 -0
  156. package/dist/scheduler/DisabledBodyDrift.d.ts.map +1 -0
  157. package/dist/scheduler/DisabledBodyDrift.js +149 -0
  158. package/dist/scheduler/DisabledBodyDrift.js.map +1 -0
  159. package/dist/scheduler/InstallBuiltinJobs.d.ts +53 -0
  160. package/dist/scheduler/InstallBuiltinJobs.d.ts.map +1 -0
  161. package/dist/scheduler/InstallBuiltinJobs.js +212 -0
  162. package/dist/scheduler/InstallBuiltinJobs.js.map +1 -0
  163. package/dist/scheduler/JobLoader.d.ts.map +1 -1
  164. package/dist/scheduler/JobLoader.js +48 -0
  165. package/dist/scheduler/JobLoader.js.map +1 -1
  166. package/dist/scheduler/MigrationInvariants.d.ts +62 -0
  167. package/dist/scheduler/MigrationInvariants.d.ts.map +1 -0
  168. package/dist/scheduler/MigrationInvariants.js +215 -0
  169. package/dist/scheduler/MigrationInvariants.js.map +1 -0
  170. package/dist/scheduler/MigrationLedger.d.ts +84 -0
  171. package/dist/scheduler/MigrationLedger.d.ts.map +1 -0
  172. package/dist/scheduler/MigrationLedger.js +114 -0
  173. package/dist/scheduler/MigrationLedger.js.map +1 -0
  174. package/dist/server/fileRoutes.d.ts.map +1 -1
  175. package/dist/server/fileRoutes.js +7 -0
  176. package/dist/server/fileRoutes.js.map +1 -1
  177. package/dist/server/routes.d.ts.map +1 -1
  178. package/dist/server/routes.js +141 -0
  179. package/dist/server/routes.js.map +1 -1
  180. package/package.json +3 -2
  181. package/scripts/classify-default-drift.mjs +238 -0
  182. package/scripts/eli16-overview-check.mjs +85 -0
  183. package/scripts/instar-dev-precommit.js +60 -1
  184. package/scripts/lint-degradation-emit-sites.js +116 -0
  185. package/scripts/lint-no-direct-destructive.js +12 -0
  186. package/scripts/protect-migration-guarantee.js +61 -0
  187. package/scripts/regen-default-job-templates.mjs +111 -0
  188. package/scripts/verify-runbook-pr-signature.js +366 -0
  189. package/src/data/builtin-manifest.json +93 -93
  190. package/src/scaffold/bootstrap.ts +138 -0
  191. package/src/scaffold/keys/instar-release-pub.pem +3 -0
  192. package/src/scaffold/templates/jobs/instar/.gitkeep +0 -0
  193. package/src/scaffold/templates/jobs/instar/commitment-detection.md +28 -0
  194. package/src/scaffold/templates/jobs/instar/evolution-overdue-check.md +28 -0
  195. package/src/scaffold/templates/jobs/instar/evolution-proposal-evaluate.md +30 -0
  196. package/src/scaffold/templates/jobs/instar/evolution-proposal-implement.md +25 -0
  197. package/src/scaffold/templates/jobs/instar/health-check.md +14 -0
  198. package/src/scaffold/templates/jobs/instar/identity-review.md +42 -0
  199. package/src/scaffold/templates/jobs/instar/insight-harvest.md +31 -0
  200. package/src/scaffold/templates/jobs/instar/overseer-development.md +23 -0
  201. package/src/scaffold/templates/jobs/instar/overseer-guardian.md +28 -0
  202. package/src/scaffold/templates/jobs/instar/overseer-infrastructure.md +26 -0
  203. package/src/scaffold/templates/jobs/instar/overseer-learning.md +28 -0
  204. package/src/scaffold/templates/jobs/instar/overseer-maintenance.md +27 -0
  205. package/src/scaffold/templates/jobs/instar/reflection-trigger.md +40 -0
  206. package/src/scaffold/templates/jobs/instar/relationship-maintenance.md +16 -0
  207. package/src/scaffold/templates.ts +1616 -0
  208. package/upgrades/0.28.102.md +6 -7
  209. package/upgrades/0.28.103.md +471 -0
  210. package/upgrades/side-effects/a47-primary-aggregator-lease.md +82 -0
  211. package/upgrades/side-effects/agentmd-atomic-save.md +66 -0
  212. package/upgrades/side-effects/agentmd-loader-200jobs-perf-benchmark.md +50 -0
  213. package/upgrades/side-effects/agentmd-reconcile-boot-lifecycle.md +66 -0
  214. package/upgrades/side-effects/api-safety-guard.md +80 -0
  215. package/upgrades/side-effects/c1-runbook-pr-gate.md +83 -0
  216. package/upgrades/side-effects/disabled-body-drift-detection.md +59 -0
  217. package/upgrades/side-effects/drift-classifier-release-time.md +71 -0
  218. package/upgrades/side-effects/eli16-overview-required-gate.md +77 -0
  219. package/upgrades/side-effects/f1-remediation-key-vault.md +195 -0
  220. package/upgrades/side-effects/f2-redactor-errorcode-extractor.md +130 -0
  221. package/upgrades/side-effects/f3-degradation-reporter-shim.md +105 -0
  222. package/upgrades/side-effects/f4-machine-locks-intent-journal-audit.md +117 -0
  223. package/upgrades/side-effects/f5-trust-elevation-source.md +258 -0
  224. package/upgrades/side-effects/f6-supervisor-handshake.md +234 -0
  225. package/upgrades/side-effects/f7-post-update-migrator-atomic-step.md +129 -0
  226. package/upgrades/side-effects/f8-remediator-skeleton.md +153 -0
  227. package/upgrades/side-effects/f8-rest-enforcement.md +72 -0
  228. package/upgrades/side-effects/file-viewer-jobs-instar-never-editable.md +41 -0
  229. package/upgrades/side-effects/frontmatter-interpolation-breakout-test.md +48 -0
  230. package/upgrades/side-effects/jobs-as-agentmd-phase-2.md +78 -0
  231. package/upgrades/side-effects/jobs-as-agentmd-phase-3.md +76 -0
  232. package/upgrades/side-effects/jobs-as-agentmd-phase-4-endpoints.md +62 -0
  233. package/upgrades/side-effects/jobs-as-agentmd-phase-5.md +67 -0
  234. package/upgrades/side-effects/jobs-as-agentmd-phase-6.md +53 -0
  235. package/upgrades/side-effects/jobs-endpoints-auth-verification.md +52 -0
  236. package/upgrades/side-effects/migration-guarantee-suite.md +61 -0
  237. package/upgrades/side-effects/migration-runtime-invariant-gate.md +59 -0
  238. package/upgrades/side-effects/migration-telemetry-invariant-8.md +68 -0
  239. package/upgrades/side-effects/npm-pack-templates-smoke.md +51 -0
  240. package/upgrades/side-effects/openclaw-import-before-prompt-build.md +84 -0
  241. package/upgrades/side-effects/openclaw-import-pre-compaction-flush.md +85 -0
  242. package/upgrades/side-effects/prompt-gate-no-prompt-cache.md +258 -0
  243. package/upgrades/side-effects/tier2-degradation-reporter-live-wire.md +146 -0
  244. package/upgrades/side-effects/w1-node-abi-mismatch-runbook.md +154 -0
  245. package/upgrades/side-effects/w2-supervisor-preflight-runbook.md +176 -0
  246. package/upgrades/side-effects/w3-messaging-delivery-failed-runbook.md +185 -0
  247. package/upgrades/side-effects/w4-db-corruption-runbook.md +114 -0
@@ -30,6 +30,9 @@ import fs from 'node:fs';
30
30
  import path from 'node:path';
31
31
  import os from 'node:os';
32
32
  import { detectJargon } from '../core/JargonDetector.js';
33
+ import { Redactor } from './Redactor.js';
34
+ import { ErrorCodeExtractor } from './ErrorCodeExtractor.js';
35
+ import { SafeFsExecutor } from '../core/SafeFsExecutor.js';
33
36
  /**
34
37
  * Safe fallback template used when the tone gate blocks the candidate
35
38
  * health-alert message. Plain English, ends with a yes/no the user can
@@ -38,6 +41,30 @@ import { detectJargon } from '../core/JargonDetector.js';
38
41
  const SAFE_HEALTH_ALERT_TEMPLATE = 'Something on my end stopped working and I haven\'t been able to fix it on my own. Want me to dig in?';
39
42
  // How long before the same feature can trigger another Telegram alert (ms)
40
43
  const ALERT_COOLDOWN_MS = 60 * 60 * 1000; // 1 hour
44
+ /**
45
+ * Monotonic timestamp source. Prefers `performance.now()` (high-resolution,
46
+ * monotonic across process lifetime). Falls back to `Date.now()` on
47
+ * environments that don't expose it. Returns a Number, not a bigint, so
48
+ * the value JSON-serializes cleanly into the durable queue.
49
+ */
50
+ function monotonicNow() {
51
+ try {
52
+ if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
53
+ return performance.now();
54
+ }
55
+ }
56
+ catch { /* environments without performance API */ }
57
+ return Date.now();
58
+ }
59
+ // Durable RestartPending queue caps (per §A5). When `_setRestartPending(true)`
60
+ // is asserted (e.g., by the lifeline supervisor staging a restart), incoming
61
+ // events are appended to a JSONL queue instead of dispatched immediately.
62
+ // Drop-and-counter on overflow — older events stay on disk, new events past
63
+ // the cap increment a counter and are discarded so the queue can't grow
64
+ // unbounded during a long restart-pending window.
65
+ const RESTART_QUEUE_MAX_ENTRIES = 1000;
66
+ const RESTART_QUEUE_MAX_BYTES = 5 * 1024 * 1024; // 5 MiB
67
+ const RESTART_QUEUE_REL_PATH = path.join('remediation', 'degradations-queue.jsonl');
41
68
  export class DegradationReporter {
42
69
  static instance = null;
43
70
  events = [];
@@ -52,6 +79,24 @@ export class DegradationReporter {
52
79
  healers = new Map();
53
80
  // Dedup: track last alert time per feature to avoid spamming Telegram
54
81
  lastAlertTime = new Map();
82
+ // F-3 additions ─────────────────────────────────────────────
83
+ // The Remediator dispatch hook (F-8 wires the consumer). When set, the
84
+ // legacy `.report(...)` and the new `.reportStructured(...)` both route
85
+ // their normalized events to `remediator.dispatch()` instead of the
86
+ // legacy alert path. When unset, the legacy alert path runs unchanged
87
+ // (backward compat — F-3 ships a shim only, no emit-site migration).
88
+ remediator = null;
89
+ // Centralized redactor for the `reason.full → reason.redacted` step.
90
+ // Lazily instantiated so tests that don't exercise normalization don't pay
91
+ // the (cheap) construction cost.
92
+ redactor = null;
93
+ // RestartPending — when true, events queue to disk instead of dispatching.
94
+ // Flipped by the lifeline supervisor (or test harness) via _setRestartPending.
95
+ restartPending = false;
96
+ // Overflow counter — incremented when the queue cap is hit so we know
97
+ // how many events were dropped during a restart-pending window. Persisted
98
+ // alongside the queue file as a sidecar JSON.
99
+ queueDropCount = 0;
55
100
  constructor() { }
56
101
  static getInstance() {
57
102
  if (!DegradationReporter.instance) {
@@ -104,6 +149,12 @@ export class DegradationReporter {
104
149
  *
105
150
  * This is the primary API. Call this whenever a fallback activates.
106
151
  * If downstream systems aren't ready yet, the event is queued.
152
+ *
153
+ * Per spec §A33 (F-3), legacy `.report(...)` callers continue to work
154
+ * unchanged. Internally the event is normalized via `_normalize()` and
155
+ * either dispatched to the registered Remediator (if `setRemediator()`
156
+ * has been called) or sent through the legacy alert path (backward
157
+ * compat). RestartPending re-routes everything to the durable queue.
107
158
  */
108
159
  report(event) {
109
160
  const full = {
@@ -119,9 +170,157 @@ export class DegradationReporter {
119
170
  ` Impact: ${event.impact}`);
120
171
  this.events.push(full);
121
172
  this.persistToDisk(full);
122
- // Try to report immediately if downstream is connected
173
+ // F-3 path: produce a NormalizedDegradationEvent and either dispatch
174
+ // it to the Remediator (if set) or queue it (if RestartPending).
175
+ const normalized = this._normalize(full);
176
+ if (this.restartPending) {
177
+ this.enqueueRestartPending(normalized);
178
+ return;
179
+ }
180
+ if (this.remediator) {
181
+ // Fire-and-forget — dispatch errors land in console.error but never
182
+ // crash the caller. The legacy `.report(...)` API is sync-shaped.
183
+ this.remediator.dispatch(normalized).catch((err) => {
184
+ console.error(`[DEGRADATION] Remediator dispatch failed for ${full.feature}: ${err instanceof Error ? err.message : err}`);
185
+ });
186
+ return;
187
+ }
188
+ // No Remediator wired — legacy alert path runs unchanged.
123
189
  this.reportEvent(full);
124
190
  }
191
+ /**
192
+ * Report a structured degradation event (F-3 / §A33 go-forward API).
193
+ *
194
+ * Callers that have already produced a NormalizedDegradationEvent (e.g.,
195
+ * via the ErrorCodeExtractor with a verified probe emission) skip the
196
+ * legacy normalization step. The caller's provenance is preserved verbatim
197
+ * — F-3 does NOT downgrade structured callers to `free-text`.
198
+ *
199
+ * Behaviour:
200
+ * - Always logged with `[DEGRADATION-NORMALIZED]` prefix for grep-ability.
201
+ * - If RestartPending → queue to disk.
202
+ * - Else if Remediator wired → dispatch.
203
+ * - Else → no consumer (event is recorded but not alerted). Structured
204
+ * callers must wire the Remediator (F-8) for it to route anywhere; this
205
+ * is intentional, since structured callers bypass the legacy alert path.
206
+ */
207
+ reportStructured(event) {
208
+ const stamped = {
209
+ ...event,
210
+ // Preserve caller-provided timestamp/monotonicTs if present; fill if not.
211
+ timestamp: event.timestamp || new Date().toISOString(),
212
+ monotonicTs: typeof event.monotonicTs === 'number'
213
+ ? event.monotonicTs
214
+ : monotonicNow(),
215
+ };
216
+ console.warn(`[DEGRADATION-NORMALIZED] ${stamped.subsystem}: ${stamped.errorCode} (provenance=${stamped.provenance})`);
217
+ if (this.restartPending) {
218
+ this.enqueueRestartPending(stamped);
219
+ return;
220
+ }
221
+ if (this.remediator) {
222
+ this.remediator.dispatch(stamped).catch((err) => {
223
+ console.error(`[DEGRADATION] Remediator dispatch failed for ${stamped.subsystem}: ${err instanceof Error ? err.message : err}`);
224
+ });
225
+ }
226
+ }
227
+ /**
228
+ * Register the Remediator dispatcher (F-8 wires the consumer). When set,
229
+ * incoming events route to `remediator.dispatch()` instead of the legacy
230
+ * alert path. Passing `null` clears the hook.
231
+ *
232
+ * F-3 only exposes the hook surface — there is no consumer in this PR.
233
+ */
234
+ setRemediator(remediator) {
235
+ this.remediator = remediator;
236
+ }
237
+ /**
238
+ * Internal: convert a legacy `DegradationEvent` into the normalized form.
239
+ * Public for testability — F-8 / downstream consumers should never call
240
+ * this directly. Exposed as `_normalize` (leading underscore) per the
241
+ * project's "private-ish" convention.
242
+ *
243
+ * Mapping (per §A33):
244
+ * feature → subsystem
245
+ * reason → reason.full (and .redacted, via Redactor)
246
+ * errorCode → extracted via ErrorCodeExtractor from free text → 'LEGACY_DEGRADATION' fallback
247
+ * provenance → always 'free-text' (legacy callers are unstructured by definition)
248
+ *
249
+ * §A6 forbids matchers against `free-text` provenance — legacy events
250
+ * therefore route to `no-matching-runbook` once F-8 ships.
251
+ */
252
+ _normalize(legacy) {
253
+ const redactor = this.getRedactor();
254
+ const { text: redacted } = redactor.redact(legacy.reason);
255
+ // Attempt errorCode extraction from the legacy reason. Per §A33 the
256
+ // canonical fallback is the literal 'LEGACY_DEGRADATION' sentinel so
257
+ // downstream observability can count legacy emit-sites distinctly.
258
+ const extracted = ErrorCodeExtractor.extract({ freeText: legacy.reason });
259
+ const errorCode = extracted.code === 'UNKNOWN_ERROR'
260
+ ? 'LEGACY_DEGRADATION'
261
+ : extracted.code;
262
+ return {
263
+ subsystem: legacy.feature,
264
+ errorCode,
265
+ provenance: 'free-text',
266
+ reason: { redacted, full: legacy.reason },
267
+ timestamp: legacy.timestamp,
268
+ monotonicTs: monotonicNow(),
269
+ legacy,
270
+ };
271
+ }
272
+ /**
273
+ * Flip the RestartPending flag. When true, incoming events queue to disk
274
+ * (`<stateDir>/remediation/degradations-queue.jsonl`) instead of being
275
+ * dispatched. When flipped back to false, the queue replays through the
276
+ * normal dispatch path.
277
+ *
278
+ * Caller contract (per §A5): the lifeline supervisor asserts this flag
279
+ * during a staged restart window; flips it off once the restart has
280
+ * completed (or aborted). F-3 exposes the hook; F-8 wires the supervisor.
281
+ */
282
+ _setRestartPending(pending) {
283
+ const prev = this.restartPending;
284
+ this.restartPending = pending;
285
+ if (prev && !pending) {
286
+ // Edge transition true→false: replay queued events.
287
+ this.replayRestartPendingQueue();
288
+ }
289
+ }
290
+ /**
291
+ * Read the durable RestartPending queue file. Public for testability /
292
+ * external observability. Returns an empty array if no queue file exists.
293
+ */
294
+ _readRestartPendingQueue() {
295
+ const queuePath = this.restartQueuePath();
296
+ if (!queuePath || !fs.existsSync(queuePath))
297
+ return [];
298
+ try {
299
+ const raw = fs.readFileSync(queuePath, 'utf-8');
300
+ return raw
301
+ .split('\n')
302
+ .filter(Boolean)
303
+ .map((line) => {
304
+ try {
305
+ return JSON.parse(line);
306
+ }
307
+ catch {
308
+ return null;
309
+ }
310
+ })
311
+ .filter((x) => x !== null);
312
+ }
313
+ catch {
314
+ return [];
315
+ }
316
+ }
317
+ /**
318
+ * How many events were dropped during a RestartPending window because the
319
+ * queue hit its cap. Persists across the queue's lifetime.
320
+ */
321
+ _getQueueDropCount() {
322
+ return this.queueDropCount;
323
+ }
125
324
  /**
126
325
  * Get all degradation events (for health check API).
127
326
  */
@@ -328,6 +527,115 @@ export class DegradationReporter {
328
527
  }
329
528
  }
330
529
  }
530
+ /** Lazily construct the shared Redactor used by `_normalize`. */
531
+ getRedactor() {
532
+ if (!this.redactor)
533
+ this.redactor = new Redactor();
534
+ return this.redactor;
535
+ }
536
+ /**
537
+ * Absolute path to the RestartPending queue JSONL file. Returns null if
538
+ * no stateDir is configured — in that case events are dropped (and counted
539
+ * via `queueDropCount`) since there's nowhere durable to persist them.
540
+ */
541
+ restartQueuePath() {
542
+ if (!this.stateDir)
543
+ return null;
544
+ return path.join(this.stateDir, RESTART_QUEUE_REL_PATH);
545
+ }
546
+ /**
547
+ * Append a normalized event to the durable RestartPending queue. Enforces
548
+ * the §A5 cap (1000 entries / 5 MiB) via drop-and-counter.
549
+ */
550
+ enqueueRestartPending(event) {
551
+ const queuePath = this.restartQueuePath();
552
+ if (!queuePath) {
553
+ // No stateDir → no durable surface → count as dropped so callers can
554
+ // observe the loss via _getQueueDropCount.
555
+ this.queueDropCount += 1;
556
+ return;
557
+ }
558
+ try {
559
+ const dir = path.dirname(queuePath);
560
+ if (!fs.existsSync(dir)) {
561
+ fs.mkdirSync(dir, { recursive: true });
562
+ }
563
+ // Check current size + entry count for the cap.
564
+ let entryCount = 0;
565
+ let byteSize = 0;
566
+ try {
567
+ const stat = fs.statSync(queuePath);
568
+ byteSize = stat.size;
569
+ const raw = fs.readFileSync(queuePath, 'utf-8');
570
+ entryCount = raw.split('\n').filter(Boolean).length;
571
+ }
572
+ catch { /* first write */ }
573
+ const line = JSON.stringify(event) + '\n';
574
+ if (entryCount >= RESTART_QUEUE_MAX_ENTRIES || byteSize + line.length > RESTART_QUEUE_MAX_BYTES) {
575
+ this.queueDropCount += 1;
576
+ // Sidecar drop-count file so it survives across processes.
577
+ try {
578
+ fs.writeFileSync(queuePath + '.drops.json', JSON.stringify({ dropped: this.queueDropCount, ts: new Date().toISOString() }, null, 2));
579
+ }
580
+ catch { /* best-effort */ }
581
+ return;
582
+ }
583
+ fs.appendFileSync(queuePath, line);
584
+ }
585
+ catch (err) {
586
+ // Disk failure inside the durable queue is itself a degradation. Log it
587
+ // and bump the drop counter — the legacy alert path is unavailable
588
+ // during RestartPending so there's nothing else to do.
589
+ console.error(`[DEGRADATION] RestartPending enqueue failed: ${err instanceof Error ? err.message : err}`);
590
+ this.queueDropCount += 1;
591
+ }
592
+ }
593
+ /**
594
+ * Replay the durable queue once `_setRestartPending(false)` fires. Each
595
+ * event is dispatched (or sent through the legacy alert path) in the order
596
+ * it was enqueued; the queue file is then removed on success.
597
+ *
598
+ * Replay is best-effort — if dispatch throws, the queue file is kept on
599
+ * disk so the next replay attempt can retry. Per §A30 the higher-layer
600
+ * Remediator dispatcher owns the 5s wall-time cap and coalescing; F-3
601
+ * does not impose its own.
602
+ */
603
+ replayRestartPendingQueue() {
604
+ const queuePath = this.restartQueuePath();
605
+ if (!queuePath || !fs.existsSync(queuePath))
606
+ return;
607
+ const queued = this._readRestartPendingQueue();
608
+ if (queued.length === 0) {
609
+ // Empty / unreadable — clean up the file.
610
+ try {
611
+ SafeFsExecutor.safeUnlinkSync(queuePath, {
612
+ operation: 'DegradationReporter.replayRestartPendingQueue: empty queue cleanup',
613
+ });
614
+ }
615
+ catch { /* ignore */ }
616
+ return;
617
+ }
618
+ for (const event of queued) {
619
+ if (this.remediator) {
620
+ // Fire-and-forget; replay does not wait for individual dispatches.
621
+ this.remediator.dispatch(event).catch((err) => {
622
+ console.error(`[DEGRADATION] Replay dispatch failed for ${event.subsystem}: ${err instanceof Error ? err.message : err}`);
623
+ });
624
+ }
625
+ else if (event.legacy) {
626
+ // Fall back to the legacy alert path for legacy-shaped queued events.
627
+ this.reportEvent(event.legacy);
628
+ }
629
+ }
630
+ // Truncate the queue file. We don't delete the drop-count sidecar — it
631
+ // records cumulative drops across restart windows.
632
+ try {
633
+ SafeFsExecutor.safeUnlinkSync(queuePath, {
634
+ operation: 'DegradationReporter.replayRestartPendingQueue: drain queue after replay',
635
+ });
636
+ }
637
+ catch { /* ignore */ }
638
+ }
331
639
  persistToDisk(event) {
332
640
  if (!this.stateDir)
333
641
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"DegradationReporter.js","sourceRoot":"","sources":["../../src/monitoring/DegradationReporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DegradationReporter.js","sourceRoot":"","sources":["../../src/monitoring/DegradationReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * ErrorCodeExtractor — structured errorCode extraction with provenance.
3
+ *
4
+ * Owns the contract that NormalizedDegradationEvent.errorCode carries a
5
+ * provenance tag. Per SELF-HEALING-REMEDIATOR-V2-SPEC.md §A6, runbooks
6
+ * may only match against events whose errorCode came from a structured
7
+ * source ("native-binding", "probe-id", "subsystem-explicit"). Free-text
8
+ * extraction is allowed at the event layer (so events aren't dropped)
9
+ * but the registry-load-time validator REFUSES to register any runbook
10
+ * whose eventPrefilter.errorCode matches free-text-provenance events.
11
+ *
12
+ * Extraction priority (highest first):
13
+ * 1. probeEmission with verified signature → "probe-id"
14
+ * 2. subsystemExplicit → "subsystem-explicit"
15
+ * 3. nativeError.code (Node Error.code) → "native-binding"
16
+ * 4. freeText regex extraction → "free-text"
17
+ * 5. Fallback → "UNKNOWN_ERROR" / "free-text"
18
+ *
19
+ * F-2 foundation module — built before any v2 wrapper PR (W-*) so the
20
+ * provenance contract exists before runbook matchers consume it.
21
+ */
22
+ export type ErrorProvenance = 'native-binding' | 'probe-id' | 'subsystem-explicit' | 'free-text';
23
+ export interface ExtractedErrorCode {
24
+ /** Canonical errorCode string, e.g. 'NATIVE_MODULE_ABI_MISMATCH'. */
25
+ code: string;
26
+ /** Where the code came from — gates runbook matching. */
27
+ provenance: ErrorProvenance;
28
+ }
29
+ export interface ProbeEmission {
30
+ probeId: string;
31
+ errorCode: string;
32
+ /** HMAC signature of (probeId|errorCode) — must verify before trust. */
33
+ signature: string;
34
+ }
35
+ export interface ErrorCodeExtractorInput {
36
+ /** The original Error object, if available. */
37
+ nativeError?: unknown;
38
+ /** Probe-supplied errorCode + signature, if probe-emitted. */
39
+ probeEmission?: ProbeEmission;
40
+ /** Subsystem-supplied explicit errorCode, if caller set one. */
41
+ subsystemExplicit?: string;
42
+ /** Free-form error text for fallback regex extraction. */
43
+ freeText?: string;
44
+ /**
45
+ * Probe signature verifier. Injected so tests don't need real HMAC keys.
46
+ * Returns true if the probe emission is trustworthy. If not provided,
47
+ * probe emissions are treated as unverified and skipped (falling through
48
+ * to lower-priority sources). Per A6, only verified probe emissions are
49
+ * allowed to populate provenance: "probe-id".
50
+ */
51
+ verifyProbeSignature?: (emission: ProbeEmission) => boolean;
52
+ }
53
+ export declare class ErrorCodeExtractor {
54
+ /**
55
+ * Extract a single ExtractedErrorCode following the priority ladder
56
+ * documented at the top of this file. Always returns a result — never
57
+ * throws — so callers can normalize unconditionally.
58
+ */
59
+ static extract(input: ErrorCodeExtractorInput): ExtractedErrorCode;
60
+ /**
61
+ * Used by the runbook registry validator to refuse runbooks whose
62
+ * `eventPrefilter.errorCode` could match free-text-provenance events
63
+ * (§A6). Free-text matchers create an injection surface — attacker
64
+ * shapes error message → forces unintended runbook to fire — and are
65
+ * structurally forbidden at registry load.
66
+ */
67
+ static isAllowedForRunbookMatch(extracted: ExtractedErrorCode): boolean;
68
+ }
69
+ //# sourceMappingURL=ErrorCodeExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorCodeExtractor.d.ts","sourceRoot":"","sources":["../../src/monitoring/ErrorCodeExtractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,UAAU,GACV,oBAAoB,GACpB,WAAW,CAAC;AAEhB,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,OAAO,CAAC;CAC7D;AAqDD,qBAAa,kBAAkB;IAC7B;;;;OAIG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,uBAAuB,GAAG,kBAAkB;IA4ClE;;;;;;OAMG;IACH,MAAM,CAAC,wBAAwB,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO;CAOxE"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * ErrorCodeExtractor — structured errorCode extraction with provenance.
3
+ *
4
+ * Owns the contract that NormalizedDegradationEvent.errorCode carries a
5
+ * provenance tag. Per SELF-HEALING-REMEDIATOR-V2-SPEC.md §A6, runbooks
6
+ * may only match against events whose errorCode came from a structured
7
+ * source ("native-binding", "probe-id", "subsystem-explicit"). Free-text
8
+ * extraction is allowed at the event layer (so events aren't dropped)
9
+ * but the registry-load-time validator REFUSES to register any runbook
10
+ * whose eventPrefilter.errorCode matches free-text-provenance events.
11
+ *
12
+ * Extraction priority (highest first):
13
+ * 1. probeEmission with verified signature → "probe-id"
14
+ * 2. subsystemExplicit → "subsystem-explicit"
15
+ * 3. nativeError.code (Node Error.code) → "native-binding"
16
+ * 4. freeText regex extraction → "free-text"
17
+ * 5. Fallback → "UNKNOWN_ERROR" / "free-text"
18
+ *
19
+ * F-2 foundation module — built before any v2 wrapper PR (W-*) so the
20
+ * provenance contract exists before runbook matchers consume it.
21
+ */
22
+ /**
23
+ * Free-text fallback patterns. Order matters — more specific patterns
24
+ * (NODE_MODULE_VERSION, SQLITE_*) run before generic ones so they win.
25
+ *
26
+ * NOTE: matchers consuming free-text-provenance results are refused at
27
+ * registry load (§A6). These patterns exist for observability and for
28
+ * SystemReviewer clustering (proposing new runbooks), not for matching.
29
+ */
30
+ const FREE_TEXT_PATTERNS = [
31
+ {
32
+ // Node native module ABI mismatches surface NODE_MODULE_VERSION first.
33
+ pattern: /NODE_MODULE_VERSION\s+\d+/,
34
+ mapper: () => 'NATIVE_MODULE_ABI_MISMATCH',
35
+ },
36
+ {
37
+ // better-sqlite3 / sqlite3 module errors prefix with SQLITE_*.
38
+ pattern: /SQLITE_([A-Z0-9]+)/,
39
+ mapper: (m) => `SQLITE_${m[1]}`,
40
+ },
41
+ {
42
+ pattern: /\b(EACCES|EPERM)\b/,
43
+ mapper: () => 'PERMISSION_DENIED',
44
+ },
45
+ {
46
+ pattern: /\b(ECONNREFUSED|ECONNRESET)\b/,
47
+ mapper: () => 'CONNECTION_FAILURE',
48
+ },
49
+ ];
50
+ function extractFromFreeText(text) {
51
+ for (const { pattern, mapper } of FREE_TEXT_PATTERNS) {
52
+ const m = pattern.exec(text);
53
+ if (m)
54
+ return mapper(m);
55
+ }
56
+ return 'UNKNOWN_ERROR';
57
+ }
58
+ /**
59
+ * Read a `.code` property off a thrown value if present and string-typed.
60
+ * Node native modules and several stdlib paths set this (`ERR_*`, `EACCES`,
61
+ * etc.). We trust this field because it comes from a structured property,
62
+ * not parsed text — hence provenance: "native-binding".
63
+ */
64
+ function readNativeCode(err) {
65
+ if (err && typeof err === 'object' && 'code' in err) {
66
+ const code = err.code;
67
+ if (typeof code === 'string' && code.length > 0)
68
+ return code;
69
+ }
70
+ return null;
71
+ }
72
+ export class ErrorCodeExtractor {
73
+ /**
74
+ * Extract a single ExtractedErrorCode following the priority ladder
75
+ * documented at the top of this file. Always returns a result — never
76
+ * throws — so callers can normalize unconditionally.
77
+ */
78
+ static extract(input) {
79
+ // 1. Verified probe emission wins. Without a verifier, probe emissions
80
+ // are untrusted (an attacker could shape errorCode by spoofing the
81
+ // probe path) so we fall through to the next source.
82
+ if (input.probeEmission) {
83
+ const verifier = input.verifyProbeSignature;
84
+ if (verifier && verifier(input.probeEmission)) {
85
+ return {
86
+ code: input.probeEmission.errorCode,
87
+ provenance: 'probe-id',
88
+ };
89
+ }
90
+ // Unverified probe emission — skip and try lower-priority sources.
91
+ // We don't trust the emission, but we also don't reject the whole
92
+ // event; the subsystem may still have supplied a structured code.
93
+ }
94
+ // 2. Subsystem-explicit errorCode — caller set this with no string
95
+ // extraction, so we trust the structured source.
96
+ if (typeof input.subsystemExplicit === 'string' && input.subsystemExplicit.length > 0) {
97
+ return {
98
+ code: input.subsystemExplicit,
99
+ provenance: 'subsystem-explicit',
100
+ };
101
+ }
102
+ // 3. Native binding: Error.code from Node native modules.
103
+ const nativeCode = readNativeCode(input.nativeError);
104
+ if (nativeCode) {
105
+ return {
106
+ code: nativeCode,
107
+ provenance: 'native-binding',
108
+ };
109
+ }
110
+ // 4. Free-text fallback. Always free-text provenance, even when a
111
+ // known pattern matches — the input was untrusted parsed text.
112
+ const freeText = typeof input.freeText === 'string' ? input.freeText : '';
113
+ return {
114
+ code: extractFromFreeText(freeText),
115
+ provenance: 'free-text',
116
+ };
117
+ }
118
+ /**
119
+ * Used by the runbook registry validator to refuse runbooks whose
120
+ * `eventPrefilter.errorCode` could match free-text-provenance events
121
+ * (§A6). Free-text matchers create an injection surface — attacker
122
+ * shapes error message → forces unintended runbook to fire — and are
123
+ * structurally forbidden at registry load.
124
+ */
125
+ static isAllowedForRunbookMatch(extracted) {
126
+ return (extracted.provenance === 'native-binding' ||
127
+ extracted.provenance === 'probe-id' ||
128
+ extracted.provenance === 'subsystem-explicit');
129
+ }
130
+ }
131
+ //# sourceMappingURL=ErrorCodeExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorCodeExtractor.js","sourceRoot":"","sources":["../../src/monitoring/ErrorCodeExtractor.ts"],"names":[],"mappings":"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"}
@@ -50,6 +50,27 @@ export declare class InputDetector extends EventEmitter {
50
50
  private static readonly REJECTED_COOLING_MS;
51
51
  /** Track pending LLM detection calls to prevent overlap */
52
52
  private pendingLlmDetection;
53
+ /**
54
+ * NO_PROMPT classification cache: session → bounded set of recent context
55
+ * fingerprints already classified by the LLM as not a blocking prompt.
56
+ *
57
+ * Without this, an idle session showing the same terminal output across every
58
+ * monitor tick re-asks the LLM "is this stuck?" every 5 seconds forever,
59
+ * because the existing rate limit (lastLlmRelay) is only updated on a
60
+ * successful emit. The cache short-circuits that loop: once we've classified
61
+ * a given context as NO_PROMPT, we don't re-classify the identical context.
62
+ * Cache is cleared in onInputSent() and cleanup().
63
+ */
64
+ private noPromptCache;
65
+ private static readonly NO_PROMPT_CACHE_MAX;
66
+ /**
67
+ * Per-session cache generation counter. Incremented whenever the cache is
68
+ * cleared for a session (onInputSent, cleanup). An in-flight llmDetect call
69
+ * captures the generation at start; if it changes before the call's
70
+ * recordNoPrompt write, the write is dropped — we don't want a stale
71
+ * pre-input verdict to repopulate the cache after a clear.
72
+ */
73
+ private cacheGeneration;
53
74
  constructor(config: InputDetectorConfig);
54
75
  /**
55
76
  * Called every monitor tick with captured terminal output.
@@ -82,6 +103,19 @@ export declare class InputDetector extends EventEmitter {
82
103
  * Clean up stale state for a session that has ended.
83
104
  */
84
105
  cleanup(sessionName: string): void;
106
+ /**
107
+ * Record a NO_PROMPT classification for the given session and context
108
+ * fingerprint, evicting the oldest entry if the per-session cache exceeds
109
+ * NO_PROMPT_CACHE_MAX. FIFO is sufficient — these are pure memoizations of
110
+ * an LLM verdict on a specific terminal-output snapshot.
111
+ *
112
+ * Drops the write if the cache generation has advanced since llmDetect
113
+ * started — that means onInputSent or cleanup fired during the LLM call,
114
+ * and our verdict was computed against output the session has now moved
115
+ * past. Without this guard, the post-input cache could get repopulated
116
+ * with a stale pre-input verdict.
117
+ */
118
+ private recordNoPrompt;
85
119
  /**
86
120
  * Prune expired entries from rejectedFingerprints.
87
121
  */