Repository navigation
docs(adr): ADR-0144 settles Open items 2, 3, 4, 6 and 9, records ruling 6539345871 (A′ and B), the rounding mode and CLDR fraction digits (multi-currency, epic #8345) - #30182
Conversation
…ng 6539345871 (A′ and B), the rounding mode and CLDR fraction digits Each settled Open item gets a dated note in the form PR #28181 used for items 11 to 13, citing the tree on main at f68b47c by file#symbol: the rate row is the latest effective_date on or before the document date (item 2), the home amount is amount ÷ rate in exact decimal, rounded once, half away from zero, to the home currency's CLDR fraction digits with the rate stored unrounded (item 3), an unset home currency refuses ERR_HOME_CURRENCY_UNSET (item 4), the same currency converts at 1 with no lookup (item 6), and three codes are in the ledger (item 9). D9 and the TL;DR record ruling 6539345871 letter A′ (18.3.0 shipped R1 and the R2 core together; #27193, #27190, #27196 are R2.1), and Open item 2 records letter B (a datetime document date is its calendar day in the organization's localization.timezone). The Context and Consequences lines on the fraction-digit table say CLDR fraction digits, not ISO 4217 minor units, and the "only ledger additions" sentence is corrected to three codes. Open item 13 is untouched. Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01Utp6CaFs7UbZV5xCiu37Kk
…reading; Open item 2 quotes the rate predicate verbatim Two should-fixes from the contract review of the amendment, prose only. Provenance §1 says that ruling 6539345871 amends D9's release gate (A′) and settles Open item 2's datetime day (B), carried as dated notes, and §3 says the 2026-11-04 notes read origin/main at f68b47c. The Open item 2 note quotes the engine's rate predicate as written in homeAmountServing (onOrBefore, the orderBy clause, limit 1) instead of a paraphrase in code spans. Co-Authored-By: Claude <[email protected]> Claude-Session: https://claude.ai/code/session_01Utp6CaFs7UbZV5xCiu37Kk
|
epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d Reviewer: fable subagent of the epic PM seat (CONTRACT_REVIEW_TIER); carried over from #30174 (comment 6641599233), same branch and same head. Full pass at 244f2ff, then delta 244f2ff..a0c8d7c. Final head a0c8d7c: PASS, no must-fix, no open should-fix. Contract review (delta) · PR #30174 · 244f2ff..a0c8d7c · CONTRACT_REVIEW_TIER Served-tier: CONTRACT_REVIEW_TIER Must-fixNone. Should-fixNone. Checks run
Contract review · PR #30174 @ 244f2ff · CONTRACT_REVIEW_TIER Served-tier: CONTRACT_REVIEW_TIER Must-fixNone. Should-fix
Checks run
|
|
epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d Seat ACCEPT · PR #30182 (supersedes #30174, same head) · Head-sha: 维护者速读
席位意见:照原文落地已裁与已合的规则,不新增任何决定;可批。 席位核对
|
|
epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d Seat note · PR #30182 · Head-sha: @os-zhuang marked this ready and enabled auto-merge at 00:30Z; the seat reads that as the Tier H landing decision and removes
[Edit: wrong reading, withdrawn. The PR entered the merge queue at 00:31Z; the After merge the seat removes |
Requested by Bill · project thread
epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d
Fixes #30102
Supersedes #30174 (same branch and head
a0c8d7ca, body unchanged; reopened through the fleet relay, which the dispatch protocol requires for a pull request).Ruling-ref: 6539345871
Not release-paired:
docs/adr/**only, no changeset — the diff publishes nothing from any released package (skip-changeset).Clause-②: no
Metadata-protocol: none
维护者速读
localization.timezone取日历日(裁决 6539345871 B);3 精确小数、除法、一次远离零舍入到本位币 CLDR 小数位,汇率原样存不舍入;4 未设本位币拒写ERR_HOME_CURRENCY_UNSET,不默认;6 同币种汇率 1 不查表;9 三个错误码已入 ledger。D9 与 TL;DR 记下裁决 A′(18.3.0 把 R1 与 R2 核心一起发出,cli:os migrate recompute-home-amounts --object X [--since DATE] [--apply]— report then apply; rows with a missing rate are listed and skipped (multi-currency M2-3, epic #8345) #27193/import: verifysys_import_jobservessys_exchange_rate(CSV of currency, rate, effective_date); add the importer only if it does not (multi-currency M1-2, epic #8345) #27190/ui: home field read-only with "converted at RATE on DATE"; live preview when a rate exists; Studio editor forhomeAmount(multi-currency M3-2, epic #8345; the read-only display is released with M2) #27196 为 R2.1);Context/Consequences 两处把「ISO 4217 最小单位」改为 CLDR 小数位;状态块「the only ledger additions」删去,改为三个码。开放项 13 未动。file#symbol引用 main(f68b47ca)上的树,符号锚门禁全部解析;Tier H(docs/adr/**)。回滚即撤 PR。pnpm check:adr-anchors、pnpm check:adr-index、pnpm check:adr-symbol-anchors、node scripts/check-adr-links.mjs均退出 0。os-zhuang或hotlong在该 head 批准。What changes
One file,
docs/adr/0144-…, eleven edits, each in the dated-note form PR #28181 used for Open items 11–13. Every claim about behaviour cites the tree onmainatf68b47cabyfile#symbol, read for this PR, not recalled; every landing cites the pull request and its merge commit.Open items (the Task list's first bullet):
sys_exchange_raterow for the record's currency with the latesteffective_dateon or before the document date; a later row never applies; none in force refusesERR_EXCHANGE_RATE_MISSING. Evidence: thefindunder$lte/desc/limit: 1, as a system read in the row's own organization (engine.ts#homeAmountServing); a non-positive rate counts as missing and the read is memoized per (organization, currency, day) (home-amount-projection.ts#projectHomeAmounts,#memoizeHomeAmountServing). Ruling 6539345871 letter B is recorded here: adatetimedocument date is its calendar day in the organization'slocalization.timezone, UTC when unset or unknown, never the request zone (#documentDateOf); not chosen: A. The blank-dateVALIDATION_FAILED/requiredrefusal is named. Review 6539117549 and its delta 6539668963 are cited.BigInt), rounded once, half away from zero (1.005→1.01,-0.125→-0.13) to the home currency's fraction digits, stored as the bare number ADR-0104 D1 requires (#divideToPlaces,#divideRoundHalfAwayFromZero,#toScaledDecimal); the rate is stored unrounded so the home amount reproduces from the stored pair; a declaredscaleon the rate field reaches display only because every numeric column takes the onedecimal(65, 30)representation (numeric-column-representation.ts#numericColumnFor), and the spec-side refusal of a scale below 12 is named as spec-lane work, not decided.CURRENCY_FRACTION_DIGITSis CLDRcurrencyData(IQD 0 vs 3; HUF, COP, IDR, PKR and other unused-minor-unit codes 0 vs 2), exported from@objectstack/spec/datafor this one reader; review F1 / should-fix S2 and the ruling's S2 order are cited.ERR_HOME_CURRENCY_UNSET/ 400 before anything is written, no default (#HomeCurrencyUnsetError, thrown by#projectHomeAmounts); the review's reasoning against D5's rejected fallbacks and D8 rule 5, and why the code is its own ledger member, are recorded (6539117549 ③.1). The settings bridge is named (engine.ts#setHomeLocalizationResolver,plugin.ts): no service or unregistered key reads as unset and refuses; any other settings error is the write's failure. The refusal is at write, not registration. The lock (service-settings: locklocalization.currencyonce asys_exchange_raterow or ahomeAmountdeclaration exists; Setup shows what uses it (multi-currency M1-3, epic #8345) #27198, PR feat(service-settings): the default currency locks once an exchange rate or a home-currency amount uses it, and Setup names what uses it (multi-currency M1-3) #28297291bf44a) refuses a change to a set value and passes the first setting of an unset one (localization-currency-lock.ts#localizationCurrencyWritePredicate).1, no lookup, no rate row needed, still rounded, rate field stores1(#projectHomeAmounts, thecode === homearm).@objectstack/objectql(error-code-ledger.zod.ts#ERROR_CODE_LEDGER):ERR_CURRENCY_CODE_REQUIRED(objectql: record-mode guards — blank code refuses the write; ungrouped sum/avg/min/max over a record-mode field refused; summary roll-up over one refused at registration (multi-currency M0-2, epic #8345) #27186, PR feat(objectql): record-currency guards — blank code refuses the write; ungrouped sum/avg/min/max over a record-mode amount refused; summary roll-up over one refused at registration #2733957c51aab;record-currency-code.ts#RecordCurrencyCodeRequiredError),ERR_EXCHANGE_RATE_MISSING(#ExchangeRateMissingError, what its message names) andERR_HOME_CURRENCY_UNSET(#HomeCurrencyUnsetError), the last two in PR feat(objectql): store a record-mode amount converted into the home currency on every write (multi-currency M2-2) #28302. The twoVALIDATION_FAILEDreuses (requiredon a blank document date;invalid_valueon a divergent predicate update,#settleBulkHomeAmounts) and thevalidate()preview (engine-references-and-master-detail.ts#previewHomeAmounts,engine-validate.ts) are recorded.Ruling 6539345871 letter A′ (second bullet): a dated note at the end of D9: 18.3.0 (Version Packages #26517, version commit
83d7e4ae, merged 2026-11-03) carries R1 and the R2 core together —sys_exchange_rate(#27185, PR #27246194e66c0),currencyConfig.homeAmount(#27191, PR #2809673b72709), the write-time projection (#27192, PR #283026762dd91) and thelocalization.currencylock (#27198, PR #28297291bf44a), each named in its package's## 18.3.0CHANGELOG section and oncontent/docs/releases/v18/18-3.mdx; the pairing rule holds as written; what changed is the release gate of ruling 6522614678 (letter A), in one respect, with the ruling's reason; #27193 / #27190 / #27196 are R2.1; the options not chosen (A, B, C). The TL;DR delivery bullet gets a two-sentence note pointing at D9, since the claim's file surface lists TL;DR and the bullet otherwise contradicts it.Rounding mode and the unrounded rate (third bullet): in the Item 3 note, as above.
CLDR, not ISO 4217 minor units (fourth bullet): in the Item 3 note; in Context §1 (the ISO 4217 value-domain bullet, whose "no reader" sentence gets a dated note: the values have their reader, and they are CLDR fraction digits); and in Consequences ("may get their first reader" — they did, as CLDR digits).
"The only ledger additions" (fifth bullet): the Status block's "Builds on" line now reads three codes — a blank code, a missing rate, an unset home currency (Open items 4 and 9) — registered in the ledger, with a dated note saying what the sentence said before and why the "only" claim is dropped. The Evidence line says where the 2026-11-04 notes were read (
f68b47ca).Open item 13 (sixth bullet): untouched. The seat reported PR #28128 S1 unruled at this head.
Not touched: code,
skills/**,.claude/**, every other ADR,docs/adr/README.md(adr-index --reportsays it is current: the record's first status line did not change).Why
The record's Open items preamble says "This record is amended with each answer." Items 2, 3, 4, 6 and 9 were answered by PR #28302 (its body's "ADR-0144 open items settled here" and its two contract-review records), and 18.3.0 shipped them on 2026-11-03; ruling 6539345871 amended the release pairing (A′) and settled the
datetimeday (B) and ordered the ADR amendment (review should-fix S4). Onmainthe five items still read as open, the Status block still says two ledger codes, and Item 3 and Context §1 still say ISO 4217 minor units where the tree reads CLDR digits. Card #30102 carries this amendment from the predecessor's sign-off ledger.Verification
Head
a0c8d7ca: two docs commits onclaude/project-thread-b5ine2, branched fromorigin/mainatf68b47ca— the amendment (244f2ff0) and the contract review's two should-fixes (Provenance §1 names ruling 6539345871 and §3 thef68b47careading; the Open item 2 note quotes the rate predicate verbatim). The four ADR checks below were re-run ona0c8d7ca, all exit 0; the 21-command gate sweep and its--ranreconciliation ran on244f2ff0, and the second commit changes prose in the same file only.pnpm check:adr-anchors(self-test 133 assertions + full sweep): exit 0.pnpm check:adr-index(self-test 46 assertions +--report): exit 0,docs/adr/README.mdcurrent.pnpm check:adr-symbol-anchors: exit 0 — everyfile#symbolthis PR adds resolves (the sweep reports 3107 anchors across 149 records, 0 line anchors).node scripts/check-adr-links.mjs: exit 0 (979 relative links resolve).node scripts/check-commit-card-trailers.mjs --range origin/main..HEAD: exit 0.node scripts/pm/dispatch-gates.mjs --commands <the ADR path>derives 21 commands (13 by path, 8 whole-tree). Each was run with its exit code captured before any pipe:node scripts/check-adr-links.mjsnode scripts/check-adr-links.mjs --self-testnode scripts/check-closing-keyword-parity.mjsnode scripts/check-closing-keyword-parity.mjs --self-testnode scripts/check-comment-mask-corpus.mjsnode scripts/ci/plan-test-core-shards.mjs --self-testpnpm --filter @objectstack/lint run check:doc-formula-expressionspnpm check:adr-anchorspnpm check:adr-indexpnpm check:adr-symbol-anchorspnpm check:ci-filter-paritypnpm check:closed-ceremony-textpnpm check:cross-package-test-inputspnpm check:doc-authoringpnpm check:driver-memory-censuspnpm check:gitlink-declaredpnpm check:nul-bytespnpm check:pm-governed-mergespnpm check:pm-prior-rulingspnpm check:refd-timer-probepnpm check:watch-hint-literalpnpm --filter @objectstack/lint run check:doc-formula-expressionsfirst exited 3 (PREREQUISITE NOT MET:@objectstack/formulaand@objectstack/lintunbuilt in a fresh clone; the gate measured nothing); afterpnpm exec turbo run build --filter=@objectstack/formula --filter=@objectstack/lintit exited 0, the code recorded above.dispatch-gates --ranreconciliation on244f2ff0: 21 derived families accounted for, 21 run, 0 NOT-MEASURED, 0 UNRUN.Clone depth: this checkout is shallow (50 commits), so the merge commits of chore: version packages #26517 (
83d7e4ae, 2026-11-03T14:44Z), feat(objectql): store a record-mode amount converted into the home currency on every write (multi-currency M2-2) #28302 (6762dd91), feat(service-settings): the default currency locks once an exchange rate or a home-currency amount uses it, and Setup names what uses it (multi-currency M1-3) #28297 (291bf44a) and feat(spec):currencyConfig.homeAmount— a record-mode amount declares its stored home-currency projection by pointer (multi-currency M2-1) #28096 (73b72709) were confirmed against the GitHub API and against the## 18.3.0CHANGELOG sections andcontent/docs/releases/v18/18-3.mdxonmain;194e66c0,a3d24c99,6dc06b2eand57c51aabare in the clone or confirmed the same way.Model tier:
dispatch-gates --tierderives the mandated tier fordocs/adr/**at effort xhigh; the text was drafted and read at that tier.Human Minimum
packages/specholds no runtime logic. (not touched)main, one pull request.docs/adr/**only), soskip-changeset; both declaration lines are above.packages/spectouched: n/a.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_01Utp6CaFs7UbZV5xCiu37Kk