Repository navigation
Commit 0d8ea5e
Fixes #21958
Clause-②: no (narrowing)
Executes the maintainer's ruling recorded on
objectstack-ai/objectui#11675 (comment 6010771237, decision batch 2,
item 1, B, verbatim 「同意」): dates, times, numbers and the first day of
the week follow the user's locale, and `date_format`, `time_format`,
`number_format` and `first_day_of_week` leave the Localization settings
without being implemented. objectui#11675 remains open for its own
remainder (the calendar and timeline week start); this PR does not touch
it.
## What changes
`packages/services/service-settings` only:
- `src/manifests/localization.manifest.ts`: the four specifiers leave,
with the Formats group they made up (it would have been an empty
header). `timezone`, `locale`, `default_country`, `currency` and
`fiscal_year_start` are unchanged. `version` goes from 1 to 2, because
the spec's `SettingsManifestSchema.version` contract reads "Manifest
version. Increment when keys are renamed/removed." The namespace
description and the module docblock say what replaced the four. While
rewriting that docblock I corrected its stale function name
(`resolveExecutionContext` no longer exists;
`resolveLocalizationContext` in `@objectstack/core` is what reads
`timezone`, `locale` and `currency`).
- `src/translations/{en,es-ES,ja-JP,zh-CN}.ts`: the four key entries and
the `formats` group leave each bundle, and the namespace description
follows the manifest.
- Tests: see below.
- `.changeset/21958-retire-locale-format-settings.md`:
`@objectstack/service-settings` minor, BREAKING banner, `Clause-②: no
(narrowing)`, ADR-0087 disposition `not-required
(no-migration-prescription)`. The four were settings values in
`sys_setting`, not metadata, so `objectstack migrate meta` has nothing
to rewrite.
No `packages/spec`, `skills/**` or `content/docs/releases/` edit.
## Stored values: measured, not assumed
Measured twice through the real REST handlers (`registerSettingsRoutes`
over `SettingsService`): on `origin/main` `80f9f7e6ba`, with a copy of
the manifest minus the four registered over a store that already held a
`date_format` row, and on this branch with the shipped manifest. Both
gave the same answers:
| Door | Result after the retirement |
|---|---|
| `GET /api/settings/localization` | 200. The four are absent from
`manifest.specifiers` and from `values`; the stored row is loaded with
the namespace but never resolved. |
| `PUT /api/settings/localization` naming one of them | `400
UNKNOWN_KEY`, `details: { namespace: 'localization', key }`. The refusal
covers the whole batch: a `timezone` sent beside it does not land. |
| `PUT` of a live key, with the stale row in the store | 200. The stale
row never blocks a save. |
| built-in `reset` action | 200, "Cleared 1 saved value(s)": it clears
the live key and leaves the retired row alone. |
| in process, `settings.get('localization', 'date_format')` | rejects
`UnknownKeyError`, `code: 'SETTINGS_UNKNOWN_KEY'`. |
| registering the old manifest shape again (a rollback) | reads
`DD.MM.YYYY`, source `tenant`: the row survived every step above. |
| `OS_LOCALIZATION_DATE_FORMAT` (and the other three) | no longer read,
and nothing is logged at registration. Before, it set a value that
nothing read. |
So a stored row is kept, never deleted: ignored on read, refused on
write. No service code changed. This is the path every undeclared key
already takes.
**Precedent, as measured.** The dispatch pointed at
`settings-routes.ts:25` and at `settings-service.ts` near line 920. Line
25 cites envelope siblings retired from the route module, not a settings
key. Line 920 is the retired `mail.provider` OPTION values (`sendgrid`,
`ses`), where a stored stale value is kept and judged only when written
(the TOUCH gate). No settings key had ever left a manifest before this
one. I checked every commit whose diff to a `*manifest*.ts` outside
`packages/spec` touches a `key:` line (26 commits, on an unshallowed
history of 15,821): no key disappears in any of them, and no manifest's
`version` was ever above 1. Two contracts already in place therefore
answer the question: the generic undeclared-key path above, and the
spec's own `version` rule. A retirement entry would have needed a home
in `packages/spec`, and nothing requires one there.
`SettingsManifest.version` has no reader in objectstack or objectui at
`main` (grep for `manifest.version` in the settings code of both), so
the bump is compliance with the declared contract and changes no
behaviour.
## Docs
No `content/docs/**` page lists the four as settings. Searched outside
`references/` and `releases/` for the four key names and for "Date
format", "Time format", "Number format", "First day of week",
"Localization settings" and "date/number formats". The only hits are
field-type and i18n-API pages describing other things
(`data-modeling/validation-rules.mdx`,
`protocol/kernel/i18n-standard.mdx`, `protocol/kernel/index.mdx`). No
page needed an edit. The repo-wide reader sweep for the four key names
finds only SQL's own `date_format()` (driver-sql, comments in core and
objectql, and the two `skills/**` rule files, which describe the SQL
function), and the export `transform` enum value `'date_format'`. None
of these is the settings key.
## Tests (head `397edabf04`)
- New pins in `src/settings-routes.test.ts`: four retired rows are
seeded in the store, as `seedGlobalSecret` in the same file seeds one.
Then:
- `GET` offers and resolves none of them;
- `PUT` naming each is refused, asserting `status` 400, `error.code`
`UNKNOWN_KEY` and `error.details`;
- a live-key save and the `reset` action both leave the four stored rows
byte-equal.
- `src/manifests/localization.manifest.test.ts`: `version` is 2; the key
list is five keys in `region`/`finance`. A new negative pin asserts that
none of the four, nor the `formats` group, is offered.
- `src/translations/settings-translation-coverage.test.ts` now also
checks the other direction, for `en` and the three translated bundles:
no copy for a group or key that no manifest declares. It measured zero
such entries across all ten manifests before it was added, so it closes
the class rather than pinning only these four.
- `src/settings-service.test.ts`: the two "domain-less select keeps
exhaustive options" pins used `first_day_of_week` and `date_format` as
their example key. They now use `fiscal_year_start`, also a domain-less
select, so they pin the same behaviour.
- `pnpm --filter @objectstack/service-settings test`: 36 files, 626
tests passed. `typecheck` (`tsc --noEmit`) exit 0; `--listFiles` shows
it compiles 36 test files, including all four edited ones. The
dependency closure (`--filter '@objectstack/service-settings^...'`) was
built first.
- The built `dist` loads through both conditions:
`require('./dist/index.cjs')` and `import('./dist/index.js')` each serve
`version 2` with five keys.
## Ablation (negative pins proven able to fail)
Both ablations used `scripts/ablation-replace.mjs` (literal anchor that
must hit; blob hashes verified; restore by blob to HEAD, `git diff HEAD`
empty):
1. **A retired row put back into the manifest** (`date_format`
re-inserted, on-disk count 1). 8 tests went red: the three new route
pins, the two manifest pins, and zh-CN, ja-JP and es-ES coverage. The
tree was restored to blob `e8f3039af917` (equal to HEAD). A first
attempt was refused by the tool, which is why there were two: the
replacement contained its own anchor, so the anchor count did not drop.
Nothing was measured on that attempt.
2. **A translation entry put back** (`date_format` re-added to `en.ts`
with no manifest row). The new reverse-direction pin went red with `en
has undeclared settings copy: localization.key:date_format`. Restored to
blob `0b0918e9ece5` (equal to HEAD).
## Gates
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on the final tree derived 63 commands. That
is the dispatch's 49 plus 14 that the changeset and test edits pull in,
including `check-adr-0087-registration`, `check-empty-changeset`,
`check:engine-double-contract` and `check:type-check-coverage`. All 63
were run at `397edabf04` with exit codes captured before any pipe. 62
exited 0. `pnpm check:dual-build-cjs-loads` exited 3, PREREQUISITE NOT
MET (53 packages outside this closure have no `dist/`): **NOT MEASURED**
locally, and CI's full build runs it. The `--ran` reconciliation answers
"63 derived, 62 run, 1 NOT-MEASURED, 0 UNRUN".
ESLint, narrowed: `pnpm exec eslint --no-inline-config --format json`
over the 9 touched `.ts` files gave 9 files linted, 0 errors and 0
warnings. All 9 are inside the config's population
(`**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}` minus the build dirs). The
config enables no type-aware linting (no `parserOptions.project`), so
this diff cannot move the verdict on any untouched file. The repo-wide
`pnpm lint` is CI's.
## Acceptance notes (not filed)
- An `OS_LOCALIZATION_*` variable naming a retired key is now silently
unread. No namespace audits `OS_` variables that name an undeclared key
(a typo such as `OS_LOCALIZATION_TIMEZON` is equally silent today).
Pre-existing and general, and the value was never read before either.
Carrier: none.
- `SettingsManifest.version` has no reader anywhere measured, so the
"increment when keys are removed" contract is honoured without being
enforced. No pull. Carrier: none.
- objectui's
`apps/console/src/pages/settings/__tests__/SettingsField.valueDomain.test.tsx`
uses `date_format` and `first_day_of_week` as hand-built fixture keys.
It does not import this manifest, so it stays green and is harmless.
Carrier: whoever next edits that file, possibly with objectui#11675's
remainder.
- `@objectstack/service-settings`' exported types are byte-unchanged
(the manifest is typed `SettingsManifest`, and only its value moved),
and no package outside this one imports `localizationSettingsManifest`
or the bundles in code. So there is no downstream consumer sweep.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WMQprn46CND82KmY8sZWBu)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent c9761cd commit 0d8ea5e
10 files changed
Lines changed: 210 additions & 106 deletions
File tree
- .changeset
- packages/services/service-settings/src
- manifests
- translations
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
28 | | - | |
29 | | - | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
47 | | - | |
| 46 | + | |
48 | 47 | | |
49 | 48 | | |
50 | 49 | | |
| |||
63 | 62 | | |
64 | 63 | | |
65 | 64 | | |
66 | | - | |
| 65 | + | |
67 | 66 | | |
68 | 67 | | |
69 | 68 | | |
70 | 69 | | |
71 | | - | |
72 | 70 | | |
73 | 71 | | |
74 | 72 | | |
75 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
76 | 88 | | |
77 | 89 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
13 | 26 | | |
14 | 27 | | |
15 | 28 | | |
| |||
18 | 31 | | |
19 | 32 | | |
20 | 33 | | |
21 | | - | |
| 34 | + | |
22 | 35 | | |
23 | 36 | | |
24 | | - | |
| 37 | + | |
25 | 38 | | |
26 | 39 | | |
27 | 40 | | |
| |||
78 | 91 | | |
79 | 92 | | |
80 | 93 | | |
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 | 94 | | |
121 | 95 | | |
122 | 96 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
666 | 666 | | |
667 | 667 | | |
668 | 668 | | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| 709 | + | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2200 | 2200 | | |
2201 | 2201 | | |
2202 | 2202 | | |
2203 | | - | |
| 2203 | + | |
| 2204 | + | |
2204 | 2205 | | |
2205 | 2206 | | |
2206 | 2207 | | |
| |||
2209 | 2210 | | |
2210 | 2211 | | |
2211 | 2212 | | |
2212 | | - | |
| 2213 | + | |
2213 | 2214 | | |
2214 | | - | |
| 2215 | + | |
2215 | 2216 | | |
2216 | 2217 | | |
2217 | 2218 | | |
| |||
2387 | 2388 | | |
2388 | 2389 | | |
2389 | 2390 | | |
2390 | | - | |
| 2391 | + | |
2391 | 2392 | | |
2392 | 2393 | | |
2393 | | - | |
2394 | | - | |
| 2394 | + | |
| 2395 | + | |
2395 | 2396 | | |
2396 | 2397 | | |
2397 | 2398 | | |
| |||
0 commit comments