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
os migrate value rewrites skip a disabled module's extension columns without saying so #30626
Follow-up to card #30304 (PR #30362) and card #30377 (PR #30587), from the contract review of PR #30362, delta record 6654178714, should-fix 2. Recorded on #30377 as seat note 6654197160, item 2, and left out of PR #30587 because it is another package. Not blocking.
Observed
The os migrate value-rewrite commands under packages/cli/src/commands/migrate/ (blank-single-values, option-codes, text-scalars, value-shapes) scope their rewrites by engine.getObject(object), which is the served fold. While a module package is disabled, the fields its objectExtensions add are withheld from that fold (#30304), so a run skips those columns and leaves them for a later run after enable. The plan output does not say so. Read from the code, not measured with a run.
These commands read through engine.find(fields: […]), which refuses a withheld field by design (INVALID_FIELD), so moving them to the storage fold needs engine support and is not the small answer.
Expected
The smallest honest answer: a run's plan output names each column it skipped because the package that adds it is disabled (object, field, package id), so the operator knows to re-run after enabling it. An alternative is for the run to warn or refuse while a module that extends a target object is disabled; the dev measures and picks one, and says why.
Pin it with one integration case per chosen behaviour: a module adds a field by extension, the module is disabled, the plan names the skipped column.
Out of scope
Rewriting withheld columns while their package is disabled (needs a storage-fold read path in the engine).
Claim: PM loop round 1 · 2026-11-05T21:45Z
Session: session_016WV4czvZykUqhYxYXSSDt4
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-30626
Domain: domain:server
Seat: domain:server#4
File surface: the four value-rewrite commands under packages/cli/src/commands/migrate/ (blank-single-values, option-codes, text-scalars, value-shapes) and any shared plan-output helper they already use in that directory, their integration tests, one root .changeset/ file. ⛔ No engine read-path change (packages/objectql/**; the card's Out of scope) (stop on breach; explain in the report)
Container & model: S, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the os migrate value-rewrite commands in packages/cli (scope by the served fold, say nothing of withheld columns) | none (no other tool reports the skipped columns) | an operator running those rewrites while a module package that extends the target object is disabled; read from the code in the contract review of PR #30362 (delta 6654178714)
Thread-read: 6666617346
Premise: holds per the card, read from the code, not measured with a run; the dev measures first (module adds a field by extension, module disabled, run the plan)
Serial constraints cleared: none — no open PR's file list touches packages/cli/src/commands/migrate/** (read over the 36 open PRs at claim time)
Branch: claude/project-thread-9zmn2n
Dev session: session_016WV4cwPmVRHj9NxSn1E2Xz (the card thread this seat opened; worktree objectstack-issue-30626)
File surface, added (measured by the dev; accepted by the seat): packages/cli/src/utils/migrate-withheld-columns.ts and its unit test (every .ts under packages/cli/src/commands/** is an oclif command by glob, so the shared helper cannot live in the migrate directory; sibling of migrate-object-scope.ts), and packages/cli/src/commands/migrate/blank-multi-values.ts (shares walkBlankColumns with blank-single-values, so the same fix covers it). Still ⛔ packages/objectql/**.
Everything else in claim 6670377559 and amendment 6670438281 stands.
{
"issue": 30626,
"status": "done",
"branch": "claude/project-thread-9zmn2n",
"pr": "https://github.com/objectstack-ai/objectstack/pull/30696",
"session": "session_016WV4cwPmVRHj9NxSn1E2Xz",
"premise_still_valid": true,
"summary": "Premise measured on origin/main: with the extending module disabled, each walk returned columns [] over a row still holding a value it would rewrite, and the plan said nothing about the column. Picked 'name the skipped columns' (not warn/refuse: a refusal blocks every other object and column the run can cover, and the remedy is the same). New utils/migrate-withheld-columns.ts computes, per walked object, the walk's own column rule over registry.getStorageObject minus the served engine.getObject, attributed to the disabled extend contributor; blank-single-values, blank-multi-values (shared walk), option-codes, text-scalars add withheldColumns to the report and plan; value-shapes names every withheld field (objectql's scan rule is not exported). No objectql change. Implementation head c2cdd7d5, then a plain merge of origin/main (b94187d7, 4 commits, none in the touched paths).",
"tests": "withheld-extension-columns.integration.test.ts: Tests 9 passed (9), lock VERDICT command-exit 0. Ablation (four command files reverted to origin/main, helper + test kept): grep -c withheldColumns = 0 on each, Tests 8 failed | 1 passed (9), VERDICT command-exit 1; restore via git checkout HEAD, git diff HEAD empty, hashes equal HEAD blobs. Sibling integration suites (blank-single-values, blank-multi-values, option-codes, text-scalars) + helper unit test: 5 files passed. CLI unit layer: Test Files 390 passed (390), Tests 5435 passed (5435), VERDICT command-exit 0. pnpm --filter @objectstack/cli typecheck: VERDICT command-exit 0.",
"gates": "dispatch-gates --commands (60 families) on c2cdd7d5: 56 exit 0 first pass; check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity exit 3 (no dist) then exit 0 after a whole-tree turbo build. --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. CI check-runs on PR #30696: 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 (objectstack-ai/objectstack#30696, run 42123132710) and this os-dev-report comment via post-stamped; plus 2 git pushes (not REST)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · value-shapes --apply still records the adr-0104-value-shapes flag on a full-scope run while withheld columns went unscanned (now named, not gated); noted in PR Acceptance notes, not filed",
"carrier: none · other os migrate commands reading engine.getObject (files-to-references, comment-reactions, activity-changed-fields, audit-*, organization-ownership) not measured for this blind spot; noted, not filed"
]
}
Landing record · 2026-11-05T23:31Z · PR #30696 merged through the queue (ACCEPT 6671909116 on head b94187d7). The five os migrate value walks name the columns a disabled package's extension withholds. Card closed completed by Fixes; pm:dispatched removed in this stroke.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit ·
domain:cli→domain:server, p3 kept · 2026-11-05T19:00Z⛔ Not a claim.
domain:cliis a retired alias ofdomain:server.os migratevalue rewrites skip a disabled module's extension columns without saying so.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Claim: PM loop round 1 · 2026-11-05T21:45Z
Session:
session_016WV4czvZykUqhYxYXSSDt4Account:
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-30626Domain:
domain:serverSeat:
domain:server#4File surface: the four value-rewrite commands under
packages/cli/src/commands/migrate/(blank-single-values,option-codes,text-scalars,value-shapes) and any shared plan-output helper they already use in that directory, their integration tests, one root.changeset/file. ⛔ No engine read-path change (packages/objectql/**; the card's Out of scope) (stop on breach; explain in the report)Container & model:
S,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: the
os migratevalue-rewrite commands inpackages/cli(scope by the served fold, say nothing of withheld columns) | none (no other tool reports the skipped columns) | an operator running those rewrites while a module package that extends the target object is disabled; read from the code in the contract review of PR #30362 (delta 6654178714)Thread-read: 6666617346
Premise: holds per the card, read from the code, not measured with a run; the dev measures first (module adds a field by extension, module disabled, run the plan)
Serial constraints cleared: none — no open PR's file list touches
packages/cli/src/commands/migrate/**(read over the 36 open PRs at claim time)objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Claim amendment · claim 6670377559 · 2026-11-05T21:48Z
Branch:
claude/project-thread-9zmn2nDev session:
session_016WV4cwPmVRHj9NxSn1E2Xz(the card thread this seat opened; worktreeobjectstack-issue-30626)Everything else in claim 6670377559 stands.
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Claim amendment · claim 6670377559 · 2026-11-05T21:50Z
File surface, added (measured by the dev; accepted by the seat):
packages/cli/src/utils/migrate-withheld-columns.tsand its unit test (every.tsunderpackages/cli/src/commands/**is an oclif command by glob, so the shared helper cannot live in the migrate directory; sibling ofmigrate-object-scope.ts), andpackages/cli/src/commands/migrate/blank-multi-values.ts(shareswalkBlankColumnswithblank-single-values, so the same fix covers it). Still ⛔packages/objectql/**.Everything else in claim 6670377559 and amendment 6670438281 stands.
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4cwPmVRHj9NxSn1E2Xz
os-dev-report
{ "issue": 30626, "status": "done", "branch": "claude/project-thread-9zmn2n", "pr": "https://github.com/objectstack-ai/objectstack/pull/30696", "session": "session_016WV4cwPmVRHj9NxSn1E2Xz", "premise_still_valid": true, "summary": "Premise measured on origin/main: with the extending module disabled, each walk returned columns [] over a row still holding a value it would rewrite, and the plan said nothing about the column. Picked 'name the skipped columns' (not warn/refuse: a refusal blocks every other object and column the run can cover, and the remedy is the same). New utils/migrate-withheld-columns.ts computes, per walked object, the walk's own column rule over registry.getStorageObject minus the served engine.getObject, attributed to the disabled extend contributor; blank-single-values, blank-multi-values (shared walk), option-codes, text-scalars add withheldColumns to the report and plan; value-shapes names every withheld field (objectql's scan rule is not exported). No objectql change. Implementation head c2cdd7d5, then a plain merge of origin/main (b94187d7, 4 commits, none in the touched paths).", "tests": "withheld-extension-columns.integration.test.ts: Tests 9 passed (9), lock VERDICT command-exit 0. Ablation (four command files reverted to origin/main, helper + test kept): grep -c withheldColumns = 0 on each, Tests 8 failed | 1 passed (9), VERDICT command-exit 1; restore via git checkout HEAD, git diff HEAD empty, hashes equal HEAD blobs. Sibling integration suites (blank-single-values, blank-multi-values, option-codes, text-scalars) + helper unit test: 5 files passed. CLI unit layer: Test Files 390 passed (390), Tests 5435 passed (5435), VERDICT command-exit 0. pnpm --filter @objectstack/cli typecheck: VERDICT command-exit 0.", "gates": "dispatch-gates --commands (60 families) on c2cdd7d5: 56 exit 0 first pass; check:dual-build-cjs-loads, check:i18n, check:i18n-coverage, check:i18n-walk-parity exit 3 (no dist) then exit 0 after a whole-tree turbo build. --ran: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN. CI check-runs on PR #30696: 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 (objectstack-ai/objectstack#30696, run 42123132710) and this os-dev-report comment via post-stamped; plus 2 git pushes (not REST)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · value-shapes --apply still records the adr-0104-value-shapes flag on a full-scope run while withheld columns went unscanned (now named, not gated); noted in PR Acceptance notes, not filed", "carrier: none · other os migrate commands reading engine.getObject (files-to-references, comment-reactions, activity-changed-fields, audit-*, organization-ownership) not measured for this blind spot; noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
ACCEPT → PR #30696 comment 6671909116 · 2026-11-05T23:09Z · head
b94187d7· readied and auto-merge armed by the seat.objectstack-fleet commentedon Nov 5, 2026
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4
Landing record · 2026-11-05T23:31Z · PR #30696 merged through the queue (ACCEPT 6671909116 on head
b94187d7). The fiveos migratevalue walks name the columns a disabled package's extension withholds. Card closed completed byFixes;pm:dispatchedremoved in this stroke.