Skip to content

feat: add memory metacognition foundation#679

Open
RayShark wants to merge 3 commits into
rohitg00:mainfrom
RayShark:feat/hermes-memory-fusion
Open

feat: add memory metacognition foundation#679
RayShark wants to merge 3 commits into
rohitg00:mainfrom
RayShark:feat/hermes-memory-fusion

Conversation

@RayShark
Copy link
Copy Markdown

@RayShark RayShark commented May 27, 2026

Summary

  • Add Phase 1 memory metacognition state, policy functions, and deterministic policy query expansion.
  • Add shadow-first write candidates plus readback verification without automatic durable writes.
  • Expose 8 authenticated REST endpoints for policy, write candidates, and readback; update REST endpoint counts to 132.

Scope notes

  • No MCP tools are added in this phase.
  • Policy suggestions remain deferred to Phase 2.
  • Shadow candidate approval only changes candidate status; it does not call mem::remember.

Related

Testing

  • npm test -- test/api-memory-metacognition.test.ts test/consistency.test.ts test/memory-policy.test.ts test/memory-policy-types.test.ts test/write-candidates.test.ts test/readback.test.ts
  • npm run build
  • env HOME="$(mktemp -d)" npm test (113 files, 1192 tests)
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Memory policy management system with query expansion and preflight rules
    • Write candidate generation pipeline for intelligent memory suggestions
    • Readback verification to validate memory retrieval accuracy
    • Eight new REST API endpoints for policy, write-candidate, and readback workflows
  • Documentation

    • Updated API endpoint count from 124 to 132
    • Added Memory Metacognition implementation roadmap

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

@RayShark is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 27, 2026

📝 Walkthrough

Walkthrough

This PR implements Phase 1 of Hermes Memory Fusion, a policy-driven memory metacognition system. It introduces KV-backed policy management for query expansion, a shadow write-candidate pipeline with regex-based extraction and review, readback verification to validate candidate searchability, and REST API endpoints for policy and candidate workflows, alongside comprehensive test coverage.

Changes

Hermes Memory Fusion Phase 1

Layer / File(s) Summary
Schema, types, and KV scope definitions
src/state/schema.ts, src/types.ts, test/memory-policy-types.test.ts
Four new KV scopes (memoryPolicy, writeCandidates, readbackResults, policySuggestions) and seven new TypeScript interfaces defining memory policy, query expansion rules, write candidates, readback results, and policy suggestions; audit operation types extended with policy/write/readback events.
Memory policy management functions
src/functions/memory-policy.ts, test/memory-policy.test.ts
SDK functions for retrieving a policy with defaults, updating and normalizing policy (rules, write constraints), and expanding queries using enabled/scoped rules; handles rule matching, deduplication, and per-policy timestamps.
Write candidate extraction and review functions
src/functions/write-candidates.ts, test/write-candidates.test.ts
SDK functions extracting candidates from source text (credentials, workflows, preferences) with secret redaction and scope resolution, listing filtered candidates, and approving/rejecting candidates; includes readback query derivation and audit logging.
Readback verification and result listing functions
src/functions/readback.ts, test/readback.test.ts
SDK functions verifying whether a target memory appears in search results across multiple queries, persisting readback outcomes with pass/fail and failure reasons, and listing filtered readback results with descending chronological sort.
REST API endpoint definitions and request validation
src/triggers/api.ts, test/api-memory-metacognition.test.ts
HTTP endpoints for policy get/update/expand-query, write-candidate generate/list/review, and readback verify/list with auth checks, payload whitelisting, type coercion, and 400 error responses for invalid inputs.
Worker registration and endpoint count update
src/index.ts, AGENTS.md, README.md
Wires three new SDK function registrations into worker startup and updates documented REST API count from 124 to 132 in deployment documentation.
Phase 1–4 implementation roadmap
docs/superpowers/plans/2026-05-27-hermes-memory-fusion.md
Detailed plan document specifying Phase 1 deliverables (policy, candidates, readback), design rationale (borrowing from Hermes, avoiding porting concerns), per-task checklists with test expectations, acceptance criteria, risk register, and suggested PR strategy for phased delivery.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • rohitg00

🐰 A memory fusion blooms so bright,
With policy rules and readback sight,
Candidates whisper what to keep,
While shadows dance through storage deep.
From chaos, wisdom learns to leap!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat: add memory metacognition foundation' accurately summarizes the main objective of adding Phase 1 memory metacognition features including policy management, write candidates, and readback verification.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
docs/superpowers/plans/2026-05-27-hermes-memory-fusion.md (1)

852-864: ⚡ Quick win

Resolve stale “pre-implementation” wording in Open Design Decisions.

This section says decisions must be made before implementation starts, but this PR already implements Phase 1. Please rephrase to reflect current status (e.g., “for follow-up phases”) to avoid process confusion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-05-27-hermes-memory-fusion.md` around lines 852 -
864, The “must be answered before implementation starts” phrasing is stale;
update the Open Design Decisions section to reflect that Phase 1 has been
implemented and that these questions apply to follow-up phases. Change the lead
sentence to something like “These questions should be resolved for follow-up
phases” and keep the four numbered items and Recommended defaults as-is,
ensuring references to Phase 1, readback verification (mem::search,
mem::smart-search), approved candidates (memory_save vs
mem::write-candidates-apply), and policy scope wording remain accurate and
present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/functions/memory-policy.ts`:
- Around line 48-52: The stored policy's updatedAt timestamp is being
overwritten on reads; update readPolicy/normalizePolicy so that when readPolicy
retrieves a stored MemoryPolicy it preserves stored.updatedAt instead of
re-stamping to now—either pass stored.updatedAt into normalizePolicy or change
normalizePolicy to keep an existing updatedAt if present; ensure the
MemoryPolicy returned by readPolicy (and the mem::policy-get flow) retains the
original updatedAt value when stored.updatedAt exists, while still falling back
to defaultPolicy() behavior when no stored policy exists.

