feat(continuum-core/persona): L0-3a.2a — EngramGraph + EngramEdge + EdgeKind (algorithm 3 substrate)#1474
Merged
Conversation
…dgeKind (algorithm 3 substrate)
Card: 8459bfa6-b40c-4c22-8f25-0963a7987c17
Sidecar substrate for algorithm 3 (activation spreading, COGNITION-ALGORITHMS.md §3). Pure storage layer — traversal logic lands in L0-3a.5. Does NOT modify the existing persona::engram admission membrane.
## What ships
### persona/engram_graph.rs (new, 376 lines)
- EdgeKind enum — SharedEntity | SharedTopic | CitedIn | RecallCoOccurrence | ConversationalReply | TaskOutcome
- EngramEdge { target: Uuid, kind: EdgeKind, weight: f32 } — algorithm-3 traversal payload
- EngramGraph — DashMap<Uuid, Vec<EngramEdge>> sharded for concurrent writes
- new() / with_capacity(n) / default()
- add_edge(from, to, kind, weight)
- neighbors(id) — outbound edges, O(1) amortized, insertion order preserved
- in_degree(id) — inbound count, O(N) scan (cold path — algorithm 4 centrality)
- edge_count() — telemetry
- evict_engram(id) — removes outbound + inbound, idempotent
- is_empty()
### ts-rs bindings
shared/generated/persona/EdgeKind.ts
shared/generated/persona/EngramEdge.ts
## Sidecar pattern
Intentionally separate from persona::engram (the admission membrane):
- engram.rs ships provenance, trust, content refs — WHERE engrams come from
- engram_graph.rs ships connectivity — HOW engrams connect
Keeping them separate means admission consumers don't grow algorithm-3 dependencies, and algorithm-3 consumers don't grow admission dependencies. Clean concern boundaries.
## Tests (16 pass, 0 fail)
- new_engram_graph_is_empty
- add_edge_increments_count
- neighbors_returns_added_edges_in_insertion_order
- neighbors_of_unknown_source_is_empty
- weights_preserved_through_neighbors
- in_degree_counts_inbound_edges_across_sources
- in_degree_counts_repeated_edges_from_same_source
- evict_engram_removes_outbound_edges
- evict_engram_removes_inbound_edges_from_other_engrams
- evict_engram_is_idempotent
- concurrent_add_edge_from_threads_is_safe (8 threads × 100 edges, all targeting same id, in_degree=800)
- default_constructor_matches_new
- with_capacity_constructor_works
- edge_kind_round_trips_through_serde
- export_bindings_edgekind (ts-rs auto)
- export_bindings_engramedge (ts-rs auto)
## What is NOT in this card
- spread_activation function (L0-3a.5, algorithm 3 — reads this graph)
- EdgeKind weights tuned by algorithm 7 (L0-4c yield-learning)
- RecallMetadata sidecar (L0-3a.2b — salience, last_touched, access_count, embedding)
- EngramRef shape (L0-3a.2b)
- Engram admission membrane modifications (no changes to persona::engram)
## Predecessors
- #1473 (L0-3a.1 HippocampusModule skeleton) — merged
- #1471 (L0-3a.0 trait machinery) — merged
- #1470 (cognition algorithms doc) — merged
## Flywheel test
Third PR (after #1471, #1473) through the auto-merger flywheel that peer's #1091/#1092/#1093 enabled. Local fmt was scoped to ONLY my file (no widespread cargo fmt -p sweep), so no companion fmt-drift PR needed this time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 task
joelteply
added a commit
that referenced
this pull request
May 30, 2026
The `avatars: ./src/models/avatars` additional_context was added in 9b1f6ca (April 2026) when the plan was to bake CC0 avatar VRMs into the continuum-core image. That plan never landed end-to-end — docker/continuum-core.Dockerfile lines 131-143 document the rollback: src/models is gitignored, the dir doesn't exist in CI checkouts, and the Dockerfile uses `RUN mkdir -p /app/avatars` as a placeholder instead of COPYing from the avatars context. The compose-side context declaration was left behind, dangling. No Dockerfile uses `--from=avatars` (verified by grep), so the declaration referenced nothing in build instructions. But docker compose validates that ALL additional_contexts resolve at build time — a missing local context dir fails the whole build with "stat /tmp/carl-smoke-NNNN/src/ models/avatars: no such file or directory". That's the exact failure mode currently blocking carl-install-smoke on PR #1475 (Mac Intel hardware tier) — any PR that touches install.sh triggers carl-install-smoke, which has been silently broken by this dangling context since the rollback. Other PRs (e.g. #1471, #1473, #1474) didn't touch install.sh so the check never ran on them; the break was invisible until now. Removing the line restores the carl-install-smoke happy path while keeping the Dockerfile's empty-dir placeholder intact. Restore the build context when the avatar-provisioning story lands (LFS, model-init download, or curl from a CC0 URL in CI before docker build) per the gap noted in docs/infrastructure/PR891-E2E-VALIDATION.md. Inline comment preserves the context-of-removal in the file so a future contributor doesn't re-add the dangling line. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
joelteply
added a commit
that referenced
this pull request
May 30, 2026
…se (#1476) The `avatars: ./src/models/avatars` additional_context was added in 9b1f6ca (April 2026) when the plan was to bake CC0 avatar VRMs into the continuum-core image. That plan never landed end-to-end — docker/continuum-core.Dockerfile lines 131-143 document the rollback: src/models is gitignored, the dir doesn't exist in CI checkouts, and the Dockerfile uses `RUN mkdir -p /app/avatars` as a placeholder instead of COPYing from the avatars context. The compose-side context declaration was left behind, dangling. No Dockerfile uses `--from=avatars` (verified by grep), so the declaration referenced nothing in build instructions. But docker compose validates that ALL additional_contexts resolve at build time — a missing local context dir fails the whole build with "stat /tmp/carl-smoke-NNNN/src/ models/avatars: no such file or directory". That's the exact failure mode currently blocking carl-install-smoke on PR #1475 (Mac Intel hardware tier) — any PR that touches install.sh triggers carl-install-smoke, which has been silently broken by this dangling context since the rollback. Other PRs (e.g. #1471, #1473, #1474) didn't touch install.sh so the check never ran on them; the break was invisible until now. Removing the line restores the carl-install-smoke happy path while keeping the Dockerfile's empty-dir placeholder intact. Restore the build context when the avatar-provisioning story lands (LFS, model-init download, or curl from a CC0 URL in CI before docker build) per the gap noted in docs/infrastructure/PR891-E2E-VALIDATION.md. Inline comment preserves the context-of-removal in the file so a future contributor doesn't re-add the dangling line. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.
Card:
8459bfa6-b40c-4c22-8f25-0963a7987c17Sidecar substrate for algorithm 3 (activation spreading, COGNITION-ALGORITHMS.md §3). Pure storage layer — traversal logic lands in L0-3a.5. Does NOT modify the existing
persona::engramadmission membrane.What ships
persona/engram_graph.rspersona/mod.rspub mod engram_graph;shared/generated/persona/EdgeKind.tsshared/generated/persona/EngramEdge.tsModule surface
Surface:
new()/with_capacity/default()/add_edge/neighbors/in_degree/edge_count/evict_engram(idempotent, removes outbound + inbound) /is_empty.Sidecar pattern
Intentionally separate from
persona::engram(the admission membrane):engram.rsships provenance, trust, content refs — where engrams come fromengram_graph.rsships connectivity — how engrams connectKeeping them separate means admission consumers don't grow algorithm-3 dependencies, and algorithm-3 consumers don't grow admission dependencies.
Tests (16 pass, 0 fail)
export_bindings_edgekind,export_bindings_engramedgeWhat is NOT in this card
spread_activationfunction (L0-3a.5, algorithm 3 — reads this graph)RecallMetadatasidecar (L0-3a.2b — salience, last_touched, access_count, embedding refs)EngramRefshape (L0-3a.2b)Predecessors merged
Flywheel
Third PR through the auto-merger after peer's #1091/#1092/#1093 shipped. Local fmt was scoped to only my file (no widespread
cargo fmt -psweep), so no companion fmt-drift PR needed this time — cleaner dogfood.🤖 Generated with Claude Code