Skip to content

Comments

feat(spo-3d): Three-Axis Content-Addressable Graph with Causal Chain Discovery#130

Merged
AdaWorldAPI merged 10 commits intomainfrom
feat/spo-3d-axes
Feb 20, 2026
Merged

feat(spo-3d): Three-Axis Content-Addressable Graph with Causal Chain Discovery#130
AdaWorldAPI merged 10 commits intomainfrom
feat/spo-3d-axes

Conversation

@AdaWorldAPI
Copy link
Owner

SPO 3D: Three-Axis Content-Addressable Graph

What

Adds ContainerGeometry::Spo — three sparse axes (Subject/Predicate/Object) packed into one 2KB CogRecord. Forward, reverse, and relation queries become native axis scans with no join or edge table.

Architecture

  • SparseContainer: bitmap + non-zero words encoding (320 bytes at 30% density)
  • NibbleScent: 48-byte per-axis nibble histogram replacing 5-byte XOR-fold
  • SpoStore: three-axis query engine with causal chain discovery
  • SpoBuilder: node/edge/meta-awareness record construction
  • Z→X chain links: causal coherence via Hamming resonance (Piaget development)

Files

Docs (docs/spo_3d/):

  • INTEGRATION_PLAN.md — Master plan, phases, decisions
  • CONTRACTS.md — Trait definitions, invariants, compile-time guarantees
  • SCHEMA.md — Byte-level layout of every field
  • NATURES_CAM.md — Biological foundations (DNA, immune system, Piaget)

Rust (src/graph/spo/):

  • sparse.rs — SparseContainer + PackedAxes (506 lines)
  • scent.rs — NibbleScent 48-byte histogram (204 lines)
  • store.rs — SpoStore three-axis queries + causal chains (434 lines)
  • builder.rs — Node/edge/meta-awareness construction (340 lines)
  • tests.rs — 6 ironclad tests (348 lines)
  • mod.rs — Module root + re-exports

What does NOT change

  • Container type (128×u64, 8192 bits)
  • CogRecord struct (meta + content = 2KB)
  • 5 RISC ops (BIND, BUNDLE, MATCH, PERMUTE, SCAN)
  • Codebook (4096 entries)
  • All existing tests (1,267+)
  • MetaView W0-W11 layout

6 Ironclad Tests

  1. Node round-trip (build → insert → retrieve → verify)
  2. Forward query (Jan KNOWS Ada → find Ada from Jan)
  3. Reverse query (find Jan from Ada — NO extra index)
  4. CAM content lookup (100 nodes → find by fingerprint)
  5. NARS reasoning (deduction + chain confidence)
  6. Causal chain coherence (Z→X resonance + meta convergence tsunami)

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 02923750c3

ℹ️ 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".

extra_flags: u16,
) -> Result<CogRecord, SpoError> {
// Pack sparse axes into content container
let (content, mut desc) = pack_axes(x, y, z)?;

Choose a reason for hiding this comment

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

P1 Badge Sparsify axes before packing SPO records

assemble_record packs whatever SparseContainer::from_dense produced, but the current builders feed it dense fingerprints (label_fp and Container::random-derived values), so each axis typically has ~128 non-zero words and violates the 6 + Nx + Ny + Nz <= 128 packing limit. In practice this makes build_node, build_edge, and build_meta_awareness return AxesOverflow for normal inputs instead of producing records.

Useful? React with 👍 / 👎.

use super::sparse::{pack_axes, unpack_axes, AxisDescriptors, SparseContainer, SpoError};

/// SPO geometry ID (matches ContainerGeometry::Spo = 6).
const GEOMETRY_SPO: u8 = 6;

Choose a reason for hiding this comment

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

P1 Badge Use a geometry id recognized by ContainerGeometry

The builder hardcodes SPO geometry as 6, but ContainerGeometry::from_u8 currently only recognizes 0..=5 and unknown values are treated as default Cam by MetaView::geometry(). Records produced here will therefore be misclassified by shared metadata readers, so downstream code cannot reliably detect or handle SPO records.

Useful? React with 👍 / 👎.

Comment on lines +331 to +332
let bitmap = [content.words[offset], content.words[offset + 1]];
let words: Vec<u64> = content.words[offset + 2..offset + 2 + count].to_vec();

Choose a reason for hiding this comment

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

P1 Badge Validate axis descriptor bounds before indexing

unpack_one_axis directly indexes content.words[offset] and slices offset + 2..offset + 2 + count without checking bounds. If metadata descriptors are corrupted (or a non-SPO record is scanned), queries will panic instead of returning a SpoError, which can crash the store during read paths.

Useful? React with 👍 / 👎.

@AdaWorldAPI AdaWorldAPI merged commit 6d01c0a into main Feb 20, 2026
6 of 11 checks 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