You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
spec(field): refuse a homeAmount rateField whose declared scale is below 12, and document CURRENCY_FRACTION_DIGITS as CLDR fraction digits, not ISO 4217 minor units (multi-currency, epic #8345) #30103
Part of #8345. Filed by the epic PM into the domain:spec seat's queue (spec children of the epic go to the spec seat; seat-lifecycle 〈Epic 子树车道〉). Owed by the predecessor's sign-off ledger (brief 6540325320). ⛔ Not a claim.
In the object-level judge of homeAmount pointers (packages/spec/src/data/object.zod.ts#refuseDishonestHomeAmount), refuse a rateField whose declared scale is below 12; the message names the field and the floor. Decide and state what an undeclared scale means.
TSDoc on CURRENCY_FRACTION_DIGITS and content/docs/data-modeling/currency.mdx: CLDR fraction digits; list each code where CLDR differs from ISO 4217 minor units, measured from the table, not recalled.
Tests: scale 4 refused, 12 and 14 accepted, undeclared per the decision.
Lane: spec · Size: S · Review: CONTRACT_REVIEW_TIER (narrowing a published accept set). Clause-②: no (narrowing) · Metadata-protocol: none.
Evidence: PR #28302 pins 0.138912345678 stored in full under a declared scale: 4 (home 71987.84); the engine never rounds the rate.
Dedupe: #8345 body ledger; open domain:spec cards searched, none carries this.
Claim: PM loop round 1 · 2026-11-05T18:10Z
Session: session_01L6bhgVugtCCwBs98FeR27P (seat; mode:subagent, so the dev shares this session id and is identified by the branch)
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-30103-rate-field-scale-floor
Worktree: objectstack-issue-30103
Domain: domain:spec
Seat: domain:spec#2
File surface: packages/spec/src/data/object.zod.ts (refuseDishonestHomeAmount, the rateField arm), packages/spec/src/data/currency-fraction-digits.ts (TSDoc only), content/docs/data-modeling/currency.mdx (the fraction-digits sentences), their tests, the regenerated spec artifacts, any in-repo carrier the census finds (a homeAmount.rateField pointing at a number field declared below scale 12; report first), one changeset with its ADR-0087 disposition. ⛔ ui/**, packages/services/**, packages/objectql/** engine code, skills/**, docs/adr/**, .claude/**, AGENTS.md (stop on breach; explain in the report)
Container & model: S (the card's own size; one object-level arm plus prose), mode:subagent, model: default (no path-derived mandate; narrowing ⇒ the seat runs a CONTRACT_REVIEW_TIER review before the queue), effort: medium
Clause-②: no (narrowing)
Metadata-protocol: narrowed (the card body says none; refusing a rateField an author can point at a scale-4 number field narrows what a metadata author can write; the dev re-reads it from the diff and says which)
Ruling-ref: 6469382727
Responsibility: packages/spec (homeAmount.rateField accepts a number field declared at scale < 12 while ruling 6469382727 sets the rate at scale 12, so the author sees a rate the engine does not use; CURRENCY_FRACTION_DIGITS is CLDR fraction digits, documented as ISO 4217) | refuseDishonestHomeAmount (object.zod.ts) | any author or AI declaring a multi-currency homeAmount
Thread-read: 6632541832
Premise: holds, read at origin/main1c5cee67. refuseDishonestHomeAmount (object.zod.ts L1990) judges the rateField pointer's target and writer, but never its declared scale. currency-fraction-digits.ts opens "ISO 4217 / CLDR currency fraction digits" and lists no code where CLDR and ISO 4217 minor units differ. Ruling 6469382727 (on #27185, retrieved this trip): "scale 12 — twelve digits after the decimal point, total precision 24". What an undeclared scale means is the dev's to state with a reading of the engine's rate column; a choice that needs the maintainer stops the dev.
Serial constraints cleared: no open pm:dispatched claim's File surface: and no open PR's file list names object.zod.ts, field.zod.ts, currency-fraction-digits.ts or content/docs/data-modeling/currency.mdx (read of every open claim and every open PR this round)
{
"issue": 30103,
"status": "done",
"branch": "claude/issue-30103-rate-field-scale-floor",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30644",
"session": "session_01L6bhgVugtCCwBs98FeR27P",
"premise_still_valid": true,
"summary": "refuseDishonestHomeAmount's rateField arm now refuses a number field declaring scale 0-11 at fields.AMOUNT.currencyConfig.homeAmount.rateField, naming the field, its scale, the floor 12 (ruling 6469382727) and the fix (scale: 12 or more, or delete scale); an undeclared scale is accepted because the engine stores the rate row's own value into a DECIMAL(65,30) column and an absent number scale declares no fixed width (resolveFieldScale undefined; console formatter maximumFractionDigits 20), so all twelve digits show. CURRENCY_FRACTION_DIGITS TSDoc and currency.mdx now say CLDR fraction digits, not ISO 4217 minor units, and list the 16 measured codes (IQD 0 vs 3; AFN ALL COP HUF IDR IRR KPW LAK LBP MGA MMK PKR SOS SYP YER 0 vs 2) against SIX List One 2024-06-25 as shipped in [email protected], cross-read with the datasets/currency-codes CSV. Changeset @objectstack/spec minor, BREAKING, FROM-TO, disposition registered home-amount-rate-field-scale-floor with a new semantic upgrade-guide entry (one file beyond the claimed surface, flagged).",
"tests": "At 997cb02d30: spec src/data/currency-config-home-amount.test.ts 38/38; full @objectstack/spec suite 816/816 files, 25671 passed, 1 todo (lock VERDICT command-exit 0, measured on 08d3f67c47 before the main merge; main's spec delta was 2 files and check:generated re-ran green after it). Ablation via scripts/ablation-replace.mjs: arm condition prefixed with false-and, anchor x1 to x0, blob 7f70cb81 to c41206f1, 3 red (scale 4; scale 0/11; shared column) 35 green; restored blob == HEAD 7f70cb81, git diff HEAD empty. Consumer files, each exit 0: objectql engine-home-amount-projection + home-amount-projection + home-amount-write-paths 3 files 73/73 (includes the scale-4 engine pin); plugin-audit home-amount-recompute-audit.integration 1/1; service-analytics home-amount-consolidated-measure 18 passed 18 skipped (PostgreSQL legs); service-settings localization-currency-lock 24/24; cli recompute-home-amounts 9/9.",
"gates": "At 997cb02d30, exit captured before any pipe: spec build 0; spec check:generated 0 (14/14 up to date, no --fix; run at --max-old-space-size=6144, CI's figure, because check:test-typecheck's tsc OOMs at the 2 GB default with no verdict); dispatch-gates --commands derived 103, all 103 exit 0 (six first exited 3 PREREQUISITE NOT MET on unbuilt dists: lint check:doc-formula-expressions, lint check:doc-security-posture, spec check:skill-examples, check:docs-transcript-drift, check:lean-entry-closure, check:dual-build-cjs-loads; each re-run 0 after the dogfood-plus-lint closure build, and the re-run is the recorded code); --ran: 103 derived, 103 run, 0 NOT-MEASURED, 0 UNRUN; check:adr-0087-registration 0; check:doc-authoring 0; check-nul-bytes 0; eslint --no-inline-config on the 4 changed .ts files 0. PR check-runs: not read at report time.",
"dogfood_battery": "997cb02d30 · os-verify-lock: VERDICT command-exit 0 · Test Files 420 passed, 3 skipped (423) · Tests 3500 passed, 36 skipped (3536) · no failure",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 42100548020, PR 30644); post-stamped comment on issue 30103. git push is not a REST write.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: domain:spec seat · noted, not filed: 20 lines in packages/spec/src (field.zod.ts describes and refusals, five ADR-0087 migration entries, registry.ts.template) and content/docs field-types.mdx L237/L248/L596, validation-rules.mdx L160 still call a currency's display decimals its ISO 4217 minor unit; several quote ruling 5805782503's remedy wording, so a sweep needs the seat's call on quoting.",
"carrier: domain:spec seat · noted, not filed: HomeAmountSchema.rateField .describe() (field.zod.ts L657) does not name the scale floor; outside this surface, and the refusal carries the prescription.",
"carrier: domain:spec seat · noted, not filed: the floor 12 is restated in spec (HOME_AMOUNT_RATE_SCALE) beside platform-objects EXCHANGE_RATE_SCALE because spec cannot import that package; no pin ties the two."
]
}
The narrowing's changeset carries **BREAKING** with a FROM → TO (scale: 4 → scale: 12, or no scale), so its ADR-0087 disposition cannot be not-required (no-migration-prescription). It must be registered, and the registration is this one semantic entry. The rest of the claim's file surface stands, and so do its other lines; the dev re-read Metadata-protocol: narrowed from the diff and it matches the claim.
State: the card is closed completed by Fixes #30103, and pm:dispatched is removed in this stroke. The ISO 4217 wording left across the repo is follow-up #30648, now in retriage for its lane (spec refusal and its ui copy move together). Nothing else is owed on this card.
Activity
objectstack-fleet commentedon Nov 4, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p3 kept ·
domain:speckept · 2026-11-04T13:57Z⛔ Not a claim.
homeAmount.rateFielddeclared below scale 12, and documentCURRENCY_FRACTION_DIGITSas CLDR fraction digits. A narrowing of an accepted set, so the PR carries its changeset note and a contract review. p3 kept.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
Claim: PM loop round 1 · 2026-11-05T18:10Z
Session:
session_01L6bhgVugtCCwBs98FeR27P(seat;mode:subagent, so the dev shares this session id and is identified by the branch)Account:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-30103-rate-field-scale-floorWorktree:
objectstack-issue-30103Domain:
domain:specSeat:
domain:spec#2File surface:
packages/spec/src/data/object.zod.ts(refuseDishonestHomeAmount, therateFieldarm),packages/spec/src/data/currency-fraction-digits.ts(TSDoc only),content/docs/data-modeling/currency.mdx(the fraction-digits sentences), their tests, the regenerated spec artifacts, any in-repo carrier the census finds (ahomeAmount.rateFieldpointing at a number field declared below scale 12; report first), one changeset with its ADR-0087 disposition. ⛔ui/**,packages/services/**,packages/objectql/**engine code,skills/**,docs/adr/**,.claude/**,AGENTS.md(stop on breach; explain in the report)Container & model:
S(the card's own size; one object-level arm plus prose),mode:subagent,model: default(no path-derived mandate; narrowing ⇒ the seat runs a CONTRACT_REVIEW_TIER review before the queue),effort: mediumClause-②: no (narrowing)
Metadata-protocol: narrowed (the card body says
none; refusing arateFieldan author can point at a scale-4 number field narrows what a metadata author can write; the dev re-reads it from the diff and says which)Ruling-ref: 6469382727
Responsibility:
packages/spec(homeAmount.rateFieldaccepts a number field declared atscale< 12 while ruling 6469382727 sets the rate at scale 12, so the author sees a rate the engine does not use;CURRENCY_FRACTION_DIGITSis CLDR fraction digits, documented as ISO 4217) |refuseDishonestHomeAmount(object.zod.ts) | any author or AI declaring a multi-currencyhomeAmountThread-read: 6632541832
Premise: holds, read at
origin/main1c5cee67.refuseDishonestHomeAmount(object.zod.tsL1990) judges therateFieldpointer's target and writer, but never its declaredscale.currency-fraction-digits.tsopens "ISO 4217 / CLDR currency fraction digits" and lists no code where CLDR and ISO 4217 minor units differ. Ruling 6469382727 (on #27185, retrieved this trip): "scale 12 — twelve digits after the decimal point, total precision 24". What an undeclaredscalemeans is the dev's to state with a reading of the engine's rate column; a choice that needs the maintainer stops the dev.Serial constraints cleared: no open
pm:dispatchedclaim'sFile surface:and no open PR's file list namesobject.zod.ts,field.zod.ts,currency-fraction-digits.tsorcontent/docs/data-modeling/currency.mdx(read of every open claim and every open PR this round)Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
os-dev-report
{ "issue": 30103, "status": "done", "branch": "claude/issue-30103-rate-field-scale-floor", "pr": "https://github.com/objectstack-ai/objectstack/pull/30644", "session": "session_01L6bhgVugtCCwBs98FeR27P", "premise_still_valid": true, "summary": "refuseDishonestHomeAmount's rateField arm now refuses a number field declaring scale 0-11 at fields.AMOUNT.currencyConfig.homeAmount.rateField, naming the field, its scale, the floor 12 (ruling 6469382727) and the fix (scale: 12 or more, or delete scale); an undeclared scale is accepted because the engine stores the rate row's own value into a DECIMAL(65,30) column and an absent number scale declares no fixed width (resolveFieldScale undefined; console formatter maximumFractionDigits 20), so all twelve digits show. CURRENCY_FRACTION_DIGITS TSDoc and currency.mdx now say CLDR fraction digits, not ISO 4217 minor units, and list the 16 measured codes (IQD 0 vs 3; AFN ALL COP HUF IDR IRR KPW LAK LBP MGA MMK PKR SOS SYP YER 0 vs 2) against SIX List One 2024-06-25 as shipped in [email protected], cross-read with the datasets/currency-codes CSV. Changeset @objectstack/spec minor, BREAKING, FROM-TO, disposition registered home-amount-rate-field-scale-floor with a new semantic upgrade-guide entry (one file beyond the claimed surface, flagged).", "tests": "At 997cb02d30: spec src/data/currency-config-home-amount.test.ts 38/38; full @objectstack/spec suite 816/816 files, 25671 passed, 1 todo (lock VERDICT command-exit 0, measured on 08d3f67c47 before the main merge; main's spec delta was 2 files and check:generated re-ran green after it). Ablation via scripts/ablation-replace.mjs: arm condition prefixed with false-and, anchor x1 to x0, blob 7f70cb81 to c41206f1, 3 red (scale 4; scale 0/11; shared column) 35 green; restored blob == HEAD 7f70cb81, git diff HEAD empty. Consumer files, each exit 0: objectql engine-home-amount-projection + home-amount-projection + home-amount-write-paths 3 files 73/73 (includes the scale-4 engine pin); plugin-audit home-amount-recompute-audit.integration 1/1; service-analytics home-amount-consolidated-measure 18 passed 18 skipped (PostgreSQL legs); service-settings localization-currency-lock 24/24; cli recompute-home-amounts 9/9.", "gates": "At 997cb02d30, exit captured before any pipe: spec build 0; spec check:generated 0 (14/14 up to date, no --fix; run at --max-old-space-size=6144, CI's figure, because check:test-typecheck's tsc OOMs at the 2 GB default with no verdict); dispatch-gates --commands derived 103, all 103 exit 0 (six first exited 3 PREREQUISITE NOT MET on unbuilt dists: lint check:doc-formula-expressions, lint check:doc-security-posture, spec check:skill-examples, check:docs-transcript-drift, check:lean-entry-closure, check:dual-build-cjs-loads; each re-run 0 after the dogfood-plus-lint closure build, and the re-run is the recorded code); --ran: 103 derived, 103 run, 0 NOT-MEASURED, 0 UNRUN; check:adr-0087-registration 0; check:doc-authoring 0; check-nul-bytes 0; eslint --no-inline-config on the 4 changed .ts files 0. PR check-runs: not read at report time.", "dogfood_battery": "997cb02d30 · os-verify-lock: VERDICT command-exit 0 · Test Files 420 passed, 3 skipped (423) · Tests 3500 passed, 36 skipped (3536) · no failure", "mcp_calls": "0", "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 42100548020, PR 30644); post-stamped comment on issue 30103. git push is not a REST write.", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: domain:spec seat · noted, not filed: 20 lines in packages/spec/src (field.zod.ts describes and refusals, five ADR-0087 migration entries, registry.ts.template) and content/docs field-types.mdx L237/L248/L596, validation-rules.mdx L160 still call a currency's display decimals its ISO 4217 minor unit; several quote ruling 5805782503's remedy wording, so a sweep needs the seat's call on quoting.", "carrier: domain:spec seat · noted, not filed: HomeAmountSchema.rateField .describe() (field.zod.ts L657) does not name the scale floor; outside this surface, and the refusal carries the prescription.", "carrier: domain:spec seat · noted, not filed: the floor 12 is restated in spec (HOME_AMOUNT_RATE_SCALE) beside platform-objects EXCHANGE_RATE_SCALE because spec cannot import that package; no pin ties the two." ] }objectstack-fleet commentedon Nov 5, 2026
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
席位核对 · Amendment · 2026-11-05T20:11Z · claim 6665552839 file surface widened
File surface (added):
packages/spec/src/migrations/entries/semantic/18.home-amount-rate-field-scale-floor.tsThe narrowing's changeset carries
**BREAKING**with a FROM → TO (scale: 4→scale: 12, or noscale), so its ADR-0087 disposition cannot benot-required (no-migration-prescription). It must beregistered, and the registration is this one semantic entry. The rest of the claim's file surface stands, and so do its other lines; the dev re-readMetadata-protocol: narrowedfrom the diff and it matches the claim.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
ACCEPT → PR #30644 comment 6669861070 · head
fcb86f79a42b967c781e8ae92ab9c4e17eeb8c3e· contract review PASS 6668524557, re-review PASS 6669807764 · 2026-11-05T21:21Zobjectstack-fleet commentedon Nov 5, 2026
domain:spec#2 · os-sales · session_01L6bhgVugtCCwBs98FeR27P
Landed · PR #30644 · merge
b77c160a02c2bb69ad6c986461b2633fa8d28c18· 2026-11-05T21:46ZGET /repos/objectstack-ai/objectstack/issues/30644/timelineadded_to_merge_queue21:21:54Z →removed_from_merge_queue21:45:38Z,merged21:45:38Zorigin/mainby content (refusal)git grep -n HOME_AMOUNT_RATE_SCALE origin/main -- packages/spec/src/data/object.zod.tsconst HOME_AMOUNT_RATE_SCALE = 12;, L2175 thescale < HOME_AMOUNT_RATE_SCALEbranchorigin/mainby content (upgrade entry)git ls-tree origin/main packages/spec/src/migrations/entries/semantic/ | grep -c home-amount-rate-field-scale-floorState: the card is closed
completedbyFixes #30103, andpm:dispatchedis removed in this stroke. The ISO 4217 wording left across the repo is follow-up #30648, now in retriage for its lane (spec refusal and its ui copy move together). Nothing else is owed on this card.Generated by Claude Code