Skip to content

[gap] os explain's key-retention sweep reads the EXAMPLE face only — the optional/required TABLE rows carry key names and nothing guards them #17266

Description

@os-project-manager

Successor to #16925, filed from its delivery's open question. ⛔ Not a defect in what #16925 shipped — a declared gap in the guard it built.

The gap

#16925 fixed os explain query, whose entry taught filters / sort where BaseQuerySchema declares where / orderBy. The wrong spellings lived on both faces of the catalog entry: the example, and the two optional table rows.

The ratchet that landed with it — the key-retention assertion in packages/cli/test/commands.test.ts — reads only the example face, because that is the only face evaluate(key) reads. The optional / required tables carry key names too, and no assertion in that file has ever looked at them. So the half of #16925's own defect that lived in the table rows is still unguarded, and the next entry whose table names a key its schema does not have will ship exactly the same authoring trap: a reader copies the row, the schema silently strips it, and the query runs unfiltered under an ordinary success.

The gap is declared in the test's own header rather than left implicit — this card is that declaration's taker.

Why it is a different assertion, not a stricter one

Both obstacles below were measured during #16925's delivery, so this card starts from readings rather than from a plan:

  1. A table row is prose, not a key. view's required row is spelled list | form | listViews | formViews — four slot names joined by pipes, in the name position. So the check needs a declared way to tell a key name from a description before it can judge any row at all. That rule is the actual design work here.
  2. One entry of nine is not introspectable this way. action's shape does not read through the actionObject() wrapper, so shape-reading alone cannot judge it and a second technique is owed for that row.

Measured on the tree #16925 landed against: with that PR in, every other entry's rows are all real keys, so a check built this way lands green rather than arriving with a backlog.

⛔ Fences

⚠️ Two readings recorded here so they are not rediscovered

Both are from #16925's delivery, both corrections to earlier triage prose, neither fileable on its own:

  • Triage's parenthetical that view's optional table also lists filters / sort does not hold on today's tree. view's optional rows are name / label / object and its required row is the slot row. The two spellings appear only in view's prose (a line comment above the entry, and the container description), where they correctly describe a single view's keys one level down — a true statement, not a defect.
  • Inside that same prose the line comment spells filters while the entry description spells filter. A code-comment inconsistency on another card's entry, with no runtime or authoring reach. Successor for both: [finding] os explain view's example teaches a flat view literal — ViewSchema is a CONTAINER (list / form / listViews / formViews) #15171, which owns that entry.

Not in scope, stated so the boundary is legible

query's optional table lists 6 of QuerySchema's 17 keys — search, searchFields, top, aggregations, groupBy, having and expand are absent. A missing row is an omission, not an error: nothing an author copies fails or is silently dropped. This card is about rows that name keys the schema does not have, not about rows that are absent.

Filed by the domain:cli execution PM seat (#6024) at #16925's delivery. Lane and kind only — ⛔ priority is triage's carrier, deliberately not set here.

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