memhtml 0.2.1 → 0.2.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.
package/README.md CHANGED
@@ -410,7 +410,7 @@ envelope. `docs/code-mode.md` is the cookbook, with a measured helper and five r
410
410
  | MemoryAgentBench FactConsolidation single-hop (26KB to 1.1MB stores) | 92% to 97% | ~60% at 26KB only |
411
411
  | MemoryAgentBench FactConsolidation multi-hop | 37% to 49% | ≤7% all methods |
412
412
  | BEAM Contradiction Resolution (100K split, 40 probes) | 43.8% mean | 0% to 5% all systems |
413
- | LongMemEval-S (25-instance smoke) | 68% | ~55% to 65% typical agent baselines |
413
+ | LongMemEval-S (full 500, judged 2026-08-07) | 67.0% | ~55% to 65% typical agent baselines |
414
414
 
415
415
  Read the cross-judge numbers as reference points rather than as a ranking: the judges here are verbatim
416
416
  prompt ports running haiku-4.5, where the papers used gpt-4o and gpt-4.1-mini. `ROADMAP.md` carries these
@@ -422,7 +422,7 @@ numbers and the horizons they rank.
422
422
  $MEMHTML_ROOT/ # its own git repo, one global memory store
423
423
  projects/<workspace-slug>/ # a workspace IS a directory. There is no workspaces table.
424
424
  areas/<area-slug>/ # ongoing responsibilities
425
- areas/arcs/ # behavioural arcs (system-written by sleep only)
425
+ areas/arcs/ # behavioral arcs (system-written by sleep only)
426
426
  areas/inbox/ # where an unplaceable memory lands
427
427
  resources/<topic>/
428
428
  resources/people/<person>.html # the person plane
@@ -441,10 +441,12 @@ The layering is strict and TypeScript project references enforce it. `@memhtml/c
441
441
  `@memhtml/domain` import `effect` and nothing else, and a test reads `domain`'s own `dist` to confirm it
442
442
  names no database driver, no SDK, and no `node:fs`.
443
443
 
444
- None of them is published. All twelve are `private`, and `mise run package:assemble` bundles them into
445
- the single `memhtml` package that carries the two binaries so the table below is a map of the source,
446
- not a list of things to install. `RELEASING.md` covers how the artifact is built and what must stay
447
- outside the bundle.
444
+ None of them is published. Every workspace package is `private`, and `mise run package:assemble`
445
+ bundles the libraries and the binary-bearing apps into the single `memhtml` package that carries the
446
+ two binaries the docs site and the integration-test harness stay outside the bundle
447
+ (`tsdown.config.ts` names the exact set). The table below is a map of the source, not a list of
448
+ things to install. `RELEASING.md` covers how the artifact is built and what must stay outside the
449
+ bundle.
448
450
 
449
451
  | Package | What it owns |
450
452
  |---|---|
@@ -459,6 +461,8 @@ outside the bundle.
459
461
  | `@memhtml/eval` | The fixture corpus generator and the refusable discrimination gate. |
460
462
  | `@memhtml/cli` | The `memhtml` binary, the envelope contract, and the one composition root. |
461
463
  | `@memhtml/mcp` | The `memhtml-mcp` stdio server: 14 tools, 2 resources. |
464
+ | `@memhtml/consolidator` | The sandboxed eve agent that distills candidate memories from raw transcripts. |
465
+ | `@memhtml/docs` | The documentation site. |
462
466
 
463
467
  ## Development
464
468
 
@@ -35,7 +35,7 @@ import { runVerifierConfig } from "../../src/run-auth.js"
35
35
  * and eve rejects a token with no `sub` before consulting any matcher. That is what keeps a secret
36
36
  * leaked into some other eve app's environment from cross-authenticating here.
37
37
  *
38
- * ## The bind address STAYS, as defence in depth
38
+ * ## The bind address STAYS, as defense in depth
39
39
  *
40
40
  * `eve start` binds ALL INTERFACES by default (node_modules/eve/docs/reference/cli.md, `eve start
41
41
  * --host`), so `src/client.ts` still spawns with `--host 127.0.0.1` from a constant that takes no
@@ -1,3 +1,3 @@
1
- import { A as MAX_QUOTE_CHARS, C as ConsolidationResult, D as ConsolidatorUnavailable, E as ConsolidatorRunFailed, F as toJsonSchema, I as ungroundedEvidenceReason, M as credentialsMissingReason, N as hasConsolidatorCredentials, O as MAX_CLAIM_CHARS, P as isConsolidationKind, S as ConsolidationPayload, T as ConsolidatorCredentialsMissing, _ as readOnlyRootsProblem, a as RUN_SECRET_ENV, b as CandidateEvidence, c as runVerifierConfig, d as SANDBOX_MOUNTS_ENV, f as SandboxMountInvalid, g as pinCorpusSnapshot, h as mountReadOnlyRoots, i as makeConsolidator, j as MAX_TRANSCRIPTS_PER_RUN, k as MAX_GIST_CHARS, l as sameRunSecret, m as encodeSandboxMounts, n as consolidatorLive, o as mintRunSecret, p as decodeSandboxMounts, r as guestPathFor, s as runSecretFrom, t as Consolidator, u as signRunToken, v as CONSOLIDATION_KINDS, w as ConsolidatorContractViolation, x as CandidateMemory, y as CONSOLIDATION_OUTPUT_JSON_SCHEMA } from "./dist-DUuomISL.mjs";
1
+ import { A as MAX_QUOTE_CHARS, C as ConsolidationResult, D as ConsolidatorUnavailable, E as ConsolidatorRunFailed, F as toJsonSchema, I as ungroundedEvidenceReason, M as credentialsMissingReason, N as hasConsolidatorCredentials, O as MAX_CLAIM_CHARS, P as isConsolidationKind, S as ConsolidationPayload, T as ConsolidatorCredentialsMissing, _ as readOnlyRootsProblem, a as RUN_SECRET_ENV, b as CandidateEvidence, c as runVerifierConfig, d as SANDBOX_MOUNTS_ENV, f as SandboxMountInvalid, g as pinCorpusSnapshot, h as mountReadOnlyRoots, i as makeConsolidator, j as MAX_TRANSCRIPTS_PER_RUN, k as MAX_GIST_CHARS, l as sameRunSecret, m as encodeSandboxMounts, n as consolidatorLive, o as mintRunSecret, p as decodeSandboxMounts, r as guestPathFor, s as runSecretFrom, t as Consolidator, u as signRunToken, v as CONSOLIDATION_KINDS, w as ConsolidatorContractViolation, x as CandidateMemory, y as CONSOLIDATION_OUTPUT_JSON_SCHEMA } from "./dist-t84Q_98w.mjs";
2
2
 
3
3
  export { CONSOLIDATION_KINDS, CONSOLIDATION_OUTPUT_JSON_SCHEMA, CandidateEvidence, CandidateMemory, ConsolidationPayload, ConsolidationResult, Consolidator, ConsolidatorContractViolation, ConsolidatorCredentialsMissing, ConsolidatorRunFailed, ConsolidatorUnavailable, MAX_CLAIM_CHARS, MAX_GIST_CHARS, MAX_QUOTE_CHARS, MAX_TRANSCRIPTS_PER_RUN, RUN_SECRET_ENV, SANDBOX_MOUNTS_ENV, SandboxMountInvalid, consolidatorLive, credentialsMissingReason, decodeSandboxMounts, encodeSandboxMounts, guestPathFor, hasConsolidatorCredentials, isConsolidationKind, makeConsolidator, mintRunSecret, mountReadOnlyRoots, pinCorpusSnapshot, readOnlyRootsProblem, runSecretFrom, runVerifierConfig, sameRunSecret, signRunToken, toJsonSchema, ungroundedEvidenceReason };
@@ -1,4 +1,4 @@
1
- import { $ as MEMORY_EXTENSION, B as ModelUnavailable, Ct as slugify, H as StorageFailure, J as relClassFor, L as DirtyTree, Q as INBOX_DIR, R as InvalidMemory, St as filenameFor, U as WriteConflict, V as PathNotFound, W as EdgeRel, X as relTokenFor, Y as relForToken, Z as ARCS_DIR, _t as TaskStatus, at as memoryPathFor, bt as parseEntity, ct as placementFor, dt as MEMORY_TYPES, et as PEOPLE_DIR, ft as MemoryStatus, gt as TASK_STATUSES, ht as PERSON_ENTITY_PREFIX, it as isValidMemoryPath, lt as Confidence, mt as PARA_BUCKETS, nt as archivePathFor, ot as normalizePath, pt as MemoryType, q as isEdgeRel, rt as isArchivePath, st as paraBucketOf, ut as Importance, vt as WRITABLE_MEMORY_TYPES, wt as withCollisionOrdinal, xt as SLUG_FALLBACK, yt as isTaskStatus, z as LlmContractViolation } from "./dist-DUuomISL.mjs";
1
+ import { $ as MEMORY_EXTENSION, B as ModelUnavailable, Ct as slugify, H as StorageFailure, J as relClassFor, L as DirtyTree, Q as INBOX_DIR, R as InvalidMemory, St as filenameFor, U as WriteConflict, V as PathNotFound, W as EdgeRel, X as relTokenFor, Y as relForToken, Z as ARCS_DIR, _t as TaskStatus, at as memoryPathFor, bt as parseEntity, ct as placementFor, dt as MEMORY_TYPES, et as PEOPLE_DIR, ft as MemoryStatus, gt as TASK_STATUSES, ht as PERSON_ENTITY_PREFIX, it as isValidMemoryPath, lt as Confidence, mt as PARA_BUCKETS, nt as archivePathFor, ot as normalizePath, pt as MemoryType, q as isEdgeRel, rt as isArchivePath, st as paraBucketOf, ut as Importance, vt as WRITABLE_MEMORY_TYPES, wt as withCollisionOrdinal, xt as SLUG_FALLBACK, yt as isTaskStatus, z as LlmContractViolation } from "./dist-t84Q_98w.mjs";
2
2
  import { createRequire } from "node:module";
3
3
  import { Config, Context, Effect, Layer, Result, Schedule, Schema } from "effect";
4
4
  import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
@@ -327,7 +327,7 @@ const pagerank = (nodes, edges, options = {}) => {
327
327
  * Communities by label propagation over the edge list read as undirected.
328
328
  *
329
329
  * Deterministic in place of a seed: nodes start labelled by themselves, sweeps visit them in
330
- * sorted order, and a node adopts the highest-weighted neighbouring label with the
330
+ * sorted order, and a node adopts the highest-weighted neighboring label with the
331
331
  * lexicographically smallest label breaking a tie. The returned labels are canonicalized to
332
332
  * the smallest member path of each community, so the partition itself is reproducible and not
333
333
  * only the grouping.
@@ -340,15 +340,15 @@ const labelPropagation = (nodes, edges, options = {}) => {
340
340
  const { sorted, folded } = normalize$1(nodes, edges);
341
341
  const minSize = options.minCommunitySize ?? 3;
342
342
  const maxSweeps = options.maxSweeps ?? 100;
343
- const neighbours = /* @__PURE__ */ new Map();
343
+ const neighbors = /* @__PURE__ */ new Map();
344
344
  const link = (from, to, strength) => {
345
- const bucket = neighbours.get(from);
345
+ const bucket = neighbors.get(from);
346
346
  const edge = {
347
347
  src: from,
348
348
  dst: to,
349
349
  strength
350
350
  };
351
- if (bucket === void 0) neighbours.set(from, [edge]);
351
+ if (bucket === void 0) neighbors.set(from, [edge]);
352
352
  else bucket.push(edge);
353
353
  };
354
354
  for (const edge of folded) {
@@ -360,7 +360,7 @@ const labelPropagation = (nodes, edges, options = {}) => {
360
360
  let changed = false;
361
361
  for (const node of sorted) {
362
362
  const weightByLabel = /* @__PURE__ */ new Map();
363
- for (const edge of neighbours.get(node) ?? []) {
363
+ for (const edge of neighbors.get(node) ?? []) {
364
364
  const label = labels.get(edge.dst);
365
365
  if (label === void 0) continue;
366
366
  weightByLabel.set(label, (weightByLabel.get(label) ?? 0) + edge.strength);
@@ -1874,7 +1874,7 @@ const buildProbes = (base, wanted) => {
1874
1874
  * the cosine. Measured before this was fixed: the kit-free control took FTS rank 1 and vector
1875
1875
  * rank 3 while its target sat at 4 and 10, on 22 of 36 probes. The gate was failing on
1876
1876
  * document length instead of on the fact. A control that wins by being terser proves nothing
1877
- * about discrimination, and a fold that "fixed" it would be tuned against an artefact.
1877
+ * about discrimination, and a fold that "fixed" it would be tuned against an artifact.
1878
1878
  *
1879
1879
  * With the kit copied, the pair differs by exactly the flipped token, which is the
1880
1880
  * high-cosine wrong-fact adversary design §5 asks for.
@@ -1956,7 +1956,7 @@ const ACCESSED_FRACTION = .6;
1956
1956
  * happens to be some probe's control.
1957
1957
  * 2. **The spread is QUERY-BLIND.** It is a function of the corpus seed and the path order. Nothing
1958
1958
  * here reads the probe list, so a target's history is whatever its position in the corpus earns it.
1959
- * A spread that favoured targets would make the gate pass by construction.
1959
+ * A spread that favored targets would make the gate pass by construction.
1960
1960
  *
1961
1961
  * The distribution is a long tail, `1 / (floor + jitter)`, because that is the shape retrieval traffic
1962
1962
  * has: a handful of memories are read constantly and most are read once. A uniform count would make
@@ -2928,11 +2928,15 @@ const articleOf = (document) => {
2928
2928
  * 24.4%. Both numbers are recorded because the measured one is the evidence and the deployed one
2929
2929
  * is the decision.
2930
2930
  *
2931
- * DETERMINISM. highlight.js is pinned EXACTLY (`11.11.1`, no caret) in this package's
2931
+ * DETERMINISM. highlight.js is pinned EXACTLY (`11.11.2`, no caret) in this package's
2932
2932
  * `package.json`, because relevance scores are grammar-dependent: a version bump silently moves
2933
2933
  * every confidence, and therefore which fences get stamped. The contract is "same input + same
2934
2934
  * pinned version → same stamp". A bump is a deliberate decision that RE-RUNS the eval and
2935
- * re-derives the threshold, not a routine dependency refresh.
2935
+ * re-derives the threshold, not a routine dependency refresh. Measured against 11.12.0 on
2936
+ * 2026-08-18, which is the size of "silently": `slice:example-service/mise.toml@42+9` fell 0.5406
2937
+ * to 0.1993 and stopped stamping `toml`, and one python row stopped stamping — coverage lost with
2938
+ * no evidence about precision, because the 332-snippet corpus that measured it lives in
2939
+ * `memhtml-evals`, not here. `.github/dependabot.yml` holds minor and major back for that reason.
2936
2940
  *
2937
2941
  * WRITE TIME ONLY. Detection runs on the write path and the result is stamped into the file, which
2938
2942
  * is the system of record. Index rebuild reads `data-lang` back (`parse.ts`) and never re-detects,
@@ -4299,7 +4303,7 @@ const text = (result) => result.stdout.toString("utf8");
4299
4303
  /**
4300
4304
  * The service against a repository root. Exported rather than only wrapped in a layer, because every
4301
4305
  * test in this package drives the real git binary against a temp-dir repo. A fake git
4302
- * verifies the shape of these calls and not git's own behaviour, and it is git's behaviour
4306
+ * verifies the shape of these calls and not git's own behavior, and it is git's behavior
4303
4307
  * (rename detection, index staging, merge conflict stages) that this package exists to use.
4304
4308
  */
4305
4309
  const makeGit = (root) => ({
@@ -4657,7 +4661,7 @@ const subjectFor = (pending) => pending.length === 1 && pending[0] !== void 0 ?
4657
4661
  const hasProvenance = (entry) => Object.keys(provenanceTrailers(entry.input)).length > 0;
4658
4662
  /**
4659
4663
  * The store over a git service. Exported so tests build it against a temp-dir repo with the
4660
- * real git binary. This package's job IS git's behaviour, so a fake git would verify only that
4664
+ * real git binary. This package's job IS git's behavior, so a fake git would verify only that
4661
4665
  * the right strings were assembled and would miss every state transition that matters.
4662
4666
  */
4663
4667
  const makeStore = (git, hooks = {}) => {
@@ -5995,7 +5999,7 @@ const IndexGit = Context.Service("memhtml/IndexGit");
5995
5999
  * `onExcessProperty: "error"` means a column added to the SELECT without being added here is a
5996
6000
  * decode failure, not a silently ignored field. Probed 2026-08-12 on node 24.19.0: `node:sqlite`
5997
6001
  * hands back null-prototype records and `Schema.decodeUnknownEffect` reads them correctly, so the
5998
- * driver's row objects need no normalisation at this seam.
6002
+ * driver's row objects need no normalization at this seam.
5999
6003
  */
6000
6004
  /**
6001
6005
  * Every column of `index_state`, in the order `0007_watermark.sql` declares them.
@@ -7260,7 +7264,7 @@ const assembleScope = (scope = {}) => {
7260
7264
  const types = (scope.memoryTypes ?? []).filter((type) => MEMORY_TYPES.includes(type));
7261
7265
  if (types.length > 0)
7262
7266
  /**
7263
- * A caller-named type list is honoured VERBATIM, `task` included. Filtering `task` back out of
7267
+ * A caller-named type list is honored VERBATIM, `task` included. Filtering `task` back out of
7264
7268
  * an explicit list would make the opt-in unreachable, and there would then be no way to search
7265
7269
  * tasks at all. The exclusion is a default and not a firewall. (The firewalls in this system are
7266
7270
  * `edge_class` and the trace tables, and both reject a write rather than defaulting.)
@@ -7856,7 +7860,7 @@ const modelFailure = (modelId, cause) => ModelUnavailable.make({
7856
7860
  * One InvokeModel round trip: send the body, decode the JSON payload. Both the transport
7857
7861
  * rejection and an unparseable payload land on `ModelUnavailable`, because neither one
7858
7862
  * says anything about the model's answer. They say only that no answer arrived. Reading
7859
- * the answer, and judging whether it honours its contract, is the caller's job.
7863
+ * the answer, and judging whether it honors its contract, is the caller's job.
7860
7864
  */
7861
7865
  const invokeJson = (client, modelId, body) => Effect.gen(function* () {
7862
7866
  const response = yield* Effect.tryPromise({
@@ -8924,7 +8928,7 @@ const ArcPlanEntry = Schema.Struct({
8924
8928
  * slug would be a model-chosen file path.
8925
8929
  */
8926
8930
  slug: Schema.String,
8927
- /** A concise behavioural-principal name, 3-8 words. */
8931
+ /** A concise behavioral-principal name, 3-8 words. */
8928
8932
  title: Schema.String,
8929
8933
  action: ArcAction,
8930
8934
  /** One or two sentences naming what changed or emerged. */
@@ -8969,34 +8973,34 @@ memory, so when the two claims COULD both be true — different scope, different
8969
8973
  aspect — answer neutral, not contradicts. Rate your confidence honestly and name the specific
8970
8974
  conflicting or compatible claims in the rationale.`;
8971
8975
  /** The arc-triage system prompt: plan only, no content. */
8972
- const ARC_TRIAGE_SYSTEM = `You triage behavioural arcs for an AI agent's long-term memory system. This is the planning pass:
8976
+ const ARC_TRIAGE_SYSTEM = `You triage behavioral arcs for an AI agent's long-term memory system. This is the planning pass:
8973
8977
  a second pass writes each arc's content, so your output is only the plan.
8974
8978
 
8975
8979
  - Assign every existing arc an action of update or skip. An arc omitted from the plan stays stale.
8976
- - Propose create only when a genuinely new behavioural pattern emerges that no existing arc covers.
8980
+ - Propose create only when a genuinely new behavioral pattern emerges that no existing arc covers.
8977
8981
  - Propose update only when the evidence materially changes or reinforces the arc. Each update costs
8978
8982
  a model call, so skip trivial or redundant evidence.
8979
8983
  - Keep evidenceKeys to the strongest 1-5 supporting memories per arc.
8980
- - Titles are concise behavioural-principal names of 3-8 words.
8984
+ - Titles are concise behavioral-principal names of 3-8 words.
8981
8985
  - Rationale is one or two sentences naming what changed or emerged.
8982
8986
  - Leave slug empty on a create.`;
8983
8987
  /** The arc-execute system prompt: one arc's content. */
8984
- const ARC_EXECUTE_SYSTEM = `You write one behavioural arc for an AI agent's long-term memory system. An arc is a self-contained
8985
- behavioural principal — a statement of a pattern, preference, or principle the agent developed
8988
+ const ARC_EXECUTE_SYSTEM = `You write one behavioral arc for an AI agent's long-term memory system. An arc is a self-contained
8989
+ behavioral principal — a statement of a pattern, preference, or principle the agent developed
8986
8990
  through experience. Arcs are read back in future sessions with no transcript context, so the
8987
8991
  content must stand alone.
8988
8992
 
8989
- - claim is the ONE load-bearing sentence: the principle itself, stated as behaviour to adopt.
8990
- - paragraphs holds 2-12 sentences across one to four paragraphs. Behavioural principles fit at the
8993
+ - claim is the ONE load-bearing sentence: the principle itself, stated as behavior to adopt.
8994
+ - paragraphs holds 2-12 sentences across one to four paragraphs. Behavioral principles fit at the
8991
8995
  tight end; an operational playbook may span the wider range.
8992
- - Use IF/THEN conditional phrasing for rules, framed positively around the behaviour to adopt.
8996
+ - Use IF/THEN conditional phrasing for rules, framed positively around the behavior to adopt.
8993
8997
  - When updating, incorporate both the existing content and the new evidence, preserving knowledge
8994
8998
  that still holds.
8995
- - Keep references like "the evidence" or "recent sessions" out of the text — name the behaviour.
8999
+ - Keep references like "the evidence" or "recent sessions" out of the text — name the behavior.
8996
9000
  - The content reads as a stable identity statement, not a changelog.`;
