Skip to content

Implemented grounded-extraction bundle via a generic coordinator capability-contribution seam

Angelo › zettelkasten › Phase: Grounded Extraction Pipeline + Reusable Schemas (coordinator capability)

Type: Decision · Status: active · Created: 2026-06-24 · Updated: 2026-06-25

Tags: coordinator,contrib,entry-points,schema,extractor,scribe,auditor,create_extraction_graph,conditional-shipping

What

A grounded-extraction run applies a fixed extractor -> scribe -> auditor (+ trailing memory) pipeline to N sources, parameterized by one named schema (a rubric). extractor emits grounded claim+verbatim-quote candidates per schema dimension; scribe commits them as claim+quote note pairs tagged with the dimension tags and linked to a per-source hub; auditor verifies grounding integrity + dimension coverage. Each schema dimension's tag becomes the note tag, so the schema is simultaneously the extraction rubric and the cross-source comparison index.

Key architectural decision: capability-contribution seam

The coordinator core stays generic. New module coordinator/contrib.py discovers capabilities via the angelo.coordinator.capabilities entry-point group (with a first-party fallback list so it works in editable/dev installs without reinstall). A capability is a zero-arg callable returning {name, enabled, agents, schemas}. The coordinator learned exactly two generic tricks: 1. Contributed agents folded into list_agents/get_persona/roles with precedence core < contributed < project-local (agents.yaml). 2. A schema task attribute resolved + flowed into task context exactly like model (Task.schema name + Task.schema_obj expanded rubric ride through get_ready_tasks/claim_task/get_task_context).

zettelkasten/coordinator_agents.py defines the three personas (extractor=planner, scribe=implementer, auditor=checker with a deliberately different model family) + the capability() entry point. zettelkasten/extraction_schemas.py + extraction-schemas.yaml are the schema registry (package defaults + project overlay, tag-uniqueness enforced).

Enablement / conditional shipping (locked)

The capability self-gates: capability() returns enabled=False unless ANGELO_ZETTELKASTEN=1 is set on the coordinator MCP process (written by mcp-zettelkasten.json). When disabled: trio absent from list_agents, create_extraction_graph not registered, and a task carrying a schema is a HARD validation error (spec 8.3). zettelkasten is now a coordinator capability, not just an MCP server.

create_extraction_graph (coordinator tool, conditional)

One tool does in-process tool-side prep (ingest -> create_source -> seed per-source hub, capturing its id) then emits the trio DAG stamping schema on every task. Prep is tool-side, NOT a graph task, because the extractor is a planner and a planner cannot depend on an implementer (graph validation forbids it), so ingest can't be a graph node. Returns {run_id, task_ids, graph, sources, graph_summary}. Driven with the normal wave loop; scribes serialize via the write-lease.

Locked decisions

  • schema-tag enforcement (strict): a written note lacking a valid schema tag is rejected.
  • grounding is a per-schema option (grounded: true/false).
  • schema attribute with the capability disabled => validation error.

Shipped rule + tests

grounded-extraction.mdc/.md (with a schema-authoring mini-guide) wired into the CLI file maps + Claude imports + live .cursor/. 23 new tests in tests/test_grounded_extraction.py (gating, schema registry, schema flow/validation, DAG shape) all pass; coordinator/CLI regression suites green. The 8 full-suite failures are pre-existing and unrelated (artifacts reruns, claude-hook registry, federation API, one intra-file-ordering-flaky memory git-pin test).

Where things live

  • contrib seam: coordinator/contrib.py
  • schema attribute on tasks: coordinator/graph.py
  • agent merge + schema flow + tool gating: coordinator/server.py, coordinator/agents.py
  • prep + DAG builder: coordinator/extraction.py
  • personas + entry point: zettelkasten/coordinator_agents.py
  • schema registry: zettelkasten/extraction_schemas.py + extraction-schemas.yaml
  • entry point + package-data: pyproject.toml ([project.entry-points."angelo.coordinator.capabilities"])
  • enablement flag: mcp-zettelkasten.json (ANGELO_ZETTELKASTEN=1)

Referenced files


Source: memory entry deci-1ebbd521.