Skip to content

Recall v2.2: trustworthy memory lifecycle, provenance, and updater#12

Merged
cashcon57 merged 12 commits into
mainfrom
feat/v2.2-trustworthy-memory
Jun 22, 2026
Merged

Recall v2.2: trustworthy memory lifecycle, provenance, and updater#12
cashcon57 merged 12 commits into
mainfrom
feat/v2.2-trustworthy-memory

Conversation

@cashcon57

@cashcon57 cashcon57 commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Summary

Ships Recall v2.2 as “trustworthy memory” rather than generic RAG:

  • add provenance/lifecycle/supersession schema fields and migrations
  • add validation helpers for source types, statuses, confidence, dates, and retrieval format
  • persist provenance/lifecycle metadata in store_memory
  • make retrieval/list status-aware with JSON output and provenance/lifecycle payloads
  • add lifecycle MCP tools: mark_memory_status, verify_memory, supersede_memory
  • upgrade consolidation reports with read-only lifecycle/provenance maintenance findings
  • add conservative optional updater (recall-update.sh) with migration tracking, protected config handling, smoke tests, rollback, and cron check support
  • document updating, Hermes cross-repo/Discord provenance integration, release checklist, and GitHub Actions example

Review notes

  • wrangler.toml, .dev.vars, .recall-api-key, MCP configs, and .recall-update/ are protected/ignored.
  • Public docs were sanitized to avoid local Hermes deployment paths/secrets.
  • --apply requires migration tracking and smoke tests; older installs can bootstrap schema_migrations and record already-applied historical migrations based on live schema.
  • Follow-up reviews fixed fresh-install migration tracking, verify_memory status preservation, secure updater temp files, optional rollback smoke behavior, and provenance line-range validation.

Verification

  • npm run typecheck
  • npm test — 6 files / 45 tests
  • bash -n recall-update.sh
  • ./recall-update.sh --install-cron weekly — prints only, no install without --yes
  • RECALL_WORKER_URL=https://recall-hermes.cashcon57.workers.dev ./recall-update.sh --doctor
  • git diff --check origin/main..HEAD
  • secret/local-detail grep across origin/main..HEAD
  • required authenticated MCP smoke: tools/list: 10 tools
  • optional smoke failure path returns exit 0 with warning
  • deployed Hermes Recall smoke: remote tools/list returned 10 tools and lifecycle/provenance store/retrieve/verify/delete smoke passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces version 2.2.0 of Recall, adding robust provenance, lifecycle controls, and supersession workflows for trustworthy agent memory. It introduces three new MCP tools (mark_memory_status, verify_memory, and supersede_memory), updates retrieval and consolidation logic to respect memory statuses, and adds an optional conservative updater script (recall-update.sh). Feedback on these changes highlights a security vulnerability in the updater script regarding insecure temporary file paths in /tmp, a bug where optional health checks can crash the script during rollback, and a validation gap in src/tools.ts allowing a source end line to be specified without a start line.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread recall-update.sh
INSTALL_CRON=""
YES=0

BACKUP_DIR=".recall-update"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

security-high high

The script uses hardcoded temporary file paths in /tmp (e.g., /tmp/recall-update-d1.err, /tmp/recall-update-health.json, /tmp/recall-update-tools.json). In shared environments, this can lead to symlink attacks, unauthorized access, or denial of service if another user creates these files first. It is highly recommended to create a secure, unique temporary directory using mktemp -d at the start of the script, register an EXIT trap to clean it up, and place all temporary files inside it.

Suggested change
BACKUP_DIR=".recall-update"
BACKUP_DIR=".recall-update"
SECURE_TMP_DIR="$(mktemp -d -t recall-update.XXXXXX)"
trap 'rm -rf "$SECURE_TMP_DIR"' EXIT

Comment thread recall-update.sh Outdated
err "worker URL not detectable; set RECALL_WORKER_URL=https://your-worker.example.com so --apply can run required smoke tests"
return 1
fi
run curl -fsS --max-time 10 "${url%/}/health" >/dev/null

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

When mode is set to "optional" (such as during a rollback), any failure in the curl health check will cause the script to crash and exit immediately due to set -e. Optional smoke tests should fail gracefully with a warning rather than aborting the entire process.

Suggested change
run curl -fsS --max-time 10 "${url%/}/health" >/dev/null
if [[ "$mode" == "optional" ]]; then
run curl -fsS --max-time 10 "${url%/}/health" >/dev/null || { warn "optional health check failed"; return 0; }
else
run curl -fsS --max-time 10 "${url%/}/health" >/dev/null
fi

Comment thread src/tools.ts
Comment on lines +451 to +453
if (source_line_start !== null && source_line_end !== null && source_line_start > source_line_end) {
throw new Error('source_line_start must be less than or equal to source_line_end');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

In validateOptionalLineRange, the script checks that source_line_start is less than or equal to source_line_end if both are specified. However, it does not prevent a logical inconsistency where source_line_end is specified but source_line_start is omitted (null). If an end line is provided, a start line must also be specified.

  if (source_line_start === null && source_line_end !== null) {
    throw new Error('source_line_start must be provided if source_line_end is specified');
  }
  if (source_line_start !== null && source_line_end !== null && source_line_start > source_line_end) {
    throw new Error('source_line_start must be less than or equal to source_line_end');
  }

@cashcon57

Copy link
Copy Markdown
Owner Author

Follow-up from pre-PR async review:

Fixed both blockers in 6b8cc44:

  1. Fresh install migration tracking

    • schema.sql, local/setup.sql, and docker/setup.sql now seed schema_migrations for bundled historical migrations (0000, 0002, 0003, 0004) so a fresh v2.2 install does not later try to re-run old ALTER TABLE migrations.
    • Added regression coverage in test/migrations.test.ts.
    • Verified with an in-memory SQLite reproduction: fresh schema.sql now records all four versions and pending count is 0.
  2. verify_memory lifecycle safety

    • verify_memory now preserves existing status when status is omitted.
    • It only reactivates / changes lifecycle status when status is explicitly provided.
    • Added regression coverage in test/lifecycle-tools.test.ts for both preservation and explicit reactivation.

Verification after fix:

  • npm run typecheck
  • npm test — 6 files / 45 tests
  • bash -n recall-update.sh
  • ./recall-update.sh --install-cron weekly
  • git diff --check

@cashcon57

Copy link
Copy Markdown
Owner Author

Addressed Gemini Code Assist review in d31b13f:

  • recall-update.sh
    • Replaced fixed /tmp/recall-update-* files with a script-scoped secure temp dir from mktemp -d and an EXIT cleanup trap.
    • Moved D1, secret-list, health, migration pending, and MCP tools/list temp files under that temp dir.
    • Optional rollback smoke now treats /health failure as a warning and returns success instead of aborting under set -e.
    • Authenticated MCP tools/list still uses the real API key at runtime but logs only redacted authorization.
  • src/tools.ts
    • validateOptionalLineRange now rejects source_line_end without source_line_start.
  • test/lifecycle-validation.test.ts
    • Added regression coverage for source_line_end without source_line_start.

Verification:

  • npm run typecheck
  • npm test — 6 files / 45 tests
  • bash -n recall-update.sh
  • ./recall-update.sh --install-cron weekly
  • RECALL_WORKER_URL=https://recall-hermes.cashcon57.workers.dev ./recall-update.sh --doctor
  • required authenticated MCP smoke: tools/list: 10 tools
  • optional smoke failure path returns exit 0 with warning
  • git diff --check

@cashcon57
cashcon57 merged commit cf6f3ae into main Jun 22, 2026
1 check passed
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