freeharness 0.4.1 → 0.4.3

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 (203) hide show
  1. package/NOTICE +2 -1
  2. package/README.md +24 -19
  3. package/canonical/HARVEST.yaml +27 -16
  4. package/canonical/PROVENANCE.yaml +3 -3
  5. package/canonical/agents/README.md +77 -36
  6. package/canonical/agents/agentic-architect.md +2 -1
  7. package/canonical/agents/database-reviewer.md +6 -8
  8. package/canonical/agents/explorer-ai-engineer-analyst.md +2 -6
  9. package/canonical/agents/implementer.md +30 -0
  10. package/canonical/agents/pr-reviewer.md +9 -11
  11. package/canonical/agents/python-reviewer.md +7 -9
  12. package/canonical/agents/report-formatter.md +7 -3
  13. package/canonical/agents/security-reviewer.md +14 -9
  14. package/canonical/agents/test-writer.md +5 -2
  15. package/canonical/hooks/cost-prices.json +11 -9
  16. package/canonical/hooks/freeharness-config-guard.mjs +4155 -93
  17. package/canonical/hooks/freeharness-context-monitor.mjs +88 -54
  18. package/canonical/hooks/freeharness-converge.mjs +78 -23
  19. package/canonical/hooks/freeharness-cost-tracker.mjs +1116 -218
  20. package/canonical/hooks/freeharness-memory-guard.mjs +20 -23
  21. package/canonical/hooks/freeharness-precompact.mjs +206 -87
  22. package/canonical/hooks/freeharness-quota-tap.mjs +173 -0
  23. package/canonical/hooks/freeharness-reload-context.mjs +197 -0
  24. package/canonical/hooks/freeharness-repeat-tool.mjs +1 -1
  25. package/canonical/hooks/freeharness-sdd-context.mjs +959 -0
  26. package/canonical/hooks/freeharness-session-start +297 -59
  27. package/canonical/hooks/hooks.claude-code.json +1 -1
  28. package/canonical/hooks/hooks.config-guard.claude-code.json +2 -2
  29. package/canonical/hooks/hooks.context-monitor.claude-code.json +1 -1
  30. package/canonical/hooks/hooks.converge.claude-code.json +1 -1
  31. package/canonical/hooks/hooks.memory-guard.claude-code.json +1 -1
  32. package/canonical/hooks/hooks.reload-context.claude-code.json +15 -0
  33. package/canonical/openspec/schema.spec-driven.yaml +29 -8
  34. package/canonical/openspec/templates/follow-ups.md +3 -2
  35. package/canonical/openspec/templates/proposal.md +1 -1
  36. package/canonical/openspec/templates/tasks.md +8 -0
  37. package/canonical/rules/CLAUDE.md +5 -4
  38. package/canonical/rules/routing.md +10 -9
  39. package/canonical/skills/agent-evaluation/SKILL.md +17 -6
  40. package/canonical/skills/agent-evaluation/evals/cases.yaml +38 -23
  41. package/canonical/skills/agentic-architecture/SKILL.md +4 -0
  42. package/canonical/skills/agentic-architecture/evals/cases.yaml +27 -0
  43. package/canonical/skills/code-review/SKILL.md +10 -3
  44. package/canonical/skills/code-review/evals/cases.yaml +1118 -27
  45. package/canonical/skills/git-workflow/SKILL.md +2 -0
  46. package/canonical/skills/local-code/SKILL.md +2 -2
  47. package/canonical/skills/local-code/evals/cases.yaml +1 -1
  48. package/canonical/skills/report-formatting/SKILL.md +10 -2
  49. package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +3 -3
  50. package/canonical/skills/report-formatting/reference/HELPERS.md +10 -5
  51. package/canonical/skills/report-formatting/reference/RELEASE.md +1 -2
  52. package/canonical/skills/report-formatting/reference/TEMPLATES.md +3 -2
  53. package/canonical/skills/report-formatting/reference/authoring.md +25 -37
  54. package/canonical/skills/report-formatting/scripts/build-architecture.js +1 -1
  55. package/canonical/skills/report-formatting/scripts/build-md-claro.js +5 -8
  56. package/canonical/skills/report-formatting/scripts/check-env.js +0 -4
  57. package/canonical/skills/report-formatting/scripts/docmodel.js +3 -11
  58. package/canonical/skills/report-formatting/scripts/example-build.js +8 -10
  59. package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +8 -10
  60. package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +8 -10
  61. package/canonical/skills/report-formatting/scripts/theme-claro.js +39 -10
  62. package/canonical/skills/subagent-driven-development/SKILL.md +35 -28
  63. package/canonical/skills/subagent-driven-development/evals/cases.yaml +3625 -19
  64. package/canonical/skills/subagent-driven-development/reference/brief.md +187 -35
  65. package/canonical/skills/subagent-driven-development/reference/handoff.md +96 -2
  66. package/canonical/skills/subagent-driven-development/reference/loop.md +56 -0
  67. package/canonical/skills/subagent-driven-development/reference/trees.md +40 -0
  68. package/canonical/skills/subagent-driven-development/reference/workspace.md +31 -0
  69. package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +4035 -327
  70. package/dist/adapters/harness/claude-code.d.ts +26 -3
  71. package/dist/adapters/harness/claude-code.js +214 -43
  72. package/dist/adapters/harness/opencode.js +17 -3
  73. package/dist/adapters/harness/plugin.js +28 -17
  74. package/dist/adapters/memory/doctor.d.ts +172 -33
  75. package/dist/adapters/memory/doctor.js +750 -139
  76. package/dist/adapters/memory/migrate.d.ts +95 -0
  77. package/dist/adapters/memory/migrate.js +497 -0
  78. package/dist/adapters/memory/paths.d.ts +15 -0
  79. package/dist/adapters/memory/paths.js +47 -0
  80. package/dist/adapters/memory/vendored.d.ts +52 -30
  81. package/dist/adapters/memory/vendored.js +161 -169
  82. package/dist/adapters/memory/worker-control.d.ts +9 -0
  83. package/dist/adapters/memory/worker-control.js +30 -0
  84. package/dist/adapters/sync/diff.js +4 -1
  85. package/dist/cli/cleanup-prompt.d.ts +35 -0
  86. package/dist/cli/cleanup-prompt.js +68 -0
  87. package/dist/cli/cleanup.d.ts +22 -24
  88. package/dist/cli/cleanup.js +204 -75
  89. package/dist/cli/cost-quota.d.ts +158 -0
  90. package/dist/cli/cost-quota.js +645 -0
  91. package/dist/cli/cost.d.ts +408 -46
  92. package/dist/cli/cost.js +1731 -57
  93. package/dist/cli/doctor.d.ts +52 -13
  94. package/dist/cli/doctor.js +199 -45
  95. package/dist/cli/hard-cleanup.d.ts +93 -0
  96. package/dist/cli/hard-cleanup.js +552 -0
  97. package/dist/cli/install-facts.d.ts +29 -0
  98. package/dist/cli/install-facts.js +68 -0
  99. package/dist/cli/json-key-edit.d.ts +18 -0
  100. package/dist/cli/json-key-edit.js +118 -0
  101. package/dist/cli/memory-import.d.ts +74 -0
  102. package/dist/cli/memory-import.js +469 -0
  103. package/dist/cli/plugin-validate.d.ts +12 -0
  104. package/dist/cli/plugin-validate.js +43 -0
  105. package/dist/cli/profile.d.ts +1 -1
  106. package/dist/cli/profile.js +10 -10
  107. package/dist/cli/uninstall.d.ts +1 -1
  108. package/dist/cli/uninstall.js +2 -2
  109. package/dist/cli/upstream-launchers.d.ts +49 -0
  110. package/dist/cli/upstream-launchers.js +287 -0
  111. package/dist/index.js +252 -73
  112. package/dist/infra/fsutil.d.ts +30 -3
  113. package/dist/infra/fsutil.js +68 -6
  114. package/dist/infra/manifest.d.ts +2 -1
  115. package/dist/infra/manifest.js +3 -2
  116. package/dist/infra/prices.d.ts +18 -0
  117. package/dist/infra/prices.js +64 -0
  118. package/node_modules/@freeharness/core/dist/registry.d.ts +1 -1
  119. package/node_modules/@freeharness/core/dist/registry.js +3 -3
  120. package/node_modules/@freeharness/core/dist/tiers.d.ts +10 -1
  121. package/node_modules/@freeharness/core/dist/tiers.js +24 -2
  122. package/node_modules/@freeharness/core/package.json +1 -1
  123. package/node_modules/@freeharness/sdd/PROVENANCE.yaml +279 -2
  124. package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +34 -8
  125. package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +7 -6
  126. package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +72 -64
  127. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +48 -16
  128. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +168 -70
  129. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +36 -6
  130. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +110 -49
  131. package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +1 -1
  132. package/node_modules/@freeharness/sdd/dist/src/shim/list.js +57 -14
  133. package/node_modules/@freeharness/sdd/dist/src/shim/nested-change.d.ts +7 -0
  134. package/node_modules/@freeharness/sdd/dist/src/shim/nested-change.js +118 -0
  135. package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +3 -1
  136. package/node_modules/@freeharness/sdd/dist/src/shim/proposal-capabilities.d.ts +12 -0
  137. package/node_modules/@freeharness/sdd/dist/src/shim/proposal-capabilities.js +94 -0
  138. package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +17 -0
  139. package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +182 -1
  140. package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +2 -2
  141. package/node_modules/@freeharness/sdd/dist/src/shim/status.js +34 -5
  142. package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +9 -0
  143. package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +49 -41
  144. package/node_modules/@freeharness/sdd/dist/src/shim/warnings.d.ts +21 -0
  145. package/node_modules/@freeharness/sdd/dist/src/shim/warnings.js +66 -0
  146. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/line-endings.d.ts +4 -0
  147. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/line-endings.js +17 -0
  148. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +95 -22
  149. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +6 -0
  150. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +14 -6
  151. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +1 -1
  152. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +1 -1
  153. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +3 -3
  154. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +24 -4
  155. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +4 -7
  156. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +13 -1
  157. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +21 -6
  158. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +80 -19
  159. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +42 -22
  160. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/project-root.d.ts +32 -0
  161. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/project-root.js +39 -0
  162. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +16 -9
  163. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +36 -1
  164. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +65 -30
  165. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +1 -1
  166. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +1 -1
  167. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +8 -13
  168. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +79 -102
  169. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +4 -9
  170. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +50 -10
  171. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +165 -37
  172. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +24 -3
  173. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +55 -8
  174. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +4 -1
  175. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +19 -9
  176. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +10 -0
  177. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +115 -0
  178. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +3 -3
  179. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +20 -20
  180. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +6 -0
  181. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +75 -14
  182. package/node_modules/@freeharness/sdd/package.json +1 -1
  183. package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +47 -7
  184. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +25 -7
  185. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +50 -11
  186. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +48 -10
  187. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +27 -7
  188. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +25 -12
  189. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +17 -5
  190. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +12 -1
  191. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +47 -33
  192. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +17 -5
  193. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +29 -1
  194. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +31 -13
  195. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +75 -27
  196. package/package.json +6 -4
  197. package/provenance/canonical.PROVENANCE.yaml +3 -3
  198. package/provenance/memory.PROVENANCE.yaml +472 -6
  199. package/provenance/sdd.PROVENANCE.yaml +279 -2
  200. package/canonical/hooks/freeharness-auto-memory.mjs +0 -158
  201. package/canonical/hooks/hooks.auto-memory.claude-code.json +0 -16
  202. package/canonical/openspec/config.base.yaml +0 -89
  203. package/canonical/rules/safety.md +0 -41
@@ -1,22 +1,59 @@
1
1
  import { spawnSync } from "node:child_process";
2
+ import { type StageResult } from "./vendored.js";
3
+ import { type MemoryPaths } from "./paths.js";
4
+ import { type StopResult } from "./worker-control.js";
2
5
  export interface CacheVersion {
3
6
  version: string;
4
7
  dir: string;
5
8
  ours: boolean;
6
9
  skills: string[];
7
- /** Found under the upstream (thedotmack/claude-mem) cache root: a previous FreeHarness
8
- * build (pre-rename) or a genuine upstream install, never our current native path. */
10
+ /** Found under the upstream (thedotmack/claude-mem) cache root: a pre-rename FreeHarness
11
+ * build or an upstream install, never our native path. */
9
12
  legacy: boolean;
10
13
  }
14
+ /** What the foreign responder said about itself, already filtered for printing. */
15
+ export interface WorkerFacts {
16
+ pid?: number;
17
+ workerPath: string;
18
+ version: string;
19
+ }
11
20
  export interface WorkerProbe {
12
21
  port: number;
13
22
  reachable: boolean;
14
23
  version?: string;
15
- viewer?: boolean;
24
+ /** Set when reachable: the engine's rule applied to the /api/health answer and the free-mem PID file. */
25
+ identity?: "ours" | "ours-stale" | "foreign";
26
+ /** Set when reachable: `identity !== "foreign"`. */
16
27
  ours?: boolean;
28
+ foreign?: WorkerFacts;
29
+ /** Absent when the worker predates the parked field of /api/health. */
30
+ parked?: ParkedHealth;
31
+ /** Absent when the worker predates the embeddings field of /api/health. */
32
+ embeddings?: EmbeddingsHealth;
17
33
  }
18
- /** Marker in the FreeHarness viewer page served on GET / (plugin/ui/viewer.html). */
19
- export declare const VIEWER_MARKER = "FreeHarness memory";
34
+ /** The `embeddings` field of /api/health: the vector stream of the configured model. */
35
+ export interface EmbeddingsHealth {
36
+ state: "off" | "ready" | "backfilling" | "degraded" | "unreachable";
37
+ reason: "unset" | "refused" | null;
38
+ /** Null while off: none configured, so no model or floor is shown. */
39
+ model: string | null;
40
+ maxDistance: number;
41
+ embedded: number;
42
+ failed: number;
43
+ total: number;
44
+ lastErrorClass: string | null;
45
+ otherModels: {
46
+ model: string;
47
+ count: number;
48
+ }[];
49
+ }
50
+ /** The `parked` field of /api/health: quota-paused sessions whose buffer holds work, in worker memory only. */
51
+ export interface ParkedHealth {
52
+ count: number;
53
+ oldestAgeMs: number | null;
54
+ }
55
+ /** The /api/health product marker of our worker; a test pins it to the engine's and the hooks' copies. */
56
+ export declare const FREE_MEM_PRODUCT = "free-mem";
20
57
  /** Mirror of engine shared/observer-health.ts: warn only after this many consecutive failures. */
21
58
  export declare const OBSERVER_UNHEALTHY_FAILURE_THRESHOLD = 3;
22
59
  /** Mirror of engine shared/quota-cooldown.ts: how long requests are withheld after a quota refusal. */
@@ -111,6 +148,17 @@ export declare function isObserverVerdictStale(ledger: ObserverHealth | null, no
111
148
  export declare function observerLines(s: ObserverStatus, now?: number): string[];
112
149
  /** Highest schema_versions row our vendored SessionStore applies (13.24.0 port; the upstream v50 observed_model/observed_billing migration is telemetry-only and not ported). */
113
150
  export declare const OUR_SCHEMA_VERSION = 49;
151
+ /**
152
+ * Build the schema status line. Upstream and FreeHarness versions are split at 9000 so a
153
+ * FreeHarness migration is never reported as a newer upstream engine. A store that records
154
+ * some FreeHarness versions but not all of them has not finished migrating (a migration
155
+ * rolled back, or the worker predates the update), so the line warns and names each missing
156
+ * version; a store with none was never opened by a FreeHarness worker and keeps the upstream verdict.
157
+ *
158
+ * Returns:
159
+ * The line, or null when the db/sqlite3 is unavailable.
160
+ */
161
+ export declare function schemaVersionLine(dbPath: string, dbName: string): string | null;
114
162
  /** One (window, model) group from the `observations` table. */
115
163
  export interface SpendRow {
116
164
  window: "today" | "seven_day";
@@ -133,18 +181,29 @@ export interface SpendUnavailable {
133
181
  /**
134
182
  * Reads observer spend (observation count and summed `discovery_tokens`) grouped by day
135
183
  * window and `generated_by_model`, through `sqlite3 -readonly` (same invocation shape as
136
- * `dbSchemaVersion`). The seven-day window includes today, matching the running total an
184
+ * `dbSchemaVersions`), plus each model's `consolidation_calls` tokens: consolidation
185
+ * observations carry `discovery_tokens` 0, and the cost-tracker hook's `observerSink` counts
186
+ * the same rows. The seven-day window includes today, matching the running total an
137
187
  * owner reads off `memory status` (not "the other six days").
138
188
  *
139
189
  * Args:
140
190
  * dbPath: Path of claude-mem.db.
141
- * spawn: Injectable spawnSync, so the missing-binary path is deterministic in tests
142
- * regardless of whether sqlite3 happens to be on the test machine's PATH.
191
+ * spawn: Injectable spawnSync, so a test of the missing-binary path does not depend on sqlite3 being on PATH.
143
192
  *
144
193
  * Returns:
145
194
  * One row per (window, model) with a row, or the reason spend could not be read.
146
195
  */
147
196
  export declare function observerSpend(dbPath: string, spawn?: SpawnSyncFn): SpendRow[] | SpendUnavailable;
197
+ /**
198
+ * The capture pipeline and retrieval health as INFO lines: spool backlog and drops,
199
+ * consolidation jobs by status, the rules tier's share of the last 7 days' observations, the
200
+ * search streams, the last gc run, the feedback counts and the parked batches the worker
201
+ * reports. Anything unreadable prints `n/a` rather than failing the report.
202
+ *
203
+ * Args:
204
+ * worker: The /api/health probe; omitted, the worker counts as not answering.
205
+ */
206
+ export declare function pipelineLines(dataDir: string, dbPath: string, spawn?: SpawnSyncFn, worker?: Pick<WorkerProbe, "reachable" | "parked" | "embeddings">): string[];
148
207
  /**
149
208
  * Model ids that name metered Claude spend: the `claude-*` families, a bare tier alias
150
209
  * (`haiku`, `sonnet`, `opus`, alone or with a `-` suffix) and the `$TIER:` placeholder the
@@ -194,6 +253,10 @@ export interface LocalProviderLogSummary {
194
253
  skippedLines: number;
195
254
  /** True when the file exceeded the read cap and only its tail was scanned (see `readLocalProviderLog`'s `maxBytes`). */
196
255
  truncated: boolean;
256
+ /** Batches marked `degraded: true` today, keyed by `tier`; empty when Claude never paused today. */
257
+ degraded: Record<string, number>;
258
+ /** `paused_window` values seen on today's degraded batches, keyed by window name. */
259
+ pausedWindows: Record<string, number>;
197
260
  }
198
261
  /** A present but unreadable batch log (permissions, I/O), distinct from one that does not exist. */
199
262
  export interface LocalProviderLogUnavailable {
@@ -215,7 +278,7 @@ export interface LocalProviderLogUnavailable {
215
278
  *
216
279
  * Returns:
217
280
  * The day's batch/fallback counts and whether the read was truncated; null when the log file
218
- * does not exist yet (a fresh `CLAUDE_MEM_PROVIDER=claude` machine has never written one);
281
+ * does not exist yet (a fresh `FREE_MEM_PROVIDER=claude` machine has never written one);
219
282
  * the reason when the file is there but could not be read, which is a different state from
220
283
  * an absent log and gets its own printed line.
221
284
  */
@@ -252,10 +315,12 @@ export interface DuplicateStats {
252
315
  export declare function observerDuplicateRate(dbPath: string, spawn?: SpawnSyncFn): DuplicateStats | SpendUnavailable;
253
316
  /**
254
317
  * Renders the local-provider log summary and near-duplicate rate as printable INFO lines: the
255
- * batch/fallback line, then the near-duplicate-rate line (omitted when the rate could not be
256
- * read). Nothing at all when `summary` is null (no `local-provider.jsonl` yet); a single WARN
257
- * naming the reason when the log is present but unreadable, so a permission or I/O failure
258
- * never reads like a machine that has not run the local provider.
318
+ * batch/fallback line, the degraded-day line (present only when today has at least one
319
+ * `degraded: true` batch, naming the tier breakdown and the most frequent `paused_window`),
320
+ * then the near-duplicate-rate line (omitted when the rate could not be read). Nothing at all
321
+ * when `summary` is null (no `local-provider.jsonl` yet); a single WARN naming the reason when
322
+ * the log is present but unreadable, so a permission or I/O failure never reads like a machine
323
+ * that has not run the local provider.
259
324
  *
260
325
  * Args:
261
326
  * summary: `readLocalProviderLog`'s return value.
@@ -288,14 +353,14 @@ export declare function effectiveObserverModels(settingsPath: string): Effective
288
353
  /** Which provider the observer actually runs on, and its model when that provider is local. */
289
354
  export interface ObserverProvider {
290
355
  provider: "claude" | "local";
291
- /** `CLAUDE_MEM_LOCAL_MODEL` (or the engine's `local-model` default) when `provider` is
356
+ /** `FREE_MEM_LOCAL_MODEL` (or the engine's `local-model` default) when `provider` is
292
357
  * `local`; null when `provider` is `claude` (no local model is in play). */
293
358
  model: string | null;
294
359
  }
295
360
  /**
296
- * Effective observer provider: `CLAUDE_MEM_PROVIDER` from settings.json (default `claude`; any
361
+ * Effective observer provider: `FREE_MEM_PROVIDER` from settings.json (default `claude`; any
297
362
  * value other than the literal `local` is treated as `claude`, mirroring the engine's own
298
- * `SettingsDefaultsManager` fallback), and when local, the configured `CLAUDE_MEM_LOCAL_MODEL`
363
+ * `SettingsDefaultsManager` fallback), and when local, the configured `FREE_MEM_LOCAL_MODEL`
299
364
  * or the engine's `local-model` default.
300
365
  *
301
366
  * Args:
@@ -306,16 +371,17 @@ export interface ObserverProvider {
306
371
  */
307
372
  export declare function effectiveObserverProvider(settingsPath: string): ObserverProvider;
308
373
  /**
309
- * The FreeHarness-recommended observer settings: a haiku base and simple tier (the daily-spend
310
- * gate), a sonnet summary tier (session summaries read by every future session, worth the
311
- * larger model), the upstream skip list extended with the tools whose decisions matter for
312
- * recall (Read, Glob, Grep and the multi-agent tools), and a concurrency cap of 2. Shared by
313
- * `memory status`'s WARN check and the `memory settings` command.
374
+ * The FreeHarness-recommended observer settings: Haiku on every tier, because the summary tier
375
+ * alone spent 25.4M Sonnet tokens in a week, and the claude provider, because a local provider
376
+ * running beside it doubled the observer work. The skip list extends the upstream one with
377
+ * the read-only and multi-agent tools, which carry no decision worth recording, and
378
+ * concurrency is capped at 2. Shared by `memory status`'s WARN checks and the `memory
379
+ * settings` command.
314
380
  */
315
381
  export declare const RECOMMENDED_OBSERVER_SETTINGS: Record<string, string>;
316
382
  /**
317
383
  * `memory settings --no-local`: the two keys that return the observer to the Claude provider —
318
- * `CLAUDE_MEM_PROVIDER` and `CLAUDE_MEM_SKIP_TOOLS` restored to the recommended default, so the
384
+ * `FREE_MEM_PROVIDER` and `FREE_MEM_SKIP_TOOLS` restored to the recommended default, so the
319
385
  * skip list follows the provider back.
320
386
  */
321
387
  export declare const NO_LOCAL_OBSERVER_SETTINGS: Record<string, string>;
@@ -342,8 +408,8 @@ export interface ObserverSettingsPreview {
342
408
  /**
343
409
  * Previews `memory settings`: the selected key set against the current file, same or
344
410
  * would-change, writing nothing. Plain (no options): the five recommended keys. `--local`:
345
- * `CLAUDE_MEM_PROVIDER` plus the four `CLAUDE_MEM_LOCAL_*` keys plus the narrowed
346
- * `CLAUDE_MEM_SKIP_TOOLS`. `--no-local`: `CLAUDE_MEM_PROVIDER` and `CLAUDE_MEM_SKIP_TOOLS`
411
+ * `FREE_MEM_PROVIDER` plus the four `FREE_MEM_LOCAL_*` keys plus the narrowed
412
+ * `FREE_MEM_SKIP_TOOLS`. `--no-local`: `FREE_MEM_PROVIDER` and `FREE_MEM_SKIP_TOOLS`
347
413
  * restored to the recommended default.
348
414
  *
349
415
  * Args:
@@ -366,7 +432,8 @@ export interface ApplyObserverSettingsResult {
366
432
  }
367
433
  /**
368
434
  * Applies `memory settings`: adds or updates the selected key set (see `previewObserverSettings`
369
- * for which set), preserving every other key, after backing up an existing file first. Refuses
435
+ * for which set) and drops each written key's `CLAUDE_MEM_` twin, preserving every other key,
436
+ * after backing up an existing file first. Refuses
370
437
  * (throws) without writing anything when `opts` fails validation or the existing file is not
371
438
  * valid JSON.
372
439
  *
@@ -399,8 +466,8 @@ export interface MemoryProviderProbe {
399
466
  * Down is a one-line reason, never a throw.
400
467
  *
401
468
  * Args:
402
- * baseUrl: `CLAUDE_MEM_LOCAL_BASE_URL`.
403
- * model: `CLAUDE_MEM_LOCAL_MODEL`.
469
+ * baseUrl: `FREE_MEM_LOCAL_BASE_URL`.
470
+ * model: `FREE_MEM_LOCAL_MODEL`.
404
471
  * timeoutMs: The whole probe's deadline (both requests together).
405
472
  *
406
473
  * Returns:
@@ -409,7 +476,7 @@ export interface MemoryProviderProbe {
409
476
  export declare function probeMemoryProvider(baseUrl: string, model: string, timeoutMs?: number): Promise<MemoryProviderProbe>;
410
477
  /**
411
478
  * The `memory provider` doctor line: only when the data dir's settings.json sets
412
- * `CLAUDE_MEM_PROVIDER=local`, a probe of the configured base URL and model, OK or WARN with
479
+ * `FREE_MEM_PROVIDER=local`, a probe of the configured base URL and model, OK or WARN with
413
480
  * the reason; absent or `claude` prints nothing.
414
481
  *
415
482
  * Args:
@@ -422,13 +489,26 @@ export declare function probeMemoryProvider(baseUrl: string, model: string, time
422
489
  export declare function memoryProviderLines(settingsPath: string, probe?: (baseUrl: string, model: string, timeoutMs?: number) => Promise<MemoryProviderProbe>): Promise<string[]>;
423
490
  /** Resolve $CLAUDE_CONFIG_DIR or ~/.claude. */
424
491
  export declare function configDir(): string;
425
- /** Mirror engine shared/paths.ts resolveDataDir (env, then settings.json, then default). */
492
+ /** The engine's data directory and database for this process. */
493
+ export declare function memoryPaths(): MemoryPaths;
426
494
  export declare function dataDir(): string;
495
+ /** One WARN per ignored `CLAUDE_MEM_*` variable in `env` and key in the settings file, naming its replacement. */
496
+ export declare function deprecatedNameLines(env: Record<string, string | undefined>, settingsPath: string): string[];
497
+ /** A WARN while a legacy database sits beside a free-mem store with no observation: the worker creates
498
+ * an empty store at its first start, so existence cannot silence it; an unreadable store stays silent. */
499
+ export declare function legacyHomeLines(env: Record<string, string | undefined>, home: string, spawn?: SpawnSyncFn): string[];
500
+ /** Engine worker port: env, then settings.json, then 37700 + uid % 100. */
501
+ export declare function workerPort(dir: string): number;
502
+ /** One WARN while the upstream plugin is still registered: both workers bind the same port. */
503
+ export declare function upstreamLines(cfg: string, port: number): string[];
504
+ /** Steps that clear a reachable foreign worker, else null; no-pid fallback as in foreignWorkerLine. */
505
+ export declare function foreignWorkerStep(worker: WorkerProbe): string | null;
427
506
  /**
428
507
  * Diagnose which claude-mem is active.
429
508
  *
430
509
  * Returns:
431
- * A MemoryDiagnosis with a verdict and printable lines (OK/WARN prefixed).
510
+ * A MemoryDiagnosis with a verdict and printable lines (OK/WARN/INFO prefixed; FAIL for a
511
+ * foreign worker on the memory port).
432
512
  */
433
513
  export declare function diagnoseMemory(): Promise<MemoryDiagnosis>;
434
514
  /**
@@ -461,20 +541,79 @@ export interface RestartResult {
461
541
  * What was (or would be) done.
462
542
  */
463
543
  export declare function restartWorker(dryRun: boolean, diagnosis?: MemoryDiagnosis): Promise<RestartResult>;
544
+ /**
545
+ * Stops the worker without starting another, then waits until its pid file names no live process
546
+ * and its port is closed.
547
+ * @param mode Only `shutdown`.
548
+ * @param opts Data dir and port (the resolved ones by default) and the wait bound in ms.
549
+ * @returns Whether it stopped, whether one was running, and the reason on timeout.
550
+ */
551
+ export declare function stopWorker(mode: "shutdown", opts?: {
552
+ dir?: string;
553
+ port?: number;
554
+ timeoutMs?: number;
555
+ }): Promise<StopResult>;
556
+ /** Whether a worker answers on the data dir's worker port right now. */
557
+ export declare function workerRunning(): Promise<boolean>;
558
+ /** The engine's log file for a day, where a failed worker start leaves its reason. */
559
+ export declare function workerLogPath(now?: Date): string;
560
+ /** Restart decision after a plugin-cache stage; `error` and `log` never fail the command. */
561
+ export interface StageRestart {
562
+ planned: boolean;
563
+ reason: string;
564
+ result?: RestartResult;
565
+ error?: string;
566
+ log?: string;
567
+ }
568
+ /**
569
+ * Restart a worker that was running before the command when the command staged a different build
570
+ * or stopped that worker itself; a worker that was not running stays stopped. A failed
571
+ * restart, including a launched worker that never answers health or an old worker that never
572
+ * gives way to a new one, is reported, never thrown.
573
+ *
574
+ * Args:
575
+ * wasRunning: Whether a worker answered before the command changed anything.
576
+ * cause: Whether the command staged a build or stopped the worker.
577
+ * dryRun: Report only.
578
+ * healthMs: How long a launched worker has to answer `/api/health`.
579
+ *
580
+ * Returns:
581
+ * The decision and, on apply, its outcome.
582
+ */
583
+ export declare function restartAfterStage(wasRunning: boolean, cause: {
584
+ staged: boolean;
585
+ stopped?: boolean;
586
+ }, dryRun: boolean, healthMs?: number): Promise<StageRestart>;
464
587
  export interface ActivateResult {
465
588
  stoppedWorker: boolean;
466
589
  disabled: string[];
467
590
  registered: boolean;
591
+ stage?: StageResult & {
592
+ cacheDir: string;
593
+ version: string;
594
+ };
595
+ /** The staging notes, or why the cached build is registered as is. */
596
+ stageNotes: string[];
597
+ restart: StageRestart;
468
598
  }
469
599
  /**
470
- * Make the FreeHarness build the only active claude-mem: stop a running worker, move
471
- * foreign cache versions aside (never deleted), point installed_plugins at ours.
600
+ * Make the FreeHarness build the only active claude-mem: stage the vendored build when it is
601
+ * built and differs from the cache, stop a running worker, move foreign cache versions aside
602
+ * (never deleted), point installed_plugins at ours, and restart the worker it stopped.
603
+ * Staging runs first, so a staging failure leaves a running worker up.
472
604
  *
473
605
  * Args:
474
606
  * dryRun: Report only.
607
+ * opts: The vendored plugin dir; without it the newest cached build is registered as is.
475
608
  *
476
609
  * Returns:
477
610
  * What was (or would be) done.
611
+ *
612
+ * Raises:
613
+ * Error: When the cache holds no FreeHarness build, the plugin version is not semver, staging
614
+ * fails, or deps need a missing Bun (refused before any cache write).
478
615
  */
479
- export declare function activateOurs(dryRun: boolean): Promise<ActivateResult>;
616
+ export declare function activateOurs(dryRun: boolean, opts?: {
617
+ pluginDir?: string;
618
+ }): Promise<ActivateResult>;
480
619
  export {};