You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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 indocs/audits/2026-07-app-metadata-reference-integrity-assessment.md§3.The gap
packages/lint/srccontains 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[].nameresolves to an action/flow by its declared typeEvidence on the real corpus (2026-07-28, hotcrm @
8b28fa2, v2.2.2)agent.skillsreferencesskill.toolsreferencesSo 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 validateandobjectstack lintcleanly.Two decisions come first (neither is a lint question)
ask/buildkernel 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 curatedPLATFORM_PROVIDED_OBJECT_NAMESregistry). Either extend that precedent with official skill/tool names, or run R7 at advisory severity. Small; take it when the rule starts.agent.knowledge.indexeshas no definition site.KnowledgeSourceSchemais never referenced bystack.zod.ts, so the namespace is unresolvable by construction — parsed, unmarked, and unenforceable, which is the state ADR-0049's trichotomy prohibits. Either add aknowledgeSourcesslot 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-referencesin@objectstack/lint, appended toREFERENCE_INTEGRITY_RULES(one line —validate/lint/compilepick it up automatically), with fixtures from the HotCRM instances and a zero-false-positive pass overexamples/. 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