Skip to content

[finding] os explain's 11 other catalog entries are hand-maintained against no schema — the flow entry's sample was unparseable and nothing said so #14811

Description

@os-trump

Found while implementing #14782 (the os explain flow sample); out of scope there, filed
unassigned for triage. Suggested domain: domain:cli.

The observation

packages/cli/src/commands/explain.ts holds a SCHEMAS catalog of 12 entries —
object, fields, field, view, flow, agent, app, query, dashboard,
action, workflow, trigger. Each carries a required list, an optional list and an
example string, and every one of them is hand-maintained: nothing derives them from
the schema they describe, and until now nothing checked them against it.

The existing test block in packages/cli/test/commands.test.ts states the hazard in its
own words, and its comment is worth quoting because it was written after this already
happened twice:

The token set is asserted EXACTLY, and that exactness is the point: this catalog is
hand-maintained and does NOT derive from the spec enum, so a spec-side enum change that
stops here is invisible to any review that only reads packages/spec.

That guard covers exactly one field of one entry (object.ownership, from #3244, widened
again at #5678).

Why this is worth a card rather than a note

#14782 measured what an unguarded entry drifts into. The flow entry's example did not
merely carry a wrong token — it did not parse as a Flow at all:

ISSUE [nodes] Invalid input: expected array, received undefined
ISSUE [edges] Invalid input: expected array, received undefined
ISSUE [] Unrecognized key(s) on this flow: `trigger`, `steps`.
         Did you mean `trigger` -> `type`, `steps` -> `nodes`?

Its required / optional lists named two keys (steps, trigger) that are strict-object
aliases, i.e. loud parse errors, and omitted two that are required (nodes, edges).
Meanwhile os generate flow, in the same package, was scaffolding the correct shape all
along — so the drift was not for want of the truth being known locally.

PR #14809 pins the flow entry by parsing its example against the real FlowSchema. That
technique generalises, and it is the only kind of guard that cannot drift alongside the
catalog it checks, because it re-derives the truth from the spec on every run. It was
deliberately not generalised in that PR: the other entries are outside that card's
face, and turning the guard on all 12 at once would fail on entries nobody has mandate to
rewrite in a p3 documentation fix.

What is NOT claimed

I did not audit the other 11 entries. This card records that they are unguarded and
that one of the twelve was measured badly wrong — not that any specific other entry is
wrong. The first step for whoever takes this is cheap: extend the parse-the-example
technique entry by entry and see which ones fail.

Suggested shape

  1. For each catalog entry with a resolvable schema in @objectstack/spec, parse its
    example against that schema in commands.test.ts.
  2. Where an entry has no single schema to parse against (fields is a fragment, query may
    be one), say so explicitly in the test rather than skipping silently.
  3. Fix whatever the parse turns up, one entry at a time.

Triage may well decide the audit is worth more than the generalised guard, or split them.

Activity

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