8997
9001
  /** The compress-synthesis system prompt. */
8998
9002
  const COMPRESS_SYSTEM = `You fold a group of related memories into ONE canonical memory for an AI agent's long-term memory
8999
- system. The members are near-neighbours in one community of the memory graph; the canonical replaces
9003
+ system. The members are near-neighbors in one community of the memory graph; the canonical replaces
9000
9004
  them, and each member you list in absorbedKeys is archived once the canonical is written.
9001
9005
 
9002
9006
  - claim is the ONE load-bearing sentence the group shares.
@@ -9012,13 +9016,13 @@ const dataBlock = (label, text) => wrapAsData(label, text);
9012
9016
  * The stance judge's user turn for one pair. Both texts are wrapped; neither carries a path.
9013
9017
  *
9014
9018
  * The prompt names no path, no cosine, and no prior verdict, so the model cannot infer which answer
9015
- * the caller is hoping for and cannot recognise a pair it judged last night.
9019
+ * the caller is hoping for and cannot recognize a pair it judged last night.
9016
9020
  */
9017
9021
  const stancePrompt = (textA, textB) => `${dataBlock("memory_a", textA)}\n\n${dataBlock("memory_b", textB)}\n\nDo these two memories contradict each other? Give your verdict, your confidence, and a rationale naming the specific claims that conflict or why they are compatible.`;
9018
9022
  /** The arc-triage user turn: the live arcs and the recent evidence, both wrapped. */
9019
- const arcTriagePrompt = (arcsText, evidenceText) => `${dataBlock("current_arcs", arcsText)}\n\n${dataBlock("evidence", evidenceText)}\n\nProduce a triage plan. Assign update or skip to every existing arc, and add a create entry for any genuinely new behavioural pattern the existing arcs do not cover.`;
9023
+ const arcTriagePrompt = (arcsText, evidenceText) => `${dataBlock("current_arcs", arcsText)}\n\n${dataBlock("evidence", evidenceText)}\n\nProduce a triage plan. Assign update or skip to every existing arc, and add a create entry for any genuinely new behavioral pattern the existing arcs do not cover.`;
9020
9024
  /** The arc-execute user turn for one arc. `current` is absent on a create. */
9021
- const arcExecutePrompt = (input) => (input.current === void 0 ? `${dataBlock("new_arc_title", input.title)}\n\n` : `${dataBlock("existing_arc", input.current)}\n\n`) + `${dataBlock("evidence", input.evidenceText)}\n\n${dataBlock("triage_rationale", input.rationale)}\n\n` + (input.current === void 0 ? "Synthesize a new behavioural principal from this evidence." : "Update the arc to incorporate the new evidence, preserving existing knowledge that holds.");
9025
+ const arcExecutePrompt = (input) => (input.current === void 0 ? `${dataBlock("new_arc_title", input.title)}\n\n` : `${dataBlock("existing_arc", input.current)}\n\n`) + `${dataBlock("evidence", input.evidenceText)}\n\n${dataBlock("triage_rationale", input.rationale)}\n\n` + (input.current === void 0 ? "Synthesize a new behavioral principal from this evidence." : "Update the arc to incorporate the new evidence, preserving existing knowledge that holds.");
9022
9026
  /** The compress user turn for one batch: every member's text, wrapped, under its offered key. */
9023
9027
  const compressPrompt = (members) => `${members.map((member) => dataBlock(`member_${member.key}`, member.text)).join("\n\n")}\n\nFold these memories into one canonical memory. List in absorbedKeys exactly the members whose content the canonical carries forward.`;
9024
9028
  /**
@@ -9077,11 +9081,11 @@ const activeCorpus = (db) => db.all(`SELECT path, memory_type, title, gist, body
9077
9081
  word_count, created_at, updated_at, valid_until, reprieves
