Skip to content

RecallNest v3.0.0 — Node 22, and conclusions that can be used

Latest

Choose a tag to compare

@AliceLJY AliceLJY released this 23 Aug 19:00
· 26 commits to main since this release

RecallNest v3.0.0 raises the runtime floor to Node 22 and opens a promotion road for synthesized conclusions, so a dream-produced conclusion can finally take part in stable memory instead of being permanently confined to the evidence layer.

Install

npm install -g recallnest@3.0.0

Breaking change

  • engines.node is now >=22 (was >=18.14.1). This is the only breaking change in the release; Bun users are unaffected.

Highlights

  • promote_synthesis (MCP) and recallnest promote-synthesis (CLI) — eligibility comes from a conclusion's own validated evidence set (synthesis_contract >= 2, at least two distinct still-active evidence memories) rather than from repetition, because a synthesis is already a cross-entry aggregate — counting how often it recurs would count the same aggregation twice. It abstains when evidence cannot be resolved, counts every rejection reason, defaults to dry-run, and writes through the existing promoteMemory path so a re-run is a revision rather than a duplicate. Exercised read-only against the live database: of 52 contract-stamped derivatives, project:codex-self-evolution yielded 10 candidates from 10 examined, project:antigravity-cli 4 from 9 (5 below importance), learnings 3 from 4 (1 with too few distinct sources). Nothing was written.
  • Synthesis generation quality, six changes. A 2026-08-22 diagnostic found derived memories had a lower conclusion density than their own input — measured over the same 40–160 character band with a deterministic regex and no LLM judge: hand-written pivots 40.4%, raw transcripts 25.1%, insights 14.4%, patterns 12.1%. Synthesis was subtracting. One of the six changes is directly measurable on its own: the synthesis_contract v2 single-JSON-object constraint took unparsable multi-object responses from 3.3% of calls to 0.0%. cluster_insight no longer routes through the chunk-summariser prompt and may now abstain; extractPattern requires two pieces of evidence as a hard gate; validateSynthesis runs before anything is written; pattern and insight fail independently; derived rows carry an explicit boundary; and a synthesis_contract version stamp replaces guessing which code produced a row.
  • MemOS value backtracking (P0/P1/P2). workflow_observe now records readerId and recalledIds, supplying the (memory_id, outcome) join the database never had. A new utility column weights outcomes with a 30-day half-life and can be negative; it lands in metadata.utility and deliberately not in importance, which is threshold-valued — at ≥0.95 it grants permanent decay exemption, so a fluctuating signal written there would hand out exemptions silently. Promotion gained a cross-source criterion that abstains when source pointers are unavailable — necessarily, since only 1.2% of cases in this database carry a src: tag and judging strictly would mostly punish three different problems solved on one day.
  • Retrieve audit rows carry revision and provenance — each served result's id, evolution.version, lifecycle status and boundary layer/authority, with retrievedTotal marking truncation.
  • openai migrated from ^4.0.0 to ^7.5.0, removing the openai@4 → formdata-node@4.4.1 → node-domexception@1.0.0 deprecated chain. Any release since v5 drops that chain; v7 was chosen because it declares engines.node >= 22.0.0, making the Node floor and the dependency cleanup one decision instead of two. Compatibility was measured against the SDK rather than assumed from its migration guide — the guide covers the httpAgent removal and the move to built-in fetch, and says nothing about the three call shapes this codebase actually depends on.
  • MCP tool count is 44, up from 43.

Fixed

  • A rate-limit reply could trigger an unbounded request storm. Found by the contract tests added in this release. embedSingle retried a context-length error by chunking and each chunk recursed back into embedSingle; the error gate also matched rate-limit wording, and short text survives chunking unchanged, so the recursion reproduced its own trigger. Measured before the fix: 61,724 requests in five seconds against an endpoint asking us to slow down. After: 4 ms, one request, correct error.
  • Multiple AccessTracker instances in one process no longer invent separate readers — one session opening two profiles counted as two, which had inflated distinctReaderCount and the skill-promotion read boost.

Deliberately not in this release

  • The verbatim self-recall ranking fix. The reproduction ships without it, and pins the mechanism: the entry is not filtered — hard_min_score, layer_admission and noise_filter each drop zero rows and its score clears the threshold — it is admitted and then ranked last. A repeatable red test is the precondition for a ranking change being measured rather than argued.
  • Making candidatePoolSize above 20 do anything. retriever.ts now records that it never has: both candidate legs land in store.ts's clampInt(limit, 1, 20), so the 30 set by the 2026-07-16 tuning was inert from the day it landed. It is left inert on purpose — making it real means widening the candidate pool, which was measured and rejected on 2026-08-22.
  • Acting on utility. See the shadow-period note below; the switch is off by design, not unfinished.

Upgrade notes

  • Node 22 or newer is required.
  • Existing LanceDB data opens in place; no export/import step.
  • promote_synthesis defaults to dry-run and writes nothing until dryRun=false.
  • audit.jsonl retrieve rows are larger now that they list what was served; the list is capped at 10 entries. Rotation is still manual.
  • utilityWeight defaults to 0 and metadata.utility is written only by an explicit memory-utility --apply run, so the MemOS work is available but not yet acting on anything. Real data starts accumulating from this release forward. This is the intended shadow period, not a defect.

Verification

  • 2,324 tests pass across 165 files, 0 fail, verified under three feature-flag combinations including the CI default.
  • The deprecated dependency chain is absent from npm ls, node_modules/, bun.lock and package-lock.json; installed openai@7.5.0 reports zero dependencies.
  • SDK compatibility was measured, not assumed: 20 sandbox probes plus a tsc --strict check of all five call sites, with a deliberately-broken control run to confirm the type check actually reports errors.
  • promote_synthesis was exercised read-only against a live database; nothing was written.
  • The verbatim self-recall and synthesis-promotion suites were reverse-verified — removing the behaviour each asserts turns the relevant tests red and no others.
  • This is the first RecallNest release published through npm Trusted Publishing. It carries GitHub Actions build provenance linked to this repository, .github/workflows/publish.yml, and the exact tagged commit. Earlier versions, including 2.6.1, were published before Trusted Publishing was configured and carry no provenance; that is not retroactively fixable.

Full details: CHANGELOG.md