Commit b69d0f5
* fix(metadata): refuse a /meta type name the platform does not have (#8421)
`PUT /api/v1/meta/fieldz/showcase_task.title` answered 200 and persisted a
`sys_metadata` row under `type='fieldz'` — a namespace for a metadata type
that does not exist. #7894 closed the sibling case (a plural spelling of a
DECLARED type) and left this one open, because a static predicate cannot tell
`fieldz` from a plugin kind and the live-registry alternative was measured to
be worse than the defect.
Maintainer ruling 2026-08-14, joint with #8586: retiring `additionalTypes`
removed the last channel by which a plugin could DECLARE a metadata kind, so
an unrecognised name can no longer be a declaration the boundary has not heard
about.
`@objectstack/spec` gains `unrecognisedMetaTypeRefusal`, deliberately separate
from the #7894 verdict: one says you spelled a declared type wrongly and can
name the replacement, the other says there is no such type and never guesses.
Its accept set is the static spelling contract — the map's keys AND the
canonical singulars they fold to — so the six plugin kinds with no registry
entry (`theme`, `webhook`, `connector`, `sharing_rule`, `analytics_cube`,
`rag_pipeline`) stay writable, including the first create of a kind that has
no items yet.
The boundary applies it at `saveMetaItem` only, which is measured rather than
timid: an ordinary `registerApp` puts `data`, `kind` and `package` into the
live type set that `GET /api/v1/meta/types` advertises, so a read-side refusal
would 400 types this same service publishes; and refusing DELETE would strand
rows minted under an unrecognised type before this change.
The residue pin in `metadata-url-spelling.test.ts` is flipped, not deleted,
and #7894's positive control keeps every assertion it was written with.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* test(spec): widen the declared-set probe to Set<string> for tsconfig.test.json
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* chore(changeset): record the ADR-0087 disposition for the /meta accept-set narrowing
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* test(metadata-protocol): key the stub rows structurally, keeping the tsc ratchet at 63
The stub's `keyOf` took `Record<string, unknown>`, which a `Row` interface is
not assignable to — one new TS2345 in a package whose measured error count is a
shrink-only ledger entry. Reading the four key fields structurally serves both
callers without a cast.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* fix(metadata): exempt the compound arity and already-stored namespaces from the /meta mint refusal (#8421)
* chore(changeset): record the compound-arity and stored-namespace exemptions (#8421)
* fix(metadata): propagate a metadata-store outage from the namespace probe instead of inventing 'no rows' (#8421)
* fix(metadata): derive /meta/types' allowRuntimeCreate from the mint door's own contract (#8421)
GET /meta/types synthesised allowRuntimeCreate: true for every live type with
no static registry entry, while the mint door added by this card refuses the
subset of them that is outside the static spelling contract. Two endpoints of
one service contradicting each other is worse for an AI author than a narrower
surface, so both doors now read one predicate.
Maintainer ruling 2026-08-15 (verbatim, untranslated):
暂时不考虑让插件申明新的元数据类型
The premise of 'no registry entry => assume plugin-declared => writable' has
expired, so policy/data/package/kind stop being advertised as runtime-creatable.
The six URL-map-only plugin kinds (theme, webhook, connector, sharing_rule,
analytics_cube, rag_pipeline) are unaffected and pinned as the discriminating
control. 暂时 is recorded as a CURRENT posture at both sites.
isRuntimeCreateAllowed keeps its permissive arm deliberately: it is now the
residue/clearance arm behind the mint door, not the read door's twin, and
narrowing it would strand rows minted before the refusal shipped.
Fixture corrections: trigger (ADR-0088-retired) replaced by mapping as the
runtime-creatable specimen in two objectql cases; policy's acceptance becomes
its own CHANGED BEHAVIOUR refusal case; #7894's never-heard-of-kind positive
control keeps its metaUrlSpellingRefusal half and updates its boundary half.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* chore(changeset): record the /meta/types advertisement narrowing and the 暂时 posture (#8421)
The changeset described the mint-door refusal only, and its 'what breaks'
section still named the accept-set question as open with the maintainer. Both
are now settled: GET /api/v1/meta/types stops advertising policy/data/package/
kind as allowRuntimeCreate, the six URL-map-only plugin kinds are explicitly
unaffected, and the ruling's 暂时 is recorded as a current posture with the two
code sites that carry the trail back to it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent fd6bdf8 commit b69d0f5
13 files changed
Lines changed: 1833 additions & 52 deletions
File tree
- .changeset
- packages
- metadata-protocol/src
- objectql/src
- runtime/src
- spec
- api-surface
- export-origins
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
0 commit comments