9078
9082
  FROM files WHERE archived = 0 ORDER BY created_at ASC, path ASC`);
9079
9083
  /**
9080
- * Per-source top-`k` nearest neighbours above a similarity floor, over first-chunk vectors.
9084
+ * Per-source top-`k` nearest neighbors above a similarity floor, over first-chunk vectors.
9081
9085
  *
9082
9086
  * `ordinal = 0` collapses a file to its first chunk, not its best chunk. The format is one
9083
9087
  * fact per file, so almost every file is a single chunk. Taking the first keeps the pair set
9084
- * symmetric, which `min(distance)` over all chunks would not. An asymmetric neighbourhood
9088
+ * symmetric, which `min(distance)` over all chunks would not. An asymmetric neighborhood
9085
9089
  * would make `(a, b)` a candidate while `(b, a)` is not, so which of two files was read first
9086
9090
  * would decide whether they merge.
9087
9091
  *
@@ -9090,7 +9094,7 @@ const activeCorpus = (db) => db.all(`SELECT path, memory_type, title, gist, body
9090
9094
  * SQL function over two `Uint8Array` arguments (`packages/index/src/database.ts`) and not a driver
9091
9095
  * builtin with a fixed calling shape.
9092
9096
  */
9093
- const neighbourPairs = (db, options) => {
9097
+ const neighborPairs = (db, options) => {
9094
9098
  const excluded = options.excludeTypes ?? [];
9095
9099
  const typeFilter = excluded.length === 0 ? "" : ` AND f.memory_type NOT IN (${excluded.map(() => "?").join(", ")})`;
9096
9100
  return db.all(`WITH vecs AS (
@@ -9551,7 +9555,7 @@ const runRetentionPass = (db, at) => Effect.gen(function* () {
9551
9555
  * `update`/`create` entries cost a second call.
9552
9556
  *
9553
9557
  * **One commit per arc, not one for the phase.** An arc is a standalone assertion about the agent's
9554
- * own behaviour, and a reviewer reads it as one thing; a commit carrying four unrelated arcs is a
9558
+ * own behavior, and a reviewer reads it as one thing; a commit carrying four unrelated arcs is a
9555
9559
  * commit nobody reviews. It also means a model failure on the third arc leaves the first two
9556
9560
  * committed, so the per-item isolation reaches the git history and not only the counters.
9557
9561
  *
@@ -9996,7 +10000,7 @@ const confidenceDecay = (env) => Effect.gen(function* () {
9996
10000
  */
9997
10001
  /** The moderate similarity floor a pair must clear to be worth a model call. */
9998
10002
  const CONFLICT_COSINE_FLOOR = .8;
9999
- /** Nearest same-entity neighbours considered per source. */
10003
+ /** Nearest same-entity neighbors considered per source. */
10000
10004
  const CONFLICT_PER_SOURCE_K = 5;
10001
10005
  /** Pairs judged per cycle. The model-cost guard. */
10002
10006
  const CONFLICT_CANDIDATE_LIMIT = 200;
@@ -10139,7 +10143,7 @@ const dedupMerge = (env) => Effect.gen(function* () {
10139
10143
  * The `files_content_hash_active` index carves tasks out for the same reason, so structural and
10140
10144
  * semantic dedup agree about them.
10141
10145
  */
10142
- const pairs = yield* neighbourPairs(env.deps.db, {
10146
+ const pairs = yield* neighborPairs(env.deps.db, {
10143
10147
  floor: NEAR_DUPLICATE_THRESHOLD,
10144
10148
  perSourceK: 5,
10145
10149
  limit: 100 * 4,
@@ -10710,7 +10714,7 @@ const preflight = (env) => Effect.gen(function* () {
10710
10714
  */
10711
10715
  /** The similarity floor a pair must clear to become a mined `relates_to`. */
10712
10716
  const MINING_COSINE_FLOOR = .85;
10713
- /** Nearest neighbours considered per source file. */
10717
+ /** Nearest neighbors considered per source file. */
10714
10718
  const MINING_PER_SOURCE_K = 5;
10715
10719
  /** Pairs mined per cycle. The cost guard on a corpus whose pair space is quadratic. */
10716
10720
  const MINING_SAMPLE_LIMIT = 2e3;
@@ -10722,7 +10726,7 @@ const relationshipMining = (env) => Effect.gen(function* () {
10722
10726
  * count. The `edges` CHECK cannot refuse it, because `relates_to` under `memory` is a
10723
10727
  * well-formed edge whatever files sit at its ends.
10724
10728
  */
10725
- const pairs = yield* neighbourPairs(env.deps.db, {
10729
+ const pairs = yield* neighborPairs(env.deps.db, {
10726
10730
  floor: MINING_COSINE_FLOOR,
10727
10731
  perSourceK: 5,
10728
10732
  limit: MINING_SAMPLE_LIMIT,
@@ -10878,7 +10882,7 @@ const headOf = (env) => env.deps.git.revParseHead().pipe(Effect.map((sha) => sha
10878
10882
  * and re-assert the fact deliberately.
10879
10883
  *
10880
10884
  * **Arcs are exempt.** An arc is system-written and carries no meaningful TTL; expiring one on age
10881
- * would delete the agent's own behavioural identity on a schedule.
10885
+ * would delete the agent's own behavioral identity on a schedule.
10882
10886
  */
10883
10887
  const reprieve = (env) => Effect.gen(function* () {
10884
10888
  const expired = (yield* runRetentionPass(env.deps.db, env.at)).scored.filter((entry) => {
@@ -11455,7 +11459,7 @@ const traceConsolidation = (env) => Effect.gen(function* () {
11455
11459
  skipped,
11456
11460
  conflicts: conflicted
11457
11461
  };
11458
- const commitSha = yield* commitPhase(env, "trace-consolidation", `${conflict === void 0 ? "distil" : "distil (frame conflict)"} ${title}`, counts, commitContextFor(candidate, conflict));
11462
+ const commitSha = yield* commitPhase(env, "trace-consolidation", `${conflict === void 0 ? "distill" : "distill (frame conflict)"} ${title}`, counts, commitContextFor(candidate, conflict));
11459
11463
  if (commitSha !== null) lastCommit = commitSha;
11460
11464
  written += 1;
11461
11465
  }
@@ -12843,4 +12847,4 @@ const latest = (left, right) => left === null ? right : right === null ? left :
12843
12847
 
12844
12848
  //#endregion
12845
12849
  export { STATE_SIDECAR_PATH as $, makeIndexRecorder as A, makeGitPort as B, ModelClientLive as C, EMBED_DIM as D, EmbeddingsLive as E, reinforce as F, STATE_MIGRATIONS_DIR as G, DatabaseService as H, Indexer as I, expandRoot as J, STATE_SCHEMA as K, makeIndexer as L, readWatermark as M, Retrieval as N, EMBED_WATERMARK as O, makeRetrieval as P, STATE_DB_PATH as Q, readIndexState as R, ModelClient as S, Embeddings as T, makeDatabase as U, sanitizeFtsQuery as V, MIGRATIONS_DIR as W, INDEX_DB_PATH as X, makeStore as Y, SLEEP_REPORTS_DIR as Z, unlink as _, parseSidecar as a, commitSubject as at, discriminationGate as b, generateArtifacts as c, isValidDatetime as ct, danglingEdges as d, REINFORCE_SIGNALS as dt, attemptIo as et, publishRows as f, frameKeyOf as ft, meta as g, link as h, makeSleep as i, makeGit as it, persistScanned as j, IndexRecorder as k, accessRows as l, closesFence as lt, hrefFor as m, scanTraceRoot as n, readFileOrNull as nt, renderSidecar as o, checkMemory as ot, applyHeadEdits as p, Store as q, Sleep as r, Git as rt, archivedFormOf as s, setMeta as st, mergeTailExtract as t, initRepo as tt, allPaths as u, fenceOpeningOf as ut, SLEEP_PHASES as v, wrapAsData as w, runDiscrimination as x, isSleepPhase as y, IndexGit as z };
12846
- //# sourceMappingURL=dist-CrYVXFO2.mjs.map
12850
+ //# sourceMappingURL=dist-dfrcDFad.mjs.map