Entity schema exposure: entity_schema / entity_types / entity_type_filter, so an entity's type and relations are one call instead of filtering triples by hand #291

Merged
toasterson merged 2 commits from claude/wi-019fce4d-entity-schema-exposure-entity-schema-ent into main 2026-08-07 16:49:09 +00:00
Owner

Anima work item 019fce4d-302b-7a01-8d64-163638ed7d0f.

Part 2 of 2, split from 019e480e-44e8-7213-b072-bdfacd98af68 (which is cancelled).
Part 1 is the Goal CRUD handlers — a separate work item. They share nothing but the
MCP/control-plane registration surface. Do not do Part 1 here.

⚠ Read this first: two traps that have already cost 10 sessions

1. The old work item's auto-generated triage plan pointed at the WRONG REPOSITORY. It
listed proto/anima/v1/agent.proto, crates/anima-core/…, crates/anima-db/…,
crates/anima-server/…, crates/anima-agent/…. Those are Anima paths. This is
akh-medu, a separate repo with its own crates, and anima-agent/anima-ai are retired
in Anima anyway (ADR 0018). That mis-generation is a plausible cause of the repeated
failures. Ignore it; work from the real akhomed surface in this repo.

2. If you hit the same wall twice, STOP and report it rather than burning turns. The
predecessor looped through 9 failed sessions before being parked.

The problem

Entity type information is buried in triples. To learn what an entity is, a caller has to
triples_of and filter for is-a by hand. There is no notion of an entity schema at the
tool level.

What to build

Three tools:

  • entity_schema {entity, workspace} — the entity's type hierarchy, its outgoing and
    incoming relation types, confidence scores, and a provenance summary.
  • entity_types {workspace} — every distinct entity type (the values of is-a
    relations) with counts.
  • entity_type_filter {workspace, type, page, page_size} — all entities of a given
    type with their core attributes. Paginate it — a common type will match a great many
    entities.

Target shape for entity_schema entity=Tecton:

{
  "entity": "Tecton",
  "types": ["DigitalArchitect", "First construct and extension of consciousness"],
  "outgoing_relations": {
    "member-of": ["Ennead"], "runs-on": ["MacMini"],
    "works-on": ["akh-medu", "oxifed"], "deity": ["Ptah"], "role": ["Coordinator"]
  },
  "incoming_relations": { "hosts": ["OpenClaw"], "has-member": ["Ennead"] },
  "provenance_summary": { "asserted": 14, "derived": 4, "episodes_referencing": 47 }
}

Open questions to resolve while implementing

  • Is episodes_referencing cheaply available? The original description assumed it. If
    episode tracking cannot answer it without new infrastructure, drop that field and say so
    rather than building tracking to satisfy an example payload.
  • Caching. Decide whether aggregating relations per call is fast enough on a real
    workspace, or whether it needs caching. Measure on a populated workspace before adding a
    cache — an unnecessary cache is its own bug.
  • Untyped entities. An entity with no is-a at all should be represented explicitly
    (empty types), not omitted — detecting incomplete identity is one of the stated uses.

Acceptance

  • All three tools registered and reachable, consistent with how the existing KG tools
    (triples_of, kg_mutate, kg_delete) are registered — check all registration sites,
    since tools here are registered in more than one place.
  • entity_schema on a well-connected entity returns both directions of relations.
  • entity_types counts match a manual count of distinct is-a objects.
  • entity_type_filter paginates correctly at a page boundary.
  • Tests for each, including the untyped-entity case.

Verify before you trust the description

Written 2026-05-21. Check the live tool surface first — what exists today may already cover
part of this.

Anima work item `019fce4d-302b-7a01-8d64-163638ed7d0f`. Part 2 of 2, split from `019e480e-44e8-7213-b072-bdfacd98af68` (which is cancelled). Part 1 is the Goal CRUD handlers — a separate work item. They share nothing but the MCP/control-plane registration surface. **Do not do Part 1 here.** ## ⚠ Read this first: two traps that have already cost 10 sessions **1. The old work item's auto-generated triage plan pointed at the WRONG REPOSITORY.** It listed `proto/anima/v1/agent.proto`, `crates/anima-core/…`, `crates/anima-db/…`, `crates/anima-server/…`, `crates/anima-agent/…`. Those are **Anima** paths. This is **akh-medu**, a separate repo with its own crates, and `anima-agent`/`anima-ai` are retired in Anima anyway (ADR 0018). That mis-generation is a plausible cause of the repeated failures. Ignore it; work from the real akhomed surface in this repo. **2. If you hit the same wall twice, STOP and report it** rather than burning turns. The predecessor looped through 9 failed sessions before being parked. ## The problem Entity type information is buried in triples. To learn what an entity *is*, a caller has to `triples_of` and filter for `is-a` by hand. There is no notion of an entity schema at the tool level. ## What to build Three tools: - **`entity_schema {entity, workspace}`** — the entity's type hierarchy, its outgoing and incoming relation types, confidence scores, and a provenance summary. - **`entity_types {workspace}`** — every distinct entity type (the values of `is-a` relations) with counts. - **`entity_type_filter {workspace, type, page, page_size}`** — all entities of a given type with their core attributes. **Paginate it** — a common type will match a great many entities. Target shape for `entity_schema entity=Tecton`: ```json { "entity": "Tecton", "types": ["DigitalArchitect", "First construct and extension of consciousness"], "outgoing_relations": { "member-of": ["Ennead"], "runs-on": ["MacMini"], "works-on": ["akh-medu", "oxifed"], "deity": ["Ptah"], "role": ["Coordinator"] }, "incoming_relations": { "hosts": ["OpenClaw"], "has-member": ["Ennead"] }, "provenance_summary": { "asserted": 14, "derived": 4, "episodes_referencing": 47 } } ``` ## Open questions to resolve while implementing - **Is `episodes_referencing` cheaply available?** The original description assumed it. If episode tracking cannot answer it without new infrastructure, drop that field and say so rather than building tracking to satisfy an example payload. - **Caching.** Decide whether aggregating relations per call is fast enough on a real workspace, or whether it needs caching. Measure on a populated workspace before adding a cache — an unnecessary cache is its own bug. - **Untyped entities.** An entity with no `is-a` at all should be represented explicitly (empty `types`), not omitted — detecting incomplete identity is one of the stated uses. ## Acceptance - All three tools registered and reachable, consistent with how the existing KG tools (`triples_of`, `kg_mutate`, `kg_delete`) are registered — check all registration sites, since tools here are registered in more than one place. - `entity_schema` on a well-connected entity returns both directions of relations. - `entity_types` counts match a manual count of distinct `is-a` objects. - `entity_type_filter` paginates correctly at a page boundary. - Tests for each, including the untyped-entity case. ## Verify before you trust the description Written 2026-05-21. Check the live tool surface first — what exists today may already cover part of this.
Entity schema exposure: entity_schema / entity_types / entity_type_filter, so an entity's type and relations are one call instead of filtering triples by hand
All checks were successful
CI / publish-chart (push) Successful in 9m24s
CI / publish-chart (pull_request) Successful in 11m56s
CI / check-seshat (push) Successful in 13m18s
CI / check-seshat (pull_request) Successful in 13m30s
CI / docker-seshd (push) Successful in 17m36s
CI / docker-seshd (pull_request) Successful in 18m27s
63a6df2662
Anima implementation session.
toasterson left a comment

Review verdict: BLOCK — the tools are dead code. The code quality inside entity_schema.rs is good (correct Tool trait usage, graceful unknown-entity handling, 9 solid unit tests), but nothing connects it to the crate:

Blocker 1 — module never declared: src/agent/tools/mod.rs has no pub mod entity_schema;, so the file is not compiled into the crate at all. CI is green because the code is invisible to the compiler.

Blocker 2 — tools never registered: Compare with KgQueryTool, which is registered in 4 places: src/agent/tools/mod.rs, src/agent/agent.rs:316, src/agent/tool_semantics.rs:438, src/agent/vsa_decide.rs:577. EntitySchemaTool/EntityTypesTool/EntityTypeFilterTool appear in none of them — no agent, ACP surface, or MCP exposure can reach them.

Blocker 3 — goal not delivered: the WI's acceptance ("an entity's type and relations are one call instead of filtering triples by hand") requires a caller to be able to make that call. Currently none can.

