Skip to content

Commit 58b526d

Browse files
committed
docs(qa): re-spell the located-error shape the authoring-validation item quotes; changeset
The studio-authoring item quoted a bracketed `[invalid_metadata]` opener and a `: Required` tail that saveMetaItem's spec-validation refusal no longer emits. The clause now quotes the measured headline, the dispatcher source pointer says what that test pins, and the producer's per-face renderer is cited beside it. Revision 2 -> 3 with its history entry. Claude-Session: https://claude.ai/code/session_01TEhopqrWQYBycZzyJHpAZr Co-authored-by: Claude <noreply@anthropic.com>
1 parent c81b541 commit 58b526d

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
'@objectstack/metadata-protocol': patch
3+
---
4+
5+
The runtime authoring gate's `422 INVALID_METADATA` refusal no longer opens its message with a bracketed `[invalid_metadata]` tag restating the `code` the same throw declares. `error` carries the human sentence, `code` carries the machine token, and the token is no longer duplicated onto the prose axis.
6+
7+
Clause-②: no
8+
9+
This is the third producer of the family the protocol and the metadata repository already retired. The gate refuses an `active` publish whose body fails an author-time rule, and its message opened with `[invalid_metadata]` in front of its own `code = 'INVALID_METADATA'` / `status = 422`. `withoutDeclaredCodePrefix` strips a leading restatement only when the message opens with the declared code followed by a colon, and a lowercase bracketed tag matches neither the casing nor the separator. So it was never stripped, and it reached every caller in `error.message`.
10+
11+
## FROM → TO
12+
13+
| before | now |
14+
| --- | --- |
15+
| `error: "[invalid_metadata] flow/leave_approval failed author-time validation: 1 issue — flows[0].nodes[1].config.approvers[0].value [approval-expression-invalid]"` | `error: "flow/leave_approval failed author-time validation: 1 issue — flows[0].nodes[1].config.approvers[0].value [approval-expression-invalid]"` |
16+
17+
**Every accept/reject verdict is unchanged.** The same bodies are refused under the same conditions, with the same `code`, `status`, `issues` and `rulesRun`. A reader matching `error.message` for `invalid_metadata` should read `error.code` (`INVALID_METADATA`) instead. A reader already using `code` needs no change.
18+
19+
- **The `[rule]` locators stay.** Each one names the rule behind a finding, for example `[approval-expression-invalid]`, and no other field on the message carries that fact. Only the opener that restated `code` is gone.
20+
- **The batch publish response is unaffected on its machine axis.** `publishPackageDrafts` already puts `code: 'INVALID_METADATA'` and the structured `issues` on the causal `failed[]` row beside this message.
21+
- **Pinned as an absence.** The package's bracketed-opener pin now scans this producer too. A re-introduced tag, or a new refusal copied from a neighbour, fails it.

‎docs/qa/platform-checklist/areas/studio-authoring.json‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@
453453
"title": "An invalid authored shape is rejected at save with a LOCATED error and is not persisted",
454454
"since": "v16",
455455
"status": "active",
456-
"revision": 2,
456+
"revision": 3,
457457
"priority": "P1",
458458
"surface": "mixed",
459459
"personas": ["admin"],
@@ -474,7 +474,7 @@
474474
],
475475
"acceptance": [
476476
{
477-
"clause": "an invalid object shape is rejected at save with a located error naming the failing path (the '[invalid_metadata] … fields.<name>.type: Required' shape)",
477+
"clause": "an invalid object shape is rejected at save with a located error naming the failing path (the 'object/<name> failed spec validation: <N> issue(s) — fields.<name>.type [<zod code>]' headline beside code INVALID_METADATA, the per-issue prose on the structured issues[] carried with it)",
478478
"oracle": "api",
479479
"verify": "the rejection is 4xx and its body names the exact field path that failed spec validation",
480480
"evidence": "the error body"
@@ -511,13 +511,15 @@
511511
],
512512
"traps": ["stale-console-bundle", "automation-input"],
513513
"source": [
514-
"packages/runtime/src/http-dispatcher.test.ts#error (the located '[invalid_metadata] object/bad failed spec validation: fields.amount.type: Required' error shape)",
514+
"packages/runtime/src/http-dispatcher.test.ts#error (the dispatcher keeps the 422 and code INVALID_METADATA and threads the field-anchored issues through details.issues; its thrown message is a hand-built mock, not the producer's text)",
515+
"packages/metadata-protocol/src/protocol.ts#specValidationFindings (the producer's per-face rendering of the spec-validation message: the REST and dispatcher doors get the 'path [zod code]' headline, the prose rides issues[])",
515516
"packages/spec/src/ui/view.zod.ts#viewKind (container guidance map: type/columns/data/viewKind/filters/sort each name the wrap prescription)",
516517
"dashboards.strict-widget-rejects-stray-keys (dashboard-kind stray keys — cross-referenced, not duplicated)"
517518
],
518519
"history": [
519520
{ "revision": 1, "date": "2026-08-07", "change": "new item: authoring validation with located errors and verified non-persistence, sampling object + view kinds and cross-referencing the deepened dashboard stray-key item instead of duplicating it", "ref": "claude/platform-test-checklist-ocwugl" },
520-
{ "revision": 2, "date": "2026-08-11", "change": "recorded run #7695's sighting of the ALREADY-KNOWN spurious '_diagnostics' banner on a freshly saved VALID draft (the designer re-validates the server's own annotation on read-back) as a knownGap + a NOT-this-item's-FAIL negative, so the sighting is not filed as a new defect and the false positive is told apart from a real located-error miss. Note only; no clause changed", "ref": "#7753" }
521+
{ "revision": 2, "date": "2026-08-11", "change": "recorded run #7695's sighting of the ALREADY-KNOWN spurious '_diagnostics' banner on a freshly saved VALID draft (the designer re-validates the server's own annotation on read-back) as a knownGap + a NOT-this-item's-FAIL negative, so the sighting is not filed as a new defect and the false positive is told apart from a real located-error miss. Note only; no clause changed", "ref": "#7753" },
522+
{ "revision": 3, "date": "2026-09-23", "change": "re-spelled the located-error shape, which had stopped being true: the clause quoted '[invalid_metadata] … fields.<name>.type: Required', but saveMetaItem's spec-validation refusal no longer opens with a bracketed restatement of its code (retired in 7a25a3ee9c; the token rides code INVALID_METADATA), and on the REST and dispatcher doors its message is a headline of 'path [zod code]' locators with the per-issue prose on issues[]. Measured on c11852406 for a field missing its type: 'object/qa_invalid_probe failed spec validation: 1 issue — fields.amount.type [invalid_value]', 422, INVALID_METADATA. The dispatcher source pointer presented that test's hand-built mock message as the producer's text; it now says what the test pins, and the producer's per-face renderer is cited beside it. The capability itself (4xx, located path, nothing persisted) is unchanged", "ref": "#19709" }
521523
]
522524
},
523525
{

0 commit comments

Comments
 (0)