You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I understand this issue needs status:approved before a PR can be opened
🔍 Problem Description
Local clients that integrate directly with engram serve cannot invoke the existing project-merge capability without also starting MCP or using the interactive CLI consolidation flow.
The capability already exists through:
MCP: mem_merge_projects
CLI: engram projects consolidate
Store: Store.MergeProjects
There is no equivalent HTTP endpoint. The existing POST /projects/migrate route is not an alternative project-merge API: it is a deprecated compatibility alias for the ownership-rescue handler.
This is an administrative transport-parity gap, not a request for new merge semantics.
mem_merge_projects is intentionally restricted to the MCP admin profile and is annotated as destructive, idempotent, non-read-only, and closed-world. Store.MergeProjects already provides the authoritative safety behavior:
every source must normalize to the canonical project;
all sources are validated before mutation;
observations, sessions, prompts, pending sync mutations, and sync enrollment are handled in one transaction;
unsafe mixed-source requests fail without partial mutation;
repeated valid requests are idempotent.
HTTP clients should be able to use that existing behavior without reimplementing it or mounting MCP solely for this administrative operation.
💡 Proposed Solution
Expose a narrowly scoped, authenticated JSON endpoint from engram serve that delegates directly to Store.MergeProjects.
The route and property names above are illustrative rather than a closed design decision. The final contract should follow maintainer preference and existing HTTP conventions.
Whichever contract is selected, the implementation should:
protect the endpoint with requireConfiguredAuth, not optional requireAuth;
return 503 when ENGRAM_HTTP_TOKEN is not configured;
return 401 for missing or invalid bearer credentials;
cap the request body at 8 KiB, matching the existing ownership-rescue admin endpoint;
require an explicit confirmed: true;
require at least one non-blank source and a non-blank canonical target;
call Store.MergeProjects directly;
keep normalization, source eligibility, atomicity, sync migration, and idempotency authoritative in the store;
avoid raw SQL or duplicated merge rules in the HTTP handler;
map store validation failures to 400 without relying on error-string matching or reimplementing those validations;
return 200 for successful merges, including valid idempotent no-ops;
return a generic 500 for unexpected store/infrastructure failures;
call notifyWrite() after a successful merge so autosync can observe any record, journal, or enrollment changes;
not gate notifyWrite() solely on observation/session/prompt counters, because sync identity or enrollment may change independently;
preserve all existing MCP, CLI, sync, and HTTP behavior;
document the final contract in DOCS.md.
Suggested acceptance criteria:
A valid authenticated and confirmed request merges observations, sessions, and prompts and returns the existing merge result fields.
Pending sync mutations and enrollment continue to follow the canonical project through Store.MergeProjects.
Autosync is notified after a successful merge.
A repeated valid request succeeds idempotently with no additional records moved.
An unset server token returns 503 without mutation or autosync notification.
Missing or invalid credentials return 401 without mutation or autosync notification.
Missing/false confirmation returns 400 without invoking the merge.
📋 Pre-flight Checks
status:approvedbefore a PR can be opened🔍 Problem Description
Local clients that integrate directly with
engram servecannot invoke the existing project-merge capability without also starting MCP or using the interactive CLI consolidation flow.The capability already exists through:
mem_merge_projectsengram projects consolidateStore.MergeProjectsThere is no equivalent HTTP endpoint. The existing
POST /projects/migrateroute is not an alternative project-merge API: it is a deprecated compatibility alias for the ownership-rescue handler.This is an administrative transport-parity gap, not a request for new merge semantics.
mem_merge_projectsis intentionally restricted to the MCP admin profile and is annotated as destructive, idempotent, non-read-only, and closed-world.Store.MergeProjectsalready provides the authoritative safety behavior:HTTP clients should be able to use that existing behavior without reimplementing it or mounting MCP solely for this administrative operation.
💡 Proposed Solution
Expose a narrowly scoped, authenticated JSON endpoint from
engram servethat delegates directly toStore.MergeProjects.One possible HTTP shape is:
A successful response could use the existing
store.MergeResultJSON shape:{ "canonical": "engram", "sources_merged": ["Engram", "ENGRAM"], "observations_updated": 12, "sessions_updated": 2, "prompts_updated": 4 }The route and property names above are illustrative rather than a closed design decision. The final contract should follow maintainer preference and existing HTTP conventions.
Whichever contract is selected, the implementation should:
requireConfiguredAuth, not optionalrequireAuth;503whenENGRAM_HTTP_TOKENis not configured;401for missing or invalid bearer credentials;confirmed: true;Store.MergeProjectsdirectly;400without relying on error-string matching or reimplementing those validations;200for successful merges, including valid idempotent no-ops;500for unexpected store/infrastructure failures;notifyWrite()after a successful merge so autosync can observe any record, journal, or enrollment changes;notifyWrite()solely on observation/session/prompt counters, because sync identity or enrollment may change independently;DOCS.md.Suggested acceptance criteria:
Store.MergeProjects.503without mutation or autosync notification.401without mutation or autosync notification.400without invoking the merge.400.400.500without exposing infrastructure details.📦 Affected Area
Other — HTTP API (
engram serve)🔄 Alternatives Considered
engram serve.Store.MergeProjectsis already the authoritative domain/store operation.POST /projects/migrate: rejected because that route is now a deprecated alias for ownership rescue and has different semantics.📎 Additional Context
Verified against current
mainat commit9632b56f21e37b41fc40bdb9c8a23bc1d6e5ecf6.Relevant implementation:
internal/mcp/mcp.goProfileAdminmem_merge_projectsregistration and annotationshandleMergeProjectsqueuedWriteHandlerinternal/store/store.goMergeResultStore.MergeProjectsprojectMergeSourceVariantsmigrateProjectSyncIdentityTxbackfillProjectSyncMutationsTxinternal/server/server.goServer.routesrequireConfiguredAuthhandleRescueProjectOwnershipnotifyWritecmd/engram/main.gocmdProjectsConsolidateRelated work:
mem_merge_projectsfor a separate administrative issue.No existing issue or PR was found for authenticated HTTP exposure of
Store.MergeProjects.