feat(hints): kind- and direction-aware empty-result hints driven by EDGE_SCHEMA#160
Conversation
Replace the generic empty-neighbors template with kind-, direction-, and type-level structural hints sourced from EDGE_SCHEMA; extend neighbors_v2 hint payload with subject_record and requested_direction. Co-authored-by: Cursor <cursoragent@cursor.com>
HumanBean17
left a comment
There was a problem hiding this comment.
Review (PR-D / HINTS-V3)
Verdict: Approve — solid, plan-aligned delivery. Query-time only, EDGE_SCHEMA-driven evaluation order, and HV1–HV20 + post-flip integration test give good confidence. Assuming CI is green, this is fine to merge.
What works well
- Faithful to locked propose: alien kind → wrong direction → type-level requery; brownfield row 4 deduped once; v2 fuzzy path unchanged on non-empty results.
- Clean split: pure
neighbors_empty_hints()/typical_traversal_for()inmcp_hints.py;mcp_v2only enriches the hint payload. - Post-flip method +
HTTP_CALLS→WRONG_SUBJECT_KINDwithmember_subjecttraversal is the right teaching moment (integration test covers it). - Dot-key post-filter + HV19 schema coverage are good guardrails.
Follow-ups (non-blocking)
-
Brownfield row 4 is broad — fires on any empty result when any requested edge is
brownfield_resolver_sourced, including structurally valid queries (e.g. method + emptyDECLARES_CLIENT/EXPOSES/CALLS). HV8/HV9 only assert no structural hints. Consider gating row 4 to Client/Producer/Route subjects or caller-side edges only if real MCP sessions get noisy. -
Failed
subject_recordload —subject_record if subject_record is not None else {}makes{}look likeSymbolwith nokind, which can emit misleading structural hints. Safer to skipneighbors_empty_hintswhen load returnsNone. -
Pagination / filter empty slice (pre-existing) — hints use sliced
results;offsetpast rows or a strict filter can yield[]while hops exist. New hints are more specific, so misleading guidance is slightly worse than the old generic template. Worth a comment oroffset == 0guard in a follow-up. -
Nits:
origin_idin payload is unused bygenerate_hints;test_hints_hv1assertshints[0](order-dependent); HV19 proves ∃ trigger per edge but not that everytypical_traversalsrole key exists at runtime. -
Process: after merge, move
propose/HINTS-V3-PROPOSE.md→propose/completed/per repo culture.
No re-index / ontology bump needed. Nice work on scope discipline.
Gate brownfield-absence hints to Client/Producer/Route subjects; skip structural hints when subject_record is missing or offset>0; add traversal key and regression tests. Co-authored-by: Cursor <cursoragent@cursor.com>
Archive landed PR-D artefacts; update cross-links in SCHEMA-V2 docs, README, mcp_hints, and PROPOSES-ORDER (no proposes in flight). Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
TPL_NEIGHBORS_EMPTY_KIND_CHECKwith four EDGE_SCHEMA-driven empty-result templates (WRONG_SUBJECT_KIND,WRONG_DIRECTION,TYPE_LEVEL_REQUERY,BROWNFIELD_RESOLVED_MAYBE_UNRESOLVED).neighbors_empty_hints()/typical_traversal_for()inmcp_hints.py; wires emptyneighborsbranch ingenerate_hints.neighbors_v2hint payload withrequested_direction,origin_id, andsubject_record(first origin when batching).ontology_versionbump.Plan / propose
plans/PLAN-HINTS-V3.md§ PR-Dpropose/HINTS-V3-PROPOSE.md(Status: locked)Test plan
test_hints_neighbors_v2_empty_post_flip_method_http_callsHTTP_CALLS)ONTOLOGY_VERSION, graph builder, orTPL_NEIGHBORS_EMPTY_KIND_CHECKchangesManual evidence
test_hints_neighbors_v2_empty_post_flip_method_http_callson session graph (post-flipClient→RouteHTTP_CALLS): method subject +HTTP_CALLSout returnsWRONG_SUBJECT_KINDwithDECLARES_CLIENTtraversal chain in hints.Made with Cursor