In `@src/functions/readback.ts`:
- Around line 192-205: The current Promise.all over queries will reject if any
sdk.trigger call throws, so modify the queries.map handler used to build
queryResults to catch errors per query (inside the async function passed to
queries.map) around the sdk.trigger/topIdsFromResult logic; on error return an
object with the original query, topIds as empty array (or null), matched: false,
and optionally log the error (e.g., via processLogger or console.error) so
mem::readback-verify can still persist/audit results even when individual
searches fail. Use the existing function names (sdk.trigger, topIdsFromResult)
and preserve the shape { query, topIds, matched } in the catch branch.

---

Nitpick comments:
In `@docs/superpowers/plans/2026-05-27-hermes-memory-fusion.md`:
- Around line 852-864: The “must be answered before implementation starts”
phrasing is stale; update the Open Design Decisions section to reflect that
Phase 1 has been implemented and that these questions apply to follow-up phases.
Change the lead sentence to something like “These questions should be resolved
for follow-up phases” and keep the four numbered items and Recommended defaults
as-is, ensuring references to Phase 1, readback verification (mem::search,
mem::smart-search), approved candidates (memory_save vs
mem::write-candidates-apply), and policy scope wording remain accurate and
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4c84549f-b3f1-4639-b12d-eaf0a4a7bd53

📥 Commits

Reviewing files that changed from the base of the PR and between 26980a8 and f6e66a7.

📒 Files selected for processing (15)
  • AGENTS.md
  • README.md
  • docs/superpowers/plans/2026-05-27-hermes-memory-fusion.md
  • src/functions/memory-policy.ts
  • src/functions/readback.ts
  • src/functions/write-candidates.ts
  • src/index.ts
  • src/state/schema.ts
  • src/triggers/api.ts
  • src/types.ts
  • test/api-memory-metacognition.test.ts
  • test/memory-policy-types.test.ts
  • test/memory-policy.test.ts
  • test/readback.test.ts
  • test/write-candidates.test.ts

Comment on lines +48 to +52
async function readPolicy(kv: StateKV): Promise<MemoryPolicy> {
const stored = await kv.get<MemoryPolicy>(KV.memoryPolicy, POLICY_ID);
if (!stored) return defaultPolicy();
return normalizePolicy(stored);
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve updatedAt when normalizing stored policy on reads.

Line 51 normalizes stored data, but Line 153/Line 166 always re-stamp updatedAt to “now”. mem::policy-get can therefore return a different policy metadata value on every read even when nothing changed.

Also applies to: 152-167

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/functions/memory-policy.ts` around lines 48 - 52, The stored policy's
updatedAt timestamp is being overwritten on reads; update
readPolicy/normalizePolicy so that when readPolicy retrieves a stored
MemoryPolicy it preserves stored.updatedAt instead of re-stamping to now—either
pass stored.updatedAt into normalizePolicy or change normalizePolicy to keep an
existing updatedAt if present; ensure the MemoryPolicy returned by readPolicy
(and the mem::policy-get flow) retains the original updatedAt value when
stored.updatedAt exists, while still falling back to defaultPolicy() behavior
when no stored policy exists.

Comment thread src/functions/readback.ts
Comment on lines +192 to +205
const queryResults = await Promise.all(
queries.map(async (query) => {
const searchResult = await sdk.trigger({
function_id: mode === "smart-search" ? "mem::smart-search" : "mem::search",
payload: { query, limit },
});
const topIds = topIdsFromResult(searchResult, limit);
return {
query,
topIds,
matched: topIds.includes(memory.id),
};
}),
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Isolate per-query search failures so verify still persists a result.

If one search call throws, Promise.all rejects and mem::readback-verify exits without persisting/auditing a readback. Handle failures per query and mark that query as unmatched instead of failing the whole verification.

Suggested patch
       const queryResults = await Promise.all(
         queries.map(async (query) => {
-          const searchResult = await sdk.trigger({
-            function_id: mode === "smart-search" ? "mem::smart-search" : "mem::search",
-            payload: { query, limit },
-          });
-          const topIds = topIdsFromResult(searchResult, limit);
-          return {
-            query,
-            topIds,
-            matched: topIds.includes(memory.id),
-          };
+          try {
+            const searchResult = await sdk.trigger({
+              function_id: mode === "smart-search" ? "mem::smart-search" : "mem::search",
+              payload: { query, limit },
+            });
+            const topIds = topIdsFromResult(searchResult, limit);
+            return {
+              query,
+              topIds,
+              matched: topIds.includes(memory.id),
+            };
+          } catch {
+            return { query, topIds: [], matched: false };
+          }
         }),
       );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/functions/readback.ts` around lines 192 - 205, The current Promise.all
over queries will reject if any sdk.trigger call throws, so modify the
queries.map handler used to build queryResults to catch errors per query (inside
the async function passed to queries.map) around the
sdk.trigger/topIdsFromResult logic; on error return an object with the original
query, topIds as empty array (or null), matched: false, and optionally log the
error (e.g., via processLogger or console.error) so mem::readback-verify can
still persist/audit results even when individual searches fail. Use the existing
function names (sdk.trigger, topIdsFromResult) and preserve the shape { query,
topIds, matched } in the catch branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant