Skip to content

docs: dn_redis is a key-shape protocol + Rust command type model#455

Merged
AdaWorldAPI merged 2 commits into
mainfrom
docs/dn-redis-emulation
Jun 3, 2026
Merged

docs: dn_redis is a key-shape protocol + Rust command type model#455
AdaWorldAPI merged 2 commits into
mainfrom
docs/dn-redis-emulation

Conversation

@AdaWorldAPI

@AdaWorldAPI AdaWorldAPI commented Jun 3, 2026

Copy link
Copy Markdown
Owner

Summary

Clarifies that lance-graph-cognitive::container_bs::dn_redis is a Redis wire-protocol EMULATION, NOT a service dependency on Redis. Adopters reading the module + the surrounding lab-vs-canonical discipline docs sometimes conclude an external Redis server is required; this doc names the FalkorDB/KùzuDB precedent and lists three valid backends.

The three valid backends

  • (a) external Redis cluster (traditional hybrid)
  • (b) in-binary OGIT class view + DataFusion query over the local Lance dataset, projected through the dn_redis adapter shape — the zero-boundary single-binary target
  • (c) anything else that produces the documented ada:dn:{hex} / ada:spine:{hex} key shape with the documented operations

Why this matters

For single-binary deployments (e.g. AdaWorldAPI/bardioc/substrate-b) the natural backend is (b): the in-binary view. This means the "zero application-level boundaries" deployment shape (per the PR #452/#454 append-only-Raft doc) survives the addition of HHTL-keyed hot lookups precisely because dn_redis is EMULATION, not a service.

The pattern is well-established outside lance-graph: FalkorDB (formerly RedisGraph) and KùzuDB both "talk Redis" while their storage + execution layers are completely different. dn_redis borrows the wire-protocol-emulation pattern.

Provenance

Asks

  1. Confirm contribution shape welcome
  2. Pick doc home (current: docs/DN_REDIS_EMULATION.md; alternative: .claude/knowledge/dn-redis-emulation.md if AdaWorldAPI prefers the Claude-Code knowledge layer)
  3. Decide if the doc should also cross-link to the protocol-only annotation in any plan or seam-map docs (operator preference)

Doc-only; zero code; pairs with PR #454.

Summary by CodeRabbit

  • Documentation
    • Updated protocol specification documentation with improved clarity on system capabilities and constraints.
    • Formalized backend implementation categories and consumer expectations.
    • Corrected previous mischaracterizations of system scope.
    • Enhanced cross-references and documentation links.

Clarifies that the dn_redis module in lance-graph-cognitive is a
PROTOCOL/SHAPE adapter, not a service dependency. Three valid
backends: external Redis (a); in-binary OGIT class view + DataFusion
query over Lance (b, the zero-boundary target); anything that
produces the documented ada:dn key shape (c).

Same pattern as FalkorDB (formerly RedisGraph) and KuzuDB — talk
Redis without BEING Redis. Adopters reading the dn_redis module +
the lab-vs-canonical discipline docs sometimes conclude that an
external Redis server is required; this doc clarifies that
'protocol-only adapter' means the SHAPE is the contract, not a
service binding.

Doc-only; new file at docs/DN_REDIS_EMULATION.md. Pairs naturally
with the cluster-asymmetry + append-only-Raft docs (PR #452/#453/
#454) — all three address common mis-reads of lance-graph idioms
through a legacy lens.

Provenance:
- Surfaced by: bardioc PR #15 conversation thread
- Draft outline: bardioc/UPSTREAM_LANCE_GRAPH_PR_CANDIDATES.md T1.5
- Sister doc: APPEND_ONLY_RAFT_DOVETAIL.md (PR #452/#454)
- Sister doc: CLUSTER_ASYMMETRY.md (PR #453/#454)
@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR updates the dn_redis module documentation to formally define it as a key-shape protocol plus Rust command type model contract, clarifying its scope, enumerating what is included (key helpers, command types, serialization) versus excluded (wire-protocol, connect API), and specifying two valid backend execution strategies with documented constraints for Redis Cluster MGET operations.

Changes

Redis Protocol Adapter Documentation

Layer / File(s) Summary
dn_redis protocol contract and backend categories
docs/DN_REDIS_KEY_SHAPE_PROTOCOL.md
Documents dn_redis as a key-shape protocol plus Rust command type model with key-construction helpers, RedisCommand/RedisPipeline types, and CogRecord serde utilities. Specifies two valid backend categories: standalone Redis execution (with documented hash-tag re-keying option and MGET cross-slot behavior caveat for the existing ada:dn:{hex} key layout), and in-binary Lance/DataFusion executor projecting results into Redis-shaped response types. Corrects earlier architectural mischaracterizations and frames the system as a consumer-supplied execution contract.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

In docs we write with care and grace,
A protocol finds its rightful place,
No wire-dance, just shape and key,
Two backends now, for all to see,
The contract clearer than before! 🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: dn_redis is a key-shape protocol + Rust command type model' directly and accurately reflects the main change documented in the PR objectives and file summary—a clarification/reframing of what dn_redis is and what it is not.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
  • Commit unit tests in branch docs/dn-redis-emulation

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aac812162f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/DN_REDIS_EMULATION.md Outdated

This doc clarifies that **"protocol-only adapter" means the SHAPE is the contract — the backend is open**. Three valid backends:

- (a) an external Redis cluster (traditional hybrid deployment)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not present the current key layout as Redis Cluster compatible

For consumers selecting option (a) with an actual Redis Cluster, the documented walk_to_root/mget_dns operations will generally fail because dn_key produces keys such as ada:dn:0102... without a shared Redis hash tag, while Redis Cluster supports multi-key operations only when every key belongs to the same hash slot (Redis Cluster specification). The adapter's MGET commands therefore make an external Redis cluster an invalid backend unless the key layout is redesigned or the backend fans the reads out, so this should not be listed as unconditionally valid.

Useful? React with 👍 / 👎.

Comment thread docs/DN_REDIS_EMULATION.md Outdated

[FalkorDB](https://www.falkordb.com/) (formerly RedisGraph) and [KùzuDB](https://kuzudb.com/) both "talk Redis" — they expose the Redis wire protocol — while the storage and execution underneath are completely different. They are NOT Redis; they emulate the wire protocol so existing Redis clients work.

`dn_redis` follows the same pattern. It defines:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Describe dn_redis as a command model, not wire-protocol emulation

The dn_redis module does not follow the stated wire-protocol-emulation pattern: it only constructs Rust String keys and RedisCommand enum values, and contains no RESP encoder/parser, listener, command executor, or backend interface. As a result, existing Redis clients cannot communicate with it and an in-binary DataFusion implementation would not emit Redis wire-protocol responses without a separate new layer; describing the module as wire-protocol emulation will mislead consumers about what is already implemented.

Useful? React with 👍 / 👎.

Comment thread docs/DN_REDIS_EMULATION.md Outdated

For the in-binary backend (option b):

1. Implement a `dn_redis::Backend` impl (or whatever the trait name resolves to in the adapter's surface) that intercepts the documented operations

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove the nonexistent Backend implementation step

For a consumer attempting the recommended in-binary backend, this first step cannot be followed: dn_redis exports no Backend trait or equivalent execution surface, and the repository has no call sites that mount either a Redis client or a backend for RedisPipeline. The parenthetical placeholder does not identify a resolvable API, so the document should either specify the new interface consumers must create themselves or avoid presenting this as an implementation procedure.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/DN_REDIS_EMULATION.md (1)

15-15: ⚡ Quick win

Avoid hardcoding module line count in docs.

“253-line protocol-only adapter” will drift quickly and create doc staleness; prefer a timeless description without exact LOC.

🤖 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/DN_REDIS_EMULATION.md` at line 15, Remove the hardcoded "253-line"
reference and any other exact LOC mentions from the DN_REDIS_EMULATION.md
description of lance-graph-cognitive::container_bs::dn_redis; instead describe
it as a "protocol-only adapter" (or "small/lightweight protocol-only adapter")
so the text remains timeless, and update any SPRINT plan docs that reference
dn_redis as "253-line protocol-only" to the new phrasing to avoid future
staleness.
🤖 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 `@docs/DN_REDIS_EMULATION.md`:
- Line 42: The doc currently uses speculative wording "dn_redis::Backend (or
whatever the trait name resolves to)"; replace that with the actual exported
symbol from the dn_redis crate (e.g., the exact trait/type name exported for
adapter backends) or explicitly mark the snippet as pseudocode. Update the
sentence to either reference the verified exported symbol (for example:
dn_redis::BackendTrait — use the real exported name you find in the crate) or
change phrasing to "Implement a backend that implements the following pseudocode
trait:" and keep the remainder as pseudocode; ensure you update any further
references in the document to use the same concrete symbol or the explicit
pseudocode label (search for "Backend" and similar occurrences to keep
consistency).

---

Nitpick comments:
In `@docs/DN_REDIS_EMULATION.md`:
- Line 15: Remove the hardcoded "253-line" reference and any other exact LOC
mentions from the DN_REDIS_EMULATION.md description of
lance-graph-cognitive::container_bs::dn_redis; instead describe it as a
"protocol-only adapter" (or "small/lightweight protocol-only adapter") so the
text remains timeless, and update any SPRINT plan docs that reference dn_redis
as "253-line protocol-only" to the new phrasing to avoid future staleness.
🪄 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 Plus

Run ID: 789c3ff8-c942-4887-986b-b66dd63649fd

📥 Commits

Reviewing files that changed from the base of the PR and between 16f879b and aac8121.

📒 Files selected for processing (1)
  • docs/DN_REDIS_EMULATION.md

Comment thread docs/DN_REDIS_EMULATION.md Outdated
…tocol emulation

Four review findings on PR #455 walked back, all real:

Codex P2 1 - Redis Cluster is not plug-and-play. The walk_to_root /
mget_dns operations use MGET, but the current key layout (ada:dn:{hex})
has no shared hash tag. Redis Cluster requires multi-key ops to belong
to the same hash slot. So external Redis CLUSTER is NOT a valid
backend without re-keying with hash tags. Added explicit caveat.

Codex P2 2 - dn_redis is NOT wire-protocol emulation. The module
exports Rust String keys + a RedisCommand enum + RedisPipeline.
There is no RESP encoder, no parser, no listener, no command
executor. Existing Redis clients cannot communicate with it. The
FalkorDB / KuzuDB precedent does NOT apply (those projects implement
the actual RESP wire protocol; dn_redis does not). Reframed the doc
to "key-shape protocol + Rust command type model" - which is what
the module actually is.

Codex P2 3 - There is no dn_redis::Backend trait to implement.
The "Recommended consumer pattern" first step cited a nonexistent
API. Rewrote the section to show what consumer code actually has
to provide: a struct + execute function that takes RedisCommand
and runs it against the chosen backend. The example is illustrative
(not a shipped trait).

CodeRabbit minor - Same critique class. The speculative API
wording is gone.

Net effect: the doc now accurately describes what dn_redis IS
(key-shape + command type model) and what adopters have to provide
(an executor). Two valid backend categories enumerated honestly:
(A) standalone Redis with optional hash-tag re-keying for clustered
deployments; (B) in-binary executor over Lance via DataFusion.

File renamed: DN_REDIS_EMULATION.md -> DN_REDIS_KEY_SHAPE_PROTOCOL.md
to match the corrected framing.

Provenance: codex P2 + coderabbit minor on PR #455 commit aac8121.
@AdaWorldAPI AdaWorldAPI changed the title docs: dn_redis is Redis-protocol EMULATION, not a Redis service dep docs: dn_redis is a key-shape protocol + Rust command type model Jun 3, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 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 `@docs/DN_REDIS_KEY_SHAPE_PROTOCOL.md`:
- Around line 50-68: The example shows an async call to
self.lance.read_by_dn(...).await inside LanceBackend::execute but execute is
declared synchronously; change the signature of execute to async (async fn
execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error>) so await is
valid, and ensure any call sites handle the returned Future, or alternatively
remove .await and make read_by_dn synchronous; update the LanceBackend::execute
and any related usages accordingly to keep consistency between execute and
read_by_dn.
🪄 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 Plus

Run ID: 4c55d01b-50af-43e0-8b60-32406ed14962

📥 Commits

Reviewing files that changed from the base of the PR and between aac8121 and 6ca9f86.

📒 Files selected for processing (1)
  • docs/DN_REDIS_KEY_SHAPE_PROTOCOL.md

Comment on lines +50 to +68
```rust
// Consumer code, NOT lance-graph code
struct LanceBackend { /* ... */ }

impl LanceBackend {
fn execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error> {
match cmd {
RedisCommand::Get(key) => {
let dn = self.parse_dn_from_key(&key)?;
let row = self.lance.read_by_dn(dn).await?;
Ok(RedisValue::Bulk(cog_record_to_bytes(&row)))
}
RedisCommand::Mget(keys) => { /* batch lookup over Lance */ }
RedisCommand::Keys(pattern) => { /* DataFusion scan filtered by prefix */ }
// ... etc per the enum's variants
}
}
}
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Fix async/await syntax error in code example.

Line 59 uses .await but the execute function on line 55 is not declared as async. This will not compile.

Either declare the function as async fn:

async fn execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error>

Or remove the .await and make the hypothetical read_by_dn method synchronous. Since this is an example showing the pattern consumers should implement, the async version is likely more realistic for I/O operations.

🔧 Proposed fix
 impl LanceBackend {
-    fn execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error> {
+    async fn execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error> {
         match cmd {
             RedisCommand::Get(key) => {
🤖 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/DN_REDIS_KEY_SHAPE_PROTOCOL.md` around lines 50 - 68, The example shows
an async call to self.lance.read_by_dn(...).await inside LanceBackend::execute
but execute is declared synchronously; change the signature of execute to async
(async fn execute(&self, cmd: RedisCommand) -> Result<RedisValue, Error>) so
await is valid, and ensure any call sites handle the returned Future, or
alternatively remove .await and make read_by_dn synchronous; update the
LanceBackend::execute and any related usages accordingly to keep consistency
between execute and read_by_dn.

@AdaWorldAPI AdaWorldAPI merged commit d790835 into main Jun 3, 2026
1 check passed
AdaWorldAPI added a commit that referenced this pull request Jun 3, 2026
…n-empty-guard

fix(post-merge #456 + #455): EMPTY guard + use crate::nars::InferenceType + EdgePair carrier + async syntax
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