Skip to content

feat: the query surface — doc query + MCP query tool (ADR-0023, stacked on #112) - #117

Draft
HenryCFnord wants to merge 5 commits into
claude/personas-user-stories-jynl8ifrom
feat/doc-query
Draft

feat: the query surface — doc query + MCP query tool (ADR-0023, stacked on #112)#117
HenryCFnord wants to merge 5 commits into
claude/personas-user-stories-jynl8ifrom
feat/doc-query

Conversation

@HenryCFnord

Copy link
Copy Markdown
Owner

Stacked on #112 (retarget to main after it merges; independent of #113#116 — the query matches predicate strings and needs no vocabulary machinery). Draft until the base lands. This closes D7, the last open design point of the knowledge-repository program.

The owner's decisions: structured conjunctive filters instead of a query language, doc query at the store, the MCP query tool in the same slice.

What this is

The P8 ask — "find all Concepts where conformsTo: ISO19115, so agents navigate without prompting" — as one primitive:

arqix doc query --kind entity --lifecycle draft --edge exact-match=dcat:* --format json
  • Filters are conjunctive: kind, lifecycle, repeatable edge patterns; a document matches when every filter holds.
  • An edge pattern is predicate=target: bare arqix property name or full IRI; a trailing * on the target matches as a prefix. Malformed patterns are usage errors (exit 2).
  • The result is the catalog shape plus each document's matching edges, versioned (schema_version), deterministic.
  • The MCP query tool joins search/read/list, backed by the same store function — the transport-separation contract (REQ-05-01-12-03) extends unchanged.
  • Deliberately absent (recorded in ADR-0023): disjunction, negation, multi-hop traversal — each returns as a filter-set extension when a real corpus question needs it, never as a language.

The load-bearing detail

Edge matching reads the declared triples from the raw frontmatter lines (declared_edges), not from Document.triples — the shared parser's triple extraction is arqix-scoped by its oracle-era contract, so external targets (dcat:Dataset, the whole crosswalk case) would be invisible through it. Same seam as the crosswalk unit in #116, same rationale, documented in place.

Commit order (spec-first)

  1. docs: ADR-0023 + chapter-9 row.
  2. spec: REQ-02-01-06-04 on US-02-01-06 (find-and-read) and REQ-05-01-12-04 on US-05-01-12 (MCP) — goals-not-features, no new story.
  3. red: two tests, verbatim evidence:
doc_query_filters_documents_by_structured_filters ... FAILED  (unrecognized subcommand 'query')
mcp_query_tool_answers_like_the_cli ... FAILED  (no query tool in the catalog)
  1. feat (green): declared_edges + query_json + store::query, the DocCommand::Query surface, the MCP tool (catalog entry + dispatch).
  2. docs: the doc query wire schema in the ICD, program status and roadmap (D7 landed).

Validation

Both tests green (cli_mcp: 7 passed); full just ci green before every commit (unpiped log, exit 0). Conjunction is pinned by the test (adding a non-matching lifecycle empties the result), as is the prefix match and the usage-error leg.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q


Generated by Claude Code

claude added 5 commits July 20, 2026 06:58
A query is a small structured filter set — kind, lifecycle, edge
patterns with prefix targets, conjunctive, no query language; doc query
and the MCP query tool answer identically from one function; edge
matching reads the raw frontmatter so external targets are first-class;
disjunction, negation, and traversal wait for a driving question.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q
REQ-02-01-06-04 (structured conjunctive filters on doc query) joins the
find-and-read story, REQ-05-01-12-04 (the query tool over the shared
function) joins the MCP story — goals-not-features, no new story.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q
Two failing tests: doc query with conjunctive kind/lifecycle/edge
filters over declared triples including external targets (red:
'unrecognized subcommand query'), and the MCP query tool answering with
the same payload (red: no query tool in the catalog).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q
Green for REQ-02-01-06-04 and REQ-05-01-12-04 (ADR-0023): doc query
filters documents by kind, lifecycle, and repeatable edge patterns —
conjunctive, bare arqix property names or full IRIs, prefix targets
with a trailing star — over the declared edges read from the raw
frontmatter, so external targets are first-class; each hit carries its
matching edges, malformed patterns are usage errors; the MCP query tool
answers from the same store function beside search, read, and list.

Full just ci green before this commit (unpiped log, exit 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q
The doc query payload joins the ICD wire schemas; program status and
roadmap record D7 as landed — the last open design point of the
knowledge-repository program.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gie4jfrHKCxQktD2UsvH4Q
@HenryCFnord
HenryCFnord force-pushed the claude/personas-user-stories-jynl8i branch 2 times, most recently from 3585b7c to 900e4c0 Compare July 29, 2026 12:23
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.

2 participants