Skip to content

Upstream gap: validate-ai-tool-references does not ship in @objectstack/* 16.1.0 — skill tool references are unchecked platform-wide #561

Description

@yinlianghui

Why this is filed here

This is an upstream (objectstack-ai/objectstack) gap, filed in hotcrm as a tracker because the session that found it has no access to the upstream repo (add_repoyou need push access to objectstack-ai/objectstack). The ready-to-paste upstream body is at the bottom — someone with push access can move it over and close this.

The gap

#512's commit message states its fix was:

Verified with the merged reference-integrity rule (objectstack#3885 validate-ai-tool-references): 22 tool references, 0 findings

and the follow-up commit adds:

Re-verified with the corrected rule (objectstack#3894, which now models AI exposure): 19 tool references, 0 findings

That rule is not present in the @objectstack/*@16.1.0 packages this repo installs. Which is why search_knowledge in customer_360 survived #512 and had to be caught by hand in #493 / #557 — nothing in the shipped toolchain could see it.

Evidence

Checked three layers, not just one:

  1. @objectstack/lint@16.1.0 — the strings skill, tool and agent do not appear anywhere in dist/index.js. Zero occurrences, so no rule of any kind inspects AI metadata.
  2. objectstack validate (@objectstack/cli@16.1.0) — runs 13 checks; none touches AI metadata:
    JSX-source pages (ADR-0080), React-source page props (ADR-0081), React-source pages (ADR-0081), SDUI styling (ADR-0065), capability providers, capability references (ADR-0066), dashboard action references (ADR-0049), dashboard widget bindings (ADR-0021), flow trigger wiring, list-view navigation modes (ADR-0053), security posture (ADR-0090 D7), source-page styling (ADR-0065), view container shape.
  3. lint-liveness-properties (@objectstack/cli) — this one does cover skills (TYPE_COLLECTIONS includes { type: 'skill', key: 'skills' }), but it is ledger-driven and only flags dead authored properties. It has no notion of resolving a tools[] name against a registry, so it cannot catch this class.

So the check either was never released, was dropped before 16.1.0, or lives only in the closed cloud distribution. Any of the three is worth knowing.

Why it matters beyond hotcrm

SkillSchema.tools is a list of bare strings. validate and build check only that each is well-formed snake_case; at runtime an unresolved name is silently dropped. The model is then handed instructions describing a capability it does not have, and improvises. Every instance of this ships green — hotcrm accumulated eleven of them across six skills before anyone noticed, and it is the reference app. Any app built on ObjectStack has the same blind spot.

Interim mitigation (already merged here)

#557 added test/skills-integrity.test.ts, a repo-local guard: every skill tool must resolve to a platform built-in or an action_<name> materialised from an Action that is ai.exposed with a headless path; AI tool metadata cannot satisfy a dangling reference (ToolSchema is a read-only projection with no executor); and skill-to-skill handoffs in instructions must resolve.

That is a workaround, not a fix — every ObjectStack app would have to reimplement it, and the built-in allowlist has to be hand-maintained because the AI runtime ships closed (ADR-0025 §2) and exposes no authoritative tool list to validate against.

Asks for upstream

  1. Confirm whether validate-ai-tool-references (objectstack#3885 / #3894) shipped, and in which package/version. If it did not, that makes refactor(ai): skills-only AI surface — real Actions instead of 10 fictional tools, retire the two agents #512's "0 findings" verification unfounded — worth a note on that PR.
  2. Ship it in the open-edition toolchain (@objectstack/lint or objectstack validate), not only in cloud. The metadata it validates is authored in the open edition, so the check belongs there.
  3. Expose the platform built-in tool registry as data the open edition can read. Without it, any local guard hardcodes a list that silently drifts from the runtime — which is a smaller version of the same bug.

Ready-to-paste body for the upstream issue

Title: validate-ai-tool-references is not in the 16.1.0 open-edition toolchain — skill tools[] names are unvalidated

SkillSchema.tools holds bare strings. objectstack validate / build check only the snake_case shape; the runtime silently drops a name it cannot resolve. The result is a skill whose instructions describe tools the model does not have — it validates, builds, and passes CI in that state.

objectstack#3885 / #3894 describe a validate-ai-tool-references rule for exactly this, and downstream work cited it as the verification. It is not present in @objectstack/*@16.1.0:

  • @objectstack/lint@16.1.0 dist/index.js contains zero occurrences of skill, tool, or agent.
  • objectstack validate (@objectstack/cli@16.1.0) runs 13 checks, none over AI metadata (ADR-0080/0081 pages, SDUI/source styling ADR-0065, capability providers + references ADR-0066, dashboard action refs ADR-0049, widget bindings ADR-0021, flow trigger wiring, list-view nav ADR-0053, security posture ADR-0090 D7, view container shape).
  • lint-liveness-properties does walk skills, but is ledger-driven over dead properties only — it has no reference-resolution step.

Impact: objectstack-ai/hotcrm, the reference app, accumulated eleven skill references to tools that exist nowhere (#493). Ten were removed by hand in #512, the last in #557, all found by human audit rather than by tooling.

Requests:

  1. Confirm whether the rule shipped, and where.
  2. Ship it in the open-edition toolchain — the metadata is authored there, so the check belongs there.
  3. Expose the built-in tool registry as data the open edition can read. Any downstream guard currently has to hardcode the built-in list, which drifts from the runtime silently — a smaller instance of the same defect.

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