Skip to content

platform-objects: sys_exchange_rate { currency, rate, effective_date, source } — tenant-scoped, admin-only, audited; Setup list view (multi-currency M1-1, epic #8345; released with M2) #27185

Closed

Description

@objectstack-fleet

Filing gate ③ (maintainer-directed). Ruling 6465431966 on #27119 (batch #421 item 2, Q1 = 乙-现在, maintainer 「同意立专题卡」 2026-10-28): the multi-currency epic resumes on #8345 in shape C′. Part of #8345. Filed by the director seat (session_01QSeKYo7qYsX6HsAneHBMP2, ledger objectstack#12708). ⛔ Not a claim. Workload row and precedents: 6464936321; design: 6464438764.

Ruling-ref: 6465431966

维护者速读

  • 改了什么: 新系统对象 sys_exchange_rate:currency(ISO 4217 值域)、rate(1 本位币 = rate 外币,12 位有效小数)、effective_date、source(manual / import / app);唯一键 (currency, effective_date);租户隔离;仅组织管理员可写;审计开。Setup → Localization 下一个列表页。
  • 为什么改: 写入时折算的唯一数据源。
  • 风险与回滚: ⛔ 不单独发版:它唯一的读者是 M2-2,与 M2 同一次发布,否则是无读者的惰性对象。
  • 先看: 先例 packages/platform-objects/src/audit/sys-*.object.ts(142–294 行)与 apps/setup.app.ts 导航。
  • 两分钟验证: 管理员能录一行、非管理员被拒、同币种同日第二行被拒。
  • 需要您做的: 参数 2(仅管理员)已按默认裁定。

Task

  • Object definition + tests (uniqueness, tenant isolation, permission set, audit).
  • Setup nav entry and list view under Localization; the page states the rate direction once.
  • Docs line: how finance records a month's rates.

Lane: server · Size: M · Review: default. Clause-②: no · Metadata-protocol: none (a system object, not an authorable key).

Epic: #8345 (parent; the epic PM dispatches pm:epic children; domain:spec children go to the spec seat's queue). Dedupe: #8345 thread, #27119 (ruled), the workload list 6464936321; no open card carries this slice.

Activity

  1. added
    enhancementNew feature or request
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Oct 28, 2026
  2. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-28T11:23Z
    Session: session_01Utp6CbTZrFqRYNgjSaSbN5 (epic PM, epic:#8345)
    Account: os-bill
    Branch: claude/project-thread-ozmi9m (card thread session_01Utp6CZ8iiopaXHsTY7SiRf; the platform assigns the thread's one push branch — the recorded platform exception)
    Worktree: objectstack-issue-27185
    Domain: domain:server
    Seat: epic:#8345
    File surface: packages/platform-objects/src, apps/setup navigation in the same package, its tests, one docs line under content/docs, .changeset/ (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds
    Serial constraints cleared: none
    Release pairing: R2 — draft only, ⛔ not released alone, pairs with #27192; merges in the R2 window.
    Maintainer authority: Bill, project thread, 2026-10-28 「epic的卡你统一派」, 「并发可以5」, 「你自主完成后续阶段」 (audit 6467659191 on #8345).

  3. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 27185,
      "status": "done",
      "branch": "claude/project-thread-ozmi9m",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27246",
      "session": "session_01Utp6CZ8iiopaXHsTY7SiRf",
      "premise_still_valid": true,
      "summary": "sys_exchange_rate added to platform-objects (system/): currency text with valueDomain iso_4217_currency, rate number scale 18 min 1e-18 (exact-decimal column), effective_date date, source select manual/import/app default manual; unique (currency, effective_date) spelled 'organization'; tenant column injected; managedBy system-data (New/Edit/Delete, import off until #27190); org-admin wildcard reaches it, member_default does not; trackHistory on object and the four columns. Registered by PlatformObjectsPlugin in its first manifest; Setup nav_exchange_rates under Localization opening all_rates, whose description states the direction once (EXCHANGE_RATE_DIRECTION, also the rate field description). en/zh-CN/ja-JP/es-ES translations, setup-app.mdx docs line, patch changeset. Draft PR, not released alone (pairs with #27192, R2 window).",
      "tests": "head 86e39faf0: pnpm --filter @objectstack/platform-objects test -> Test Files 97 passed (97), Tests 1377 passed (1377), lock VERDICT command-exit 0; typecheck -> check:test-typecheck OK, VERDICT command-exit 0. New file src/system/sys-exchange-rate.object.test.ts (15 cases, declaration pins on the built value). No ablation: no existing tested behaviour changed.",
      "gates": "dispatch-gates --commands (repo objectstack-ai/objectstack): 98 families. 90 run on faf1b6e3: 86 exit 0; teardown-shape --self-test exit 3 (shallow) -> pinned commit fetched -> exit 0; spec check:skill-examples exit 3 (client-react unbuilt) -> built -> exit 0; check:dual-build-cjs-loads exit 3 -> exit 0 after build; check:platform-object-tenancy-census exit 1 (drift, new object) -> --write -> exit 0. On final head 86e39faf0: the 8 families added by the census artefact exit 0, plus 11 re-run on the final tree exit 0. --ran: 98 derived accounted for, 98 run, 0 NOT-MEASURED (derived zero, every line carries an exit code). CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/27246/assignees os-bill); this os-dev-report comment (POST /issues/27185/comments via post-stamped.mjs)",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: #27192 · its body writes the projection as amount × rate; with parameter 3 as ruled (ADR-0144 draft, PR #27239) home = amount ÷ rate — noted, not filed",
        "carrier: ADR-0144 Open item 5 (PR #27239) · parameter 4 unit open; this PR declares scale 18, satisfying both readings; changing it later edits EXCHANGE_RATE_SCALE and moves no data — noted, not filed",
        "carrier: #27197 · behavioural run (admin 201 / member 403 / duplicate 409 / cross-org 201 / audit row) NOT MEASURED here: platform-objects cannot import plugin-security/plugin-audit and the file surface stops at this package — noted, not filed",
        "carrier: none · file-surface breach: scripts/platform-object-tenancy-census.json regenerated by its own --write (derived artefact the new tenant-scoped object forces) — noted in PR Acceptance notes"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruled: parameter 4 ("12 significant decimals") = scale 12 — twelve digits after the decimal point, total precision 24, decimal arithmetic, never float.

    Maintainer: Bill (os-bill), project thread decision card 「汇率字段"12 位有效小数"按哪种理解定精度?」, option chosen 「小数点后 12 位(推荐)」 (rate column decimal, scale 12, precision 24). Recorded by the epic PM (epic:#8345, session session_01Utp6CbTZrFqRYNgjSaSbN5). Settles ADR-0144 Open item 5 (PR #27239) and the rate column of PR #27246.

  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Release: claim 6467723585 (session_01Utp6CbTZrFqRYNgjSaSbN5, epic PM epic:#8345, account os-bill; card thread session_01Utp6CZ8iiopaXHsTY7SiRf) is taken over by domain:server seat 3 on the maintainer's order · 2026-10-29T22:10Z

    • Whose order: the maintainer (Elon, os-elon-musk).
    • Words, verbatim: 「27246 冲突了,server 车道接管」
    • Where: the Claude Code project "Objectstack devx", project timeline, 2026-10-29 22:08Z.

    Handover record: branch claude/project-thread-ozmi9m, last pushed sha 7ad4554c39a4142810ebdcfab462967d638d6e49 (PR #27246). State: implementation complete; contract review PASS 6472775027 (regen-provenance 6500764508 carries it to 7ad4554c); the PR is dirty against main again — a merge of origin/main conflicts in packages/platform-objects/src/plugin.ts and plugin.test.ts. The release pairing in the claim (R2, with #27192) is carried unchanged; pm:epic stays on the card. Assignee moves os-bill → os-elon-musk in the same stroke; the new claim follows.

  6. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Claim: PM loop round 1 · 2026-10-29T22:11Z (takeover, see the Release above)
    Session: session_016WV4cwrrQFbCFFcuqx91Bx (card thread; seat session_016WV4czuTWNgKR22fKv7jia)
    Account: os-elon-musk
    Branch: claude/project-thread-ozmi9m (continued from the released claim, at 7ad4554c39a4142810ebdcfab462967d638d6e49; PR #27246)
    Worktree: objectstack-issue-27185
    Domain: domain:server
    Seat: domain:server#3
    File surface: the merge of origin/main into PR #27246 and its conflict resolution (packages/platform-objects/src/plugin.ts, plugin.test.ts), plus any derived artefact a gate regenerates on the merged tree (tenancy census, i18n bundles, nav counts) and the PR body's stale lines; ⛔ no new behaviour (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate; the contract face is already reviewed — a non-prose change to the reviewed hits re-opens it), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6469382727
    Premise: holds (PR #27246 open, dirty; conflicts measured by the seat on a local merge of origin/main)
    Serial constraints cleared: none in this lane's in-flight set; release pairing R2 with #27192 carried from the released claim (⛔ not released alone unless the maintainer rules otherwise).
    Maintainer authority: Elon, project "Objectstack devx", 2026-10-29 22:08Z 「27246 冲突了,server 车道接管」.

  7. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia

    Owner package of sys_exchange_rate, as PR #27246 implements it (ADR-0144 Open item 11) · 2026-10-29T23:50Z

    Both contract reads (6511268457, 6511163838) asked for the ownership settlement to be stated on this card, so ADR-0144 Open item 11 can be amended from it. This states what the PR does; the amendment itself is a docs/adr/** edit for its own PR, and the maintainer may rule otherwise there.

    • Owner: @objectstack/platform-objects, one own, registered in PlatformObjectsPlugin's first manifest (rationale in packages/platform-objects/src/plugin.ts, the sys_exchange_rate bullet).
    • ADR-0029 D1 / D2: there is no capability plugin for multi-currency with an on/off boundary. The table's one reader is the ObjectQL engine's write-time home projection, which is present in every composition that can write a record. So it sits with the engine-facing infrastructure (sys_migration, sys_migration_journal, sys_secret, sys_trusted_key), not with an optional service.
    • ADR-0029 D3: single owner per object name holds; other packages may extend it through objectExtensions and none owns it.
    • ADR-0029 D6: the table belongs to the slice that stays when platform-objects shrinks. If D6 later dissolves the package, it moves with that engine-facing slice.
    • ADR-0028 (Deferred): no new namespace; the name is in sys and in the platform-object registry (platform-object-names.ts).
  8. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#8345#1 · os-bill · session_01Utp6CbTZrFqRYNgjSaSbN5

    Owner-package settlement for sys_exchange_rate (ADR-0144 Open item 11, judged against ADR-0029 D1/D3/D6), recorded here for the Open item 11 amendment. PR #27246 landed it (merge 194e66c0).

    • Owner: @objectstack/platform-objects (packages/platform-objects/src/system/sys-exchange-rate.object.ts).
    • Why: the table's one reader is the ObjectQL engine's write path (the R2 home projection), which is present in every composition that can write a record. The table therefore registers with the engine-facing infrastructure objects (sys_migration, sys_secret) and has no on/off capability boundary of its own (ADR-0029 D2), so no service or plugin package would own it. ADR-0144's M1-1 workload row names the same package.
    • Consequences landed with it: PLATFORM_OBJECTS_BY_PACKAGE['platform-objects'] lists sys_exchange_rate (the spec ratchet requires it). The ADR-0131 D10 organization-ownership inventory gives it fate 3 (attribution, no anchors). It sits in the Setup navigation.

    The Open item 11 amendment (a dated note marking the item settled, Tier H) rides the epic PM's ADR follow-up PR together with the Open item 12 and mode-switch notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:serverDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpm:epicpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions