Repository navigation
Commit 2265bb0
docs(lint): put translation-section-name-missing's warning on its own reading (#18970)
Fixes #18768
Clause-②: no
`packages/lint/src/validate-translatable-sections.ts` justified its own
`warning`
severity by citing its sibling rule's reading. The sibling abandoned
that reading at
#16310, which promoted `translation-target-unknown` from `warning` to
`error`. The
conclusion is still right; the argument was not. This rewrites the
Severity note so it
stands on its own reading, and fixes the one other place that narrates
the superseded
note in the present tense.
Comments and docblock prose only — no severity, no schema, no assertion
moves.
## Subject leg — the Severity note, sentence by sentence
**Before** (`validate-translatable-sections.ts:42-47`), four sentences:
1. `Same reading as its sibling rule (ADR-0072 D1): nothing crashes and
nothing is dead — one heading renders in the source locale.`
2. `That is weaker than the dead references validate-object-references
reports as errors, and the severity should say so.`
3. `Requiring name outright is a SCHEMA change (FormSection.name is
optional today), …`
4. `… which is a breaking authoring change needing a maintainer decision
and a migration — deliberately not taken here.`
Sentence 1 is the whole defect: it is an appeal to a neighbour's
position, and the
neighbour moved. Sentences 2 to 4 were always this rule's own and are
kept.
**After**, the mapping:
- Sentence 1 is **replaced** by two paragraphs. The first names the
staleness instead of
inheriting it — the sibling `stopped holding this reading at #16310`,
and the verdict
here `survives that; the borrowed argument for it did not`. The second
states the
reading that actually holds here: `A nameless section MISDESCRIBES
NOTHING` — the
section is real and renders, the whole cost is one heading staying in
the source
locale, and it `leaves behind no artefact for the next author to trust:
there is no
key, so there is nothing to grep`. The contrast with the orphan key the
sibling gates
on (a confident-looking hit, in every locale, for a surface that was
DELETED) is the
asymmetry that earns that one `error` and this one `warning`.
- Sentences 2, 3 and 4 are **carried over unchanged in substance**
(sentence 2 re-worded
only to read as an addition: `It is weaker … too`).
The reasoning is not invented here.
`packages/lint/src/reference-integrity-suite.ts:406`
already carries it — `warning-only on its own reading — NOT on its
sibling's any more`.
That file is read as evidence and is **not** touched by this PR; the
rule's own header is
now consistent with it.
## Second carrier — narration only
`packages/lint/src/validate-translation-references.test.ts:24-28`
described the
superseded note in the present tense (`the rule's own Severity note
argued an orphan key
is inert`), inviting a reader to go find an argument that the same
change deleted. The
narration is now past-tense and self-limiting (`the rule's Severity note
AS IT THEN STOOD
argued that an orphan key was inert`), with a pointer that the note
itself was rewritten.
**No assertion moved.** All ten `severity: 'error'` sites in that file
are byte-identical;
only their line numbers shift by +2 because the docblock grew two lines.
A diff restricted
to non-comment lines in that file is empty:
```
git diff -U0 BASE -- packages/lint/src/validate-translation-references.test.ts \
| grep -E '^[+-]' | grep -v '^[+-][+-]' | grep -vE '^[+-] \*'
(no output)
```
## Firing control — the probe cannot be fooled by a line wrap
Both anchors this round turns on are wrapped across comment lines, and
so is the card's
designated positive control
(`skills/objectstack-i18n/SKILL.md:196-197`). A line-scoped
`git grep -F` reads **0** on two of the three needles below — on the
unedited tree, where
all three are present. The census therefore strips comment leaders,
collapses all
whitespace including newlines to one space, and only then matches.
| needle | line-scoped grep, unedited tree | fold-proof, before |
fold-proof, after |
|---|---|---|---|
| `Same reading as its sibling rule (ADR-0072 D1)` | 1 | **1** | **0** |
| `warning-only on its own reading — NOT on its sibling's any more` | 0
(wrapped) | **1** | **1** |
| `` `translation-target-unknown` is an **error** and fails the run `` |
0 (wrapped) | **1** | **1** |
Population: 8885 tracked text files (10 binary/non-file skipped). The
two 1s are read in
the *same run* as the 0, so the 0 is a reading and not a dead index.
## DARK
`packages/lint` before and after, both through the shared verify lock:
```
Test Files 104 passed (104)
Tests 3910 passed (3910)
```
identical on both sides, plus `pnpm --filter @objectstack/lint
typecheck` green after.
Repo-wide `eslint . --no-inline-config` at this branch's head: **6855
files, 0 errors,
0 warnings**, exit 0.
## Changeset — `skip-changeset`, measured rather than assumed
`@objectstack/lint` publishes `files:
["dist","README.md","CHANGELOG.md"]`. Built at BASE
and at BASE-plus-this-diff in two separate worktrees and compared file
by file:
- **byte-identical**: `index.js`, `index.cjs`, `runtime.js`,
`runtime.cjs`, `index.d.ts`,
`index.d.cts`, `runtime.d.ts`, `runtime.d.cts` — every executable and
every type output.
- **moved**: the four `.map` files, in exactly one field. `version`,
`sources` and `names`
are identical; `sourcesContent` is **absent on both sides** (this repo
gates that with
`check:sourcemap-no-sources-content`), so no source text — and therefore
no comment
prose — ships at all. What moved is `mappings`, the original-position
index, because
code moved 15 lines down a source file.
- grep control over every `files[]` path: the changed prose scores **0**
hits, while the
positive control `translation-section-name-missing` scores hits in 6
`dist` files.
So nothing an upgrading consumer can read, grep, type-check or execute
differs. The
`.map` shift is the unavoidable arithmetic of editing any comment above
code in a built
package, not a published change. Flagged here rather than assumed,
because a
byte-comparison of the tarball does technically move.
## Gates
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`, derived
on this tree, run one by one with each exit code landed to disk before
anything read it,
then reconciled with `--ran`:
```
Run reconciliation — 51 derived, 49 run, 2 NOT-MEASURED, 0 UNRUN.
```
The two NOT-MEASURED are `check:dual-build-cjs-loads` and
`check:type-check-debt`. Both
exited **3** — their own `PREREQUISITE NOT MET` code, which each gate's
output states is
neither a pass nor a failure. Both need the whole workspace built (83
packages and 27
dependency closures respectively); CI builds before running them.
`check:lean-entry-closure` was in the same state, its one prerequisite
package was built,
and it then passed.
## Acceptance notes
- `validate-translation-references.test.ts`'s docblock says `Eight
assertions in this file
pinned severity: 'warning'`. That is a statement about the #16310 cohort
and is still
exactly right — the landing commit flipped eight and added one. The file
carries **ten**
textual `'error'` sites today, the tenth having landed since. Noted, not
filed: the
sentence is not wrong, and nothing reads that number.
-
`docs/audits/2026-07-app-metadata-reference-integrity-assessment.md:93`
still says
`warning` for this rule. It is stamped `Landed 2026-07-28` and was true
then; left
alone deliberately.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 873e0e8 commit 2265bb0
2 files changed
Lines changed: 27 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
48 | 63 | | |
49 | 64 | | |
50 | 65 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
29 | 31 | | |
30 | 32 | | |
31 | 33 | | |
| |||
0 commit comments