refactor(connectors): rename lore-connectors to rac-connectors [roadmap:rac-connectors]#1
Merged
Merged
Conversation
Establishes the Lore/RAC companion that pushes the corpus export into external memory, RAG, and graph backends (rac-core ADR-073). Apache-2.0 to match rac-core; CI runs ruff, mypy, and the offline test-suite. Dogfoods Lore via an LCON-keyed rac/ corpus.
… seam) ADR-001 fixes lore-connectors as a Python package matching the RAC ecosystem. ADR-002 fixes the shared, outbound-only push seam — one module per backend (rac-core ADR-073). Both validate under rac validate rac/.
…ry connector Reads a 'rac export --documents' JSON Lines stream and upserts each record into Supermemory, idempotent on the canonical id (custom_id) so a re-push updates rather than duplicates. Outbound only — no pull, re-rank, or route; no embeddings here (rac-core ADR-002, ADR-066). Auth via SUPERMEMORY_API_KEY; --dry-run previews without an API call. The lore-connect CLI wires stdin or --input to the connector. Implements the corpus-export-shape-contract / lore-supermemory-interplay designs in rac-core.
…rmed-line guard Drives a fake Supermemory client — no live API in CI. Covers record->add mapping, idempotent re-push on id, dry-run making no call, env-auth guard, and malformed/blank-line handling. Fixture captured from a real rac export.
Explains the fuzzy-recall/verify-in-Lore loop, the Supermemory usage and flags, the export contract consumed, and how a new backend slots in.
Adopt the rac-core house style: centered nav, badge row, tagline, and the same section headers where they map (How it compares, Quickstart, Install, How it works, Python API, Who it's for, Documentation, Origin, Repository layout, Test, Project status, License).
Vendor the Lore header (light/dark) from rac-core under rac/assets/images/ and wire it into the README via a prefers-color-scheme <picture>, matching the rac-core masthead.
Verified SdkSupermemoryClient against the real supermemory SDK (v3.48.0): client.add(content, container_tag, metadata, custom_id) with metadata typed str|float|bool|list[str] (so the export's aliases/tags lists are accepted) and an AddResponse carrying id/status. Adds a stubbed-SDK test of the adapter so the shape can't silently drift, and pins the extra to the verified v3 major. Note: no live network round-trip — exercised against a stub, not a real key.
Adopt setuptools-scm so the version comes from the git tag (vX.Y.Z), matching rac-core. Add python-publish.yml: on a published GitHub Release, gate on the reusable CI workflow, build sdist+wheel, and publish to PyPI via trusted publishing (OIDC, no token). CI checkouts fetch full history for scm.
…kage model Add a PyPI/from-source Install section (the name is reserved, pre-release installs come from the repo), a 'Run it in CI' GitHub Actions example, and a 'One package, many backends' section: backends are CLI subcommands with optional per-provider extras, not separate packages (ADR-073, ADR-002).
The what/why of consuming rac export --graph and loading Lore's validated relationship graph into a graph backend (Neo4j first). Companion to the documents target already shipped.
…[roadmap:graph-connector] The how: typed node/edge reader, a sibling push_graph seam beside the documents push, MERGE-on-id idempotency, and the undirected/unresolved edge handling. Implements rac/designs/graph-connector-shape.md.
…ap:graph-connector] Locks the node/edge push seam, Neo4j as the first graph backend, MERGE-on-id idempotency, undirected-as-single-edge, and skip-unresolved. Validated under rac validate rac/.
…graph-connector] Parse rac export --graph into typed Graph/GraphNode/GraphEdge dataclasses, and add a sibling push_graph(graph) seam beside the documents push. Additive — the documents Connector, reader, and CLI are unchanged. Implements rac/designs/graph-connector-shape.md (ADR-003).
…p:graph-connector] MERGE nodes by id and edges by type for idempotency; undirected edges written once, unresolved edges skipped (no phantom nodes); Cypher fully parameterised. Driver behind a thin client (env auth: NEO4J_URI/USERNAME/PASSWORD), optional [neo4j] extra. Exposes 'lore-connect neo4j' with --dry-run/--input.
…roadmap:graph-connector] Drives a fake driver — no live Neo4j in CI. Covers node/edge->MERGE mapping, idempotent re-push, skip-unresolved, dry-run, parameterisation, the stubbed-SDK driver adapter (env creds), and the CLI subcommand.
…raph-connector] Add the Neo4j section, the [neo4j] extra, the --graph contract shape, a graph Python API example, and frame both shipped targets (documents + graph).
Each connector documents itself once in docs/connectors/<backend>.md; a small stdlib generator (scripts/sync_readme.py) stitches those into collapsible <details> sections in the README's Connectors region, rewriting page-relative links to the repo root. So a reader gets every connector on one page while each connector owns its own file (no cross-PR README conflicts). A CI drift-guard (sync_readme.py --check) fails if a page is edited without re-syncing. Migrates the Supermemory usage into its page as the first one.
…s-graph-neo4j # Conflicts: # README.md
… pages pattern) Adopt the generated-pages structure from main: drop the inline README edits (including the --graph contract and graph Python API, which now live on the page) and document Neo4j in docs/connectors/neo4j.md, then regenerate the README Connectors region.
feat(neo4j): add the graph connector for the --graph projection
…nds] (#3) * docs(decisions): record ADR-004 (Mem0 documents backend, resync idempotency) Mem0 reuses the documents push(records) seam; it has no per-record upsert key (verified against mem0ai 2.0.7), so idempotency is a container resync — clear the source partition, then add. infer=False stores text as-is. Validated under rac validate rac/. * feat(mem0): add the Mem0 documents connector and CLI subcommand Reuse the documents seam: map source->Mem0 user_id partition, ship text + metadata (lore_id/type/status/title) with infer=False. Idempotent by container resync (clear partition, then add). Driver behind a thin client (env auth MEM0_API_KEY), optional [mem0] extra. Exposes 'lore-connect mem0'. * test(mem0): cover record mapping, resync idempotency, dry-run, auth guard Drives a fake client — no live API in CI. Covers record->add mapping with lore_id metadata, clear-once-then-add, idempotent re-push (partition holds the same set), dry-run, the stubbed-SDK adapter (infer=False, env key), and the CLI. * docs(readme): document the Mem0 documents backend Add the Mem0 section, the [mem0] extra, and frame both documents backends (Supermemory + Mem0). * docs(mem0): move usage into docs/connectors/mem0.md (align with the pages pattern) Adopt the generated-pages structure from main: drop the inline README edits and document Mem0 in its own docs/connectors/mem0.md, then regenerate the README Connectors region. No conflict surface beyond the generated block.
…s] (#4) * docs(decisions): record ADR-005 (Zep documents backend, graph-resync idempotency) Zep reuses the documents push(records) seam; it has no per-record upsert key (verified against zep-cloud 3.23.0), so idempotency is a graph resync — delete and recreate the source graph, then add text episodes. Validated under rac validate rac/. * feat(zep): add the Zep documents connector and CLI subcommand Reuse the documents seam: map source->Zep graph_id, add each record as a type=text episode with metadata (lore_id/type/status/title). Idempotent by graph resync (delete+create the graph, then add). SDK behind a thin client (env auth ZEP_API_KEY), optional [zep] extra. Exposes 'lore-connect zep'. * test(zep): cover record mapping, graph-resync idempotency, dry-run, auth guard Drives a fake client — no live API in CI. Covers record->episode mapping with lore_id metadata, clear-once-then-add, idempotent re-push, dry-run, the stubbed-SDK adapter (delete+create, tolerates a missing graph), and the CLI. * docs(readme): document the Zep documents backend Add the Zep section, the [zep] extra, and frame both documents backends (Supermemory + Zep). * docs(zep): move usage into docs/connectors/zep.md (align with the pages pattern) Adopt the generated-pages structure from main: drop the inline README edits and document Zep in its own docs/connectors/zep.md, then regenerate the README Connectors region.
…kends] (#5) * docs(decisions): record ADR-006 (Letta documents backend, archive-resync idempotency) Letta reuses the documents push(records) seam; a corpus source maps to a Letta archive, and the connector resolves the opaque archive_id behind the client. No per-record upsert key (verified against letta-client 1.12.1), so idempotency is an archive resync. Validated under rac validate rac/. * feat(letta): add the Letta documents connector and CLI subcommand Map source->Letta archive; add each record as a passage with metadata (lore_id/type/status/title). Idempotent by archive resync (delete archives by name, create, add). Adapter hides the archive_id indirection; env auth (LETTA_API_KEY cloud or LETTA_BASE_URL self-hosted), optional [letta] extra. Exposes 'lore-connect letta'. * test(letta): cover record mapping, archive-resync idempotency, dry-run, auth guard Drives a fake client — no live API in CI. Covers record->passage mapping, clear-once-then-add, idempotent re-push, dry-run, the stubbed-SDK adapter (archive list/create/delete + passage create by resolved id, cloud and self-hosted auth), and the CLI. * docs(readme): document the Letta documents backend Add the Letta section (cloud + self-hosted auth) and the [letta] extra. * docs(letta): move usage into docs/connectors/letta.md (align with the pages pattern) Adopt the generated-pages structure from main: drop the inline README edits and document Letta in its own docs/connectors/letta.md, then regenerate the README Connectors region.
…ackends] (#6) * docs(decisions): record ADR-007 (Cognee documents backend, two-phase pipeline) Cognee is the odd backend: a module-level async add->cognify pipeline with native content-hash idempotency (incremental_loading), no per-record metadata filter, verified against cognee 1.2.0. The connector stages records then cognifies once per dataset; provenance rides in a Lore-Id header. Validated under rac validate rac/. * feat(cognee): add the Cognee documents connector and CLI subcommand Map source->Cognee dataset; stage each record (with a Lore-Id provenance header) then build the graph once per dataset via add+cognify. Idempotency is Cognee's native content-hash dedup, not a resync. Async pipeline run behind a thin client (env auth LLM_API_KEY, lazy import), optional [cognee] extra. Exposes 'lore-connect cognee'. * test(cognee): cover stage-then-commit, provenance, dedup, dry-run, auth guard Drives a fake client and a stubbed async cognee module — no pipeline in CI. Covers stage-per-record + commit-once, the Lore-Id provenance header, content-hash dedup on re-push, empty-push no commit, dry-run, the batched add+cognify adapter, and the CLI. * docs(readme): document the Cognee documents backend Add the Cognee section (two-phase pipeline, content-hash idempotency, the no-deletion-prune caveat) and the [cognee] extra. * docs(cognee): move usage into docs/connectors/cognee.md (align with the pages pattern) Adopt the generated-pages structure from main: drop the inline README edits and document Cognee in its own docs/connectors/cognee.md, then regenerate the README Connectors region.
…he cross-repo dependency) Adopt CalVer (YYYY.M.<minor>, independent cadence — not lock-step with rac-core). Capture the real cross-repo dependency as the export contract schema_version, checked in code, never a rac-core package pin (ADR-007, ADR-063). Validated under rac validate rac/.
Add SUPPORTED_CONTRACT_VERSION ("1") and check_contract_version: the documents
and graph readers warn (ContractVersionWarning, on stderr) on an unknown
contract major and still proceed best-effort. The connector depends on the
contract version, not the rac package version (ADR-008).
…version Update the setuptools-scm note for CalVer (tag 2026.6.1, not 2026.06.1 — PEP 440 strips the zero), and note the schema_version-1 target in the README export contract section.
The version comments in pyproject.toml and python-publish.yml still carried the SemVer-era 'tag vX.Y.Z' guidance, which wrongly implies a leading 'v' and contradicts the CalVer decision. The PyPI publish triggers on a published GitHub Release (no tag-pattern filter), and setuptools-scm strips a leading 'v', so no 'v' is required; the tag is YYYY.M.<minor> (e.g. 2026.6.1). Comment-only change; no behaviour, build, or contract change. Implements rac/decisions/adr-008-calver-and-contract-version.md.
…ap:rac-connectors] Implements rac/roadmaps/repo-topology/rac-connectors.md (ADR-092). Seeds the rac-connectors repository from the former lore-connectors with history preserved, and applies the rac-* naming: - distribution lore-connectors -> rac-connectors (registered on PyPI) - import package src/lore_connectors -> src/rac_connectors (one dist, one subdir per integration: cognee, letta, mem0, neo4j, supermemory, zep) - CLI entry point lore-connect -> rac-connect The export-contract field names (lore_id) and the "Lore" product brand are unchanged. Connectors remain thin export-contract consumers over the public rac CLI; no engine internals (ADR-073, ADR-063, ADR-002).
…map:rac-connectors]
…:rac-connectors] Implements rac/roadmaps/repo-topology/rac-connectors.md (ADR-092). Renames the outbound contract field the connectors write into backends: - metadata key lore_id -> rac_id (mem0, letta, zep, supermemory) - cognee header Lore-Id: -> Rac-Id: The value is unchanged (the canonical RAC-* artifact id), so name and value now agree (rac_id: RAC-...). This is a deliberate outbound data-contract change, recorded in the rac-core ADR for the connectors repackage. The "Lore" product brand and the verify-in-Lore loop wording are unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Seeds the
rac-connectorsrepository per ADR-092 (one repo per concern, subdir per member) and therac/roadmaps/repo-topology/rac-connectors.mdroadmap.What this does
itsthelore/lore-connectorsin with full history preserved (31 commits + this rename commit;git log --follow src/rac_connectors/supermemory/connector.pytraces back through the move).rac-*naming:lore-connectors→rac-connectors(to be registered on PyPI)src/lore_connectors→src/rac_connectors— one dist, one subdir per integration (cognee/ letta/ mem0/ neo4j/ supermemory/ zep/)lore-connect→rac-connectrac/corpus references to the new slug/package.Deliberately unchanged
lore_id) — renaming would break the data contract.itstheloreorg name.racCLI; no engine internals (ADR-073, ADR-063, ADR-002).Scope note
This move also repackages + renames (beyond pure topology), per your direction. I'm recording the structure + PyPI-rename decision as a short ADR in
rac-core(separate PR on the same feature branch).Merging
mainis an empty-root trunk already contained as an ancestor, so this fast-forwards cleanly. Create a merge commit — do not squash (squash would collapse the 31 preserved commits)..github/workflows/until you wire up / re-enable them; the publish workflow now targets therac-connectorsdist.Remaining maintainer org actions
lore-connectorswith a redirect note torac-connectors.rac-connectorsname on PyPI; optionally setmainas the default branch.Execution tracking: asdecided/core#228 (
rac-connectorsitem).