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 + docs: judge --code before boot in os migrate record-currency-codes, and document the command and the record-mode switch (multi-currency, epic #8345) #28168
Filed by the epic PM from the contract review of PR #28128 (#27577), should-fix S2 and S3. Part of #8345. ⛔ Not a claim. Not release-paired; ⛔ needs #28128 on main first.
两分钟验证:os migrate record-currency-codes --object x --field y --code usd 在不 boot 的情况下立即以 INVALID_FIELD 退出。
需要您做的: 无。
Task
S2. In packages/cli/src/commands/migrate/record-currency-codes.ts, judge --code against isValueDomainMember('iso_4217_currency', code) before the --apply confirmation prompt and before bootSchemaStack. Use the same INVALID_FIELD / 400 envelope and wording the engine function returns, and keep the engine-side check unchanged. Add a test showing the boot is never reached for a non-member code.
S3. In content/docs/deployment/cli.mdx, add a table row and a section for os migrate record-currency-codes, shaped like summary-nulls. In content/docs/data-modeling/currency.mdx, add a short passage on switching a field with stored rows to currencyMode: 'record': the 409 destructive_change (finding currency_mode_to_record, lifted by force), then the dry run and --apply. Say that the code is the operator's and is never derived.
Acceptance
A non-member --code exits before any prompt or boot, with the same envelope as today.
Both docs pages name the command, and currency.mdx names the 409 and the dry-run/--apply steps.
dispatch-gates --commands exit codes captured.
Lane: server (cli + docs) · Size: S · Review: default. Declarations, for the card to confirm: Clause-②: no · Metadata-protocol: none; @objectstack/cli patch changeset.
⛔ Out of scope: skills/** and docs/adr/**. The epic PM's Tier H PR carries those.
Epic: #8345. Dedupe: PR #28128 review record (S2, S3); no open card carries this.
Claim: PM loop round 1
Session: session_01QUs3BtyH9zgxKzYrJiH18J
Account: os-zhuang
Branch: claude/project-thread-et4dvl (the card thread's platform-assigned push branch, the measured platform exception to the protocol branch shape)
Worktree: objectstack-issue-28168
Domain: domain:server
Seat: domain:server#4
File surface: packages/cli/src/commands/migrate/record-currency-codes.ts and its test, content/docs/deployment/cli.mdx, content/docs/data-modeling/currency.mdx, a new .changeset/28168-*.md (stop on breach; explain in the report). ⛔ Not skills/** or docs/adr/**.
Container & model: S, mode:thread, model: default judgment tier (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the CLI's own migrate command and its docs entries | none: no other path judges --code before boot | operators running os migrate record-currency-codes
Thread-read: none
Premise: holds; the prerequisite PR #28128 is merged, and the command still boots before judging --code (bootSchemaStack at record-currency-codes.ts:165 on origin/main)
Scope: the card's S2 and S3 as written. If either docs page is release-owned under AGENTS.md's Documentation Guardrails, the dev stops and reports instead of editing it.
Serial constraints cleared: no in-flight claim names these files; none
Taken at 2026-10-31T11:34Z: p3, filed by the epic PM for the server lane (Part of #8345); the lane's next unclaimed card by the full order whose triage note does not hold it back from dispatch on its own.
{
"issue": 28168,
"status": "done",
"branch": "claude/project-thread-et4dvl",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28416",
"session": "session_01QUs3BvyNBMezKJUd7aydyG",
"premise_still_valid": true,
"summary": "S2: os migrate record-currency-codes judges --code with isValueDomainMember('iso_4217_currency', code) first in run(), before the occupancy probe, the --apply prompt and bootSchemaStack, throwing the engine's INVALID_FIELD / 400 envelope (code, status, httpStatus) with the engine's prefix and sentences; the one wording difference is that the code field's name is not known before boot, so the message names OBJECT.FIELD's code field. objectql's backfill check is unchanged. S3: cli.mdx gains a data-migrations table row and an os migrate record-currency-codes section shaped like summary-nulls; currency.mdx gains 'Switching a field that already holds rows' (409 destructive_change, finding currency_mode_to_record, lifted by force; dry run; --apply; the code is the operator's, never derived). Both pages are hand-written trees, not release-owned. Changeset 28168-record-currency-code-before-boot.md, @objectstack/cli patch. File surface held to the claim's five paths.",
"tests": "head 738019ef. pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/migrate/record-currency-codes.test.ts: Test Files 1 passed, Tests 12 passed (lock VERDICT command-exit 0); new cases: --json --apply with usd exits 1 with code INVALID_FIELD httpStatus 400 equal to the real engine refusal's and its leading clause, boot/probe/backfill never called; human face --apply on a TTY with EURO prints the refusal, opens no readline prompt, never boots or probes; control USD boots. The existing envelope case now feeds the engine's field refusal. --project unit test/migrate-confirmation-exit.pin.test.ts: Tests 38 passed. pnpm --filter @objectstack/cli typecheck: exit 0. Ablation via scripts/ablation-replace.mjs (call replaced by marker, anchor 1 to 0, blob 6bf55f78 to 9501b58a): Tests 2 failed | 10 passed, the two new refusal cases red; restored, blob equals HEAD 6bf55f78, git diff HEAD empty. Test imports src, no build in the path. Rest of unit + integration layers declared to CI.",
"gates": "local: dispatch-gates --commands --repo objectstack-ai/objectstack derived 93; all 93 run, each recorded as COMMAND :: exit N; 88 exit 0 first pass, 5 (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity) exit 3 PREREQUISITE NOT MET until a full pnpm build (lock VERDICT command-exit 0, Tasks 116/116), then exit 0. dispatch-gates --ran: 93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint: exit 0. CI check-runs on PR 28416: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "4 — mcp__github__issue_read x4 (get 28168, get_comments 28168 x3); no write tool",
"api_writes": "2 — relay pr_create POST /repos/objectstack-ai/objectstack/pulls (draft, no labels, no assignees; read-back 8041 bytes identical); relay comment POST /repos/objectstack-ai/objectstack/issues/28168/comments (this report). git push is not counted.",
"open_questions": [],
"out_of_scope_findings": []
}
Activity
objectstack-fleet commentedon Oct 31, 2026
domain:server#4 · os-zhuang · session_01QUs3BtyH9zgxKzYrJiH18J
Claim: PM loop round 1
Session:
session_01QUs3BtyH9zgxKzYrJiH18JAccount:
os-zhuangBranch:
claude/project-thread-et4dvl(the card thread's platform-assigned push branch, the measured platform exception to the protocol branch shape)Worktree:
objectstack-issue-28168Domain:
domain:serverSeat:
domain:server#4File surface:
packages/cli/src/commands/migrate/record-currency-codes.tsand its test,content/docs/deployment/cli.mdx,content/docs/data-modeling/currency.mdx, a new.changeset/28168-*.md(stop on breach; explain in the report). ⛔ Notskills/**ordocs/adr/**.Container & model:
S,mode:thread,model: default judgment tier (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
the CLI's own migrate command and its docs entries | none: no other path judges --code before boot | operators running os migrate record-currency-codesThread-read: none
Premise: holds; the prerequisite PR #28128 is merged, and the command still boots before judging
--code(bootSchemaStackatrecord-currency-codes.ts:165onorigin/main)Scope: the card's S2 and S3 as written. If either docs page is release-owned under AGENTS.md's Documentation Guardrails, the dev stops and reports instead of editing it.
Serial constraints cleared: no in-flight claim names these files; none
Taken at 2026-10-31T11:34Z: p3, filed by the epic PM for the server lane (Part of #8345); the lane's next unclaimed card by the full order whose triage note does not hold it back from dispatch on its own.
objectstack-fleet commentedon Oct 31, 2026
domain:server#4 · os-zhuang · session_01QUs3BvyNBMezKJUd7aydyG
os-dev-report
{ "issue": 28168, "status": "done", "branch": "claude/project-thread-et4dvl", "pr": "https://github.com/objectstack-ai/objectstack/pull/28416", "session": "session_01QUs3BvyNBMezKJUd7aydyG", "premise_still_valid": true, "summary": "S2: os migrate record-currency-codes judges --code with isValueDomainMember('iso_4217_currency', code) first in run(), before the occupancy probe, the --apply prompt and bootSchemaStack, throwing the engine's INVALID_FIELD / 400 envelope (code, status, httpStatus) with the engine's prefix and sentences; the one wording difference is that the code field's name is not known before boot, so the message names OBJECT.FIELD's code field. objectql's backfill check is unchanged. S3: cli.mdx gains a data-migrations table row and an os migrate record-currency-codes section shaped like summary-nulls; currency.mdx gains 'Switching a field that already holds rows' (409 destructive_change, finding currency_mode_to_record, lifted by force; dry run; --apply; the code is the operator's, never derived). Both pages are hand-written trees, not release-owned. Changeset 28168-record-currency-code-before-boot.md, @objectstack/cli patch. File surface held to the claim's five paths.", "tests": "head 738019ef. pnpm --filter @objectstack/cli exec vitest run --project integration --maxWorkers=2 src/commands/migrate/record-currency-codes.test.ts: Test Files 1 passed, Tests 12 passed (lock VERDICT command-exit 0); new cases: --json --apply with usd exits 1 with code INVALID_FIELD httpStatus 400 equal to the real engine refusal's and its leading clause, boot/probe/backfill never called; human face --apply on a TTY with EURO prints the refusal, opens no readline prompt, never boots or probes; control USD boots. The existing envelope case now feeds the engine's field refusal. --project unit test/migrate-confirmation-exit.pin.test.ts: Tests 38 passed. pnpm --filter @objectstack/cli typecheck: exit 0. Ablation via scripts/ablation-replace.mjs (call replaced by marker, anchor 1 to 0, blob 6bf55f78 to 9501b58a): Tests 2 failed | 10 passed, the two new refusal cases red; restored, blob equals HEAD 6bf55f78, git diff HEAD empty. Test imports src, no build in the path. Rest of unit + integration layers declared to CI.", "gates": "local: dispatch-gates --commands --repo objectstack-ai/objectstack derived 93; all 93 run, each recorded as COMMAND :: exit N; 88 exit 0 first pass, 5 (spec check:skill-examples, check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity) exit 3 PREREQUISITE NOT MET until a full pnpm build (lock VERDICT command-exit 0, Tasks 116/116), then exit 0. dispatch-gates --ran: 93 derived, 93 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint: exit 0. CI check-runs on PR 28416: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "4 — mcp__github__issue_read x4 (get 28168, get_comments 28168 x3); no write tool", "api_writes": "2 — relay pr_create POST /repos/objectstack-ai/objectstack/pulls (draft, no labels, no assignees; read-back 8041 bytes identical); relay comment POST /repos/objectstack-ai/objectstack/issues/28168/comments (this report). git push is not counted.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:server#4 · os-zhuang · session_01QUs3BtyH9zgxKzYrJiH18J
Landed · #28168 · 2026-10-31T23:20Z
2bba35a3965b0e53aae5ba3dd7899213e7c19087, ACCEPT 6550340734 at head2a029310ccompletedby the PR'sFixes2026-10-31T23:20:03ZState change:
pm:dispatchedremoved. S2 and S3 are both on main.skills/**anddocs/adr/**stay with the epic PM's Tier H PR, as the card says.