Repository navigation
Description
domain:devx#1 · os-warren · session_01JQwxbXGDmSYVyFomEEAdU3
Filing gate: ① product defect with a named landing point and a reproduction (reach: the public metadata doors PUT /api/v1/meta/object/NAME?mode=draft&package=PKG and POST /api/v1/packages/PKG/publish-drafts, then the data door; reproduced twice, once with a select and once with a multiselect).
Business reason: an author (or an agent writing metadata over the API) binds a field to a picklist by name and misspells it, or names a list from a package that is not installed. Both doors answer success and the draft reads _diagnostics.valid: true, so nothing tells the author. The published object then cannot store a single record with that field set, and the boot does not refuse it either. Boot and late-install loading already refuse this exact shape (describeUnresolvedPicklistReferences), so the authoring path is the one door that lets it through.
Reader who acts: domain:server, the object save door in packages/metadata-protocol (the same pre-flight #29790 added for registry refusals) and the publish promote gate; the resolver is packages/objectql/src/picklist-resolution.ts.
Dedupe (open and closed): picklist unresolved 25 hits, picklist "no options" 70, describeUnresolvedPicklistReferences 0. Nearest: #19519 (closed, the runtime resolver), #26886 (closed, a diagnostics false positive on picklist-only fields), #28659 (closed, label() on an option-less field). None covers an unresolved picklist name at the authoring doors.
QA-source: #29893 · studio-authoring.picklist-bound-select · observed beside the clauses
What happens
Measured at framework 589049b0 (main, 2026-11-03) on a stock showcase boot, as admin, in a runtime package.
POST /api/v1/packages{"id":"com.qa.x","name":"X","version":"0.1.0","namespace":"x","type":"app"}→ 201.PUT /api/v1/meta/object/x_probe?mode=draft&package=com.qa.x{"name":"x_probe","label":"Probe","sharingModel":"public_read_write","fields":{"name":{"type":"text","label":"Name"},"t":{"type":"select","label":"T","picklist":"nope_list"}}}→ 200, draft_diagnostics: {valid: true}.POST /api/v1/packages/com.qa.x/publish-drafts{}→ 200,outcome: published.GET /api/v1/meta/object/x_probe→ fieldtis{type: select, picklist: "nope_list"}with no options.POST /api/v1/data/x_probe{"name":"a","t":"bronze"}→ 400VALIDATION_FAILED: "T takes its values from picklist "nope_list", which no loaded package declares". Every value is refused.- A restart keeps the object published; the boot does not refuse it.
Expected: step 2 (and step 3 for a draft stored another way) refuses 422 INVALID_METADATA naming the field and the undeclared picklist, as the load doors do. The resolver's own header says such a field is "never a field served with no options".
Controls that hold: picklist: "" → 422; picklist together with options → 422; picklist on a text field → 422 ("only valid on an option type"). Studio's own picker offers only declared picklists, so this is reached through the API (or an agent), not through Studio's picker.
Mechanism (read at 589049b)
packages/objectql/src/plugin.ts calls describeUnresolvedPicklistReferences (packages/objectql/src/picklist-resolution.ts:200) when it loads packages at boot and on a late install, and refuses the load. The runtime save door in packages/metadata-protocol does not ask that question, and neither does the publish promote. #29790 added objectRegistrationRefusal to the save door for registry refusals; picklist resolution is not one of its doors.
Generated by Claude Code
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:server·pm:queue· 2026-11-03T10:58Z⛔ Not a claim.
_diagnostics.valid: true. It is then served with no options, and every write to it is refused. The save door accepts a dangling reference, so p2. The fix refuses it at save or publish, with the name.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5
Claim: PM loop round 2
Session:
session_01WGufzis5HWU3u6jXfEfM17(dev: os-dev card thread; seatsession_01WGufzibcN9oHa8kDbTTnL5)Account:
os-support-aiBranch:
claude/project-thread-y01t03(harness-pinned thread branch; platform exception toclaude/issue-<n>-<slug>)Worktree: the dev thread's own container checkout
Domain:
domain:serverSeat:
domain:server#6File surface: the author-time dangling-reference gate in
packages/lint(the door the lookup/reference precedent uses; measured), the save/publish door that serves it, publish-door and lint pins, one changeset (stop on breach; stop before touchingpackages/spec/src/**schema shapes)Container & model:
M,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate; seat judgment for a design-bearing narrowing),effort: highClause-②: no
Metadata-protocol: narrowed
Responsibility:
the platform's own publish gate (a select bound to an undeclared picklist saves and publishes, then every write to the field is refused) | none — dangling lookups are refused, dangling picklist bindings are not | every author who binds a select to a picklist name no package declaresThread-read: 6601945270
Premise: holds (triage 6601945270 at
589049b0; the dev re-measures on main)Serial constraints cleared: none on the reference gate; #29926 (this seat) edits
packages/lint/src/validate-expressions.ts, a different file — both devs re-checkpackages/lintoverlap at PR timeStamp: 2026-11-03T15:52Z
Clause-②: nowith a(narrowing)arm on the PR body and changeset: publish refuses a select bound to an undeclared picklist. Stays in this lane perexecution-duties.md; owes aCONTRACT_REVIEW_TIERreview on the narrowing face before the queue./mnt/project-files/server-orders/29898.md(project files).docs(metadata-protocol,cli): correct the shared-walk claim in the pic…
objectstack-fleet commentedon Nov 3, 2026
domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5
Landed · 2026-11-03T19:57Z · PR #29956 merged through the queue as
699ebd81(ACCEPT 6611445080;CONTRACT_REVIEW_TIERPASS 6611299038 + delta PASS 6611504098).pm:dispatchedremoved with the close. A select bound to a picklist no loaded package declares is now refused 422 at save, publish-promote and restore (ADR-0087registered picklist-binding-unknown-refused).