The whole idea in one picture. Every Ally reasons over a single Postgres that holds semantic vectors (pgvector) beside the relationship graph (Apache AGE). The external vector service goes away.
01

## Why graph-native

Most AI apps answer with vector search: embed the text, find the most similar passages, hand them to the model. That is good at “find text that looks like this,” but it is blind to the things you have said Kiduna is about — who owns a fact, who it is about, how it connects, and who may see it.

Your design is full of those statements: “all allies have the same context about Jeya,” “node types such as member, ally, and Duna,” knowledge that is “public, private, or secret.” Those are relationship and permission claims. A graph expresses them natively; a vector index cannot.

The difference is the fan-out. A vector store returns a flat list. The graph lands on the same passage, then follows the edges to who it is about, who owns it, which organization it belongs to, and the reader’s own lineage.
The decision

Consolidate knowledge into the graph (Apache AGE on Postgres), keep fast semantic search by moving vectors into the same database (pgvector), and retire Pinecone.

02

## The unified graph model

Everything in Kiduna is a node; every meaningful relationship is an edge. One model carries both the organization and its knowledge — so an Ally can reason across people, orgs, and facts in a single traversal.

It spans six layers — identity/wallet, the Ally and its skills, community & access, social & commerce, governance, and the knowledge content itself — all projected from your three databases, joined by `wallet`. The full node-and-edge catalog is in the appendix.

The organization and its knowledge in one graph. The structural half (Person, Ally, Wallet, KnowledgeBase, communities, forums, lineage) already exists in the system today; this proposal completes it by pulling knowledge content — Chunk and Entity — into the same graph.
Person Ally Wallet Knowledge Entity Alliance DUNA / Forum

Each Ally is an NFT. At registration, Kiduna mints an NFT identity for the Ally into the owner’s wallet. In the graph that is one node — `NFT` — that links the Ally to the Wallet holding it. It delivers two things you called for: traceability (every action an Ally takes is attributable to a token on-chain — “if the ally has an address … we can trace”) and portable ownership (transfer the token, transfer the Ally).

The Ally has an on-chain identity. A per-Ally NFT in the owner’s wallet makes ownership transferable and every action traceable — the graph records it as an `NFT` node between Ally and Wallet.
03

## “Inform” is writing into the graph

When a user — or an Ally, on command — adds knowledge (an upload, a Google Doc/Drive connection, or a “research X and build me a knowledge base” instruction), it flows through one pipeline and lands in the graph:

Org-default knowledge is connected once and everyone inherits it — the code’s “everybody automatically gets those” rule, expressed as a shared connection instead of a copy. The Inform tab in Create is just the human view of this pipeline.
04

## Fast semantic search — without Pinecone

Dropping Pinecone does not mean dropping similarity search. It moves into the same Postgres via pgvector, so vectors sit next to the graph. A single query can then filter by relationship, then rank by similarity — impossible when the vectors live in a separate system.

Embeddings already live in Postgres today (as a JSON array, with a standing note to “use pgvector”). Turning that into a real pgvector index is a contained, well-trodden change — not a rebuild.
05

## How an Ally answers

Every question runs the same loop. The step that makes the Ally understand the situation rather than just retrieve text is Traverse — walking the graph out from the passages it found.

Retrieve finds the passages; Traverse explains them — who they’re about, who owns them, which DUNA they belong to, the reader’s own lineage — all scoped to what this Ally may see.
06

## The permission model — who sees what

This is the part to get exactly right. Your rule — “my ally also sees what Jeya says, but it won’t take instructions from Jeya — just context that it stores — and all allies have the same context about Jeya” — falls straight out of the graph: context is shared, authority is not.

Context is shared; authority is not. Every Ally can read the public layer, so they agree on the facts. Private and secret knowledge is simply never traversed for a reader who lacks the edge, and another person’s message becomes stored context — never a command.

Concretely, every knowledge base and chunk carries one of three scopes, and every read is checked against the Ally that is asking:

Who can read what. Public is shared across the network; private stays with the owner and their own Allies; secret is sealed — stored for the owner but never surfaced in ordinary reasoning (the right home for keys and seed phrases).

Four rules make those scopes actually hold — this is where permission is enforced, not merely described:

- Structural, not a filter. Scope is a `SCOPED_TO` edge. Every read is anchored to the caller and only walks edges they are allowed — an off-limits chunk is never traversed, not “fetched then hidden.”
- Enforced in the tool, not the prompt. An Ally’s reach is baked into its retrieval tool (a closure over the caller’s wallet and allowed knowledge bases). No chat message — however clever — can make an Ally widen its own access.
- Injection-safe. A user’s words only ever go to vector search; they never become part of a graph query. Only validated ids traverse the graph, so a crafted prompt cannot exfiltrate someone else’s data.
- Shared structure, isolated content. The relationships (who owns what, who belongs where) are shared so Allies can reason about the organization; the text of private and secret knowledge stays hard-isolated to its owner.

07

## How this maps to what you asked for

You said (meeting / whiteboard) | The architecture answer
--- | ---
“Users interact exclusively through natural language” | The Ally reasons over the graph; chat is the only interface — no menus.
“Node types such as member, ally, and Duna” | Those are the graph’s core nodes (§02).
“Update the graph database to include these tasks/actions” | Skills, Tools and Actions are nodes; the action inventory lives in the same graph.
Knowledge is “public, private, or secret” | A `SCOPED_TO` edge, enforced during retrieval (§03, §06).
“All allies have the same context about Jeya” | Shared read over one graph; authority gated by ownership (§06).
“Create a knowledge base about X … do research” | The ingestion pipeline the Ally drives on command (§03).
A single per-person Ally | One Ally node per person, reasoning over the shared graph (§02, §05).
Traceability (the Ally-NFT idea) | Every write is a provenance-linked node/edge (§01, §05).

08

## Getting there — phased, low-risk

No big-bang cutover. Each phase leaves the system fully working, and Pinecone is only removed once pgvector matches it on recall.

The structural graph, the hybrid-search entry point, and the chunk-graph stubs already exist in the codebase — this is completion, not reinvention.
09

## Trade-offs we accept

- Scale of vector search. Pinecone is tuned for very large corpora; pgvector with an HNSW index comfortably covers Kiduna’s launch and growth horizon. If one corpus ever gets huge, we tune the index or shard — a good problem for later, not a launch concern.
- Migration effort. Real, but contained (embeddings already in Postgres; scaffolding present) and fully parallelizable behind a flag.
- Graph discipline. A shared brain needs a clean, permissioned model. That is a feature — it is what makes traceability and “shared context, private authority” enforceable rather than aspirational.

—

## Appendix · What lives in the graph

The graph is a projection of your three databases (joined by `wallet`), organized in six layers — about 27 node types and 46 edge types. Postgres stays the system of record; the graph is rebuildable from scratch.

The Wallet is the hub. The whole wallet section — balance, deposits, withdrawals, rewards, and history — anchors on the `Wallet` node.

The wallet section, as a graph. Balance is a property of the `Wallet`; rewards fan out up the lineage tree as `Reward` nodes (`EARNED`); deposits, withdrawals and transfers are recorded as transaction nodes — all anchored on the one Wallet.
Six layers, one graph (`kiduna_kb`). Left column names the layer and the database it is projected from; chips are representative node types — the full list is below.

Layer | Nodes | Key edges | From
--- | --- | --- | ---
Identity · wallet · rewards | Wallet (holds balance) · User · Reward · Ally NFT · OnchainAccount · OnchainTx | `IDENTIFIED_BY` · `REFERRED_BY` · `EARNED` · `HELD_BY` · `RECORDED` | kinship-backend
Agent — the Ally | Agent (Ally / Presence / Worker) · KnowledgeBase · Prompt · Skill · SkillTemplate · Tool · GlobalToolAccount | `OWNED_BY` · `USES_KB` · `HAS_SKILL` · `USES_PROMPT` · `REPORTS_TO` · `MINTED_AS` | kinship-agent-be
Community & access | Context · NestedContext · ContextRole · Code | `MEMBER_OF` · `GRANTS_ACCESS_TO` · `SCOPED_TO` · `REDEEMED` · `PART_OF` | kinship-agent-be
Social & commerce | Alliance · Bot · Offering · Purchase | `TEAM_MEMBER` · `INSIDE` · `OF_OFFERING` · `CAME_FROM` | kinship-backend
Governance · forums | Market (Forum) · Objective · Dimension · Operator · Elector · Proposal | `IN_MARKET` · `IS_AGENT` · `PRODUCED` · `TRADED` · `VOTED` · `SPONSORED_BY` | kinship-shared
Content | Document · Chunk · Entity | `HAS_DOCUMENT` · `HAS_CHUNK` · `NEXT` · `MENTIONS` · `RELATED_TO` | KB text (LLM)

On every node — scope

`owner_wallet` · `visibility` {public · private · secret} · `access_level` {PUBLIC · PRIVATE · ADMIN · CREATOR} · `kb_id` / `market_id` / `context_id`. No node exists without a scope — that is what the permission model (§6) enforces.

Live today vs. planned. The structural, content and lineage layers are built; a few nodes are planned extensions that slot into the same model without changing it — `OnchainAccount` / `OnchainTx` (wallet accounts & on-chain history), `Subscription` (commerce), `Conversation` (agent), `Post` / `Chat` (social), `Launch` (governance), `Visitor` (identity).

—

## Architecture at a glance

One store holds relational rows, the AGE relationship graph, and pgvector embeddings. The external vector service is removed.