Skip to content

Commit 73725c2

Browse files
docs(adr): ADR-0144 multi-currency — record currency, dated rates, write-time home projection; dated note on ADR-0104 (#27239)
<!-- claude-projects-attribution: {"github_login":"os-bill"} --> _Requested by **Bill** · [project thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wg9oTskgBVZmtxXLAEh251Cb)_ Fixes #27183 Clause-②: no Metadata-protocol: none ## 维护者速读 - **改了什么:** 新增 ADR-0144,把 #27119 的裁决 6465431966 记成 Accepted 决策:C′ 形状、子问题 Q0–Q4、参数 1–4、五条设计规则、R1/R2/R3 成对发布与卡号对照;裁决没定的细节列为 10 条 Open items,交给各实现卡定。ADR-0104 币种段加日期注记;ADR 索引重新生成。 - **为什么改:** 三张 spec 卡(#27184、#27187、#27191)和引擎卡按同一份记录复核,形状不再重开。 - **风险与回滚:** 纯文档,无代码、无 changeset;Tier H(`docs/adr/**`),需您批准后由您落地。回滚 = revert 本 PR。 - **先看:** ① ADR-0144 的 Decision 节(D1–D9,逐条引裁决原文);② Open items 节(裁决没定的 10 件,含参数 3 折算公式与卡面不一致);③ ADR-0104 新增注记。 - **两分钟验证:** `node scripts/adr-index.mjs --check` → 预期打印 `adr-index: OK`;`docs/adr/README.md` 出现 ADR-0144 一行,状态 Accepted。 - **需要您做的:** 批准本 PR。 ## What changes - `docs/adr/0144-multi-currency-record-currency-dated-rates-write-time-home-projection.md` (new, **Accepted** 2026-10-28) records ruling `6465431966` on #27119: - **Provenance**: what is ruled, what is analysis the ruling read (design record `6464438764`, workload rows `6464936321`, measurement round `6041378776`, shape verdict `6041482631`), and what is a reading at `cdec7473`. It also separates the shape's sub-questions Q0–Q4 from the batch items "#27119 Q1" and "#27119 Q2 X". - **Context**: today's surface (bare-number value, `dynamic` / `fixed`, `localization.currency`, no conversion code, the pure CEL stdlib), the pull, and the four shapes considered (A, A′, B, C′) with the four Q0 options. - **Decision D1–D9**: C′; Q0 sibling code field (`currencyMode: 'record'` + `currencyField`); Q1 `sys_exchange_rate`; Q2 `localization.currency`, locked once used; Q3 at write, stored with the rate, a missing rate refuses, explicit recompute; Q4 raw aggregates refuse unless grouped, consolidation through the home field; parameters 1–4; the five design rules; the R1/R2/R3 pairing with the card map from the epic body. - **Non-goals**, **Consequences**, ten **Open items** (each names its card and quotes the source's lean without adopting it), **Verification notes**. - `docs/adr/0104-field-runtime-value-shape-contract.md`: a dated note at the end of D1: multi-currency keeps D1 (the value stays a bare number; the record's currency lives in a sibling ISO 4217 field named by `currencyField`). The retirement note for `CurrencyValueSchema` belongs to #27182 / PR #27233. - `docs/adr/README.md`: regenerated by `node scripts/adr-index.mjs` (one new row; 144 → 145 records, Accepted 126 → 127, on main as of the merge of 8d79bbd). ## Tests No test of record. The diff is three Markdown files under `docs/adr/` and touches no package, so no build closure, package test or typecheck is owed. The derived gate union ran at `12cc227f` (below). ## Acceptance notes - **Decisions carry only the ruling's text.** A detail found only in the design record or the workload rows is listed under Open items, with the source's lean quoted. The review should see four discrepancies: 1. Parameter 3 ("1 home unit = `rate` units of the foreign currency") makes the home amount the record amount divided by `rate`. Workload row M2-2 and card #27192's body write "amount × rate". That card's own two-minute check (USD 10,000 at 0.1389 gives ¥71,994.24) is the division. D7 records this. 2. The measurement round and design record §9/§10 drafted the home field as a `fixed` field. The ruling's design rule says `dynamic`. D8 rule 5 records this. 3. Workload row M2-1 and card #27191 make `rateField` optional, while the ruling says the amount is "STORED with the rate used". Settled in D5 (contract review 6468858562, M2): both pointers are required whenever `homeAmount` is declared; Open item 1 keeps only their spelling for #27191, whose body the epic PM corrects before dispatch. 4. Parameter 4 ("12 significant decimals") was ambiguous (significant digits, or digits after the point). Ruled scale 12, precision 24 by the maintainer (6469382727 on #27185); recorded in D7, Open item 5 is a settled pointer. - **Number 0144.** The highest record on `main` is 0143. The numbers 0136 and 0140 were taken by proposals that never landed and are not reused (ADR-0141 and ADR-0142 say so). No open PR adds an ADR file. - **Anchors.** The first push cited line numbers, and `check:adr-symbol-anchors` refused them. The readings now anchor to the declaring symbol or the file. - **No changeset.** `docs/adr/**` publishes nothing, so `skip-changeset` is applied with this PR. - **Status Accepted.** The maintainer ruled the shape on #27119. Landing is Tier H: an authorised approval and the maintainer's merge. - **Release.** This record is a member of R1 as ruled. It ships no code, so it carries no "not released alone" marker. - **Follow-up review.** The maintainer ordered a second review of this record about ten hours after it opens. Every Decision line quotes or cites the ruling for that check. ## Verification <details><summary>Derived gate union at 12cc227: 21 derived, 21 run, every exit 0</summary> ```text node scripts/check-adr-links.mjs :: exit 0 node scripts/check-adr-links.mjs --self-test :: exit 0 node scripts/check-closing-keyword-parity.mjs :: exit 0 node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0 node scripts/check-comment-mask-corpus.mjs :: exit 0 node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0 pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0 pnpm check:adr-anchors :: exit 0 pnpm check:adr-index :: exit 0 pnpm check:adr-symbol-anchors :: exit 0 pnpm check:ci-filter-parity :: exit 0 pnpm check:closed-ceremony-text :: exit 0 pnpm check:cross-package-test-inputs :: exit 0 pnpm check:doc-authoring :: exit 0 pnpm check:driver-memory-census :: exit 0 pnpm check:gitlink-declared :: exit 0 pnpm check:nul-bytes :: exit 0 pnpm check:pm-governed-merges :: exit 0 pnpm check:pm-prior-rulings :: exit 0 pnpm check:refd-timer-probe :: exit 0 pnpm check:watch-hint-literal :: exit 0 dispatch-gates --ran: Run reconciliation — 21 derived, 21 run, 0 NOT-MEASURED, 0 UNRUN. ✓ 21 derived families accounted for — a DERIVED zero (all 21 recorded an exit code and none of them is 3). ``` `check:doc-formula-expressions` needs the compiled `@objectstack/formula` and `@objectstack/lint`. They were built under the shared lock first: `turbo run build --concurrency=2 --filter=@objectstack/formula --filter=@objectstack/lint` printed `VERDICT command-exit 0` (4 tasks). </details> <details><summary>adr-index --check</summary> ```text adr-index: OK — docs/adr/README.md is current and every record parsed. ``` </details> CI runs the rest of the farm: the artifact rosters, the wide-population families, the Test Core shard plan and the type-check lanes. dispatch-gates names these outside the derived total. --- _Generated by [Claude Code](https://claude.ai/code/session_01Utp6CbTZrFqRYNgjSaSbN5)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 74801d1 commit 73725c2

3 files changed

Lines changed: 400 additions & 3 deletions

File tree

‎docs/adr/0104-field-runtime-value-shape-contract.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ assertion that every MATRIX entry `parse`s under `valueSchemaFor` — so the
213213
contract and the executable oracle cannot drift apart, and a contract change
214214
that would break the wire fails a test instead of shipping silently.
215215

216+
> **Note 2026-10-28 (#27183; [ADR-0144](./0144-multi-currency-record-currency-dated-rates-write-time-home-projection.md)) — multi-currency keeps D1's currency value.**
217+
> ADR-0144 (ruling `6465431966` on #27119) puts a record's currency in a
218+
> sibling ISO 4217 code field that the amount names through `currencyField`,
219+
> never in the value. A `currency` value therefore stays a bare number, as
220+
> the "Reality wins" paragraph above decides. The `CurrencyValueSchema`
221+
> retirement that paragraph records belongs to #27182, whose own dated note
222+
> (PR #27233) goes under that paragraph.
223+
216224
### D2 — Typed action handlers: declared params become the enforced, typed handler input
217225

218226
Action params are already fields-lite (`ActionParamSchema` mirrors `FieldType`,

0 commit comments

Comments
 (0)