Required fix: add pub mod entity_schema; + pub use entity_schema::{EntitySchemaTool, EntityTypesTool, EntityTypeFilterTool}; to mod.rs, and register all three at every registry construction site (agent.rs, tool_semantics.rs, vsa_decide.rs, plus the manifest/tool-exposure lists). Then verify with a test that resolves the tools by name through ToolRegistry.

Minor 4 — entity_schema.rs:47: local const IS_A: &str = "is-a" duplicates PRED_IS_A in src/schema/compile.rs:25; reuse the existing constant to avoid drift.

Minor 5 — entity_schema.rs:351: page.max(0) on a usize is a no-op; drop it.

**Review verdict: BLOCK — the tools are dead code.** The code quality inside `entity_schema.rs` is good (correct `Tool` trait usage, graceful unknown-entity handling, 9 solid unit tests), but nothing connects it to the crate: **Blocker 1 — module never declared:** `src/agent/tools/mod.rs` has no `pub mod entity_schema;`, so the file is not compiled into the crate at all. CI is green *because* the code is invisible to the compiler. **Blocker 2 — tools never registered:** Compare with `KgQueryTool`, which is registered in 4 places: `src/agent/tools/mod.rs`, `src/agent/agent.rs:316`, `src/agent/tool_semantics.rs:438`, `src/agent/vsa_decide.rs:577`. `EntitySchemaTool`/`EntityTypesTool`/`EntityTypeFilterTool` appear in none of them — no agent, ACP surface, or MCP exposure can reach them. **Blocker 3 — goal not delivered:** the WI's acceptance ("an entity's type and relations are one call instead of filtering triples by hand") requires a caller to be able to make that call. Currently none can. **Required fix:** add `pub mod entity_schema;` + `pub use entity_schema::{EntitySchemaTool, EntityTypesTool, EntityTypeFilterTool};` to `mod.rs`, and register all three at every registry construction site (`agent.rs`, `tool_semantics.rs`, `vsa_decide.rs`, plus the manifest/tool-exposure lists). Then verify with a test that resolves the tools by name through `ToolRegistry`. **Minor 4 — `entity_schema.rs:47`:** local `const IS_A: &str = "is-a"` duplicates `PRED_IS_A` in `src/schema/compile.rs:25`; reuse the existing constant to avoid drift. **Minor 5 — `entity_schema.rs:351`:** `page.max(0)` on a `usize` is a no-op; drop it.
toasterson force-pushed claude/wi-019fce4d-entity-schema-exposure-entity-schema-ent from 63a6df2662
All checks were successful
CI / publish-chart (push) Successful in 9m24s
CI / publish-chart (pull_request) Successful in 11m56s
CI / check-seshat (push) Successful in 13m18s
CI / check-seshat (pull_request) Successful in 13m30s
CI / docker-seshd (push) Successful in 17m36s
CI / docker-seshd (pull_request) Successful in 18m27s
to 1699571fd1
Some checks failed
CI / check-seshat (push) Successful in 12m17s
CI / check-seshat (pull_request) Successful in 15m37s
CI / publish-chart (pull_request) Successful in 17m3s
CI / docker-seshd (push) Failing after 21m50s
CI / publish-chart (push) Failing after 21m58s
CI / docker-seshd (pull_request) Successful in 22m45s
2026-08-06 21:21:08 +00:00
Compare
Entity schema exposure: entity_schema / entity_types / entity_type_filter, so an entity's type and relations are one call instead of filtering triples by hand
All checks were successful
CI / check-seshat (pull_request) Successful in 16m7s
CI / check-seshat (push) Successful in 16m7s
CI / publish-chart (pull_request) Successful in 17m52s
CI / publish-chart (push) Successful in 17m55s
CI / docker-seshd (push) Successful in 23m39s
CI / docker-seshd (pull_request) Successful in 27m12s
74010c260f
Anima implementation session.
toasterson changed title from WIP: Entity schema exposure: entity_schema / entity_types / entity_type_filter, so an entity's type and relations are one call instead of filtering triples by hand to Entity schema exposure: entity_schema / entity_types / entity_type_filter, so an entity's type and relations are one call instead of filtering triples by hand 2026-08-06 23:47:05 +00:00
toasterson deleted branch claude/wi-019fce4d-entity-schema-exposure-entity-schema-ent 2026-08-07 16:49:10 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
toasterson/akh-medu!291
No description provided.