Skip to content

[bug] The catalog claims lint runs on agent create but not on update — the path where descriptions actually change #362

Closed

Description

@serge-ivo

The lint runs on create and not on update

lintAgentClaims (#66) is the catalog-integrity check: it flags a description promising a runtime
capability — browser automation, posting/publishing, a local runner, cron/scheduled runs — when the
agent's capabilities declare no runtime and no workflow. Pure, heuristic, deliberately
overridable, and loud.

POST /v1/agents runs it (routes/agents.ts:385) and returns the warnings alongside the 201:

const claimWarnings = lintAgentClaims({ description: body.description, capabilities: {…} });
return c.json(claimWarnings.length ? { id, slug, warnings: claimWarnings } : { id, slug }, 201);

PUT /v1/agents/:id accepts description in its patch body and returns { success: true }. It never
calls the lint.

Why that is the path that matters

Description edits overwhelmingly happen on update, not create — copy gets rewritten as the agent
finds its audience, long after the capabilities were declared. So the realistic sequence is:

  1. Create an agent with honest copy and no runtime → clean 201.
  2. Later, rewrite the description to "runs a headless browser and posts on your behalf" → 200, no
    warning
    , published to the catalog.

The check exists, is already imported in that file, and is simply not in the path where the thing it
checks actually changes. #66 framed this as "for a store, a description that overstates what the
agent does is an integrity bug, not polish"
— and this is the one surface in the batch that faces
buyers rather than the owner.

Fix

Call lintAgentClaims in the update handler with the post-patch description and the post-patch
capabilities, and return the warnings the same advisory way create does. Both routes should read the
resolved values rather than only body.description — an update that changes capabilities while
leaving the copy alone can create the same mismatch from the other direction, and today neither route
would notice.

Advisory is the right strength; the header calls it heuristic and overridable and that should not
change. This is about the check being present, not about making it block.

Class: the same mismatch as #351, #353, #354, #358 — a surface accepting a claim the runtime cannot
back — seen from the creator side.

Activity

  1. added
    bugSomething isn't working
    catalogAgent catalog integrity/cleanup
    on Aug 7, 2026
  2. serge-ivo commented on Aug 7, 2026

    @serge-ivo
    ContributorAuthor

    Fixed on main — 455db2d (fix) + 4fc7e38 (tests + spec).

    The claim held, exactly as written. PUT /v1/agents/:id accepted description and never called lintAgentClaims, while POST /v1/agents did. The half of #141 the ticket wondered about — sanitizeDeclaredCapabilities — was already wired into update; it was only the lint that was missing.

    Both directions now, and from all three doors. lintResolvedAgentClaims reads the post-patch description against the post-patch capabilities, so it also catches the mismatch arrived at backwards: capabilities dropped under copy nobody touched. PUT /:id/capabilities is that door, so it reports the same way; create was moved onto the same call.

    Resolved capabilities, not the declared block — agentCapabilities is the fact the runtime itself reads, and it falls back to the slug/category derivation for pre-registry agents. Linting only config.capabilities would have accused coder, whose honest copy promises a local runner backed entirely by that fallback, of overclaiming. There is a test for exactly that. Deriving from the same fact the executor reads is what stops the surfaces disagreeing (#354, #358).

    Advisory and unchanged in strength: the warnings ride alongside the 200, the write always lands, and the heuristic stays overridable per #66's header. Documented on all three operations in store/openapi.yaml.

    CI green on 4fc7e38.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcatalogAgent catalog integrity/cleanup

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions