Skip to content

lint: no reference-integrity for AI metadata (agent skills, skill tools) — R7, blocked on D1/D2 #3820

Description

@os-zhuang

Split out of #3583, which is otherwise closed: eight of its nine bug categories are now gated on validate/lint/compile, and the ninth (hook body write sets) is an accepted, documented gap. This is the one category with resolvable references and no rule — assessment R7 in docs/audits/2026-07-app-metadata-reference-integrity-assessment.md §3.

The gap

packages/lint/src contains zero AI rules. Nothing checks that:

  • agent.skills[] names a skill the stack declares (ai/agent.zod.ts)
  • skill.tools[] — wildcard-aware — names a declared tool (ai/skill.zod.ts)
  • agent.tools[].name resolves to an action/flow by its declared type

Evidence on the real corpus (2026-07-28, hotcrm @ 8b28fa2, v2.2.2)

Surface Count
agents 2
skills 6
agent.skills references 8
skill.tools references 16
tools declared by the stack 0

So all 16 skill→tool references are dead today — the original audit's "agent skills listing 11 tools with no definitions", still shipping. Every one passes objectstack validate and objectstack lint cleanly.

Two decisions come first (neither is a lint question)

  • D2 — runtime-registered kernel skills/tools vs. static lint. The ask/build kernel agents register their skills/tools via service at boot, so a stack can legitimately reference names no static analysis can see (same invisibility as plugin objects, which feat(lint): reference-integrity validation for object and action names (#3583) #3657 solved with the curated PLATFORM_PROVIDED_OBJECT_NAMES registry). Either extend that precedent with official skill/tool names, or run R7 at advisory severity. Small; take it when the rule starts.
  • D1 — agent.knowledge.indexes has no definition site. KnowledgeSourceSchema is never referenced by stack.zod.ts, so the namespace is unresolvable by construction — parsed, unmarked, and unenforceable, which is the state ADR-0049's trichotomy prohibits. Either add a knowledgeSources slot to the stack (spec change, ADR-worthy) or mark the fields [EXPERIMENTAL — not enforced]. Linting a namespace with no definition site would institutionalise the gap, so the knowledge half of R7 stays blocked until this lands. HotCRM carries 2 such references.

Out of scope

The "hand-off to a nonexistent skill" instance from the original audit: hand-off has no schema field anywhere — it lives in free-form prompt text, which has no structure to check (§7 non-goal).

Done looks like

validate-ai-references in @objectstack/lint, appended to REFERENCE_INTEGRITY_RULES (one line — validate/lint/compile pick it up automatically), with fixtures from the HotCRM instances and a zero-false-positive pass over examples/. Note the verification lesson from #3806: the false-positive floor must be read per branch — an example corpus that declares no agents proves nothing about the agent branch.

Refs #3583 · ADR-0049 · ADR-0072 · ADR-0078

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions