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
cli + objectql: record-currency backfill scoped per organization — --org, refuse multi-org runs without it, --all-organizations explicit; recompute takes the same --org (multi-currency, epic #8345, ruling C item A) #30674
backfillRecordCurrencyCodes gains an organizationId option; the walk and every engine.update run under { isSystem: true, tenantId: organizationId } (the mechanism engine-driver-read-scope.test.ts already pins). The report counts per organization.
os migrate record-currency-codes --org <id>. On a database holding more than one organization, a run without --org is refused before any write (exit 1); the refusal lists each organization's codeless row count, and MAY show that organization's current localization.currency beside it as a reference only. ⛔ It is never written (ADR-0144 D8 rule 4).
--all-organizations is the explicit way to write one code into every organization. --org and --all-organizations together are a usage error.
A single-organization database behaves exactly as today (pin it).
Keep all logic in the objectql functions; the CLI only parses and prints, so the REST door (the B card) reuses them unchanged.
Tests: two organizations on memory, SQLite and Postgres: refusal lists both counts and writes nothing; --org writes only that organization; --all-organizations writes both; single-org unchanged; --json envelope for the refusal. Docs beside the commands in content/docs/deployment/cli.mdx.
Lane: server · Size: S · Model: opus, effort medium · Review: default. Clause-②: yes (widening: new optional option on two exported objectql functions) · Metadata-protocol: none.
Out of scope: the REST door (B card); docs/adr/** and skills/** (the seat's Tier H close-out card).
Dedupe: #8345 thread; PR #28128 review 6525881524 S1; no open card carries organization scoping for these commands.
Handover: epic #8345 → domain:server queue. The epic seat signed off (6670841501); the maintainer agreed the remaining cards go to the server lane. Labels and dependencies only; this seat is signing off and does not dispatch it.
Maintainer: 「同意」, project chat, 2026-11-05T22:14Z.
State change: pm:epic off, pm:queue on. It goes first: dispatch order epic-8345/dispatch-30674.md in the project files. The next server seat claims it with the full claim protocol and re-reads the thread.
Claim: PM loop round 1 · 2026-11-05T22:40Z
Session: session_016WV4cytLmJxfAmgPVjUbbW
Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
Branch: the card thread's designated claude/project-thread-* branch, named in a claim amendment once the thread reports it
Worktree: objectstack-issue-30674
Domain: domain:server
Seat: domain:server#1
File surface: packages/objectql/src/record-currency-backfill.ts (organizationId option, per-organization walk and report), packages/objectql/src/home-amount-recompute.ts (organization filter), packages/cli/src/commands/migrate/record-currency-codes.ts and recompute-home-amounts.ts (--org, --all-organizations, the multi-organization refusal), their tests, one root .changeset/ file. ⛔ packages/spec/**; ⛔ writing any organization's localization.currency as a code (ADR-0144 D8 rule 4) (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the record-currency backfill in packages/objectql and its CLI (one --code writes every organization's codeless rows) | none (no per-organization scope exists today) | an operator running os migrate record-currency-codes on a multi-organization database, which silently writes a wrong currency code for some organizations
Thread-read: 6671016825
Premise: holds per the card's ruling-derived task list (ruling 6670707546, letter C, maintainer 「同意」); the dev re-reads both engine functions and both commands on origin/main first
Serial constraints cleared: no open PR touches the two engine files or the two migrate commands (open PR file lists read at claim time; #30696 edits other migrate/ commands, not these). Handover from epic #8345 by domain:server#2 (6671016825), maintainer 「同意」 22:14Z.
Branch: this is the card thread's harness-designated branch (the project-thread platform exception). The dev thread is session session_016WV4cyT9hHRjH6qFYychv1.
File surface: adds content/docs/deployment/cli.mdx, the docs beside the two commands that the card's Task list names.
Clause arm: the card body declares yes (widening: new optional option on two exported objectql functions), and that wins over the claim's no. The option widens the exported signatures of backfillRecordCurrencyCodes / recomputeHomeAmounts; it touches no published schema. The review owed is the lane seat's own review of record, at the default tier. The dev re-derives the arm from the diff and flags any difference.
席位核对 · Amendment · 2026-11-05T22:58Z · claim 6671428099 clause arm and test surface
Clause-②: yes (narrowing)
The card thread re-derived the arm from its diff. Called with no organization over rows of two organizations, the exported backfillRecordCurrencyCodes now refuses (VALIDATION_ERROR / 400) where main wrote, and os migrate record-currency-codes without --org exits 1. That is the narrowing the ruling orders, and it dominates the new optional options. This replaces the (widening) arm of 6671472723.
The arm owes: the BREAKING banner and the ADR-0087 disposition marker in the changeset, the full dogfood battery on the final head, and one contract-review-tier review before the queue.
File surface, tests only: packages/objectql/src/federated-injected-column-readers.test.ts (registers the new organization_id reader) and the SQLite/Postgres cells under packages/qa/dogfood/test/.
Mechanism note, measured: { isSystem: true, tenantId } scopes the driver only under a walled posture, so the walk also filters on the row's own organization_id.
{
"issue": 30674,
"status": "done",
"branch": "claude/project-thread-erl0zi",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30737",
"session": "session_016WV4cyT9hHRjH6qFYychv1",
"premise_still_valid": true,
"summary": "backfillRecordCurrencyCodes takes organizationId / allOrganizations. An unscoped run over the rows of more than one organization is counted read-only and refused with 400 VALIDATION_ERROR (field organizationId, per-organization counts on the error) before any write, on dry and apply runs alike. Rows of one organization run exactly as before, with the same report text. os migrate record-currency-codes gains --org and --all-organizations as an oclif exclusive pair (exit 2 together), the refusal prints each organization's codeless count, exit 1. recomputeHomeAmounts gains organizationId and the recompute command gains --org, never refused. No localization.currency is read. Measured correction to the brief: { isSystem, tenantId } narrows the driver only under a walled posture, and a CLI shell boots single, so both scoped walks also filter where organization_id = the organization.",
"tests": "objectql whole package 556 files / 11079 passed; cli --project integration migrate tests 2 files / 26 passed; dogfood record-currency-backfill-organizations + home-amount-projection 2 files / 57 passed incl. PostgreSQL 16 cells; type-check objectql, cli, dogfood exit 0. Ablations: (1) refusal threshold > 999 -> objectql pin 'two organizations and no scope' red, restored green; (2) scoped where filter removed -> 2 objectql pins red, then rebuilt into dist with ablation-dist-preflight confirming the mutation -> dogfood scoped pin red on better-sqlite3, sqlite-wasm and pg; restored + rebuilt, preflight marker absent, clean tree, green. A first src-only dogfood ablation was a false green (dogfood reads dist) and is not counted.",
"gates": "dispatch-gates --commands derived 94 families, each run with its exit code captured; --ran: 94 derived, 94 run, 0 NOT-MEASURED, 0 UNRUN. Three exit-3 prerequisites on the first pass (plugin-teardown-shape --self-test: shallow clone; check:skill-examples and check:dual-build-cjs-loads: missing dist) cleared by git fetch --unshallow plus a build of those packages, rerun exit 0. pnpm lint exit 0. CI check-runs on the PR: pending at report time; the seat thread gets them when green.",
"dogfood_battery": "f7b7814e · os-verify-lock: VERDICT command-exit 0 · held the lock 1466s · Test Files 422 passed | 3 skipped (425) · Tests 3547 passed | 17 skipped (3564) · no failures",
"mcp_calls": "2 — mcp__github__issue_read (card read), mcp__github__pull_request_read (PR read-back); no MCP write tool",
"api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, draft, no assignees, no labels) and this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/30674/comments); plus git push of the branch (not a REST write)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: skills close-out card (Tier H) · skills/objectstack-data/rules/field-types.md L174 'Backfill: os migrate record-currency-codes' names neither --org nor --all-organizations; declared in the PR as Skills-docs: follow-up owed · noted, not filed",
"carrier: the B card (REST door) · RecordCurrencyBackfillOrganization and RecordCurrencyBackfillOrganizationsRefusal are not re-exported from the @objectstack/objectql barrel (outside this file surface) · noted, not filed",
"carrier: seat (landing) · the four branch commits are WIP commits without the Claude-Session / Co-authored-by trailer pair; the branch was already pushed and is not force-pushed, so the pair belongs in the squash message · noted, not filed"
]
}
File surface adds content/docs/data-modeling/currency.mdx (~L140, ~L362–365): it says the code backfill writes its one code into every organization's codeless rows, which PR #30737 makes false (os-dev: a published statement the diff falsifies is fixed in the same PR). Docs only, +8/−3. The skills line stays the follow-up card #30740; content/docs/releases/** stays untouched. Everything else in the claim and its amendments stands.
Activity
objectstack-fleet commentedon Nov 5, 2026
domain:server#2 · os-bill · session_01Utp6Cbvcmv8YWFhFJwzjKL
Handover: epic #8345 →
domain:serverqueue. The epic seat signed off (6670841501); the maintainer agreed the remaining cards go to the server lane. Labels and dependencies only; this seat is signing off and does not dispatch it.Maintainer: 「同意」, project chat, 2026-11-05T22:14Z.
State change:
pm:epicoff,pm:queueon. It goes first: dispatch orderepic-8345/dispatch-30674.mdin the project files. The next server seat claims it with the full claim protocol and re-reads the thread.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Claim: PM loop round 1 · 2026-11-05T22:40Z
Session:
session_016WV4cytLmJxfAmgPVjUbbWAccount:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch: the card thread's designated
claude/project-thread-*branch, named in a claim amendment once the thread reports itWorktree:
objectstack-issue-30674Domain:
domain:serverSeat:
domain:server#1File surface:
packages/objectql/src/record-currency-backfill.ts(organizationIdoption, per-organization walk and report),packages/objectql/src/home-amount-recompute.ts(organization filter),packages/cli/src/commands/migrate/record-currency-codes.tsandrecompute-home-amounts.ts(--org,--all-organizations, the multi-organization refusal), their tests, one root.changeset/file. ⛔packages/spec/**; ⛔ writing any organization'slocalization.currencyas a code (ADR-0144 D8 rule 4) (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable),effort: highClause-②: no
Metadata-protocol: none
Responsibility: the record-currency backfill in
packages/objectqland its CLI (one--codewrites every organization's codeless rows) | none (no per-organization scope exists today) | an operator runningos migrate record-currency-codeson a multi-organization database, which silently writes a wrong currency code for some organizationsThread-read: 6671016825
Premise: holds per the card's ruling-derived task list (ruling 6670707546, letter C, maintainer 「同意」); the dev re-reads both engine functions and both commands on
origin/mainfirstSerial constraints cleared: no open PR touches the two engine files or the two migrate commands (open PR file lists read at claim time; #30696 edits other
migrate/commands, not these). Handover from epic #8345 bydomain:server#2(6671016825), maintainer 「同意」 22:14Z.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
席位核对 · Amendment · 2026-11-05T22:43Z · claim 6671428099 branch, docs, clause arm
Branch:
claude/project-thread-erl0ziClause-②: yes (widening)
session_016WV4cyT9hHRjH6qFYychv1.content/docs/deployment/cli.mdx, the docs beside the two commands that the card's Task list names.yes (widening: new optional option on two exported objectql functions), and that wins over the claim'sno. The option widens the exported signatures ofbackfillRecordCurrencyCodes/recomputeHomeAmounts; it touches no published schema. The review owed is the lane seat's own review of record, at the default tier. The dev re-derives the arm from the diff and flags any difference.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
席位核对 · Amendment · 2026-11-05T22:58Z · claim 6671428099 clause arm and test surface
Clause-②: yes (narrowing)
backfillRecordCurrencyCodesnow refuses (VALIDATION_ERROR/ 400) wheremainwrote, andos migrate record-currency-codeswithout--orgexits 1. That is the narrowing the ruling orders, and it dominates the new optional options. This replaces the(widening)arm of 6671472723.packages/objectql/src/federated-injected-column-readers.test.ts(registers the neworganization_idreader) and the SQLite/Postgres cells underpackages/qa/dogfood/test/.{ isSystem: true, tenantId }scopes the driver only under a walled posture, so the walk also filters on the row's ownorganization_id.objectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cyT9hHRjH6qFYychv1
os-dev-report
{ "issue": 30674, "status": "done", "branch": "claude/project-thread-erl0zi", "pr": "https://github.com/objectstack-ai/objectstack/pull/30737", "session": "session_016WV4cyT9hHRjH6qFYychv1", "premise_still_valid": true, "summary": "backfillRecordCurrencyCodes takes organizationId / allOrganizations. An unscoped run over the rows of more than one organization is counted read-only and refused with 400 VALIDATION_ERROR (field organizationId, per-organization counts on the error) before any write, on dry and apply runs alike. Rows of one organization run exactly as before, with the same report text. os migrate record-currency-codes gains --org and --all-organizations as an oclif exclusive pair (exit 2 together), the refusal prints each organization's codeless count, exit 1. recomputeHomeAmounts gains organizationId and the recompute command gains --org, never refused. No localization.currency is read. Measured correction to the brief: { isSystem, tenantId } narrows the driver only under a walled posture, and a CLI shell boots single, so both scoped walks also filter where organization_id = the organization.", "tests": "objectql whole package 556 files / 11079 passed; cli --project integration migrate tests 2 files / 26 passed; dogfood record-currency-backfill-organizations + home-amount-projection 2 files / 57 passed incl. PostgreSQL 16 cells; type-check objectql, cli, dogfood exit 0. Ablations: (1) refusal threshold > 999 -> objectql pin 'two organizations and no scope' red, restored green; (2) scoped where filter removed -> 2 objectql pins red, then rebuilt into dist with ablation-dist-preflight confirming the mutation -> dogfood scoped pin red on better-sqlite3, sqlite-wasm and pg; restored + rebuilt, preflight marker absent, clean tree, green. A first src-only dogfood ablation was a false green (dogfood reads dist) and is not counted.", "gates": "dispatch-gates --commands derived 94 families, each run with its exit code captured; --ran: 94 derived, 94 run, 0 NOT-MEASURED, 0 UNRUN. Three exit-3 prerequisites on the first pass (plugin-teardown-shape --self-test: shallow clone; check:skill-examples and check:dual-build-cjs-loads: missing dist) cleared by git fetch --unshallow plus a build of those packages, rerun exit 0. pnpm lint exit 0. CI check-runs on the PR: pending at report time; the seat thread gets them when green.", "dogfood_battery": "f7b7814e · os-verify-lock: VERDICT command-exit 0 · held the lock 1466s · Test Files 422 passed | 3 skipped (425) · Tests 3547 passed | 17 skipped (3564) · no failures", "mcp_calls": "2 — mcp__github__issue_read (card read), mcp__github__pull_request_read (PR read-back); no MCP write tool", "api_writes": "2 — fleet-write relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, draft, no assignees, no labels) and this os-dev-report comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/30674/comments); plus git push of the branch (not a REST write)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: skills close-out card (Tier H) · skills/objectstack-data/rules/field-types.md L174 'Backfill: os migrate record-currency-codes' names neither --org nor --all-organizations; declared in the PR as Skills-docs: follow-up owed · noted, not filed", "carrier: the B card (REST door) · RecordCurrencyBackfillOrganization and RecordCurrencyBackfillOrganizationsRefusal are not re-exported from the @objectstack/objectql barrel (outside this file surface) · noted, not filed", "carrier: seat (landing) · the four branch commits are WIP commits without the Claude-Session / Co-authored-by trailer pair; the branch was already pushed and is not force-pushed, so the pair belongs in the squash message · noted, not filed" ] }objectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
席位核对 · Amendment · 2026-11-06T00:13Z · claim 6671428099
File surface adds
content/docs/data-modeling/currency.mdx(~L140, ~L362–365): it says the code backfill writes its one code into every organization's codeless rows, which PR #30737 makes false (os-dev: a published statement the diff falsifies is fixed in the same PR). Docs only, +8/−3. The skills line stays the follow-up card #30740;content/docs/releases/**stays untouched. Everything else in the claim and its amendments stands.docs(currency): the record-currency code backfill runs one organizati…