Repository navigation
Commit a65a59b
feat(spec)!: retire the ADR-0078 conversion-conflict channel — onConflict / reservedNodeTypes, the notice types, the conflicts arrays and the FLOW_CONVERSION_CONFLICT 409 (#24045)
Fixes #24001
Clause-②: yes (narrowing)
## What this does
Retires ADR-0078's conversion-**conflict** channel, which has had no
producer since #23543 F5-http (PR #23954) reserved the three old callout
node types (`FLOW_RESERVED_NODE_TYPES`). Per the card's "Reader who
acts" and triage `6221525633`:
- **`@objectstack/spec`**: the root exports `CONVERSION_CONFLICT_CODE`,
`ConversionConflictNotice`, `ConversionConflictDetail` leave;
`ApplyConversionsOptions` loses `onConflict` / `reservedNodeTypes` (and
so `StoredConversionOptions`), `ConversionContext` loses
`reservedNodeTypes` / `reportConflict`,
`IAutomationService.canonicalizeStoredFlow`'s result loses `conflicts`.
`api-surface/root.json` and `export-origins/root.json` regenerated (−3
each); `declaration-map/` did not move (`check:generated`: all 14
current).
- **Error code**: `FLOW_CONVERSION_CONFLICT` comes out of
`ERROR_CODE_LEDGER` by the ledger's own "Retiring a code" rule ("A row
whose last EMITTER is deleted comes out with it"; precedent
`OVERLAY_PERSISTENCE_FAILED`). `retired-error-codes.ts` is NOT used:
that table is for `StandardErrorCode` catalogue members only (#17707's
`CONCURRENT_LIMIT_EXCEEDED`), and this is a ledger row. The error
catalog's 409 row is the generated
`content/docs/references/api/{contract,error-code-ledger}.mdx` entry
(regenerated by `gen:docs`); `content/docs/api/error-catalog.mdx` never
listed it.
- **Dispatcher vocabulary**: the `OS_METADATA_CONVERSION_CONFLICT`
`foreign-vocabulary` row (its stamp site in `apply.ts` is gone) is
deleted; the running-log comments no longer spell the retired code.
- **`@objectstack/service-automation`**: `canonicalizeFlow` /
`canonicalizeStoredFlow` no longer build the live-name set or collect
`conflicts`; `plugin.ts`'s inert-mode rationale is restated for what
still needs the registry (the registration preview's descriptor checks).
- **`@objectstack/metadata-protocol`**: `StoredFlowCanonicalization`
loses `conflicts`; four consumer branches go — the save door's 409, the
stored-migration pass's `failed` row, `duplicatePackage`'s failed item
and `importUnmanagedPackage`'s 409 — with their docblocks.
- **D3 semantic entry** `conversion-conflict-channel-removed` (no D2
conversion, no tombstone: no metadata document ever carried any of it).
One BREAKING `minor` changeset with FROM → TO, marker `adr-0087:
registered conversion-conflict-channel-removed`.
`FLOW_RESERVED_NODE_TYPES` and the F5-http reservation are untouched.
## Hypothesis 1 — zero producers (measured on `origin/main`
`fd9664ffac`, before any edit)
`git grep -n -E
'reportConflict\(|onConflict|reservedNodeTypes|ConversionConflictNotice|ConversionConflictDetail|FLOW_CONVERSION_CONFLICT|ConversionConflict'`
(excluding `CHANGELOG.md`), plus
`CONVERSION_CONFLICT_CODE|OS_METADATA_CONVERSION_CONFLICT` and
`reportConflict|\.conflicts\b`:
| site | role |
| --- | --- |
| `packages/spec/src/conversions/types.ts:37`
`CONVERSION_CONFLICT_CODE`, `:96` `ConversionConflictDetail`, `:110`
`ConversionConflictNotice`, `:178`-`:180` context members | declaration
|
| `packages/spec/src/conversions/apply.ts:70` / `:96` options, `:139`,
`:158`-`:168` the `reportConflict` bridge | bridge (sink wiring), not a
producer |
| `packages/spec/src/conversions/index.ts:13,17,18` | re-export |
| `packages/spec/src/contracts/automation-service.ts:20,857` |
declaration (contract field) |
| `packages/spec/src/conversions/registry.ts:84` | comment (the guard's
own retirement note) |
|
`packages/services/service-automation/src/engine.ts:70,4528,4575,4609-4628`
| consumer (builds the set, collects into an array) |
| `packages/metadata-protocol/src/protocol.ts:23077` (save door 409),
`:24168` (stored pass), `:27555` (`duplicatePackage`), `:27829`/`:27853`
(unmanaged import 409); `stored-migration.ts:60` | consumer |
| `packages/runtime/src/dispatcher-error-vocabulary.ts:292,598,672` |
gate ledger |
| conversions / stored / metadata-protocol / service-automation tests |
test doubles that CONSTRUCT a conflict (not producers) |
| `onConflict` hits in `automation/execution.zod.ts`,
`data/data-engine.zod.ts`, `driver-sql`,
`types/unbacked-conflict-target.ts`, `check-tenant-chokepoint.mjs` |
unrelated members of the same name |
**Producer of a conflict = a conversion entry calling
`context.reportConflict`: zero.** No `MetadataConversion.apply` reads
`context` for it; `flow-node-http-callout-rename`'s `apply(stack, emit)`
takes no context at all. No fork, so the hard delete proceeded.
Cross-repo: `objectui` at the pinned `.objectui-sha` `f8267df9` and at
its HEAD `360e27a` — **0** hits for all seven spellings, control
`defineStack` lit (38 / 37 files). `cloud` is private and was **NOT
MEASURED** (the ledger rule asks for it; see the report's open
question).
## Pins (one per retired export / code), all in
`packages/spec/src/conversions/conversion-conflict-channel-retirement.test.ts`
- `§1 … every retired name has ZERO holders on any public entry, and the
survivors still stand on the root` — `CONVERSION_CONFLICT_CODE`,
`ConversionConflictNotice`, `ConversionConflictDetail` by resolved
symbol identity (`export-origins/`), survivors `CONVERSION_TODO_CODE`,
`ConversionTodoNotice`, `ConversionContext`, … present.
- `§1 … the runtime barrel resolves without the retired constant and
keeps its TODO twin`.
- `§1 … the D3 semantic entry is registered on step 18`.
- `§2 … the retired members are absent at the type level, the surviving
ones present` — `onConflict`, `reservedNodeTypes` (options and context),
`reportConflict`, the result's `conflicts`; compiled by
`check:test-typecheck`.
- `§3 … ErrorCode no longer parses it, and no owner lists it` —
`FLOW_CONVERSION_CONFLICT`, with `DEFAULT_RECORD_PAGE_CONFLICT` /
`CONCURRENT_UPDATE` as lit controls.
- `tree-scoped absence … no retired spelling survives inside the
declared radius outside the retirement kit` — all seven spellings over
`packages` / `examples` / `skills` / `content` / `scripts` (the #15513
radius, this file added as a witness on each `heldBy` row in
`scripts/cross-package-test-inputs.mjs`, and in
`vitest.repo-tests.json`). Excluded: the pin itself,
`packages/spec/src/migrations/` (the D3 entry), the git-ignored
generated `content/docs/protocol-upgrade/` (the D3 registry's
projection), `content/docs/releases/`, `.changeset/`, `CHANGELOG.md`.
## Ablation (one, on the pin file)
Restored the deleted export in `packages/spec/src/conversions/index.ts`
through `scripts/ablation-replace.mjs` (anchor 1 → 0, blob `630ed35f` →
`2bec0047`), ran the pin file: **2 failed / 4 passed** — `the runtime
barrel resolves without the retired constant…` and the tree-scoped
absence (offenders `index.ts spells CONVERSION_CONFLICT_CODE` /
`OS_METADATA_CONVERSION_CONFLICT`). The `export-origins` holder pin
stayed green, as it must: it reads the committed artifact, which the
source mutation does not regenerate (`check:export-origins` is that
half's gate). Restored: blob == HEAD `630ed35f`, `git diff HEAD` empty;
re-run **6 / 6 passed**. A first attempt was a no-op — its replacement
contained its own anchor, so the tool refused (count 1 → 1) and ran
nothing; it is not counted.
The ablation also surfaced a real gap, fixed before push: the
git-ignored upgrade-guide page `content/docs/protocol-upgrade/18.md`,
once generated locally, prints the D3 entry verbatim, so the scan now
excludes that projection like the registry it projects.
## Serial constraint (hypothesis 5)
PR #23986 (#23903) also edits `protocol.ts`: its hunks sit at the
`flowSaveReplaysRetired` docblock/body (~6612–6700) and the save door's
comment and fallback lines (~23025–23115). This PR's save-door hunk is
the `result.conflicts` branch below them (~23077–23094 at the base) plus
three other doors. **Disjoint**: each lands on its own, and whichever
lands second merges `main`. #23986's new test builds its canonicalizer
stub with `conflicts: []` as a standalone arrow (no contextual type, so
no excess-property check): it should still compile after this lands, as
a dead key — whichever lands second re-runs that suite on the merge.
#24010's three lines are in the package door, not touched here.
## Acceptance notes
- File surface beyond the claim, comment/doc only:
`packages/cli/src/commands/migrate/meta.ts`,
`packages/cli/src/utils/data-migration-plugins.ts` (comments that
justified the inert engine by the conflict guard) and
`content/docs/deployment/cli.mdx` (the "flow whose rename the conflict
guard refused" decline row and two sentences) — each described a failure
mode this PR removes.
`packages/metadata-protocol/src/stored-migration.ts` is the
`StoredFlowCanonicalization` declaration the claim's "the contract's
`conflicts` arrays" names. `scripts/cross-package-test-inputs.mjs` and
`packages/spec/vitest.repo-tests.json` declare the new pin's radius.
- Four tests that pinned the removed branches are deleted with them (`a
refused rename fails the item…`, `a refused rename fails the save
loudly…`, `the conflict path stays silent — the 409 IS the signal`,
`fails the row loudly when the guard refuses a rename over a live
name`): each constructed a conflict through a test double and asserted
the branch this PR deletes.
- The stored pass's `skipped` reason for a flow with no engine is
reworded (it named the conflict guard); no test pins its prose.
- ADR-0078's status note and the ADR-0087 addendum note are in a
separate governed PR (`claude/issue-24001-adr-0078-note`).
## Verification
Reported in full in the `os-dev-report` comment on #24001 (local gate
union with exit codes, reconciled `--ran` 139/139; per-package `pnpm
test`).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01WdZxJadrrYettvjrqiWeAV
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WdZxJadrrYettvjrqiWeAV)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e246f06 commit a65a59b
32 files changed
Lines changed: 486 additions & 436 deletions
File tree
- .changeset
- content/docs
- deployment
- references/api
- packages
- cli/src
- commands/migrate
- utils
- metadata-protocol/src
- runtime/src
- services/service-automation/src
- spec
- api-surface
- export-origins
- src
- api
- contracts
- conversions
- migrations/entries/semantic
- scripts
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1610 | 1610 | | |
1611 | 1611 | | |
1612 | 1612 | | |
1613 | | - | |
1614 | 1613 | | |
1615 | 1614 | | |
1616 | 1615 | | |
| |||
1627 | 1626 | | |
1628 | 1627 | | |
1629 | 1628 | | |
1630 | | - | |
1631 | | - | |
1632 | | - | |
| 1629 | + | |
| 1630 | + | |
| 1631 | + | |
1633 | 1632 | | |
1634 | 1633 | | |
1635 | 1634 | | |
| |||
1684 | 1683 | | |
1685 | 1684 | | |
1686 | 1685 | | |
1687 | | - | |
| 1686 | + | |
1688 | 1687 | | |
1689 | 1688 | | |
1690 | 1689 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
197 | 196 | | |
198 | 197 | | |
199 | 198 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
360 | 360 | | |
361 | 361 | | |
362 | 362 | | |
363 | | - | |
364 | 363 | | |
365 | 364 | | |
366 | 365 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1477 | 1477 | | |
1478 | 1478 | | |
1479 | 1479 | | |
1480 | | - | |
1481 | | - | |
| 1480 | + | |
| 1481 | + | |
1482 | 1482 | | |
1483 | 1483 | | |
1484 | 1484 | | |
| |||
1520 | 1520 | | |
1521 | 1521 | | |
1522 | 1522 | | |
1523 | | - | |
1524 | | - | |
| 1523 | + | |
| 1524 | + | |
1525 | 1525 | | |
1526 | 1526 | | |
1527 | 1527 | | |
| |||
1591 | 1591 | | |
1592 | 1592 | | |
1593 | 1593 | | |
1594 | | - | |
1595 | | - | |
1596 | | - | |
1597 | | - | |
1598 | | - | |
1599 | | - | |
1600 | | - | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
1601 | 1602 | | |
1602 | 1603 | | |
1603 | 1604 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
71 | | - | |
72 | | - | |
73 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
77 | | - | |
78 | | - | |
| 77 | + | |
| 78 | + | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
55 | 54 | | |
56 | 55 | | |
57 | 56 | | |
| |||
155 | 154 | | |
156 | 155 | | |
157 | 156 | | |
158 | | - | |
159 | 157 | | |
160 | 158 | | |
161 | 159 | | |
| |||
250 | 248 | | |
251 | 249 | | |
252 | 250 | | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | 251 | | |
281 | 252 | | |
282 | 253 | | |
| |||
0 commit comments