fix(spec): align config-schema.json object ownership with the record-ownership vocabulary - #7436
Conversation
…d-ownership vocabulary `packages/spec/config-schema.json` declared the object-level `ownership` property as `enum ["own", "shared"]`. That matched neither vocabulary in the package: the record-ownership model is `user | business_unit | org | none` (`packages/spec/src/data/object.zod.ts`, post-#7260), and the package *contribution* kind is own/extend/overlay and lives on the registry's contributor record, not on the object schema. `["own","shared"]` was a stale third spelling with no acceptance face behind it. This artifact is hand-written authoring guidance served to config authors as IDE autocomplete/validation, so the entry actively steered an author toward `ownership: "shared"` — a value no schema in the package accepts (#3244 confusion class: same key name, different vocabularies, adjacent surfaces). Aligns the enum to the acceptance face and adopts its `.describe()` text, whose closing sentence carries the own/extend disambiguation that caused the drift. The acceptance face itself is untouched — `object.zod.ts` is byte-identical to `origin/main`. Fixes #7286
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
⛔ 7 release-owned page(s) also reference the affected code. These are read-only:
|
Fixes #7286
The defect
packages/spec/config-schema.json:67-69declared the object-levelownershipproperty asenum ["own", "shared"]. That matched neither vocabulary in the package:user/business_unit/org/nonepackages/spec/src/data/object.zod.ts:1402(post-#7260)own/extend/overlayregisterObjectown/sharedsharedappears in no acceptance face anywhere in the package. Since this artifact is hand-written authoring guidance served to config authors as IDE autocomplete/validation, the entry actively steered an author towardownership: "shared"— a value no schema accepts. This is the #3244 confusion class exactly: same key name, different vocabularies, adjacent surfaces.The fix
Aligns the enum to the acceptance face and adopts that face's own
.describe()text, whose closing sentence carries the own/extend disambiguation that caused the drift in the first place:The acceptance face is untouched.
packages/spec/src/data/object.zod.tsis byte-identical toorigin/main(git diff --quiet origin/main -- packages/spec/src/data/object.zod.tspasses). The whole diff is 2 lines in one hand-written JSON artifact.Measurements behind the route
The dispatch carried a two-branch decision rule; branch A was selected by measurement — the zod acceptance face does declare an object-level
ownership, so the artifact entry is aligned rather than removed:Mechanical set-difference before and after (scan script over the artifact's parsed JSON vs. the zod enum literal):
Three mechanism hypotheses were checked before editing; all three hold:
config-schema.jsonare prose in a code comment,CHANGELOG.mdand a changeset. Note the CLI does have a correct generated route (objectstack generate schemabuilds the config JSON Schema live fromObjectStackDefinitionSchemaviaz.toJSONSchema), but it writesobjectstack.schema.jsonin the user's cwd, not this file.user/business_unit/org/none— verified atorigin/main.check:generateddoes not cover it. Filed as an out-of-scope finding rather than built here (S-card scope).Verification
node -e "JSON.parse(...)"— parses as valid JSON.pnpm --filter @objectstack/spec typecheck— green (tsc, scripts-typecheck, test-typecheck all pass).pnpm --filter @objectstack/spec test— 366 files / 9557 tests passed.node scripts/check-nul-bytes.mjs— OK, 6803 files scanned; targeted control-byte self-scan of the edited file clean.No changeset — measured, not assumed
config-schema.jsonis not published.npm pack --dry-run --ignore-scriptson@objectstack/specpacks 269 entries and zero matchconfig-schema; the only root-level JSON entries shipped arepackage.jsonandspec-changes.json. It is absent from the package'sfileslist. Nothing user-visible ships, so this carries theskip-changesetlabel instead of a changeset.Out-of-scope findings (reported, deliberately NOT fixed here)
A sweep of every enum in the artifact found two siblings of the same class. Neither is the identical defect with an identical mechanical fix, so both are left for separate triage rather than widened into this diff:
objects[].fields.*.typeoffers 6 phantom field types —integer,slug,uuid,ip_address,geo_point,encryptedare in the artifact but not inFieldType(packages/spec/src/data/field.zod.ts:17); and 21 real types are hidden, includingsecret,toggle,radio,checkboxes,tree,user,composite,repeater,record,location,address,code,tags. Aligning it is a 34-value list becoming a 49-value list, and whether the artifact deliberately offers a curated subset is a judgement call — not mechanical.data[].modehidesupdate— artifact has["upsert","insert","ignore","replace"],SeedMode(packages/spec/src/data/seed.zod.ts:12) has 5 includingupdate. Different shape from this card's defect: it hides a valid value rather than offering an invalid one, so no author is steered wrong.Also noted: the artifact's own top-level
descriptionclaims it is "Generated from ObjectStackDefinitionSchema", which is false — that false provenance claim is plausibly why nobody re-derived it as the vocabularies moved.Generated by Claude Code