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
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
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
维护者速读
改了什么: 写入时 record 模式金额的币种码为空 ⇒ 拒写;sum/avg/min/max 跨 record 字段未按币种分组 ⇒ 拒收;summary 汇总 record 子字段 ⇒ 注册时拒收。
两分钟验证: 测量轮的 fx_invoice 探针变成固定测试:混币 sum 被拒,分组 sum 通过。
需要您做的: 无。
Task
Validator: ERR_CURRENCY_CODE_REQUIRED with the field named.
Aggregate door: refuse unless grouped by the code field; message carries the prescription (group, or use the home field).
Summary registration: refuse a roll-up over a record-mode child field.
Fixtures from 6041378776 (PROBE-A / PROBE-R) as tests on memory and SQLite.
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.
{
"issue": 27186,
"status": "done",
"branch": "claude/project-thread-1v9hrc",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27339",
"session": "session_01Utp6CboxRwQPbQZnhxyuzt",
"premise_still_valid": true,
"summary": "Three ADR-0144 guards in objectql: (1) validation/record-currency-code.ts refuses a row image holding a record-mode amount beside a blank code field with ERR_CURRENCY_CODE_REQUIRED / 400 (field = code field, amountField), judged on insert, by-id update (prior row + payload) and predicate update (matched rows + payload, read only when the payload touches the pair); the code is registered under @objectstack/objectql in the ADR-0112 ledger and the reference pages regenerated. (2) record-currency-aggregate-door.ts, after the aggregate x field-type door: sum/avg/min/max over a record-mode amount answers INVALID_FIELD / 400 unless groupBy names the code field, prescription first. (3) SchemaRegistry.registerObject refuses a summary roll-up (sum/avg/min/max) over a record-mode child field with INVALID_METADATA / 422 (RecordCurrencySummaryRefusedError), judged at whichever registration completes the pair. Declared rider (the #27184 dev's class-c finding): formula-return.ts currencyOf/inferFormulaReturn carry currencyMode 'record' + currencyField. Base: branch claude/project-thread-0wmk7j (#27268) at 5232c8b1; PR base main, Merge-after #27268, R1 pairing line in the body. File-surface addition approved by the epic PM at 14:03Z: packages/qa/dogfood/test/record-currency-probes.test.ts. Card assignee was set by the PM; not written here.",
"tests": "Head 4201bb53. objectql src/record-currency-guards.test.ts: Tests 12 passed (12). dogfood test/record-currency-probes.test.ts on SqlDriver better-sqlite3 + SqliteWasmDriver: Tests 6 passed (6). Full objectql local project at a1954847: Test Files 478 passed (478), Tests 8911 passed (8911); full formula at a1954847: 58/58 files, 1534/1534 tests (later commits touch only the two new test files and generated reference pages). objectql typecheck incl. check:test-typecheck OK at 901cbb01; formula typecheck OK at a1954847; dogfood typecheck NOT MEASURED (unbuilt closure, no error line names the new file). Ablation via ablation-replace.mjs --delete on the committed tree, src-imported suite, restore blob == HEAD each leg: aggregate-door call 2 failed/12, insert code check 1 failed/12, registry summary throw 2 failed/12; by-id and predicate update call sites not ablated separately. No driver-memory arm: closed census (check:driver-memory-census); the rows-shaped in-memory aggregation face is covered in the objectql suite.",
"gates": "dispatch-gates --commands (derived at a1954847, 120 families; includes #27268's paths; warned the base tree is behind origin/main). All 120 run; --ran reconciliation on 4201bb53: 116 run, 4 NOT-MEASURED, 0 UNRUN. Fixed in-PR after the first sweep: spec check:docs + check:generated (reference pages lacked the new code; regenerated via check:generated --fix, re-run exit 0), check:objectql-double-limit + check:query-options-erasure (new test double / option casts; re-run exit 0), check:dts-closure (red once mid spec rebuild; re-run exit 0). NOT MEASURED exit 3: check-plugin-teardown-shape --self-test (shallow), spec check:skill-examples (client-react unbuilt), check:dual-build-cjs-loads, check:i18n. Re-run on new head: check:error-code-casing, check:dispatcher-error-vocabulary, spec check:error-code-provenance, check:nul-bytes, check:engine-double-contract all exit 0. CI check-runs: in_progress at report time (not awaited).",
"dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read (get x1, get_comments x3); no MCP write tool",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/27339/assignees), relay comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27186/comments); plus git pushes",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — ADR-0144 has no rule for a row stored with a record-mode amount and no code before this guard (only reachable outside a released build, since record mode ships in the same R1 release); such a row is refused only when a write touches the amount or its code. In the PR's Acceptance notes."
]
}
Activity
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 1 · 2026-10-28T13:58Z
Session:
session_01Utp6CbTZrFqRYNgjSaSbN5(epic PM,epic:#8345)Account:
os-billBranch:
claude/project-thread-1v9hrc(card threadsession_01Utp6CboxRwQPbQZnhxyuzt; the platform assigns the thread's one push branch — the recorded platform exception)Worktree:
objectstack-issue-27186Domain:
domain:serverSeat:
epic:#8345File surface:
packages/objectql/src(validator, aggregate door, summary registration, tests), riderpackages/formula/src/formula-return.ts, the ADR-0112 extension ledger,.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: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Premise: holds
Serial constraints cleared: no — builds on #27184's draft PR #27268 (branch
claude/project-thread-0wmk7j) by maintainer-authorised acceleration;pm:blocked→pm:dispatchedin this stroke,Blocked-by:lines stay as merge order; the PR stays draft and merges after #27268.Release pairing: R1 — ⛔ not released alone, pairs with #27184, #27187, #27188.
Maintainer authority: Bill, project thread, 2026-10-28 「epic的卡你统一派」, 「并发可以5」, 「你自主完成后续阶段」, 「后续开发如何加速」 (audit 6467659191 on #8345).
objectstack-fleet commentedon Oct 28, 2026
epic:#8345#1 · os-bill · session_01Utp6CboxRwQPbQZnhxyuzt
os-dev-report
{ "issue": 27186, "status": "done", "branch": "claude/project-thread-1v9hrc", "pr": "https://github.com/objectstack-ai/objectstack/pull/27339", "session": "session_01Utp6CboxRwQPbQZnhxyuzt", "premise_still_valid": true, "summary": "Three ADR-0144 guards in objectql: (1) validation/record-currency-code.ts refuses a row image holding a record-mode amount beside a blank code field with ERR_CURRENCY_CODE_REQUIRED / 400 (field = code field, amountField), judged on insert, by-id update (prior row + payload) and predicate update (matched rows + payload, read only when the payload touches the pair); the code is registered under @objectstack/objectql in the ADR-0112 ledger and the reference pages regenerated. (2) record-currency-aggregate-door.ts, after the aggregate x field-type door: sum/avg/min/max over a record-mode amount answers INVALID_FIELD / 400 unless groupBy names the code field, prescription first. (3) SchemaRegistry.registerObject refuses a summary roll-up (sum/avg/min/max) over a record-mode child field with INVALID_METADATA / 422 (RecordCurrencySummaryRefusedError), judged at whichever registration completes the pair. Declared rider (the #27184 dev's class-c finding): formula-return.ts currencyOf/inferFormulaReturn carry currencyMode 'record' + currencyField. Base: branch claude/project-thread-0wmk7j (#27268) at 5232c8b1; PR base main, Merge-after #27268, R1 pairing line in the body. File-surface addition approved by the epic PM at 14:03Z: packages/qa/dogfood/test/record-currency-probes.test.ts. Card assignee was set by the PM; not written here.", "tests": "Head 4201bb53. objectql src/record-currency-guards.test.ts: Tests 12 passed (12). dogfood test/record-currency-probes.test.ts on SqlDriver better-sqlite3 + SqliteWasmDriver: Tests 6 passed (6). Full objectql local project at a1954847: Test Files 478 passed (478), Tests 8911 passed (8911); full formula at a1954847: 58/58 files, 1534/1534 tests (later commits touch only the two new test files and generated reference pages). objectql typecheck incl. check:test-typecheck OK at 901cbb01; formula typecheck OK at a1954847; dogfood typecheck NOT MEASURED (unbuilt closure, no error line names the new file). Ablation via ablation-replace.mjs --delete on the committed tree, src-imported suite, restore blob == HEAD each leg: aggregate-door call 2 failed/12, insert code check 1 failed/12, registry summary throw 2 failed/12; by-id and predicate update call sites not ablated separately. No driver-memory arm: closed census (check:driver-memory-census); the rows-shaped in-memory aggregation face is covered in the objectql suite.", "gates": "dispatch-gates --commands (derived at a1954847, 120 families; includes #27268's paths; warned the base tree is behind origin/main). All 120 run; --ran reconciliation on 4201bb53: 116 run, 4 NOT-MEASURED, 0 UNRUN. Fixed in-PR after the first sweep: spec check:docs + check:generated (reference pages lacked the new code; regenerated via check:generated --fix, re-run exit 0), check:objectql-double-limit + check:query-options-erasure (new test double / option casts; re-run exit 0), check:dts-closure (red once mid spec rebuild; re-run exit 0). NOT MEASURED exit 3: check-plugin-teardown-shape --self-test (shallow), spec check:skill-examples (client-react unbuilt), check:dual-build-cjs-loads, check:i18n. Re-run on new head: check:error-code-casing, check:dispatcher-error-vocabulary, spec check:error-code-provenance, check:nul-bytes, check:engine-double-contract all exit 0. CI check-runs: in_progress at report time (not awaited).", "dogfood_battery": "n/a — no ! in the PR title and Clause-②: no without a (narrowing) arm", "mcp_calls": "4 — mcp__github__issue_read (get x1, get_comments x3); no MCP write tool", "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST /issues/27339/assignees), relay comment via post-stamped (POST /repos/objectstack-ai/objectstack/issues/27186/comments); plus git pushes", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — ADR-0144 has no rule for a row stored with a record-mode amount and no code before this guard (only reachable outside a released build, since record mode ships in the same R1 release); such a row is refused only when a write touches the amount or its code. In the PR's Acceptance notes." ] }