Skip to content

Scope skill schema_metadata retrieval per node_types, so write-tool field declarations target one type #2148

Closed

Description

@mstomar125

Context

core#2120 added routing::declare_write_tool_fields, which generates create_node/update_node's field_values parameter per request by declaring the retrieved type's fields as typed sub-properties (measured in packages/agent/goldens/PATTERN.toml to fix a value silently dropped 3/3 across eight prose-only arms — see that PR for the full mechanism).

The gap

No seeded skill in skill_pipeline.rs currently declares node_types, so every candidate's schema_metadata carries the full non-core schema list rather than a subset scoped to what that specific skill/request concerns (skill_ops's unscoped fallback — see routing.rs's own doc comments on no_seeded_skill_scopes_its_schema_metadata).

Consequence for declare_write_tool_fields: when more than one type is relevant on a turn (e.g. both ticket and adr retrieved), it currently unions every candidate type's fields onto the write tool's declaration, rather than declaring only the fields of the type the request actually operates on. This is a safe, defensible fallback (it widens rather than narrows what the model can legally write, and a conflicting field name across types widens to string rather than picking one arbitrarily), but it is not what the golden corpus's own hand-curated cases do — each case declares exactly one type's fields, chosen by the case author's judgment about what that specific scenario concerns, not a rule mechanically derivable from "which schemas were retrieved."

What's needed

Scope schema_metadata retrieval per-skill (or per-turn) to the single type a request most concerns, when that's determinable — likely via node_types declared on the relevant skills, or a narrower retrieval pass keyed to the specific tool call rather than the whole turn. This would let declare_write_tool_fields (or its replacement) pick one type's fields with confidence instead of unioning, matching the corpus's per-case precision.

Not in scope for this issue

Deciding which type a turn concerns when more than one is plausible — that's a routing/retrieval design question requiring its own measurement (per ADR-038/ADR-064's methodology), not something to guess at ad hoc.

Activity

  1. mstomar125 commented on Aug 19, 2026

    @mstomar125
    ContributorAuthor

    Resolved in #2156.

    Fix: Added a per-query narrowing pass (`schema_named_in_query` in `packages/core/src/ops/skill_ops.rs`) — when the query text names exactly one non-core schema by id or display name, `find_skills`' unscoped fallback branch scopes `schema_metadata` to just that type instead of the top-N (5) unscoped list. Two-or-more named types, or none, leave today's fallback unchanged (no attempt to resolve genuine ambiguity).

    Why not per-skill `node_types`: looked at this first (the issue's primary suggested lever), but it doesn't fit — the seeded skills whitelisting `create_node`/`update_node` (Node Creation, Graph Editing) are deliberately generic across every non-core type, so there's no single static type to give them. Documented this reasoning in the PR and in the updated doc comment on the pinned `no_seeded_skill_scopes_its_schema_metadata` test (still holds — this fix adds no `node_types` to any seed).

    Not measurable via golden_runner: it bypasses retrieval entirely (hand-authored `schema_metadata`, no DB/embedding calls), so this production retrieval-mechanism fix isn't something the corpus can exercise directly. Verified via 7 new unit tests plus the full existing suite (nodespace-core: 1162 passed, nodespace-agent: 507 passed) and confirmed the `prompt_assembly_snapshot` gate is unaffected (it drives off hand-built fixtures, not `find_skills`).

    See PR #2156 for full detail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions