You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fe463b4
Browse filesBrowse the repository at this point in the historyBrowse files
fix(metadata-protocol): refusals, hints and log lines state each decision in words instead of a tracker number (stage 2) (#20830)
Part of #20513
Clause-②: no
**Stage 2 of 5 of this lane (`metadata-protocol`), under the
maintainer's A / A ruling on the card.** The card stays open for stages
3-5, so this PR carries no closing keyword. Text only: no error `code`,
field name, HTTP status, export or control flow moves. Every changed
source line is a string-literal line (108 changed lines in 11 `.ts`
files, checked line by line against the merge base).
## What this does
The metadata protocol's refusals, hints and log lines sent the reader to
a tracker number for the reason behind them. Each rewritten string now
says that reason in words (form D, as the migration-entry rewrite and
stage 1 applied it). Where the sentence already stated what was decided,
only the citation goes. Where it did not, the decision is added in
words:
| Where | Cited | The sentence now says |
|---|---|---|
| `protocol.ts` `insertManyData` refusal (thrown) | 3172 | `insertMany`
is the partial-success batch insert: an outcome per row, so a bad row
neither fails the whole batch nor makes the good rows run their
`beforeInsert` hooks twice. |
| `protocol.ts` unknown metadata type refusal (400) | 8586 | A plugin
cannot declare a type either: `additionalTypes` was retired because
nothing ever read it. |
| `protocol.ts` stored non-canonical type refusals on publish and on
revert (`STORED_TYPE_NOT_CANONICAL`) | 7894, 8957 | The `/meta` URL door
now folds a type to its canonical spelling before it writes, so such a
row predates that; the stored migration's `skipped` report "with that
same reason" loses only its citation. |
| `runtime-authoring-gate.ts` schedule-flow `organization_id` hint |
6153 | The author's value wins, and the engine fills only an
organization the run resolved, so for a schedule run the author is the
one source. |
| `plugin.ts` the three `kernel:ready` "migration skipped" warnings |
5839, 8629, 8686 | What the migration that did not run would have
ensured: view-name uniqueness among ACTIVE rows only; the NULL-safe
`sys_setting` row identity on tenant and global rows; the adoption of
untenanted seed rows and their autonumber counter. |
| `sys-metadata-repository.ts` history-counter abort (`error`) | 4867 |
The old path answered 1 because it took a failed read for an empty
table. |
| `protocol.ts` publish-closure degrade (`warn`) | 10377 | Validation
falls back to the LIVE declarations without the batch's own drafts in
the closure. |
| `protocol.ts` cold-boot org-scoped audit (`warn`) | 6190, 6992 | The
write refusal it points at covers declared types only; the trailing
"See" keeps ADR-0005. |
| everything else: the overlay, `sys_view_definition` and `sys_setting`
index migration messages (ADR-0120 D4 stays), the seed/API tenancy
repair, its receipt and its skips, the batch-row withhold, the
object-existence gate's no-registry warning, the nested-select, overlay
and non-canonical-registry refusals, and the live-MySQL testkit error |
6418, 8725, 8629, 5839, 6417, 8686, 9451, 9261, 8502, 3770, 4196, 6190,
4432, 10382 | The sentence already said what was decided; only the
citation goes. |
Each claim was checked against today's code, not only against the cited
card: `saveMetaItem` folds the request type before it persists;
`additionalTypes` is a `retiredKey()` tombstone in `packages/spec`; the
org-scoped write refusal is live in `orgScopedWriteRefusal`. One cited
number (10382) answers 404 and was read through its landing commit
`ee09d2119`; the testkit sentence already says what it guards.
## Order inside the stage
All 46 id-bearing literals (50 occurrences) fit one PR, under the stop
line, so the stage lands whole, in three commits in the ordered
sequence:
1. `dc8a1a112` author-visible text: 10 literals (thrown refusals, the
stored-type refusals, the hint);
2. `730cbcaf6` log lines: 35 literals, plus the two re-pinned tests;
3. `442473234` the `src/`-shipped testkit string, and the changeset.
Each commit recomputes the ledger, so every commit on the branch is
green on `check:doc-authoring`.
## Pins re-pinned: 3 assertion lines in 2 test files
- `migrations/view-definition-active-index.test.ts` 342-343 asserted the
two numbers in the MySQL degradation line. They now assert the two gaps
in words: "an archived view keeps occupying its name slot" and "two
same-name ACTIVE shared views (owner NULL)".
- `protocol.batch-row-driver-text.test.ts` 396 asserted the number in
the withhold warning. It now asserts "must not be quoted back on
response data", the decision itself.
A one-off mutation proves each new pin can fail, run on the committed
head with `scripts/ablation-replace.mjs` (anchor hit once,
disk-verified) under a shell trap. Changing "name slot" gives 1 failed /
27 passed. Changing "(owner NULL)" gives 1 failed / 27 passed. Changing
"quoted back" gives 2 failed / 14 passed: the re-pin, and a knock-on in
the next test, because the failed test never reached its `mockRestore`.
After each leg, the blob equals HEAD and `git diff HEAD` is empty. The
tree is clean after the run, and no test file was left behind.
No string here is compared byte for byte with a twin in another package.
The consumer pins outside the package read unchanged fragments:
`runtime`'s `batch-row-driver-text-real-driver.integration.test.ts`
reads the withhold prefix,
`seed-tenancy-autonumber-split.integration.test.ts` reads "backfill
skipped", and `meta-field-overlay-lock.test.ts`, `objectql`'s
`protocol-meta.test.ts` and `rest`'s
`meta-unknown-type-read-refusal.test.ts` read "is not a metadata type".
I ran the three `runtime` files against the rebuilt `dist/`, and they
passed.
## Ledger burn-down
`scripts/doc-authoring-prose-id.baseline.json` was regenerated with
`node scripts/check-doc-authoring.mjs --census-ledger` into a scratch
file, so the growth refusal ran against the checked-in baseline, and
then copied into place. Only `metadata-protocol` rows moved, and every
one of them leaves:
| File | Occurrences before | after | (file, id) pairs before | after |
|---|---:|---:|---:|---:|
| `metadata-protocol/src/protocol.ts` | 15 | 0 (row leaves) | 11 | 0 |
| `metadata-protocol/src/migrations/seed-tenancy-backfill.ts` | 14 | 0
(row leaves) | 3 | 0 |
| `metadata-protocol/src/migrations/view-definition-active-index.ts` | 7
| 0 (row leaves) | 3 | 0 |
| `metadata-protocol/src/migrations/overlay-index.ts` | 4 | 0 (row
leaves) | 2 | 0 |
| `metadata-protocol/src/migrations/sys-setting-identity-index.ts` | 4 |
0 (row leaves) | 1 | 0 |
| `metadata-protocol/src/plugin.ts` | 3 | 0 (row leaves) | 3 | 0 |
| `metadata-protocol/src/migrations/live-mysql-database.testkit.ts` | 1
| 0 (row leaves) | 1 | 0 |
| `metadata-protocol/src/runtime-authoring-gate.ts` | 1 | 0 (row leaves)
| 1 | 0 |
| `metadata-protocol/src/sys-metadata-repository.ts` | 1 | 0 (row
leaves) | 1 | 0 |
| **whole ledger** | 861 | 811 | 572 | 546 |
The ledger's file count goes from 224 to 215, and other packages' rows
moved: 0. The census's 40 messages reconcile with the ledger's 50
occurrences. The gate counts 46 string literals: 45 in the census
population plus the testkit string, which the census filed as
test-facing. The census folds a `+` chain into one message, so 5
two-literal chains make 45 literals into 40 messages. Four literals
carry two ids each, which makes 46 literals into 50 occurrences.
## Verification (head `442473234`)
- build: turbo over `@objectstack/runtime...` (30/30), then the whole
workspace (72/72), then `@objectstack/metadata-protocol` directly. The
new sentences are in `dist/index.js`, and the only citations left in
`dist/` are docblocks.
- `@objectstack/metadata-protocol` test: Test Files 190 passed, 3
skipped (193); Tests 2792 passed, 19 skipped. The skips are the live
MySQL/PostgreSQL files: this container has no server.
- `@objectstack/metadata-protocol` typecheck: exit 0; `tsc --listFiles`
reads 193 of 193 test files.
- `@objectstack/runtime`, the three consumer files above: 3 files, 33
tests passed.
- `node scripts/pm/dispatch-gates.mjs --commands` (no paths; 13 paths
against merge base `261c529f0`): 70 commands, all exit 0.
`check:dual-build-cjs-loads` and `check:type-check-debt` first answered
exit 3 PREREQUISITE NOT MET on the partial build. After the full build
(and a direct rebuild of this package, whose `dist` a turbo cache hit
had left older than the restored sources), both exit 0;
`check:dts-closure` and `check:lean-entry-closure` were re-run there
too. `--ran`: 70 derived, 70 run, 0 NOT-MEASURED, 0 UNRUN, exit 0.
- `check:doc-authoring`: sibling-package prose ids hold the baseline, no
growth, no burn-down unrecorded.
- narrowed lint: `eslint --no-inline-config --format json` over the 11
touched `.ts` files reports 11 files, 0 errors and 0 warnings. The
resolved `parserOptions` for these files are `ecmaVersion` and
`sourceType` only, with no `project` or `projectService`. So no
type-aware rule can move an untouched file. The repo-wide `pnpm lint` is
CI's.
- NOT MEASURED locally (CI's): the live PG/MySQL files, whose messages
changed only ahead of the pinned MySQL statement lead-in; the Test Core
shards; Dogfood; the workspace type-check lanes.
## Acceptance notes
- PR #20817 (another lane, draft) also edits `protocol.ts`. Whichever
lands second merges `main` and recomputes the ledger with
`--census-ledger`.
- Docblocks and `//` comments in this package still cite numbers. They
are out of scope here: comments are the sanctioned home for internal
anchors, and a separate card owns stale ones.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DEvba2nBuD4tWzfq8r8NFY)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments