Skip to content

Phase 6: publish stable consumption seams for research and SDK consumers#17

Merged
ethanj merged 1 commit intoarchitecture2from
phase6
Apr 18, 2026
Merged

Phase 6: publish stable consumption seams for research and SDK consumers#17
ethanj merged 1 commit intoarchitecture2from
phase6

Conversation

@ethanj
Copy link
Copy Markdown
Contributor

@ethanj ethanj commented Apr 18, 2026

Summary

Phase 6 of the rearchitecture — publishes the composition root built in Phases 1A–1B as a stable consumption surface. Research harnesses, the extension, and SDK consumers can now boot core through three documented seams (HTTP, in-process runtime container, docker/E2E compose) instead of re-building a parallel runtime.

The work in this repo is narrow on purpose: publish the seams, prove they work in a contract test, document the boundary. The actual migration of research harnesses onto these seams lives in atomicmemory-research, tracked separately.

What changed

Public API (src/index.ts)

  • Adds createCoreRuntime + types (CoreRuntime, CoreRuntimeDeps, CoreRuntimeConfig, CoreRuntimeRepos, CoreRuntimeServices, CoreRuntimeConfigRouteAdapter)
  • Adds createApp, checkEmbeddingDimensions + EmbeddingDimensionCheckResult, bindEphemeral + BootedApp
  • Existing exports preserved — current research paths keep working (Risk 4: avoid breaking research in the same step that gives it a new seam)

Seam promotion

  • src/__tests__/test-helpers.tssrc/app/bind-ephemeral.ts so research can import the canonical HTTP-boot helper without reaching into a test dir. JSDoc refreshed. Two importers updated.

Contract test (src/app/__tests__/research-consumption-seams.test.ts)

  • In-process seam: runtime.services.memory.ingest / .search end-to-end

  • HTTP seam: POST /memories/ingest + /memories/search via bindEphemeral

  • Parity, both directions:

    1. in-process write → HTTP search sees the IDs
    2. HTTP write → in-process search sees the IDs

    Two-directional parity is the requirement because direction (1) alone would miss a regression where POST /memories/ingest transforms or validates the request body differently from runtime.services.memory.ingest(...). Direction (2) is what pins the HTTP ingest contract to the in-process contract.

Docs

  • docs/consuming-core.md — new. HTTP / in-process / docker seams, copy-pastable examples using the literal package.json#name (@atomicmemory/atomicmemory-engine), stability boundary for deep-path imports, what belongs in research vs. core.
  • docs/README.md + CLAUDE.md — pointers to the new doc.

Out of scope (explicit)

  • No research-repo changes — migrating harnesses is follow-up work there.
  • No narrowing of ./services/* / ./db/* deep-path exports in package.json — Risk 4 again; deprecate in docs now, remove once research has migrated.
  • No config split (Phase 1B/2) or retrieval decomposition (Phase 3). Phase 6 publishes only the seams Phases 1A–1B already built.

Test plan

  • npx tsc --noEmit — clean
  • npm test — 957/957 pass (was 953 pre-Phase-6; +4 contract tests)
  • fallow --no-cache — 0 above threshold, maintainability 90.9 (good)
  • Existing composed-boot-parity.test.ts still passes after the import-path update
  • Existing memory-route-config-seam.test.ts still passes after the import-path update
  • CI green on the branch
  • Optional sanity: npm run test:docker-smoke still green (no compose files changed — regression check only, not a new requirement)

🤖 Generated with Claude Code

Phases 1A–1B built the composition root (`createCoreRuntime`, `createApp`)
but kept it internal. Phase 6 promotes the seams to the public surface,
documents them, and pins behavior with a contract test so HTTP and
in-process ingest cannot silently diverge.

Public API:
- src/index.ts exports createCoreRuntime + types, createApp,
  checkEmbeddingDimensions, bindEphemeral. Existing exports preserved —
  current research paths keep working.

Seam promotion:
- src/__tests__/test-helpers.ts moved to src/app/bind-ephemeral.ts so
  research harnesses can import the canonical HTTP-boot helper without
  reaching into a test dir. Two importers updated.

Contract test (src/app/__tests__/research-consumption-seams.test.ts):
- in-process seam: runtime.services.memory.ingest/search end-to-end
- HTTP seam: POST /memories/ingest + /memories/search via bindEphemeral
- parity, both directions: in-process write → HTTP search, and HTTP
  write → in-process search. Two-directional parity catches regressions
  where HTTP input parsing or response shaping drifts from the in-process
  contract — one direction alone would miss that.

Docs:
- docs/consuming-core.md: HTTP / in-process / docker seams, copy-pastable
  examples using the actual package name (@atomicmemory/atomicmemory-engine),
  stability boundary for deep-path imports, what belongs in research.
- docs/README.md + CLAUDE.md: pointers to the new doc.

Out of scope (per plan): no research-repo migration, no narrowing of
deep-path exports in package.json (Risk 4 — avoid breaking research in
the same step that gives it a new seam), no config split or retrieval
decomposition.

957/957 tests pass. tsc --noEmit clean. fallow --no-cache 0 above threshold.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ethanj ethanj merged commit f65db73 into architecture2 Apr 18, 2026
@ethanj ethanj deleted the phase6 branch April 18, 2026 05:32
ethanj added a commit that referenced this pull request Apr 19, 2026
Cuts over `main` to the Phase 1A–7 rearchitecture (composition root,
  explicit scope/observability contracts, store-narrowed repository access,
  public consumption seams, config split, leaf-module config threading,
  retrieval orchestration polish) plus the OSS-release-prep on top.

  ⚠️ Breaking changes for HTTP / SDK consumers
  - All API endpoints are now mounted under `/v1` (e.g.
    `POST /v1/memories/ingest`, `PUT /v1/agents/trust`). The unversioned
    `/health` liveness probe is unchanged.
  - Workspace `GET /memories/list`, `GET /memories/:id`, and
    `DELETE /memories/:id` now require `agent_id` when `workspace_id`
    is present; missing returns 400 (no visibility-unsafe fallback).
  - `PUT /memories/config` returns 410 Gone in production. Provider/model
    fields (embedding_provider, embedding_model, llm_provider, llm_model)
    are rejected with 400 — they were never honored mid-flight (provider
    caches are fixed at first use). Set via env at process start.
  - npm package renamed `@atomicmemory/atomicmemory-engine` →
    `@atomicmemory/atomicmemory-core`. Tarball now ships `dist/` (built
    via `tsc`); `main`/`types`/`exports` point at compiled output.
  - Deep-importers of `services/embedding` and `services/llm` must call
    `initEmbedding(config)` / `initLlm(config)` before hot-path APIs.
    Consumers using `createCoreRuntime({ pool })` are auto-initialized.

  Rearchitecture (Phases 1A–7)
  - Phase 1A: composition root via `createCoreRuntime` + `createApp` (#8)
  - Phase 2A: canonical search scope contract (#9)
  - Phase 2B: explicit retrieval observability contract (#10)
  - Phase 3: runtime-config seam cleanup to Phase 4 boundary (#11)
  - Phase 4: ingest pipeline decomposition (475 → 215 lines) (#13)
  - Post-Phase 4: unify scope contract via `scopedSearch`/`scopedExpand`,
    document schema scoping gaps as deferred (#15)
  - Phase 5: narrow repository access behind 8 domain-facing stores;
    workspace ingest now flows through canonical lineage (#16)
  - Phase 6: publish stable consumption seams (HTTP, in-process, docker)
    with two-direction parity contract test (#17)
  - Phase 7 Steps 3a–3c: split runtime config into supported/internal
    partitions; deprecate `PUT /memories/config` for production (#18)
  - Phase 7 Step 3d: thread config through 5 leaf modules (33→28
    singleton audit) (#21)
  - Phase 7 Item 4: retrieval polish — `memory-search.ts` reduced to
    pure orchestration (374 → 248 lines, -34%) (#22)
  - Chore: reduce fallow duplication 367 → 234 lines (#12)

  OSS release prep
  - `"private": true` removed; package renamed to
    `@atomicmemory/atomicmemory-core`. `files` field scopes the tarball.
  - `tsconfig.build.json` + `prepublishOnly` so `npm publish` always ships
    compiled `dist/`. Bare-import smoke test passes.
  - `release.yml` publishes to public npm on tag push (NPM_TOKEN secret).
  - SuperMem codename scrubbed from `src/`, tests, docker-compose, and
    `.env.example` (DB user/name/password renamed to `atomicmemory`).
  - Private-research-repo URLs unlinked from public docs.
  - README links to docs.atomicmemory.ai.
  - `/v1` API prefix on all routes; mount-coverage test added.
  - CI workflow: set `CORE_RUNTIME_CONFIG_MUTATION_ENABLED=true` to
    match `.env.test` (gitignored) and unblock the composed-boot-parity
    test on `PUT /v1/memories/config`.

  Verification
  - 966/966 tests pass (100 files)
  - npx tsc --noEmit clean
  - fallow --no-cache: 0 above threshold (maintainability 91.0)
  - npm publish --dry-run succeeds
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