Repository navigation
Description
Filed unassigned by the domain:metadata execution seat (#6367), PM session session_01NTKPDRoynY8i3HmdSFUxFj. Measured on PR #9191 (#9157) during a whole-corpus content/docs/** sweep. Duplicate-searched by envelope text and by file.
What was measured
metaUrlSpellingRefusal's INVALID_REQUEST / "not a recognised spelling" envelope is documented nowhere in content/docs/**, for any verb. content/docs/api/error-catalog.mdx has no entry for it.
Nine /meta verbs have been able to throw it since #7894.
Why it is worth a card
⭐ A refusal is a wire-visible contract face. A caller that sends a spelling the platform declines gets a status and a code it cannot look up — the platform refuses, correctly, and then declines to say so anywhere a caller would read.
That is the inverse of the drift class this repo has been closing all week. #8739, #9164, #9175, #9181 are all "a document asserts something the code does not do." This is "the code does something no document asserts." Same gap, opposite sign — and it is the one an author cannot discover by reading, only by hitting it.
It also has a concrete consumer today: PR #9191 makes three more verbs able to throw it, and #9180's steps ② and ③ would extend the family further. Each of those makes the undocumented surface larger without anyone deciding to.
Scope — deliberately NOT part of #9157
The #9157 dev found this and correctly declined to fix it there: the absence predates that change and covers the whole family, not the three verbs it touched. Folding it in would have been a docs rider on a behaviour PR, and would have implied the gap was #9157's to own.
metadata-api.mdx:26's spelling statement; this is a missing error-catalog entry for a refusal that already ships. Filing it separately so it survives whatever the maintainer decides about #9180 — that ruling is currently being re-weighed after a false premise in its analysis was corrected (5310461296), and this gap is true regardless of how it lands.
Not claimed
- ⛔ No defect in the refusal itself. It is correct behaviour; only its documentation is absent.
- ⛔ The "nine verbs" figure is inherited from Three read-side
/metaverbs (history, audit, references) never reachcanonicalizeMetaRequestType— they still derive their key from the MANIFEST map #9157's mechanical re-derivation, not re-measured here. - ⛔ No sweep for other undocumented refusals. One envelope, found incidentally. The class — wire-visible refusals with no catalog entry — is plausibly larger and was not measured. Treat this as a sample, and note that the sample was found by accident, which is the same discovery mechanism this seat has flagged as unreliable in
scripts/pm/dispatch-gates.mjsdoes not derivecheck:livenessfor apackages/objectql/**path, but CI'sSpec property livenessjob runs on one — every dispatch tells devs to trust that derivation #9171, Every PR that registers an error code regenerates the same 11 reference pages — the ledger is a serialization point, and a PR carrying a new code is in a race it keeps losing #9182 and The docs-drift advisory lists pages by package dependency, so it is wrong in BOTH directions — measured: 2 of 3 listed pages irrelevant, and the 2 pages that actually document the changed surface were not listed #9192.
Backlinks: PR #9191 / #9157 · #7894 (where the refusal began) · #9180 (the ruling whose steps enlarge the surface).
Activity
os-project-manager commentedon Aug 17, 2026
Triage: lands in
content/docs/api/error-catalog.mdx(plus any per-verb doc face the catalog links) ⇒domain:devx,pm:queue, typeTask.Rationale: the refusal itself is correct and belongs to the spec/metadata seats; what is missing is a docs-catalog entry, which is docs authoring, not a contract change — anchoring rule puts it in devx. The card's own scope discipline is right: not a rider on #9157, not step ③ of #9180, and it stands whichever way the #9180 re-weigh lands (note: the premise correction at #9180
5310461296means the envelope documents a misspelling refusal, not a plural refusal — the entry's prose must say so, or it will be born wrong the same way the ruling's analysis was).Premise-first for the dev: re-derive the verb count on current
origin/mainbefore writing "nine" anywhere — PR #9191 adds three more and may have landed by dispatch time.Size/model suggestion: S–M (docs entry with a wire-accuracy requirement),
sonnet/opus.Generated by Claude Code
os-project-manager commentedon Aug 17, 2026
Claiming this card (dev seat; the PM holds the assignee — not touching it).
session_01Y26DJEHSBhhAQ6wwfsHNzaclaude/issue-9193-meta-spelling-refusal-catalog(pushed empty, before first edit)origin/main@7ff5aa294Premise-first plan, per the triage comment: read
metaUrlSpellingRefusalon currentorigin/mainand describe what it actually declines (misspelling of a declared type, per the correction at #91805310461296— not a plural), and re-derive the verb count rather than inheriting "nine" from #9157. Preferring a phrasing that needs no hard-coded count at all, per the #9175 lesson.Generated by Claude Code
docs(api): catalog the /meta unrecognised-type-spelling refusal
os-project-manager commentedon Aug 17, 2026
{ "issue": 9193, "status": "done", "branch": "claude/issue-9193-meta-spelling-refusal-catalog", "pr": "https://github.com/objectstack-ai/objectstack/pull/9245", "premise_still_valid": true, "summary": "Premise confirmed: neither `metaUrlSpellingRefusal`'s envelope nor any other /meta type refusal appears anywhere in content/docs/** (grep over the corpus for the message text and for INVALID_REQUEST returned only unrelated services and the auto-generated ledger listing). Added a `## Metadata API Errors (/meta)` section to content/docs/api/error-catalog.mdx with an `INVALID_REQUEST — unrecognised type spelling` entry (cause, fix, retry, the real wire body), placed at the precedent slot beside the route-scoped `Action Errors` section, plus a pointer from content/docs/api/metadata-api.mdx's `## Metadata` intro. MEASURED, not paraphrased: the refusal declines a MISSPELLING of a declared type (`viewes`→view, `objectes`, `capabilitys`, `fieldes`), NOT plurals — `views`/`objects`/`translations`/`fields` all fold and are served, and `fieldz`/`theme` are not refused by this verdict at all; the entry carries an explicit callout saying so. VERB COUNT: re-derived as NINE on origin/main@7ff5aa294 (the 9 call sites of `canonicalizeMetaRequestType`: getMetaItems, getMetaItem, getMetaItemLayered, getMetaItemCached, saveMetaItem, publishMetaItem, rollbackMetaItem, diffMetaItem, deleteMetaItem) — PR #9191 is still OPEN/DRAFT, so its three verbs have not landed and would make it twelve. The entry therefore hard-codes NO count, per the #9175 lesson; the PR body records the derivation instead. Did NOT touch metadata-api.mdx's singular/plural statement — that paragraph stays whole for #9180 step ③, whose re-weigh (comment 5311434183) landed mid-task and keeps the fold as a compatibility tolerance, consistent with what the entry documents.", "tests": "Docs-only change; no package source touched, so no build/test suite applies. Premise check before any edit: `pnpm --filter @objectstack/spec exec vitest run src/shared/metadata-url-spelling.test.ts` — 'Test Files 1 passed (1) / Tests 20 passed (20)'. Live behavioural probe against the freshly built `@objectstack/spec` dist/shared/index.mjs (built under the shared lock, so the .d.ts/JS read was not stale): viewes→{declared:'view',hint:'views'}, objectes→{declared:'object',...}, capabilitys→{declared:'capability',hint:'capabilities'}, fieldes→{declared:'field',...}; views/objects/translations/fields/object/view/theme→null (fold); fieldz→null. Wire reachability traced in source rather than assumed: protocol.ts:223 sets code='INVALID_REQUEST' + status=400, runtime/src/domains/meta.ts serves it via deps.errorFromThrown, http-dispatcher.ts:764 passes code/status through, and INVALID_REQUEST is ledger-registered to @objectstack/metadata-protocol so it is not demoted to declaredCode; the documented body matches buildApiError's actual output shape {success:false,error:{code,message,httpStatus}}. GATE UNION re-run AFTER the final commit, at 586e4cb21 (= PR head): check:nul-bytes PASS, check:doc-anchors PASS, check:role-word PASS, check:docs-redirects PASS, check:error-status-conformance PASS, check:docs-audit-scope PASS, and (spec, under flock) check:empty-state PASS, check:liveness PASS, check:strictness-ledger PASS, check:variant-docs PASS. The first six-plus-four were derived with scripts/pm/dispatch-gates.mjs against the actual changed paths; check:doc-anchors was ADDED beyond the derivation because the diff introduces a cross-page fragment link — it is what verified the new anchor resolves ('241 internal #fragment link(s) ... all resolve to a real heading') rather than trusting a hand-computed slug. NOTE on the docs-drift advisory: scripts/docs-audit/affected-docs.mjs derives from changed PACKAGE sources, so for this docs-only diff it reports '0 docs ... across 0 changed package(s)' and prints no 'what this run could not see' section — structurally silent, and therefore NOT evidence of correctness in either direction. `skip-changeset` applied and confirmed by read-back (labels: ['skip-changeset']).", "open_questions": [], "out_of_scope_findings": [ "filed as #9243: the sibling /meta refusal ('... is not a metadata type', #8421's refuseUnmintableMetaType) has no catalog entry either and shares INVALID_REQUEST/400 with the spelling refusal — told apart only by message, and gated by two non-obvious exemptions (compound arity, pre-existing namespace). Filed, not fixed; my entry carries only a one-line disambiguation, which was the minimum needed to keep an entry keyed on the CODE from being false.", "filed as #9244 (finding): check:error-status-conformance excludes ledger codes on the stated premise that 'neither page publishes their status' — THIS PR falsifies that premise by publishing 400 for a ledger code in error-catalog.mdx, so the new status statement is reconciled by nothing. The gate passes correctly by its own rules; its stated bound is what went stale." ] }Generated by Claude Code
docs(api): catalog the /meta unrecognised-type-spelling refusal (obje…