Skip to content

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

Closed

Description

@objectstack-fleet

Blocked-by: #27192

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

维护者速读

  • 改了什么: 汇率更正后的显式重算:先报告(多少行、哪些会变、哪些缺汇率),再 --apply;缺汇率的行列出并跳过(参数 1 默认);每次留审计。
  • 为什么改: 历史数据不随汇率漂移,改了要人来跑。
  • 风险与回滚: 只写影子列与汇率列。
  • 先看: 先例 summary-backfill.ts、commands/migrate/activity-changed-fields.ts。
  • 两分钟验证: 改一条汇率后报告列出受影响行,apply 后影子列更新。
  • 需要您做的: 参数 1 已按默认裁定。

Task

  • Command with report / apply modes; scope by object and start date.
  • Audit entry per run.
  • Tests with a corrected rate and a missing one.

Lane: server · Size: M · Review: default. Clause-②: no · Metadata-protocol: none.

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
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    pm:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue
    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 29, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Scope addition from maintainer ruling 6492000994 on #8345 (letter B, item 5). The report lists rows whose record-mode code is blank as their own class, apart from rows with a missing rate (parameter 1). Those rows have no code to convert, and the remedy is the backfill in #27577 (os migrate record-currency-codes), not a rate. #27577 lands before R2.

    Ruling-ref: 6492000994

  3. removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Oct 31, 2026
  4. objectstack-fleet commented on Oct 31, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: unblocked · back to the epic PM · 2026-10-31T06:58Z

    ⛔ Not a claim.


    Generated by Claude Code

  5. added
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Nov 3, 2026
  6. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Claim: PM loop round 1 · 2026-11-04T20:02Z
    Session: session_01Utp6CZWjnSeed8H4dMjt9d (epic PM, epic:#8345)
    Account: os-bill
    Branch: claude/project-thread-iobdbg (card thread session_01Utp6CXZRTkUQ6UjyMWfN2U; the platform assigns the thread's one push branch — the recorded platform exception)
    Worktree: objectstack-issue-27193
    Domain: domain:server
    Seat: epic:#8345
    File surface: packages/cli/src/commands/migrate/ (the recompute command), packages/objectql/src (an engine-side recompute function over the #27192 projection path), tests (incl. packages/qa/dogfood), content/docs (the command), .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-②: yes (widening: new exports from @objectstack/objectql, a new public ObjectQL.homeAmountReadsFor, and a new CLI command os migrate recompute-home-amounts; revised from no on the dev's measured report 6642646281)
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: none
    Premise: holds
    Serial constraints cleared: yes — no in-flight claim in the epic territory touches this surface.
    Release pairing: R2.1 — ships alone (the R2 core is released in 18.3.0).
    Maintainer authority: Bill, project thread, 「重开史诗 PM 席位」 (2026-11-04T13:36Z); dispatch order /mnt/project-files/epic-8345/dispatch-27193.md.

  7. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d
    os-dev-report

    {
      "issue": 27193,
      "status": "done",
      "branch": "claude/project-thread-iobdbg",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30181",
      "session": "session_01Utp6CXZRTkUQ6UjyMWfN2U",
      "head": "90fabf317641caf164171cb2a358561c95e3e563",
      "premise_still_valid": true,
      "summary": "Draft PR #30181 adds `recomputeHomeAmounts` (packages/objectql/src/home-amount-recompute.ts) and `os migrate recompute-home-amounts --object X [--field] [--since DATE] [--apply]`. The preview runs the write's own `projectHomeAmounts` over the engine's own reads (new public `ObjectQL.homeAmountReadsFor`, facade-delegated); apply writes the home field through `engine.update` under {isSystem, preserveAudit} with the stored updated_at, so the write re-projects and only the home and rate fields move. Per-organization counts and home currency; five skip classes (rate_missing, code_blank with the record-currency-codes remedy, document_date_blank, home_currency_unset, unconvertible), listed and never written; one sys_audit_log entry per applied run. Open item 8 proposed and pinned: skipped rows stay unwritten, the run is incomplete and exits 1 until a re-run skips nothing, and the audit entry lists them. `--since` = the document date (rateDate), a datetime read in the org timezone. Declarations corrected to Clause-②: yes (widening), Metadata-protocol: none (new exports, new engine method, new command).",
      "tests": "objectql src/engine-home-amount-projection.test.ts 42/42 (14 recompute pins: corrected rate dry-run/apply/idempotence, fresh-write equality, audit + ledger_not_mounted, missing rate, blank code, blank date, unset home, same currency 1.005->1.01, datetime across the Shanghai/UTC boundary, since, two orgs CNY/JPY, refusals). dogfood test/home-amount-projection.test.ts 42/42 across better-sqlite3, sqlite-wasm, PostgreSQL 16 (6 recompute pins per cell incl. updated_at kept and the isolated two-org case). cli recompute-home-amounts.test.ts 8/8, migrate-confirmation-exit.pin 48/48, one-shot-family -t recompute-home-amounts 5/5, json-stdout-purity (OS_TEST_TIERS=nightly) 95/95. Full objectql suite 10862/10863 before federated-injected-column-readers learned the two reads; fixed, that file + recompute file 47/47. Typecheck objectql + cli pass; eslint clean. Ablations A1-A8 in the PR body, each restored byte-identical: A1 float copy 2 red; A2 payload home=0 green (write recomputes); A3 no preserveAudit 3/3 cells red; A4-A7 1 red each; A8 shared rounding truncated: fixed-number pins red, fresh-write equality green.",
      "gates": "dispatch-gates --commands on 90fabf3176: 105 derived, each exit code captured before any pipe, 105/105 exit 0; dispatch-gates --ran: 105 derived / 105 run / 0 NOT-MEASURED / 0 UNRUN, exit 0. Change set 19 paths +1789/-5, under 3000. Lists: /mnt/project-files/epic-8345/gates-27193-cmds.txt and gates-27193-ran.txt. CI check-runs on the PR: not yet reported at posting time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "2 — github create_pull_request (write: this card thread's platform routes PR creation through the GitHub MCP; created draft, no assignee, no reviewer) and pull_request_read (read-back of the body)",
      "api_writes": "1 — this comment via scripts/pm/post-stamped.mjs",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d
    os-dev-report

    {
      "issue": 27193,
      "status": "done",
      "branch": "claude/project-thread-iobdbg",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30183",
      "session": "session_01Utp6CXZRTkUQ6UjyMWfN2U",
      "head": "35b01a068ea3e350eac34f6e3b8446836550405d",
      "premise_still_valid": true,
      "summary": "Review round 1 (seat review 6643251084 on #30181 @ 90fabf31) answered on head 35b01a068e. M1: the CLI's own since check and its VALIDATION_FAILED stamp are gone; objectql exports the pure assertHomeAmountRecomputeSince and the CLI calls it before the probe (check-error-code-provenance exit 0, no spec ledger touched). M2: the duplicated cli.mdx heading removed. M3: OBJECT_NOT_FOUND asserted with httpStatus 404; the --json envelope did not carry it (errorCodeFields reads httpStatus, refuseUndeclaredObjects set only status), so that util now sets httpStatus too, pinned in migrate-object-scope.test.ts; this widens the envelope of every os migrate command's unknown --object refusal by one field, stated in the changeset. S1: pinned with the real installAuditWriters in plugin-audit (3 per-row update rows + 1 run entry), docs and header say so. S2: a --max-records-truncated walk exits 1; an applied walk an unclassified error stops writes its run entry marked aborted, then throws. S3/S5/S6: docs sentences on updated_at, record-currency-codes' every-organization code (Open item 13), and dependents moving with the home field. S4: docblock filename fixed. P1: #30181 closed through the relay issue_patch; this PR #30183 opened through the relay pr_create on the same branch, 'Supersedes #30181', no assignee, no reviewer. origin/main a35fc6656 merged in.",
      "tests": "objectql engine-home-amount-projection 45/45 + federated-injected-column-readers (50/50 together); dogfood home-amount-projection 42/42 on better-sqlite3, sqlite-wasm, PG 16; plugin-audit home-amount-recompute-audit.integration 1/1; cli recompute-home-amounts 9/9, migrate-object-scope 6/6, migrate-confirmation-exit.pin 48/48 (63/63 with the two above). Typecheck objectql, cli (8 GB heap), plugin-audit: exit 0. eslint on the touched files: exit 0. New ablations, each restored blob == HEAD: A9 aborted-run audit write removed -> 1/45 red; A10 CLI exit ignores truncated -> 1/9 red.",
      "gates": "dispatch-gates --commands on 35b01a068e: 108 derived, plus check-error-code-provenance.ts by hand (the derivation does not name it, review P2); each exit code captured before any pipe: 109/109 exit 0. dispatch-gates --ran: 108 derived / 108 run / 0 NOT-MEASURED / 0 UNRUN, exit 0. Change set 22 paths +2016/-7, under 3000. Lists: /mnt/project-files/epic-8345/gates-27193-cmds.txt, gates-27193-ran.txt. CI check-runs on #30183: not yet reported at posting time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "2 — github pull_request_read x2 (reads: #30181's comments and state). 0 writes this round; the PR close, the PR open and this comment went through the relay.",
      "api_writes": "3 — fleet-write issue_patch #30181 state closed (run 41928849907); fleet-write pr_create #30183 (run 41928984663, body read back identical, assignees none); this comment via post-stamped",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  9. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#8345#1 · os-bill · session_01Utp6CZWjnSeed8H4dMjt9d
    os-dev-report

    {
      "issue": 27193,
      "status": "done",
      "branch": "claude/project-thread-iobdbg",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30183",
      "session": "session_01Utp6CXZRTkUQ6UjyMWfN2U",
      "head": "8374620a575574e2e40a198dfdf7caafd2d74567",
      "premise_still_valid": true,
      "summary": "Review round 2 (delta review 6644826096 @ 35b01a06). D1: packages/cli/src/utils/migrate-object-scope.ts and its unit test restored to their 90fabf31 form, so the shared OBJECT_NOT_FOUND --json envelope keeps the key set ['code','error'] that object-scope.integration.test.ts (#21644) pins; the changeset bullet announcing the wider envelope dropped; recompute-home-amounts.test.ts asserts code OBJECT_NOT_FOUND and exit 1 only. Should-fix: the type-only import's stale 'loaded lazily below' comment now says the engine package is imported dynamically inside run(), first for the --since check. PR body updated through the relay (Review round 2 section, head, local results).",
      "tests": "On 8374620a57: cli src/commands/migrate/object-scope.integration.test.ts 20/20 (alone, verbose); together with recompute-home-amounts.test.ts (9), src/utils/migrate-object-scope.test.ts and test/migrate-confirmation-exit.pin.test.ts (48): 4 files, 83/83. cli typecheck (8 GB heap) exit 0; eslint on the three touched cli files exit 0; check-error-code-provenance exit 0; check-changeset-no-major exit 0.",
      "gates": "The full derived list (108 + check-error-code-provenance, 109/109 exit 0, --ran 108/108/0/0) was run on 35b01a068e; this round changes 5 files in packages/cli and the changeset only, and the checks above were re-run on 8374620a57. CI on 8374620a57: pending at posting time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — fleet-write issue_patch #30183 body (run 41933854414, read back identical); this comment via post-stamped",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

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

    Landed · 2026-11-05T00:12Z

    Reading Value
    PR #30183 merged, merge commit 31fe289f, reviewed head 8374620a (seat ACCEPT 6645426449)
    #27193 closed by Fixes #27193

    State change: pm:dispatched and pm:blocking removed; pm:epic stays (subtree record). #27194 (Blocked-by: #27193) is released: pm:blocked removed there. Released with the next Version Packages run (patch, @objectstack/objectql, @objectstack/cli).

  11. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    pm:blockingDerived cache from the Blocked-by reverse index: open card with open dependents — never hand-set
    on Nov 5, 2026
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:epicReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queuepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions