Repository navigation
fix(cli): os migrate value walks name the columns a disabled package's extension adds - #30696
Conversation
…s extension adds blank-single-values, blank-multi-values, option-codes, text-scalars and value-shapes scope by the served fold, which withholds a disabled package's objectExtensions fields (their columns are kept). Each report now names every in-scope column it skipped that way (object, field, package id), in the plan and in the --json document as withheldColumns, so the operator re-runs after enabling the package. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwPmVRHj9NxSn1E2Xz
📓 Docs Drift CheckThis PR changes 1 package(s): 14 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 5 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 35 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin f40cda2cf9e4e2154231cd63d4c2018e341f47b0 && git checkout f40cda2cf9e4e2154231cd63d4c2018e341f47b0
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 788715ef5cb205d3e70052d25a595e13a8aa9d7c b94187d76821d0ca670478789e543511a9e67857 && git checkout -B drift-repro 788715ef5cb205d3e70052d25a595e13a8aa9d7c && git merge --no-ff b94187d76821d0ca670478789e543511a9e67857
node scripts/docs-audit/affected-docs.mjs --json 788715ef5cb205d3e70052d25a595e13a8aa9d7c
|
|
domain:server#4 · os-elon-musk · session_016WV4czvZykUqhYxYXSSDt4 维护者速读
席位意见:ACCEPT(#30626)。运维看报告就知道「启用那个包后再跑一次」。 席位核对Head-sha:
|
Requested by Elon · project thread
Fixes #30626
Clause-②: no
Metadata-protocol: none
维护者速读
os migrate的五个值迁移命令(blank-single-values、blank-multi-values、option-codes、text-scalars、value-shapes)在报告里逐条列出因所属模块包被停用而没读到的列(对象.字段 + 包 id),--json里同名withheldColumns。packages/cli/src/utils/migrate-withheld-columns.ts(判定:存储折叠减对外折叠,按停用扩展包归属);blank-single-values.ts的walkBlankColumns返回处;value-shapes.ts(无列规则,列出全部被隐去字段)。pnpm --filter @objectstack/cli exec vitest run src/commands/migrate/withheld-extension-columns.integration.test.ts,预期 9 个用例全绿。What changes
packages/cli/src/utils/migrate-withheld-columns.ts:withheldColumns(engine, objects, select?)reads, per walked object, the extend contributors whose packageisPackageDisabled, takes the walk's own column rule overregistry.getStorageObject(object)minus the same rule over the servedengine.getObject(object), and attributes each remaining column to the disabled package whose extension declares it.formatWithheldColumnsrenders the list (nothing when empty). It lives inutils/because every.tsundersrc/commands/**is an oclif command (pattern strategy); the seat amended the claim's file surface for it.blank-single-valuesandblank-multi-values(they sharewalkBlankColumns, so one change covers both),option-codes,text-scalars: the report gainswithheldColumns, the human plan prints it, the command's engine view passesregistry.value-shapes: the scan is objectql's (scanValueShapes) and its column rule (isScannableValueShapeField) is not exported, so the command names every withheld field of the scanned objects (noselect), in the plan and in the--jsondocument. Nopackages/objectql/**change.Behaviour picked: name the skipped columns, not warn-or-refuse. Measured on
origin/main(the integration fixture below with the module disabled): each walk reportedcolumns: []over a row still holding a value it would rewrite, so the plan said "✓ No stored empty string found." (and the like) with no mention of the column. Refusing while a module that extends a target object is disabled would block the run for every other object and column it can cover, and the operator's remedy (enable, re-run) is the same either way; naming the columns keeps the run useful and makes the gap explicit. The withheld values cannot be rewritten in place while disabled (the card's out of scope:engine.findrefuses a withheld field withINVALID_FIELD).Changed lines: 9 files, +321 / −1 (code 5 command files +58/−1, helper +89, tests +164, changeset +10).
Tests
src/commands/migrate/withheld-extension-columns.integration.test.ts(integration tier:new ObjectQL(+ sqliteSqlDriver): an app package ownswx_account, a module package addswx_tier/wx_level(select),wx_tags(multiselect),wx_note(text) by extension; a row below the door holds a value for each walk to rewrite. Per walk: control (enabled: the column is read, nothing named) and the pin (disabled:report.columnsempty,withheldColumnsequals the walk's in-scope extension columns with the package id, the plan printswx_account.COLUMN (package com.qa.wx.loyalty)). One more case for the value-shapes path (no column rule: all four fields named).src/utils/migrate-withheld-columns.test.ts(unit): attribution, the column-rule narrowing, an engine without the registry surface, the empty format.Ablation (the four command files reverted to origin/main, helper and test kept; commit c2cdd7d)
grep -c withheldColumnson the four files = 0 each;Tests 8 failed | 1 passed (9)(every walk case red, e.g.expected undefined to deeply equal [ Array(2) ]; the value-shapes helper case stays green as it does not go through a walk). LockVERDICT command-exit 1.git checkout HEAD -- FILES,git diff HEADempty, each file's hash equals its HEAD blob.Tests 9 passed (9),VERDICT command-exit 0. The CLI tests importsrc/directly, so no dist rebuild sits between the legs.Acceptance notes
value-shapes --applystill records theadr-0104-value-shapesdeployment flag on a full-scope run while withheld columns went unscanned; this PR only names them. Whether such a run should record no flag (as a--object-narrowed run does) is a posture question for the seat; carrier: none.os migratecommands that readengine.getObject(files-to-references,comment-reactions,activity-changed-fields, theaudit-*commands,organization-ownership) target platform objects or a scan in objectql; not measured for this blind spot here. carrier: none.Verification
Local, on c2cdd7d (the implementation head; b94187d only merges 4
origin/maincommits, none touchingpackages/cli/src/commands/migrate/**orpackages/cli/src/utils/migrate-*):pnpm --filter @objectstack/cli typecheck(includescheck:test-typecheck):VERDICT command-exit 0.pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2:Test Files 390 passed (390),Tests 5435 passed (5435),VERDICT command-exit 0.blank-single-values,blank-multi-values,option-codes,text-scalarsintegration suites + the helper unit test): the four sibling integration suites and the helper unit test5 passed; the new pin, rerun after a fixture fix,Tests 9 passed (9). The rest of the integration layer is declared to CI.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 60 families, each run with its exit code captured before any pipe; 56 exit 0 first pass, 4 exit 3 (no dist:check:dual-build-cjs-loads,check:i18n,check:i18n-coverage,check:i18n-walk-parity) cleared by a whole-treeturbo run buildand then exit 0.--ran: "60 derived famil(ies) accounted for — 60 run, 0 NOT-MEASURED".🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4cwPmVRHj9NxSn1E2Xz