Commit 54e2d36
feat(metadata): versioned ADR-0087 forward conversion at the artifact-ingestion door (#12843)
* feat(metadata): run the versioned ADR-0087 forward conversion at the artifact-ingestion door
Artifacts built by released 17.x tooling carry then-legal keys (allowRestore/
allowPurge, retired in spec 17.2.0) and were refused by the strict parse in
MetadataPlugin._parseAndRegisterArtifact — the retiredKey tombstone fired with
no operator remedy, since 'os migrate meta' targets sources, not built
artifacts.
New policy in @objectstack/metadata-core (applyArtifactForwardConversions):
replay the full ADR-0087 conversion chain — retired entries included — over an
artifact whose declared engines.protocol floor predates the running spec
version; an artifact authored at the current (or newer) surface converts
nothing and still answers to the tombstone. Versioned, not a blanket strip:
the retired keys return with M2 (#1883), and artifacts authored against that
surface must never be stripped by history.
The door (MetadataPlugin) applies it before every strict parse — bare
definitions and environment-artifact envelopes — and surfaces notices
operator-visibly, deduped per conversion per artifact, modeled on the
stored-row pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVYmuhHW6qZmNBqciaS7BN
* test(metadata): NodeNext-safe imports in the new suites; changeset
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVYmuhHW6qZmNBqciaS7BN
* fix(metadata-core): keep the spec ROOT out of the policy module's declaration surface
The artifact-forward-conversion module's public types referenced
ConversionNotice from the @objectstack/spec root, so the emitted
dist/index.d.ts imported the root entry - and every downstream type program
reading metadata-core's declarations began loading the ~2MB spec root d.mts
BESIDE the d.ts flavor it already read. Measured: the TEST_DEBT re-measure of
packages/qa/http-conformance crossed CI's ~4GB tsc heap ceiling and OOM'd
(listFiles diff between merge-base and branch: the only additions were
spec/dist/index.d.mts and its chunk; the capped re-measure passes at the
merge base and fails on the branch, same box, same command).
Public surface now speaks ArtifactConversionNotice, a structural mirror
pinned in both assignability directions in the module's test; the runtime
applyConversions import stays and no longer reaches declaration emit. The
rebuilt d.ts carries only the pre-existing spec/data subpath imports, and the
capped (4096MB) http-conformance re-measure is green on this tree.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVYmuhHW6qZmNBqciaS7BN
* chore(runtime): classify the metadata-core mirror's notice-code literal in the dispatcher vocabulary
check:dispatcher-error-vocabulary flagged the new
ArtifactConversionNotice.code literal in
packages/metadata-core/src/artifact-forward-conversion.ts as an unclassified
code-stamping site. Classified foreign-vocabulary beside the existing
OS_METADATA_CONVERTED row for spec's apply.ts: the literal sits in a TYPE
position of the structural mirror (declared to keep the spec ROOT import out
of the package's public declaration surface), stamps nothing at runtime, and
the notices flow to an onNotice callback exactly as in the classified spec
site - nothing thrown, no envelope built.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVYmuhHW6qZmNBqciaS7BN
* test(metadata): re-aim the refuse-direction pin at the surviving refusal surface under the #12845 residue ruling
Main landed acceptRetiredDefaultResidue (maintainer ruling 2026-08-28): a
retired DEFAULTED key's emitted default parses as inert residue and strips
silently at the schema layer; only a NON-default value keeps the #12497
tombstone. The real 17.1-built fixture carries exclusively the emitted
default (150 x false, premise-guarded), so the old current-version refusal
pin now describes a shape the ruled contract accepts - the merge queue
measured exactly that on its merge tree.
The pin is re-aimed, not weakened: current-version + NON-default value
(true, authorable on the 17.1 surface, never emitted by a default) still
refuses with the tombstone and prescription; and a new pin holds the other
half of the ruling at the door - current-version + pure residue parses
clean with the keys stripped by the SCHEMA layer while this door's
versioned window stays closed (no conversion notice), keeping the door's
amnesty versioned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SVYmuhHW6qZmNBqciaS7BN
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 28a5c3e commit 54e2d36
9 files changed
Lines changed: 1888 additions & 5 deletions
File tree
- .changeset
- packages
- metadata-core/src
- metadata/src
- __fixtures__
- runtime/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
Lines changed: 194 additions & 0 deletions
| 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 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
0 commit comments