Repository navigation
Commit 73725c2
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
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
216 | 224 | | |
217 | 225 | | |
218 | 226 | | |
| |||
0 commit comments