Repository navigation
spec: a shared picklist (global value set) metadata kind — option lists reused across objects and packages are TypeScript constants today #18164
Description
Epic: session_016tKoy8NJa35Yih1FdzrVmn (director seat, summon #32), taken over on the maintainer's order 「你负责接手,并派发处理所有所有相关的」 · 2026-10-03T09:43Z · checklist 5967887779
Epic territory: objectstack-ai/hotcrm#2000 (hotcrm src/**: _picklists.ts, new *.picklist.ts, the select fields and consumers that import the lists, locale bundles); objectstack-ai/objectui#10202 when it unlocks (Studio picklist page, object designer field editor)
Ruled: 5904864936 · letter Q1 A · Q2 A — #19518 (the spec layer) is dispatchable now; the kind is named picklist (*.picklist.ts, Field.select({ picklist }), picklists.<name>, picklistExtensions); #19519 and objectui#10202 keep their Blocked-by order · 2026-09-30T05:42Z
Path: 本地跑起来、看到 — records-forms (清单项待写, authored with #19518) | P2
Parent of a cross-layer feature point (ruling batch #209 item 1 · A · maintainer 「18164 同意」): sub-issues in Blocked-by: order — #19518 (spec) → #19519 (runtime) → objectui#10202 (Studio). This card is a coordination node and is never dispatched itself; the road order (behind the open product P0/P1 items) decides when #19518 is taken.
Gap
There is no metadata kind for an option list that several objects share. Checked on @objectstack/spec 17.4.0's dist/index.d.ts and dist/data/index.d.ts: no globalPicklist, valueSet, picklists or equivalent key. An app that wants industry, lead_source, salutation, opportunity_stage or territory to mean the same thing on several objects keeps them as exported TypeScript arrays and spreads them into each Field.select({ options: [...] }).
Evidence (hotcrm, origin/main c716a2c)
src/objects/_picklists.ts— ~3,001 authored tokens; imported by 17 files: seven objects (account,contact,lead,opportunity,task,event,event_attendee, pluscontractandquote), two views, a flow, an action, a dashboard, an import mapping and a locale bundle.- Under the ADR-0130 package split (Epic: split HotCRM into ADR-0130 packages — sales is the app, service / revenue / marketing are modules, a directory is a package hotcrm#1904) those consumers sit in three packages (sales, revenue, and the app's own dashboards and translations), so the file becomes cross-package source that every module must import from the app package — the shape a metadata kind would replace with a reference by name.
- The same lists are what a customer overlay most often wants to extend (a customer-specific industry or lead-source value), and today that is a source edit in the app, not an overlay (ADR-0005 has nothing to overlay).
Ask
A picklists (or valueSets) stack collection: { name, label, options: SelectOption[] }, owned by a package like any other metadata, referenced from a select field by name (Field.select({ picklist: 'crm_industry' })), translatable through the locale packs the way field options are, and extensible by an org overlay (ADR-0005) so a customer can add a value without forking the object. Salesforce Global Value Sets and Dataverse global option sets are the reference shape.
Dedupe words: global picklist, value set, shared select options, _picklists.ts, picklist metadata kind.
Generated by Claude Code
Activity
objectstack-fleet commentedon Sep 30, 2026
Ruling: batch #251 item 3 · letter Q1 A · Q2 A · maintainer 「同意」 2026-09-30T05:39Z
Director seat (objectstack#12708, summon #30 续 2,
session_01AsCNgFBs8HCjwhyHQsFbx3). Provenance: maintainer, live PM chat with the director seat, 2026-09-30, replying 「同意」 to batch #251 as presented (this card as item 3, with #20281 and #18386); 「同意」 is to the director's recommendation in chat, which adopted the seat's decision request5903510250(Q1 A, Q2 A) after this seat's own reading: open P0 2 / P1 19 at 04:3xZ and none takeable in thedomain:speclane; #19518pm:queue, p2, unclaimed; "picklist" incontent/docs9 hits and in the reference app's_picklists.ts,valueSet0 hits inpackages/spec/src; the design of record5715762696item 1 already spellspicklistwith the name left to confirm; ruling5755653853(batch #209 item 1, A).Ruled: Q1 A. #19518 (the spec layer) is dispatchable now: the maintainer's 2026-09-23 release of the P0/P1-first rule in the
domain:speclane covers the sequencing sentence of ruling5755653853for this layer. #19519 (runtime) and objectui#10202 (Studio) keep theirBlocked-by:order and are released as that ruling states, not by this one.Ruled: Q2 A — the kind is named
picklist. File pattern*.picklist.ts; the field referenceField.select({ picklist: 'industry' }), mutually exclusive withoptions; translationTranslationData.picklists.<name>; the package-level extensionpicklistExtensions— the design of record with its one open name closed. ⛔ NotvalueSet: the repository, the reference app and the docs already say picklist, and a published name is permanent.Readings recorded with the ruling:
Execution parameters (ruled in the same stroke):
domain:specseat 5 claims picklist metadata kind — spec:picklistcollection,Field.select({ picklist }), server-resolved options, translation face (phase 1 of objectstack#18164) #19518 under its Scope with the ruled name, corrects Scope item 1 ("name to confirm") on that body, and runs the full claim, at-tier review (Clause-②: yes: a new metadata kind) and landing. The NORTH-STAR feature-map line and the tworecords-formschecklist items ride their own small Tier H docs PR, as ruling5755653853states.State:
needs-user-decision→pm:queueon this parent (the coordination node;priority:p2,domain:spec,area:recordsstay); #19518 stayspm:queueand is takeable now; the Ruled line goes on the body in the same stroke; a pointer goes on #19518.objectstack-fleet commentedon Oct 3, 2026
Epic checklist: #18164 (shared picklist) · epic PM taken over · 2026-10-03T09:42Z
Director seat, summon #32,
session_016tKoy8NJa35Yih1FdzrVmn, now this card's epic PM. This is on the maintainer's order in the live director chat, verbatim 「你负责接手,并派发处理所有所有相关的」, after the maintainer asked why the card had stalled. ⛔ Not a new ruling: every step below executes ruling5755653853(batch #209 item 1) and ruling5904864936(batch #251 item 3).Why it looked stalled. Ruling
5755653853said an epic PM takes this parent when work starts. None did. The spec and runtime seats landed their sub-issues and closed them, and two steps had no owner:picklistkind,Field.select({ picklist }), translation face, NORTH-STAR line, two checklist itemspicklistExtensions, write validation88b484e00, shipped in 17.6.0picklistmetadata, plus the live-boot checklist runoptionswhenpicklistis set before a PUT (the producer obligation in objectui#102025925784898)pm:on-hold. Restart-when: objectui resolves a 17.6.0. Blocked behind objectui#11438 (ruled A′ on batch #272; PR objectui#11531, the trunk). The road-order clause ("after the open product P0/P1 items") is lifted by the maintainer's order above.records-forms.picklist-org-append)The parent closes when ③ and ④ land. Each dispatch and each landing appends one audit line here.
Generated by Claude Code
objectstack-fleet commentedon Oct 3, 2026
Epic audit · #18164 · 2026-10-03T09:54Z ·
session_016tKoy8NJa35Yih1FdzrVmn. This updates checklist5967887779.picklistmetadata —*.picklist.tsandField.select({ picklist })replace_picklists.ts(acceptance of objectstack#18164) hotcrm#2000: filed, then claimed (5967912141,pm:epic+pm:dispatched). An os-dev is dispatched (mode:subagent): the shared option lists become*.picklist.tswithField.select({ picklist }), followed bypnpm verifyand a live-boot run ofrecords-forms.picklist-shared-across-objects.5967926862) and claimed (5967957684). An os-dev is dispatched on a branch based on the 17.6.0 trunk (chore(deps): resolve @objectstack/* 17.6.0 in pnpm-lock.yaml and follow its mechanical contract moves; five owner-held reds reported by row (objectui#11438) objectui#11531). Its draft PR targetsmain, so CI runs on 17.6.0. It lands after the trunk, whose row 3 waits on 17.7.0 (the maintainer's 「先等,暂不处理」, recorded on deps: bump objectui's @objectstack/* to 17.6.0 — nineteen held cards' conditions are met on npm, and objectui's lockfile still resolves 17.5.0 objectui#11438). It does not wait on the road order any more.picklistkind is package-owned, with no runtime create (spec docblock). If the metadata API refuses picklist writes, Studio builds the read-only page and the designer reference only, and create/edit returns as an open question. ⛔ No work-around.Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
Epic audit · #18164 · 2026-10-06T00:10Z · director seat, summon #34,
session_0195diSK6vuqxgiJ38VWBHb6. This updates checklist 5967887779 by one line; ⛔ not a takeover of the epic.session_016tKoy8NJa35Yih1FdzrVmnis unreachable, the branch has no commit of its own, the worktree is gone). The card is back inpm:queueunderdomain:uiwithpm:epicremoved, its scope cut to the protocol: the designer's 「use picklist」 picker, the save path dropping resolvedoptionswhenpicklistis set, and a READ-ONLY Studio picklist page. ⛔ No Studio create or edit:kernel/metadata-plugin.zod.ts:825declares the kind withallowRuntimeCreate: false.picklistmetadata —*.picklist.tsandField.select({ picklist })replace_picklists.ts(acceptance of objectstack#18164) hotcrm#2000: NOT read from this session (the repository is not attached). Its claim belongs to the same unreachable session; whether its dev finished is unknown here.pm:epic, body line namingsession_016tKoy8NJa35Yih1FdzrVmn) is left as it stands: step ③ may still be in flight under that session, and triage's zombie rule or the maintainer decides the reservation. The parent closes when ③ and ④ land, as the checklist says.feat(objectql): resolve picklist references at runtime — served optio…
feat(spec): offer onSuccess and outcomeMessages in Studio's action fo…
test(spec): the last system/ file group's test titles state each cite…
objectstack-fleet commentedon Oct 8, 2026
Cross-seat note from the
repo:hotcrmseat,session_012zh91QzFgePbkmuHnugLN3, 2026-10-08T03:08Z. ⛔ Not a claim on this card; its body and labels are untouched.objectstack-ai/hotcrm#2000, the hotcrm acceptance step of this epic, left this subtree and is now in the
repo:hotcrmlane'spm:queue.pm:epicwas removed from it.Generated by Claude Code
objectstack-fleet commentedon Oct 11, 2026
Epic close-out at 2026-10-11T22:28Z: completed. The shared
picklistkind shipped in all three layers that stayed in this subtree. The one remaining item is ruled out. Sessionsession_01EgxC4UNYnzhuvmG12fh5A8.Provenance: the maintainer gave the order in live PM chat in this session, verbatim 「该关的关,改开卡的开卡」 and 「按组织追加 picklist 值,不考虑」, and this session executed it.
Landed
picklistcollection,Field.select({ picklist }), server-resolved options, translation face (phase 1 of objectstack#18164) #19518.picklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519, PR feat(objectql): resolve picklist references at runtime — served options, additive extensions, write validation, load-time refusal #21047.pnpm dev -- --fresh -p PORTreach oclif, or does the separator swallow the flags the port rule depends on? #11669.mainat8532783f,packages/spec/src/kernel/metadata-plugin.zod.ts:826registers thepicklistkind.6051363510.Dropped
6051363510left here. It was never filed. The maintainer's 「按组织追加 picklist 值,不考虑」 drops it.docs/adr/0131-total-organization-ownership-no-null-organization-id.md:105).Filed as #22869
docs/qa/platform-checklist/areas/records-forms.json:4372(records-forms.picklist-org-append,planned) anddocs/NORTH-STAR.md:43.records-forms.picklist-org-appendand the "customers append values per organization" promise — the per-organization picklist append is ruled out #22869 retires both.Reservation
session_016tKoy8NJa35Yih1FdzrVmnwas recorded unreachable in6006149092.pm:epicis removed in the same act.