Repository navigation
Commit 25f2e64
Fixes #20946
Clause-②: no
## What
For a flow name the loader ships from a managed package, the by-name
read (`GET /api/v1/meta/flow/NAME`) now answers the loader's body. That
is the same body the flow list (`GET /api/v1/meta/flow`) and the
execution view have answered since #20913. A stored row of that name is
no longer served by name as the package's definition.
`getMetaItem` in `packages/metadata-protocol/src/protocol.ts` now calls
the two predicates PR #20942 introduced for the list, and adds no
precedence rule of its own:
- **The stored-row half, `isShippedFlowName`, judged by name.** The
active read does not adopt the environment-wide stored row of a shipped
flow name. The row's package binding and the body's package-provenance
stamps decide nothing.
- **The registry half, `isStoredFlowEntryOfShippedName`.** The registry
answers its bare slot first, and for a shipped flow name that slot holds
the hydrated stored row. That entry is not one of the loader's, so the
loader's entry is served.
The predicates are called, not edited. Only `getMetaItem` moves in
`protocol.ts` (+36 / -1 there).
## Why
- Triage direction `5920432754` on #20946 (the interim): "the by-name
read serves the loader's artifact for a shipped flow name, using the
same predicates PR #20942 introduces for the list and the execution view
… ⛔ No third precedence path. The by-name read calls the predicate the
list calls."
- ADR-0126 §2 (`flow` is Regime C): "⛔ Never silent override, never an
overlay read path". ADR-0131 D6: managed definitions are sealed.
- #20761's ruling `5904938166`, rule 1: a body's package-provenance
stamps are display only.
What becomes of the stored rows themselves (keep, refuse, migrate)
belongs to #15206. This PR does not decide it.
## Repro, before and after
Showcase composition on a database file, cold boot. Between two boots, a
stored row was placed at rest under a shipped flow name, with a body
that can be told apart from the loader's (its own label, one node
renamed). Two more rows were placed: an organization-scoped row under a
second shipped name, and an environment-wide row under a name no package
ships.
| Door or reading | `origin/main` `f6ccca4a44` | this branch |
|---|---|---|
| `GET /meta/flow/NAME`, shipped name with a stored row | 200, the
stored body, under the package's stamps | 200, the loader's body |
| the same door with a package scope | 200, the stored body | 200, the
loader's body |
| `GET /meta/flow`, the entry for NAME | the loader's body | the
loader's body (unchanged) |
| startup receipt for NAME | armed: package, shadowed: runtime |
unchanged |
| control: a shipped name with no stored row | the loader's body |
unchanged |
| control: a shipped name with an organization-scoped row only | the
loader's body | unchanged |
| control: an unshipped name with a stored row | the stored body |
unchanged |
## Pins
- **Unit:**
`packages/metadata-protocol/src/protocol.flow-by-name-shipped-name.test.ts`,
10 cases. It uses a registry double with the real `SchemaRegistry` key
shapes, its `getItem` precedence (the bare slot first) and its artifact
lookup.
- A shipped name with a stored row answers the loader's body, both
before and after the row is hydrated.
- By name and in the list, the shipped name answers the same body.
- The package-scoped read and the plural type spelling answer the same.
- A row bound to the shipping package, or one whose body claims the
package's stamps, is judged by name alone.
- Controls: an unshipped name keeps its stored row; a shipped name with
no row is unchanged; an organization-scoped row is out of reach; an
overlay-regime type keeps its overlay.
- **Dogfood cold boot:**
`packages/qa/dogfood/test/flow-shipped-name-by-name-read.dogfood.test.ts`,
8 cases.
- By name, on both spellings of the door, the loader's body.
- By name and in the list, one and the same body.
- The stored row is still reported as a shadowed contender, and the
loader's body is what is armed.
- The three controls in the table above.
- The pin is a new file. `flow-provenance-server-held.dogfood.test.ts`
is not touched.
## Verification, at head `07843e6889`
- `pnpm --filter @objectstack/metadata-protocol exec vitest run
--maxWorkers=2` (the whole package): 195 files passed, 3 skipped; 2896
tests passed, 19 skipped.
- `pnpm --filter @objectstack/metadata-protocol run typecheck`: exit 0.
`tsc --listFiles` includes the new unit pin.
- Dogfood, `vitest run` over four files: the new pin, PR #20942's
`flow-shipped-name-stored-row-boot`, `flow-provenance-server-held` and
`automation-authoring-doors-durable`. 4 files, 35 tests passed. The
metadata-protocol `dist` carries the fix.
- `pnpm --filter @objectstack/dogfood run typecheck`: exit 0.
`--listFiles` includes the new pin.
- **Red before:** the dogfood pin against the `origin/main` build of
metadata-protocol gives 3 failed and 5 passed. The three failures are
the by-name cases; the store check, the receipt and the controls pass.
**Ablation.** The fix was committed first (`09f3a596bd`). Each leg ran
through `scripts/ablation-replace.mjs`, with its anchor hit once and a
blob change confirmed on disk. The unit pin imports `./protocol.js` from
source, so no rebuild was involved.
| Leg | What was removed | Result |
|---|---|---|
| A1 | the stored-row half | 6 failed, 4 passed |
| A2 | the registry half | 2 failed, 8 passed: the post-hydration case
and the list-agreement case |
Both restores were proven: the blob equals HEAD (`5d475cd667`) and `git
diff HEAD` is empty.
**Derived gates.** `node scripts/pm/dispatch-gates.mjs --commands`
printed 74 commands for this tree. All 74 were run, each exit code
captured before any pipe. `--ran` reconciliation: 74 derived, 74 run, 0
NOT-MEASURED, 0 unrun.
- On the first pass, `check:dts-closure` and
`check:dual-build-cjs-loads` exited 1. Both named
`@objectstack/organizations` missing `dist/index.d.ts`, a package
outside this diff that was partially built in the shared local tree.
After `pnpm --filter @objectstack/organizations build`, both exited 0.
- The seven roster gates whose roster sits beside a path of this diff
were also run, all exit 0: `check-changeset-fixed`,
`check-published-list-mirrors`, `check:authz-resolver`,
`check:console-injection`, `check:error-code-casing`,
`check:i18n-stale-fill` and `check:published-readme-exports`.
- The head is 3 commits behind `origin/main` `7fa67dada3` (formula,
plugin-security, service-analytics and the PM fleet-write scripts). None
of those commits touches a path of this diff.
**Lint, a proven narrowing of `pnpm lint` (the repo-wide run is CI's):**
1. **Population, from eslint's own config:** of the 5 touched paths, the
config matches the 3 `.ts` files. The `.md` and `.json` files answer
"File ignored because no matching configuration was supplied."
2. **Count, from `--format json`:** 5 results. The 3 linted files have 0
errors and 0 warnings.
3. **Invariance:** `eslint.config.mjs` never enables type-aware linting
(every `parserOptions` is `ecmaVersion` and `sourceType` only, with no
`project`). The only other files it reads are
`scripts/slot-lookup-baseline.json` and
`scripts/query-options-erasure-baseline.json`, and this diff touches
neither. So the diff cannot move the verdict on any untouched file.
**NOT MEASURED locally, declared to CI:**
- Test Core shards, Temporal Conformance, the full Dogfood Regression
Gate and Dogfood Verify CLI.
- Build Core and the workspace type-check lanes.
## Deviations
1. **`scripts/engine-double-contract.pinned.json`, one generated row.**
The new unit pin's engine double has a `findOne`, so it routes through
`assertEngineFindOnePredicate`. `check:engine-double-contract` then
requires the coverage ledger to learn the file, and it prescribes
`--write`. The diff is exactly that one row. The file is outside the
claim's file list, and the gate compels it.
2. **The package-scoped spelling is changed too.** The dispatch's
mechanism hypothesis listed reads with a package id as unchanged.
Measured on `origin/main`, the package-scoped by-name read served the
stored body as well, because the stored-row lookup falls back to the
package-less row. The list applies the two predicates whatever the
package scope. Leaving this spelling out would have left the defect
reachable on the same door, so it follows the ruling's intent, and it is
pinned in the unit and dogfood suites.
3. **Two merges of `origin/main`.** Neither had conflicts. The net delta
against `main` is 5 files, +601 / -1.
## Acceptance notes
- **Unchanged, and named:**
- the strict draft read and the draft-preview arm (a draft is answered
as a draft, never under the artifact's envelope, and the list's preview
arm is equally unfiltered);
- every other metadata type (both predicates gate on `flow` first);
- flow names no managed package ships;
- organization-scoped flow rows, which this read never reaches because
`flow` declares no org override.
- **The metadata-service step of the by-name read is untouched.**
Measured on the showcase composition, it answers nothing for a shipped
flow name, an unshipped one or a stored one. The list's own
metadata-service merge is not filtered by the predicates either.
- **The pending note
`.changeset/20913-flow-stored-row-shipped-name.md`** ends with "The
by-name read, `GET /api/v1/meta/flow/:name`, is not changed."
- That stays true as that PR's own delta. This is the reading the #20942
record applied to the 20864 note's bullet 5.
- This PR's note states the change in the same release.
- It is not corrected here because it is outside the claim's file list.
The seat may choose to correct it.
- **The ADR anchor for `protocol.ts`** already lists ADR-0126. Its
invariant sentence names only the list, which is still true. It could
gain a by-name clause on its next touch. Carrier: none.
## Out-of-scope finding, for the seat to file
- **class b · the layered read door, `GET
/api/v1/meta/flow/NAME/layers`.**
- **What it serves:** for a shipped flow name with a stored row, it
answers its effective layer as the stored body, and the response's
provenance names the package.
- **Measured:** 200 both before and after this PR, on the cold boot
above.
- **Contract:** the method's own docblock says the effective layer is
"what `getMetaItem` would return". ADR-0126 §2 says "never an overlay
read path".
- **Why now:** after this PR it is the one read door for that name that
disagrees with the list and the by-name read.
- **Remedy shape:** the same predicate, so the effective layer takes the
code layer for a shipped flow name.
- **Not done here:** this claim's region is `getMetaItem` only.
- Dedupe words: `meta flow layers effective stored row shipped name` ·
`layered read effective overlay flow regime C`.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VvcEokUG1tvVxkceYfR5XB)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent f8178ff commit 25f2e64
5 files changed
Lines changed: 601 additions & 1 deletion
File tree
- .changeset
- packages
- metadata-protocol/src
- qa/dogfood/test
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
Lines changed: 272 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 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8676 | 8676 | | |
8677 | 8677 | | |
8678 | 8678 | | |
| 8679 | + | |
| 8680 | + | |
| 8681 | + | |
| 8682 | + | |
| 8683 | + | |
| 8684 | + | |
| 8685 | + | |
| 8686 | + | |
| 8687 | + | |
| 8688 | + | |
| 8689 | + | |
| 8690 | + | |
| 8691 | + | |
| 8692 | + | |
| 8693 | + | |
| 8694 | + | |
| 8695 | + | |
| 8696 | + | |
| 8697 | + | |
| 8698 | + | |
| 8699 | + | |
| 8700 | + | |
| 8701 | + | |
| 8702 | + | |
| 8703 | + | |
| 8704 | + | |
| 8705 | + | |
8679 | 8706 | | |
8680 | 8707 | | |
8681 | 8708 | | |
| |||
8778 | 8805 | | |
8779 | 8806 | | |
8780 | 8807 | | |
8781 | | - | |
| 8808 | + | |
| 8809 | + | |
8782 | 8810 | | |
8783 | 8811 | | |
8784 | 8812 | | |
| |||
8904 | 8932 | | |
8905 | 8933 | | |
8906 | 8934 | | |
| 8935 | + | |
| 8936 | + | |
| 8937 | + | |
| 8938 | + | |
| 8939 | + | |
| 8940 | + | |
| 8941 | + | |
8907 | 8942 | | |
8908 | 8943 | | |
8909 | 8944 | | |
| |||
0 commit comments