Repository navigation
picklist metadata kind — spec: picklist collection, Field.select({ picklist }), server-resolved options, translation face (phase 1 of objectstack#18164) #19518
Description
Activity
- addedpriority:p2Medium: important, M3Medium: important, M3
on Sep 21, 2026 - addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, search
on Sep 21, 2026 ⛔ Not dispatched — this card's own face gates it behind the open product P0/P1 items, and they are open, 2026-09-22T01:20Z
Seat
domain:spec#4(session_01AmH9bKvGoLjiY86Q4Z3og2, seat post #18917), R20 card selection. ⛔ Not
claimed, ⛔ noClaim:written, ⛔ no label moved — the card stays exactly as triage left it.The gate, quoted from this card's own body
Position in the road: step ②「本地跑起来、看到」, records/studio; it is taken after the open product
P0/P1 checklist items by the road order — ⛔ not dispatched before them.The reading, taken now
probe value open priority:p0, excludingtooling4 — #12243, #11663, #11632, #2714 open priority:p1, excludingtooling28 of those p1, in this lane and takeable 0 — #19543 already carries pm:dispatched, #18670 ispm:blocked, #18215 is an epic⇒ the gate is not satisfied. ⛔ Dispatching would be this seat overriding a road-order constraint the
card states on its face.⚠️ One ambiguity, resolved in the restrictive direction on purpose. The gate says 「the open product P0/P1
checklist items」, which may mean specifically thedocs/qa/platform-checklist/items rather than every
open P0/P1 card. This seat has ⛔ no reading that those checklist items are done, and ⛔ will not resolve an
ambiguity in the permissive direction in order to obtain a dispatch. If the intended reading is narrower, the
card's author or triage can say so and it becomes takeable immediately.Two other things a future claimant should know before reading the scope as a single PR
- It is not one lane. Scope item 6 puts the
osCLI compile/validate path indomain:clias a sibling
PR by that seat, filed from this card. - It carries a Tier H half. The
docs/NORTH-STAR.mdfeature-map line plus the tworecords-forms
checklist items are 「its own small docs PR, the maintainer merges」 — ⛔ that half is never this seat's to
land. ⚠️ And scope item 1 leaves a name unconfirmed: 「picklistvsvalueSet— name to confirm on the parent
before the PR」. A dispatch that guesses the name of a new metadata kind would be declaring a published
collection name by accident.
Generated by Claude Code
- It is not one lane. Scope item 6 puts the
Reached in 取卡全序 and NOT taken — two gates, both on the card's own face. ⛔ Not a claim, ⛔ not a re-grade, ⛔ no label written. 2026-09-22T06:48Z
domain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357). This is the highest-ranked dispatchable-lookingpriority:p2in this lane's queue, so it is the one a later seat will reach first. Recording why it was passed over, so that reading is not re-derived three times.① The card's own road-order fence has not lifted
Its first paragraph, verbatim:
Position in the road: step ②「本地跑起来、看到」, records/studio; it is taken after the open product P0/P1 checklist items by the road order — ⛔ not dispatched before them.
Measured in this act: 4 open
priority:p0cards on this board — #12243, #11663, #11632, #2714. None isdomain:spec; ⛔ that is not the point. The fence is the road's order, and the road still has open P0 ahead of step ②'s records group.⚠️ ⛔ This is NOT the NORTH-STAR clause 3 bar (「产品仓还有开放的 P0/P1 时,任何车道不派 p2/p3 的工具卡、契约卫生卡」). That clause governs 工具卡 / 契约卫生卡, and this card is neither — it is a product feature. The gate here is the one the filing seat wrote onto this card, and it is stricter than clause 3 for this card specifically.② One name is unsettled, and it belongs to the parent
Scope item 1, verbatim: 「name to confirm on the parent before the PR:
picklistvsvalueSet」. The kind's name is its published metadata surface, its file pattern (*.picklist.ts), its registry row, its translation face (TranslationData.picklists.<name>) and its extension key (picklistExtensions) all at once. ⇒ ⛔ this is not a thing to hand a dev with 「pick one」, and ⛔ this seat does not pick it either — the card routes it to #18164.What would make it dispatchable
- the road order reaches step ②'s records group, and
- the name is settled on spec: a shared picklist (global value set) metadata kind — option lists reused across objects and packages are TypeScript constants today #18164.
Then the dispatch is well-shaped: the six scope items are enumerated, the acceptance criteria are executable, and the Tier H docs half (the NORTH-STAR feature-map line plus the two
records-formschecklist items) is already split out as its own small PR for the maintainer to merge.⛔ Nothing about this card is wrong, and ⛔ nothing here asks anyone to change it. It is ready in every respect except the two above.
Generated by Claude Code
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsPointer: dispatchable now, and the kind is named
picklist· ruling 5904864936 on #18164 (batch #251 item 3 · Q1 A · Q2 A · maintainer 「同意」) · 2026-09-30T05:43ZDirector seat (objectstack#12708,
session_01AsCNgFBs8HCjwhyHQsFbx3). The maintainer's 2026-09-23 release of the P0/P1-first rule in thedomain:speclane covers ruling 5755653853's sequencing sentence for this layer, so this card is takeable now; #19519 and objectui#10202 keep theirBlocked-by:order. The name is closed:picklist—*.picklist.ts,Field.select({ picklist: 'industry' })(mutually exclusive withoptions),TranslationData.picklists.<name>,picklistExtensions. The claiming seat corrects Scope item 1 ("name to confirm") on this body in its claim stroke;Clause-②: yes(a new metadata kind); the NORTH-STAR line and the tworecords-formschecklist items ride their own small Tier H docs PR, as 5755653853 states.objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsClaim: PM loop round 19 · 2026-09-30T06:24Z
Session:session_01Sfe5YjBLwB9J3y8fvm2xq1
Account:os-justin(the seat's linked user asGET /useranswers it; the card's assignee from this act)
Branch:claude/issue-19518-picklist-kind
Worktree:objectstack-issue-19518
Domain:domain:spec
Seat:domain:spec#5(seat post #19357)
Clause-②: yes (a new published metadata kind and a newField.selectreference)
Rulings in force:- The maintainer's
5904864936on spec: a shared picklist (global value set) metadata kind — option lists reused across objects and packages are TypeScript constants today #18164 (batch 🔗 Broken links detected in documentation #251 item 3, Q1 A and Q2 A, 「同意」). This layer is dispatchable now, and the kind is namedpicklist. - The design of record
5715762696and ruling5755653853. - In this act, the body's Scope item 1 reads the ruled name.
Scope: this card's Scope items 1 to 5 (the spec layer), taken whole: - the
picklistkind:{ name, label, description?, options: SelectOption[] }with today's option shape, package-owned,*.picklist.ts, registered beforeobject, and a stack collection; Field.select({ picklist }), mutually exclusive withoptions. Both or neither is refused at the schema door with a prescription;- the served shape carries the resolved
options; - the translation face
TranslationData.picklists.<name>; - additive
picklistExtensions. - ⛔ Not the per-organization overlay (phase 2).
File surface (stop on breach and explain it in the report): packages/spec/src/for the kind, the field reference, the translation face, the stack collection and the kind registry row.- Every place that ENUMERATES metadata kinds or stack collections (registries, load order, manifest listing, generated JSON schema and reference docs, authorable-surface baselines, liveness ledgers and their state counts), and every pin that COUNTS them. The dev owns this census and lists it in the report.
.changeset/19518-*.md(@objectstack/specminor).- ⛔ Not item 6 (the CLI compile/validate path,
domain:cli): the report names it for a sibling card. ⛔ Not the runtime (picklist metadata kind — runtime: resolvepicklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519) or Studio (objectui#10202). - ⛔ Not the NORTH-STAR feature-map line or the two
records-formschecklist items. They ride their own small Tier H docs PR, which the seat dispatches separately. - ⛔ No
docs/adr/**.
Container & model:M,mode:subagent,model: opus.
Review: an at-tier contract review is owed before enqueue.
Thread-read: 5904911376
Serial constraints cleared: read at this stamp, no open PR touchesdata/field.zod.ts,stack.zod.ts,system/translation.zod.ts,kernel/metadata-plugin.zod.tsordata/field-value.zod.ts.
Generated by Claude Code
- The maintainer's
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsos-dev-report
{ "issue": 19518, "status": "needs_decision", "branch": "claude/issue-19518-picklist-kind", "pr": "https://github.com/objectstack-ai/objectstack/pull/20823", "session": "session_01Sfe5YjBLwB9J3y8fvm2xq1", "premise_still_valid": true, "summary": "Premise verified on origin/main (base 7a09eee1b1, main merged at df990eedac): the kind, the Field key, the translation group and the stack collections were all absent. The only prior `picklist` in FieldSchema was an alias to `options`; it is removed now that `picklist` is a declared key, and `valueSet`/`globalValueSet`/`optionSet` alias to it instead. Delivered Scope 1-5 in packages/spec: (1) `PicklistSchema` {name, label, description?, options: SelectOption[] min 1, ADR-0010 envelope} and `definePicklist`. It is a registered kind: MetadataTypeSchema, DEFAULT_METADATA_TYPE_REGISTRY (loadOrder 8, before object at 10), BUILTIN_METADATA_TYPE_SCHEMAS, files `*.picklist.ts/.yml/.json`, and it is a `picklists` stack collection (compose: concat, PLURAL_TO_SINGULAR). allowRuntimeCreate:false and allowOrgOverride:false: package-owned, the per-org overlay is phase 2, and no reader exists for a runtime row. (2) FieldSchema.picklist (snake_case). The schema door refuses it together with `options` (path options, prescription) and refuses it on a non-option type. Field.select({ picklist }) returns the reference form without options. (3) `PicklistServedFieldSchema` (looseObject {picklist, options min 1}) declares the served shape: resolved options, picklist kept. (4) TranslationData/TranslationItem/PlatformTranslationData gain `picklists.NAME.{label?, options}`. translateObject lets a picklist-bound field inherit `picklists.NAME.options.VALUE`, and a field-level entry wins over it. translatePicklist is registered in METADATA_DOCUMENT_TRANSLATORS. (5) `PicklistExtensionSchema` {extend, options} and the `picklistExtensions` collection are additive only. checkFieldCompleteness counts a `picklist` reference as an options source. NOT delivered: the acceptance line 'neither refused'. A schema-door refusal of select/radio without options was implemented and measured, then withdrawn because it narrows the accept set with stored-data fallout (open question 1). The PR is `Part of #19518` for that reason. The report dispatch named no labels and a changeset exists, so zero labels were written. PR assignee is os-justin, mirroring the card. Worktree node_modules and worktree are removed after this report.", "tests": "All local runs used os-verify-lock with VERDICT command-exit 0 unless noted. spec: full `vitest run --project local` gives 578 files, 17065 passed, 1 todo (at ba32d57588, pre-merge; spec/src unchanged since). spec typecheck (tsc, scripts, test-typecheck) is green after the merge. The test-typecheck debt shrank: src/data/field.test.ts GRADUATED (2 TS2322 gone, entry deleted), because Field.select now accepts mixed string/object options. `check:generated` at final head 569b88a475 reports 'All 15 generated artifacts are up to date' and `check:liveness` at 569b88a475 exits 0. Targeted consumer files against the rebuilt spec dist: objectql 10 files / 580 passed; lint 20 files / 1815 passed after the one pin update, then the 3 edited-area files / 243 passed; metadata-protocol 9 files / 213 passed; app-showcase coverage.test 13 passed. metadata-protocol and lint typecheck exit 0. Derived gate list (dispatch-gates --commands, 121 rows) run lock-free with exit codes captured before any pipe. Green unless named below: check:llms-txt was red then fixed. check:skill-examples first said PREREQUISITE NOT MET; after building client-react it was green (259 blocks). check:i18n and check:i18n-walk-parity first said PREREQUISITE NOT MET; after building the CLI, check:i18n is green (bundles regenerated plus 3 hand translations), check:i18n-coverage is OK ('none new'), and check:i18n-walk-parity is RED (open question 3). check:skill-top-level-keys is RED (open question 2). check:quick-reference-counts, check:overlay-whitelist-table and check:stack-collection-maps (plus --self-test, 18 assertions) were red, fixed, and are now green. check:platform-checklist is RED on `coverage.json picklist UNCLASSIFIED` (docs/qa is off-limits; manual cadence, not per-PR CI) and on a pre-existing identity-auth twoFactor anchor. NOT MEASURED: check:dual-build-cjs-loads (reason: local organizations dist has no index.d.ts, a partial build in this worktree; rebuild queue-timed-out, exit 99); check:type-check-debt and check:pm-dispatch-gates (reason: killed by a 500s timeout under a contended box). Ablations: each ran picklist.test.ts with the mutation on disk via scripts/ablation-replace.mjs (anchor hit x1, marker count checked), then restored with blob == HEAD and `git diff HEAD` empty. The mutations were: A1 both-refusal off: 3 tests red ('`picklist` + `options` together is refused at `options`', '`Field.select` handed both keeps both, so the pair still reaches the refusal', 'the served form is not an authoring input — the field door refuses the pair'). A2 option-type check off: 3 red ('`picklist` on the non-option type text/lookup/number is refused at `picklist`'). A3 translateObject picklist fallback off: 2 red ('a field that references the picklist inherits its option labels', 'a field-level option label is the more specific and wins'). A4 completeness picklist source off: 2 red ('neither on a select/radio is the completeness gate's error, not a parse refusal'). A5 translatePicklist unregistered: 1 red ('a served picklist item translates its label and options, and is a translatable type'). A6 loadOrder 8 to 11: 1 red ('loads before `object`, whose fields reference it'). The first A3/A4 attempts were refused by the tool, whose replacement text was a substring of the anchor, so the count was ambiguous and no verdict was taken. They were re-run with unique markers as A3b/A4b, which are the results above. Not ablated (plain schema shape pins): picklist min(1)/strict/name, extension min(1)/remove, served min(1), stack parse/compose, TranslationData parse. CI on 569b88a475, deduplicated by name at report time: 12 success, 2 skipped, 17 in_progress, 1 failure. The failure is 'Type Check · source gates', step 31 'Check the platform skill enumerates every authorable top-level stack key' (= check:skill-top-level-keys, expected). 'Type Check · consumer gates' is still running and is expected to red on check:i18n-walk-parity.", "mcp_calls": "0", "api_writes": "3 relay writes through scripts/pm (transport dispatch, as objectstack-fleet[bot]): pr_create POST /repos/objectstack-ai/objectstack/pulls (draft #20823; body read back byte-identical); assign POST /repos/objectstack-ai/objectstack/issues/20823/assignees (os-justin, via label-write.mjs; read-back matches); comment POST /repos/objectstack-ai/objectstack/issues/19518/comments (this os-dev-report). Plus git push of the branch, which is not a REST write.", "open_questions": [ { "question": "The card's acceptance says 'neither refused'. Should a select/radio with neither `options` nor `picklist` be refused at the FieldSchema door?", "options": [ "A: a separate card, ruled as a BREAKING accept-set narrowing like the lookup-reference precedent (commit 0fb8760bec: minor with a BREAKING header plus an ADR-0087 not-required marker). The card carries the fixture triage it needs: measured on this branch, 4 spec fixtures and 9 tests in metadata-protocol's stored-conversions and stored-migration suites went red, because a stored select row with no options stops validating and migrateStoredMetadata stops rewriting it. Studio drafts of a select before its options exist would 422 too.", "B: fold it into this PR. That widens the file surface into metadata-protocol and other packages' fixtures, turns the changeset BREAKING, and changes the PR's Clause-② line from `yes` to `yes (narrowing)`.", "C: leave 'neither' at the completeness gate permanently. That is today's error-severity field/choice-without-options at os lint/validate plus the registry warning; its prescription now names picklist." ], "recommendation": "A: it is the design of record's intent, but it is a stored-data narrowing that the card never costed. Multiselect/checkboxes/tags keep their free-form mode in every option, per the functional-completeness NON-rule." }, { "question": "check:skill-top-level-keys (required, via TypeScript Type Check) is red: the published skills/objectstack-platform/SKILL.md must list `picklists` and `picklistExtensions`. That file is a governed Tier H surface, and its token ratchet has 4 tokens of headroom; the addition costs about 9.", "options": [ "A: this PR carries the two keys plus a deletion of at least 5 tokens elsewhere in that skill, and becomes Tier H (maintainer approval, 维护者速读 section, before/after readings).", "B: the Tier H docs PR the seat dispatches carries it. It still cannot land apart from this PR, because the gate is red in the opposite direction until the keys exist.", "C: the maintainer raises that file's ceiling." ], "recommendation": "A: the one diff that keeps the gate green in every order." }, { "question": "check:i18n-walk-parity (required) is red: `picklists` is declared in TranslationDataSchema, but no extractor emits it. The remedy is to walk it in packages/cli/src/utils/i18n-extract.ts collectExpectedEntries and to add a member to scripts/fixtures/i18n-walk-parity/every-group.stack.json, about 30 lines modelled on the datasets block. Both paths are outside this claim's surface; the gate's ledger path is maintainer-only.", "options": [ "A: widen this PR's surface to those two files.", "B: put the walk on the Scope 6 CLI sibling card and land that card in the same merge.", "C: a maintainer KNOWN_NO_EXTRACTOR_FACE row." ], "recommendation": "A: the gate cannot be green on either side alone." }, { "question": "Conflict: the dispatch said the first line of the PR body is `Closes #19518`; os-dev.md says `Part of` when the merge should not close the card.", "options": [ "A: keep `Part of #19518` until the neither line is ruled.", "B: switch to Closes if the ruling is option 1A or 1C." ], "recommendation": "A, as written. The body is the seat's to change." } ], "out_of_scope_findings": [ "class: c · reach: `os lint` on a stack whose object has `{ type: 'select', picklist: 'industry' }`, measured through @objectstack/lint lintDataModel, answers warning field/select-missing-options 'select field \"account.industry\" has no options'. packages/lint/src/data-model-rules.ts R8 (OPTION_FIELD_TYPES) does not count `picklist` as an options source, and its fix points at `options`, which the schema door now refuses together with picklist. · dedupe words: select-missing-options, picklist, lint R8, option source · route into the Scope 6 CLI sibling card (same family).", "carrier: #19519 (runtime) · runtime enumerations left to it and waived in check-stack-collection-maps as PENDING rows that fail stale when it lands: objectql engine.ts METADATA_ARRAY_KEYS, metadata plugin.ts ARTIFACT_FIELD_TO_TYPE; runtime app-plugin.ts APP_CATEGORY_KEYS / SECURITY_FIELDS (DELIBERATE rows); metadata-protocol reference-sites (field.picklist is a new cross-kind reference); metadata-core types.ts 'lockstep' enum (already drifted, no pin) · noted, not filed.", "carrier: #19519 · served-shape round trip: a served picklist-bound field carries both keys by contract, so a client that PUTs the served object back is refused at the field door (loud, prescribed). The write path must strip resolved options for a resolvable picklist, or keep refusing. Studio's designer is phase 2 · noted, not filed.", "carrier: #19519 / objectui#10202 · resolveObjectFieldLabels (the field-labels endpoint) returns field-level option labels only, so a client reading fieldOptions off that route does not see picklist-inherited labels; server-side translateObject does · noted, not filed.", "carrier: the seat's Tier H docs PR · check:platform-checklist (manual cadence) reports coverage.json picklist UNCLASSIFIED until the records-forms items and a coverage row land; the same run shows a pre-existing identity-auth.json ABSENT SYMBOL plugin-auth auth-plugin.ts#twoFactor, untouched by this branch · noted, not filed." ], "census": { "method": "Add the kind, then read every red test and gate by name: full spec suite, check:generated, check:liveness, the 121-row dispatch-gates list, and targeted consumer suites (objectql, lint, metadata-protocol, app-showcase). Also a heuristic source scan for select/radio fixtures without options (82 files flagged; the measured fallout is in open question 1).", "enumerations_updated": [ "MetadataTypeSchema; DEFAULT_METADATA_TYPE_REGISTRY; BUILTIN_METADATA_TYPE_SCHEMAS", "STACK_DEFINITION_COLLECTIONS_SHAPE + COMPOSE_KEY_DISPOSITIONS (picklists, picklistExtensions)", "PLURAL_TO_SINGULAR, then regenerated meta-url-data.generated.ts", "METADATA_DOCUMENT_TRANSLATORS, so TRANSLATABLE_METADATA_TYPES", "data barrel + root export definePicklist", "liveness: GOVERNED list, picklist.json (all planned), field.json picklist (planned + authorWarn; the lint warning measured firing), translation.json picklists (planned), README table row + heading 40 to 41, state-counts shards", "generated: authorable-surface data/system, json-schema.manifest, api-surface data/root/system + signatures, export-origins, declaration-map, 12 reference docs incl. new data/picklist.mdx", "strictness ledger triage row + counts shards; llms.txt data 30 to 31, total 203 to 204", "platform-objects metadata-forms bundles: en regenerated; zh-CN/ja-JP/es-ES translated by hand", "examples/app-showcase KIND_COVERAGE.picklist + STACK_COLLECTION_COVERAGE.picklistExtensions (waived, linked to #19519)", "scripts/check-stack-collection-maps.mjs waiver rows (8 sites)", "content/docs: metadata-lifecycle registry count 27 to 28; quick-reference Data 'of 29' to 'of 30'" ], "count_pins_updated": [ "spec metadata-type-schemas.test.ts '#4001 — registered-type closure is derived, not tallied > reports the campaign number so a reader never has to count' 25/26 to 26/27", "spec metadata-create-seeds.test.ts 'surfaces schema-backed authorable types still missing a seed (no silent cap)' KNOWN_UNSEEDED += picklist", "spec metadata-form-zod-reconciliation.test.ts 'field: every top-level key the author may write is offered, or its omission is recorded' omit row for picklist", "lint lint-liveness-properties.test.ts 'the SHIPPED field ledger warns on ...' [] to ['picklist']", "metadata-protocol protocol.code-only-types.test.ts 'covers every code-only type the registry declares' += picklist, plus a probe (11 generated cases)", "metadata-protocol protocol.meta-types-degenerate-derivation.test.ts 'control: `field` still serves N top-level properties' 74 to 75", "spec test-typecheck-debt.json: field.test.ts entry deleted (graduated)" ], "regeneration_turned_green": "metadata-url-spelling.test (7 cases), export-origins.test (3), check-liveness.test (19)" }, "governed_merges_test": "node scripts/pm/check-governed-merges.mjs --branch HEAD at 569b88a475: 'governed-surface predicate: 0 of 64 path(s) hit the register', NOT governed, +1228/-111 (1339 lines, under 5000). Head-repo line: NOT MEASURED by --branch. If open question 2 goes to option A, the PR becomes Tier H.", "scope6_sibling_card_draft": "Title: picklist kind: CLI compile/validate/lint accept `*.picklist.ts` / `picklists` / `picklistExtensions` (phase 1 of #18164, Scope 6 of #19518). Points: (1) build/compile ingest of the two collections and `os generate picklist` file naming (packages/cli/src/utils/metadata-file-name.ts parity with the registry filePatterns); (2) `os validate` refuses picklist+options (inherited from FieldSchema) and a field whose `picklist` names no picklist in the stack or its declared dependencies (the loud wrong-reference refusal of ruling 5755653853 item 3); (3) lint R8 field/select-missing-options counts `picklist` as an options source (finding above); (4) `os i18n extract` walks `picklists.NAME.{label, options.VALUE}` (check:i18n-walk-parity, open question 3). Blocked-by: #19518. Dedupe words: picklist, picklistExtensions, os validate, i18n extract, select-missing-options." }
Generated by Claude Code
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsRuling on the report
5908082075, and round 2 · 2026-09-30T09:23Zdomain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim5905425409. Draft PR #20823 at569b88a475.Accepted as delivered: Scope items 1 to 5, as listed below. The census of enumerations and count pins, the six ablations, and the graduation of the test-typecheck debt entry are accepted too.
- the
picklistkind: registered,loadOrder8, a stack collection; FieldSchema.picklist, and its refusal whenoptionsis also declared or when the type carries no options;PicklistServedFieldSchema;- the
picklists.NAMEtranslation face and its fallback, with the field-level entry winning; - additive
picklistExtensions.
Open question 1 ("neither refused"): split to #20827 for the maintainer. Refusing a select or radio that has neither key narrows stored data, and the design of record never costed that. #20827 carries the decision analysis (
5908178556) andneeds-user-decision. This PR does not wait for it. The card body's Scope 2 and Acceptance now point there.Open question 2 (
check:skill-top-level-keys): A. This PR addspicklistsandpicklistExtensionstoskills/objectstack-platform/SKILL.md, and cuts at least the same number of tokens elsewhere in that file. The cut must be text that is redundant or false, and nothing an author needs. With that change the PR is Tier H: it needs an authorized approval before it goes ready. The NORTH-STAR line and the tworecords-formschecklist items stay in their own Tier H docs PR, after this lands.Open question 3 (
check:i18n-walk-parity): A. The surface widens topackages/cli/src/utils/i18n-extract.ts(collectExpectedEntrieswalkspicklists.NAME.{label, options.VALUE}) andscripts/fixtures/i18n-walk-parity/every-group.stack.json. Neither side can be green alone. #20825 (the Scope 6 sibling, filed fordomain:cli) records that this walk rides this PR.Open question 4: A. The PR stays
Part of #19518, because the Tier H docs PR is still owed after it.Out-of-scope findings:
- The lint R8 finding (
select-missing-optionsdoes not countpicklist) goes to picklist kind: theosCLI compile / validate / lint path accepts*.picklist.ts,picklistsandpicklistExtensions, andos validaterefuses apicklistthat names no picklist (Scope 6 of #19518) #20825. - The served-shape round trip,
resolveObjectFieldLabels, and the runtime enumerations go to picklist metadata kind — runtime: resolvepicklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519, as the report names.
Round 2: the two gate fixes above. Then CI goes green, the at-tier review runs with
needs:contract-reviewon the PR and this card, and the maintainer's approval follows.
Generated by Claude Code
- the
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsos-dev-report
{ "issue": 19518, "status": "done", "branch": "claude/issue-19518-picklist-kind", "pr": "https://github.com/objectstack-ai/objectstack/pull/20823", "session": "session_01Sfe5YjBLwB9J3y8fvm2xq1", "premise_still_valid": true, "head": "388dcceb29", "summary": "Round 2 per ruling 5908214854, appended onto 569b88a475 with no force-push; origin/main was merged twice (3a85fdf5c2, 12896a0902) via os-regen-merge.sh, each followed by a regeneration commit (45dddd7f2b, 388dcceb29). Gate 1: skills/objectstack-platform/SKILL.md now lists `picklists` and `picklistExtensions` (4049ae31ba), paid for by deleting two pieces of text in the same file, so the file shrinks by 7 bytes and 2 tokens. Gate 2: `collectExpectedEntries` walks `picklists.NAME.{label, options.VALUE}` and an extension's options under the list it extends. It follows the datasets block, adds a `picklist` coverage bucket (`i18n/missing-picklist`), a `parity_tier` member in every-group.stack.json and a 6-test pin; the ablation took the gate red (c9fe5047d4). Round 1 missed six census pins that enumerate registered kinds, and CI went red on them (Test Core shards 1-5, and driver-sql). They are fixed here: 12592f1753 (driver-sql builtin-column-collision classifies `picklist` as presentation) and a1f0668666 (CLI metadata-type-schema-gate GATED_AT, metadata-protocol recovery-doors bootstrap set, platform-objects bare-type and metadata-form echo counts, runtime meta list/item census cells). Also fixed: the picklist docblock no longer opens on a level-1 heading (56d7584e0e; spec file-description corpus 32 back to 31). The changeset now names @objectstack/cli and @objectstack/driver-sql (14b1f68221). CI on 388dcceb29 is GREEN, and the PR stays `Part of #19518` (ruling 4A). No labels were written: the dispatch named none, and a changeset exists.", "gate_readings": { "check:skill-top-level-keys": "before (569b88a475): exit 1, `[missing] picklists` and `[missing] picklistExtensions` at skills/objectstack-platform/SKILL.md:43. after (388dcceb29): exit 0, 'enumerates all 46 authorable top-level keys of ObjectStackDefinitionSchema (2 declared machine-written and held out: viewItems, runtimeModule)'; self-test 14 cases pass.", "check:i18n-walk-parity": "before (569b88a475): exit 1, 'picklists — declared in TranslationDataSchema, produced by no emitter'. after (388dcceb29): exit 0, '11 declared group(s), 9 walked, 2 exempted — every declared group has an extractor face'; self-test 43 cases pass. Ablation (lock-held, trap-restored): anchor `walkPicklists(config, out);` hit 1 then 0, marker 0 then 1, cli rebuilt, ablation-dist-preflight marker present exit 0. Gate under ablation exit 1 ('picklists — ... produced by no emitter'); pin test/i18n-picklist-walk.test.ts 5 failed / 1 passed (the one that stays green asserts an absence: no field-level option key for a picklist-bound field). Restore: ablation-replace 'blob == HEAD (37843a0e963d) and git diff HEAD is empty', rebuilt, preflight --absent exit 0 over 552 dist files, gate exit 0 again." }, "skill_md": { "added": "In the Full Configuration Reference enumeration, `picklists`, `picklistExtensions` after `objectExtensions`, next to the object keys they serve (+35 bytes; re-wrapped, 1 line added).", "deleted": [ "CLI Commands: 'covered in **Part 3 — Operations** below' became 'in [Part 3 — Operations](...)'. The words 'below' and 'covered in' and the bold are dropped (31 bytes), because the text is DISTORTED. Part 3 is not below: commit 595621d35c (#19738, 2026-09-23) moved it verbatim to references/operations.md, as line 479 of the same file says. The link target is unchanged.", "CLI Commands: 'High-level cheat sheet' became 'Cheat sheet' (11 bytes), because it is REDUNDANT: a cheat sheet is by definition high-level, and the block that follows says what it covers (the bootstrap loop). The join also removed 1 line." ], "readings": "bytes 23313 to 23306 (-7); tokens (ceil(bytes/4), check-skills-token-ratchet) 5829 to 5827, ceiling 5833, headroom 4 to 6; file lines 489 to 489; skills package lines (all SKILL.md) 4396 to 4396; authored ratcheted total 143408 to 143406. No re-wrap was used to buy lines: the +1 line in the enumeration is paid by the -1 line of a content deletion." }, "maintainer_brief_draft": "## 维护者速读(草稿)\n改了什么:objectstack-platform 技能的顶层键清单加上 picklists、picklistExtensions 两个键。同一文件的 CLI 小节有一句指路文字,删掉其中已失真的“below”和重复的“High-level”。整文件 489 行不变,token 从 5829 降到 5827(上限 5833),技能包总行数 4396 不变。\n为什么改:本 PR 给 stack 新增了这两个顶层键。必需门禁 check:skill-top-level-keys 要求技能页的清单与 schema 一致,页面没列出的键,AI 作者就不会写。删掉的两处:Part 3 在 595621d35c 已拆到 references/operations.md,不在本页下方,所以“below”是错的;“High-level cheat sheet”里的 High-level 与 cheat sheet 意思重复。\n风险与代价(含回滚):只改文字,链接目标不变,作者需要的内容没有删。回滚办法是 revert 4049ae31ba,但回滚后该门禁会重新变红,除非同时去掉这两个 stack 键。\n席位意见:\n你要做的:本 PR 为 Tier H(skills/** 命中 1 个文件),需要您亲手合并,或给出授权的 APPROVED 审阅后由席位落地。请看 SKILL.md 的两处改动(第 43 行起的清单,第 453 行的 CLI 句子)。", "governed_merges": "node scripts/pm/check-governed-merges.mjs --branch HEAD at 388dcceb29: exit 3 = GOVERNED, landing tier H (人合); skills/** x1 (skills/objectstack-platform/SKILL.md); 1 of 75 paths hit the register; +1432 / -132 (1564 changed lines, under the 5000 threshold); merge-base 820d3f4f8e, origin/main 05a7547c9f; head repo NOT MEASURED by --branch.", "tests": "All runs used os-verify-lock at head 388dcceb29 with VERDICT command-exit 0, and each exit code was captured before any pipe. Build: turbo build of the cli/runtime/showcase/lint/client dependency closures (60 tasks, exit 0), after spec build + `check:generated --fix`, which reports 'All 15 generated artifacts are up to date'. Tests: spec scripts/file-description.test.ts 111 passed; platform-objects, the 2 echo-decision files + sys-job.global-unique, 82 passed; metadata-protocol whole package 191 files, 2818 passed, 19 skipped; runtime meta-list-projection-parity + 4 registry-reading files 741 passed; cli integration metadata-type-schema-gate 8 passed; cli unit project whole 238 files, 3377 passed (includes i18n-picklist-walk 6/6). Registry-reading census files in packages my diff does not touch, run as a declared narrowing so that a hidden red would surface (CI stops a shard at its first red package): lint 5 files 221 passed; metadata-core 2 files 45 passed; metadata 5 files 173 passed; objectql 8 files 207 passed; rest 2 files 24 passed; client 2 files 27 passed; app-showcase coverage.test 13 passed. Typecheck: @objectstack/spec and @objectstack/cli typecheck exit 0 (test-typecheck: spec 52 files/137 pinned signatures held; cli 3 files/6 held). Before this round's fixes, the whole-package runs at 12592f1753 reproduced CI's red exactly: spec file-description 32 vs 31; platform-objects 5 red; metadata-protocol recovery-doors 1 red; runtime parity census 2 red; cli integration gate 1 red ('expected [ picklist ] to deeply equal []'). Gates: dispatch-gates --commands at 388dcceb29 derives 149 families (147 last round, plus check:driver-conformance and check:route-envelope), all run under the lock. Two are non-zero: check:platform-checklist exit 1 (coverage.json picklist UNCLASSIFIED, since docs/qa is off-limits, and the pre-existing identity-auth twoFactor anchor, unchanged) and check:pm-dispatch-gates exit 124 (killed by its 900s timeout; recorded with its reason). check:dual-build-cjs-loads, NOT MEASURED last round, is now exit 0. `dispatch-gates --ran`: '149 derived famil(ies) accounted for — 148 run, 1 NOT-MEASURED (0 DERIVED from a recorded exit 3, 1 a KILL code with a stated reason)', exit 0. NOT MEASURED: check:pm-dispatch-gates (reason: timeout kill, exit 124; the gate reads scripts/pm tooling this PR does not touch). CI on 388dcceb29, deduplicated by name: 26 names over 35 check-runs, with 24 success and 2 skipped (Console Pin Gate, Packed-tarball smoke (opt-in)). Success: Auto Label, Build Core, Build Docs, Check Changeset, Check Documentation Links, Check PR Size, Dogfood Regression Gate x4, Dogfood Verify CLI, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, Spec property liveness, Temporal Conformance (live PG + MySQL), Test Core x7, The card this PR closes must claim this branch, Type Check · consumer gates, Type Check · debt ledger, Type Check · source gates, Type Check · workspace, TypeScript Type Check, filter. ci-failure.mjs --pr 20823: 'VERDICT: GREEN — all 35 check-run(s) completed, none failed', exit 0.", "mcp_calls": "0", "api_writes": "1 relay write through scripts/pm/fleet-write/dispatch.mjs (transport dispatch, as objectstack-fleet[bot]): comment POST /repos/objectstack-ai/objectstack/issues/19518/comments (this os-dev-report). Plus git push of the branch (12592f1753 and then 12592f1753..388dcceb29), which is not a REST write. No PR body edit and no label write this round.", "open_questions": [], "out_of_scope_findings": [ "carrier: the seat's docs/qa follow-up · check:platform-checklist still reports coverage.json picklist UNCLASSIFIED (docs/qa/platform-checklist is off-limits to this card). The same run shows the pre-existing identity-auth.json ABSENT SYMBOL plugin-auth auth-plugin.ts#twoFactor, which this branch does not touch · noted, not filed.", "carrier: the seat · a PR-body update is owed, since dev does not PATCH. The body predates round 2, so the seat adds the 维护者速读 section (draft in maintainer_brief_draft), the governed-merges line and the round-2 file surface (packages/cli/src/utils/i18n-extract.ts + i18n-coverage.ts, scripts/fixtures/i18n-walk-parity/every-group.stack.json, skills/objectstack-platform/SKILL.md, packages/drivers/driver-sql/src/builtin-column-collision.ts, and census test pins in cli, metadata-protocol, platform-objects and runtime) · noted, not filed." ] }
Generated by Claude Code
10 remaining items
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsDispatched: the Tier H docs PR, the last follow-up on this card · 2026-09-30T20:13Z
domain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim5905425409.- Branch
claude/issue-19518-picklist-docs, oneos-dev. Part of picklist metadata kind — spec:picklistcollection,Field.select({ picklist }), server-resolved options, translation face (phase 1 of objectstack#18164) #19518. The seat closes the card by hand after it lands, because Closes does not fire through the merge queue. - Scope: this card's section "Also with this card", plus one item carried from spec(integration): build the connector sync executor that
syncConfigandfieldMappingsdeclare (14 keys), once and on the mainstream shape #20281:- The
docs/NORTH-STAR.md「路上的功能点」 step ② records line for the shared picklist, carrying the two new item ids. - The two
records-formschecklist items indocs/qa/platform-checklist/areas/records-forms.json. docs/qa/platform-checklist/coverage.json. The seat readaaad682dbc:packages/spec/liveness/picklist.jsonexists, andmetadataKindshas nopicklistentry.skills/objectstack-upgrade/references/examples-upgrade.md. It walks a 16-erafieldMappings[].transformsource, which feat(spec)!: connector-attached sync leaves the connector — syncConfig / fieldMappings retired, mapping gains the connectorSource pull binding (#20281 stage 1) #20903 retired (spec(integration): build the connector sync executor thatsyncConfigandfieldMappingsdeclare (14 keys), once and on the mainstream shape #20281 stage ①). It is carried here under ruling5916259513rather than as its own card.
- The
- Known tension, left to the dev to report: Scope 5 above puts the per-organization overlay in phase 2, undeclared. But the second checklist item as written on this card ("org A adds a value, A writes it, B is refused") names that behaviour.
- Tier H (
docs/NORTH-STAR.md,skills/**): the maintainer merges. The seat hands off with the 维护者速读,needs-user-decision, and review requests to both approvers. - Serial check: none of the 10 open PRs touches these four files (the seat read their file lists).
Generated by Claude Code
- Branch
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsos-dev-report
{ "issue": 19518, "status": "done", "branch": "claude/issue-19518-picklist-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/20938", "session": "session_01Sfe5YjBLwB9J3y8fvm2xq1", "premise_still_valid": true, "head": "8e7420019e", "summary": "Draft PR #20938 (Part of #19518, Tier H, assigned os-justin, labels documentation, size/m and skip-changeset) delivers the four files of dispatch 5918866874 on base aaad682dbc. Each seat fact was re-measured there. NORTH-STAR had no 共享选项集 (grep exit 1); line 13 defines the row format and line 24 uses 清单项待写. records-forms.json had 40 items, all active. coverage.json has keys $comment and metadataKinds and no picklist entry, while packages/spec/liveness/picklist.json exists. examples-upgrade.md line 11 is the 16-era fieldMappings source; the 'connector sync run' sentence is at line 67, under the line-61 heading. evals line 26 is as described. (1) NORTH-STAR: the card's line verbatim, ids picklist-shared-across-objects and picklist-org-append. It is placed after the last records row (search), so it ranks below every existing records capability; the PR body flags placement as the maintainer's priority call. (2) records-forms.json: two items, both status planned, since null, P2, mixed, with no steps, per README 'Implementation status'. No code outside packages/spec reads a picklist (liveness grades every key planned; check-stack-collection-maps holds picklists and picklistExtensions as PENDING rows for #19519), so neither item has anything to drive. picklist-shared-across-objects is phase 1: two objects served the same resolved options, a package extension value, the write door refusing an out-of-set value, and the locale relabel. It has three drafted acceptance clauses from the design of record and #19519's acceptance sentence, plus four negatives. picklist-org-append is phase 2: org A appends, A writes, B is refused. It has no acceptance clauses, because the overlay is undesigned. A knownGaps entry states it is not declared: the picklist registry row has allowOrgOverride false, and ruling 5904864936 defers the overlay to its own sub-issue. (3) coverage.json: picklist is a waiver, not items. The gate's own rule settles this: a kind whose only items are planned is UNMAPPED, the remedy is 'add an item that RUNS, or waive the kind with a reason', and an entry cannot hold both. The waiver gives the measured reason, names both planned ids, and states what retires it. Side effect: checklist-select capability:picklist matches nothing until the waiver flips to items. (4) examples-upgrade.md: #20903 retired connector.syncConfig and connector.fieldMappings whole. The D2 conversion connector-sync-keys-removed (toMajor 18) is inside the default `os migrate meta --from 16` terminus, and the fieldMappings tombstone points at a target-side mapping with connectorSource and a job. So three statements were false and now say what is true: the transform tombstone as the prescription, the connector 'landing raw values', and the report template's 'connector sync run against staging'. The file drops from 1197 to 1188 tokens at the same 119 lines. evals/protocol-major-upgrade.json eval 3 was read and is not false (it claims no sync run), so it is unchanged, per the four-file scope. Two standard-text points: the newest Claim (5905425409) names branch claude/issue-19518-picklist-kind while this branch is picklist-docs, which the parent's instruction and dispatch 5918866874 cover, so no claim was posted. That claim's `Clause-②: yes` belongs to the spec layer, and this PR releases nothing, so the line was not copied into the body and skip-changeset was applied (pr-automation route 2 names skills/ and docs/). Worktree node_modules and the worktree are removed after this report.", "tests": "All at head 8e7420019e unless stated; exit codes captured before any pipe. dispatch-gates --commands --repo objectstack-ai/objectstack (stderr: tree of objectstack-ai/objectstack at 8e7420019e; 4 paths vs merge base aaad682db; +111/-9) derives 25 families. All 25 ran: 24 exit 0, and check:platform-checklist exits 1 (below). pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 (PREREQUISITE NOT MET: no formula/lint dist). It exits 0 after `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint --concurrency=2` under os-verify-lock (VERDICT command-exit 0, held 95s, waited 0s), with '22 record-scoped formula example(s) across 458 files / 1382 TS blocks judged clean'. dispatch-gates --ran: '25 derived famil(ies) accounted for — 25 run, 0 NOT-MEASURED (a DERIVED zero — all 25 recorded an exit code and none of them is 3)', exit 0. check:platform-checklist exits 1 on both trees. On aaad682dbc it reported 2 problems: 'coverage.json · picklist: UNCLASSIFIED' and 'areas/identity-auth.json: ABSENT SYMBOL … auth-plugin.ts#twoFactor'. At 8e7420019e it reports 1 problem, the same twoFactor anchor, which is pre-existing and untouched; self-test 221 assertions pass, and the 5 anchors added (PicklistServedFieldSchema, PicklistSchema, PicklistExtensionSchema, translateObject, DEFAULT_METADATA_TYPE_REGISTRY) resolve. gen:checklist-status: self-test 28 pass; records-forms 40 active / 2 planned; 264 active · 2 planned overall. checklist-select on the new id: 0 runnable, 1 PLANNED. check-skills-token-ratchet: 'examples-upgrade.md is 1188 tokens (ceiling 1197; headroom 9)', authored total 143461 to 143452, exit 0. check:skill-identifier-liveness OK (457 citations over 53 files). check:doc-authoring '53 published skill files clean'. check:nul-bytes OK, plus a manual control-byte scan of the 4 files (grep exit 1, none). check-governed-merges --branch HEAD: exit 3, GOVERNED, tier H, 2 of 4 paths (skills/** and docs/NORTH-STAR.md), 120 changed lines. Skill readings: examples-upgrade.md 119 to 119 lines, 4788 to 4751 bytes; package (all 10 SKILL.md) 4394 to 4394 lines. No ablation: docs-only, with no gate or test added. CI on 8e7420019e at 2026-09-30T20:38Z (one read, no polling): 33 check-runs, 10 success, 11 skipped, 12 in_progress, 0 failed.", "mcp_calls": "0", "api_writes": "4 REST writes in 3 relay dispatches through scripts/pm (transport dispatch, as objectstack-fleet[bot]): pr_create POST /repos/objectstack-ai/objectstack/pulls (draft #20938; 9303 bytes sent and stored, identical, re-read by REST and byte-equal); labels_add POST /repos/objectstack-ai/objectstack/issues/20938/labels (skip-changeset) plus assign POST /repos/objectstack-ai/objectstack/issues/20938/assignees (os-justin), via label-write.mjs, read back matching; comment POST /repos/objectstack-ai/objectstack/issues/19518/comments (this os-dev-report, via post-stamped.mjs). Plus 3 git pushes of the branch (the empty probe, then 2c41e486c8 and 8e7420019e), which are not REST writes.", "open_questions": [ { "question": "The card's NORTH-STAR text includes 客户按组织追加值 and its second item names org append, but ruling 5904864936 defers the per-organization overlay to its own sub-issue on a measured customer requirement. As authored, the overlay is on the road and on the checklist as a planned requirement. Keep it?", "options": [ "A: keep as authored. The line is verbatim, and records-forms.picklist-org-append is planned with a knownGaps entry naming the deferral. A planned item never runs and is never coverage, so nothing is claimed, but the overlay becomes a road item eligible for P2 under NORTH-STAR 优先级 rule 2 before a customer requirement is measured.", "B: trim the line to its phase-1 half and drop records-forms.picklist-org-append before this lands (an id that never landed is not a retired one). The overlay's line and item arrive with its sub-issue. The road then carries only ruled, scheduled work, at the cost of editing the card's dictated text." ], "recommendation": "A. The maintainer named per-organization extension as the motivating need on #18164 (the park's Restart-when). The design of record's verification sentence names it. The planned status is the ledger's honest form for a required-but-unbuilt capability. The maintainer merges this PR and can take B by deleting two strings." }, { "question": "The card groups 'locale switch relabels' with the org item. It was authored on the phase-1 item (picklist-shared-across-objects) instead. Accept?", "options": [ "A: as authored. Phase-1 behaviour (the translation face landed in #19518; resolution arrives with #19519) sits on the item #19519 can promote. Promotion is per item and needs a passing run, and #19519's acceptance sentence groups the relabel with phase 1.", "B: follow the card's grouping. The relabel then stays unverifiable until phase 2 lands, although it ships in phase 1." ], "recommendation": "A: B would leave a phase-1 capability with no runnable item." }, { "question": "Where in step ② should the new line sit? It is after the last records row (search), so it ranks below every existing records capability.", "options": [ "A: keep it last among the records rows. It is new, P2 and unbuilt, and the card says it is taken after the open product P0/P1.", "B: move it beside the forms row (表单能用 … 级联选项), grouping it with option behaviour and raising its rank." ], "recommendation": "A: 改它即改优先级, and the lowest-disruption placement is the one that raises nothing." } ], "out_of_scope_findings": [ "carrier: 承接者:无 · scripts/check-platform-checklist.mjs: the --self-test success line ('driven on fixtures rather than on a ledger that carries none of it') and two comments (BATTERY_PLANNED_STATUS roster note; selfTestPlannedStatus docblock) state the live ledger carries zero planned items. This PR makes that prose stale (2 planned); assertions are unaffected, 221 pass · noted, not filed (drift, not one of the three classes). Named in the PR's Acceptance notes.", "carrier: the daily platform-checklist-watchdog workflow (files or refreshes one issue while the gate is red) · check:platform-checklist is red on origin/main aaad682dbc for areas/identity-auth.json ABSENT SYMBOL packages/plugins/plugin-auth/src/auth-plugin.ts#twoFactor, identically before and after this diff · noted, not filed.", "carrier: the seat · the Path: lines on #19518 and #19519 still read 清单项待写. Once #20938 lands they can name records-forms.picklist-shared-across-objects and records-forms.picklist-org-append · noted, not filed.", "carrier: 承接者:无 · the #19518 card body cites 'ADR-0136 D2.4', but this repo's ADR registry has no 0136 (git grep ADR-0136 and 0136- give 0 hits in docs/adr). If it is a cloud ADR, AGENTS.md #13 spells it 'cloud ADR-0136'. Neither new item cites it · noted, not filed." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsRuling on report
5919353754(the Tier H docs PR) · 2026-09-30T20:42Zdomain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim5905425409.- Verified against GitHub: PR docs: shared picklist — NORTH-STAR feature line, two planned records-forms items, coverage waiver; upgrade skill stops claiming a connector sync ran #20938 is at head
8e7420019e, the head the report names. It has 4 files (+111 / -9), is a draft, is assigned to os-justin, carriesskip-changeset, and saysPart of #19518. The path face hits Tier H ondocs/NORTH-STAR.mdandskills/**, so the maintainer merges. - Q1 (keep the organization-append half on the road and the checklist): the seat's opinion is A. The line is this card's text verbatim. The card was filed under the maintainer's 「18164 同意」, and
plannedwith aknownGapsentry claims nothing. This is the maintainer's priority table, though (「改它即改优先级」). So the 维护者速读 puts the question to the maintainer, and B is two deletions at merge. - Q2 (locale relabel on the phase-1 item): A. Promotion is per item. picklist metadata kind — runtime: resolve
picklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519's acceptance sentence puts the relabel in phase 1. - Q3 (placement last among the records rows): A, as the seat's opinion. The 速读 names it, because the row order is the priority order.
- Out-of-scope findings:
- The stale "zero planned items" prose in
scripts/check-platform-checklist.mjsis recorded in the PR's acceptance notes. - The
twoFactorABSENT SYMBOL is red onmainbefore this diff; it is the watchdog's. - This card cites "ADR-0136 D2.4", which has no match in this repository. Noted.
- The
Path:lines on this card and picklist metadata kind — runtime: resolvepicklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519 are the seat's to update once this PR lands.
- The stale "zero planned items" prose in
- Next: the CI wait, then the at-tier review, because the diff has a
skills/**hunk. Then, at ACCEPT and in one act: the final 维护者速读 comment,needs-user-decisionon the PR, and review requests to both authorized approvers. The PR stays draft.
Generated by Claude Code
- Verified against GitHub: PR docs: shared picklist — NORTH-STAR feature line, two planned records-forms items, coverage waiver; upgrade skill stops claiming a connector sync ran #20938 is at head
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsos-dev-report
{ "issue": 19518, "status": "done", "branch": "claude/issue-19518-picklist-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/20938", "session": "session_01Sfe5YjBLwB9J3y8fvm2xq1", "premise_still_valid": true, "head": "cab0e1b557", "summary": "Cut round per coordinator message and review 5919896214 (PASS at 8e7420019e). The worktree was recreated at 8e7420019e and the route checked (transport dispatch). The coordinator asked for the smaller true edit of two; the four review cuts follow, one append-only commit cab0e1b557, with no main merge (main moved, but none of the five paths) and no rebase. (i) examples-upgrade.md: the smaller true edit was the template's chain line, '**Chain:** 16 → 17' to '16 → 18' (the chain the default `os migrate meta --from 16` replays: terminus max(17, MIGRATION_MAJORS) = 18). The walkthrough now matches sentence 1. The heading 'Protocol 16 → 17 upgrade' and 'replay-from-17 applies 0' stay true under SKILL.md's own box: `--to` defaults one past the installed major, and replay-from-17 applies nothing once the 18-step edits are ported. It is a same-length edit: 4751 bytes, 1188 tokens, 119 lines. (ii) 'nothing outside packages/spec reads a picklist' became 'no runtime reads a picklist' in the records-forms history (≈:4234) and the coverage waiver (≈:229). Measured at 8e7420019e: objectql, metadata, metadata-core, metadata-protocol, runtime and rest src (non-test) carry the word 3 times, all in comments. The CLI's walkPicklists (i18n-extract.ts) reads picklists only to emit translation keys. (iv) scripts/check-platform-checklist.mjs: FOUR sentences, not three, said the live ledger has zero planned items: the :1059 roster comment, the :2280 docblock, the :2541 self-test success string and the :2622 comment ('planned count is the 0 this gate prints'). Each now states the true condition, that no coverage.json entry maps a planned item, which is why the fixtures are still the only witness. The :2541 string lost 'rather than on a ledger that carries none of it'. No test pins that text: git grep outside the file gives 0 hits, and no *.test.* names the script. Not changed: the same success line's 'the N live items are judged exactly as before' now counts the 2 planned items among N; the non-planned items are judged as before. (iii) The PR body was NOT edited. os-dev.md says a dev writes the body once, at pr_create, never PATCHes it, and names the edits for the seat to write. The seat's own adoption in 5919896214 says it writes the final 速读 at ACCEPT. This conflicts with the coordinator's instruction to edit the body; the standard wins, and the exact edits are in open_questions[0] for the seat. The PR is now 5 files, +119/-17, still Tier H (2 of 5 paths). The worktree is removed after this report.", "tests": "At head cab0e1b557; exit codes captured before any pipe. dispatch-gates --commands --repo objectstack-ai/objectstack derives 43 families (5 paths vs merge base aaad682db; +119/-17). All 43 ran. 42 exit 0, and check:platform-checklist exits 1 on the pre-existing twoFactor anchor: '1 problem(s)', only 'areas/identity-auth.json: ABSENT SYMBOL … auth-plugin.ts#twoFactor'; self-test 221 assertions pass, and its success line now reads 'the `planned` status is driven on fixtures — the accept set widened…'. check:doc-formula-expressions first exited 3 (no dist in the fresh worktree). It exits 0 after a locked build of formula and lint (os-verify-lock VERDICT command-exit 0, waited 155s, held 2s, 4/4 cached). check:pm-dispatch-gates exits 0: 'dispatch-gates self-test: 1976 cases pass', 1058.6s, run in the background and awaited in the foreground on its recorded PID. The script's own suite (rule ⑤) is its --self-test, which ran inside check:platform-checklist; no *.test.* names the script, and the derived self-test families (check-self-test-wired, check-self-test-workflow-commands, check-comment-mask-corpus, check-scripts-symbol-anchors, check-declaration-mirrors) all exit 0. dispatch-gates --ran: '43 derived famil(ies) accounted for — 43 run, 0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3)', exit 0. check-skills-token-ratchet exits 0: 'examples-upgrade.md is 1188 tokens (ceiling 1197; headroom 9)'. Skill readings: examples-upgrade.md 119 lines / 4751 bytes (unchanged by this round); all 10 SKILL.md 4394 lines. check-governed-merges --branch HEAD: exit 3, tier H, 2 of 5 paths, 136 changed lines. Control-byte scan of the 4 edited files: grep exit 1 (none). CI on cab0e1b557 at 2026-09-30T21:40Z, one read: 31 check-runs, 22 success, 8 skipped, 1 in_progress, 0 failed.", "mcp_calls": "0", "api_writes": "1 REST write in 1 relay dispatch: comment POST /repos/objectstack-ai/objectstack/issues/19518/comments (this os-dev-report, via post-stamped.mjs). Plus 1 git push (8e7420019e..cab0e1b557), which is not a REST write. No PR body edit, and no label or assignee write.", "open_questions": [ { "question": "The PR body edits this round owes, for the seat to write (the dev does not PATCH a PR body). Apply them at ACCEPT together with the final 速读?", "options": [ "A: the seat applies E1 to E8 verbatim. E1, first paragraph: 'Four files' becomes 'Five files'. E2, What changes: add item 5 '`scripts/check-platform-checklist.mjs`: four sentences said the live ledger carries zero planned items; they now say no coverage.json entry maps a planned item', and append to item 4 'The report template's chain line now reads 16 → 18, the chain the default run replays.' E3, the How section: 'no code outside `packages/spec` reads a picklist yet' becomes 'no runtime reads a picklist yet'. E4, Local verification: head cab0e1b557, 43 families, 43 run, 0 NOT-MEASURED; check:pm-dispatch-gates exit 0; governed 2 of 5 paths, +119 / -17. E5, Acceptance notes bullet 1 becomes '`scripts/check-platform-checklist.mjs` said in four places that the live ledger carries zero planned items; this PR corrects them (cab0e1b557). Carrier: this PR.' E6, 速读 改了什么 third bullet becomes 'upgrade 技能示例改正三处:第一句把处方指向一个已不存在的 `transform` 墓碑;第二、三句说连接器同步跑过、落过数据,实际从未有引擎跑过。报告模板的链改为 16 → 18。' E7, 速读 你要做的 becomes one action: '合并本 PR(Tier H:需您亲手合并,或给出授权的 APPROVED 后由席位落地)。' E8, 速读 风险与代价: '回滚是 revert 两个提交' becomes '回滚是 revert 三个提交'.", "B: the coordinator re-authorizes a dev PATCH of the body under os-dev.md's rule, and a later round applies A." ], "recommendation": "A: os-dev.md reserves body writes after pr_create to the seat, and the seat's adoption in 5919896214 already plans to write the final 速读 at ACCEPT." } ], "out_of_scope_findings": [ "carrier: this PR · the stale 'zero planned items' prose that last round's report gave as carrier none is now corrected here, in four places, not three · closed in cab0e1b557." ] }
Generated by Claude Code
objectstack-fleet commented
on Sep 30, 2026 ContributorMore actionsLanded: PR #20938 →
c1602ba429(the Tier H docs follow-up); the card closes · 2026-09-30T23:26Zdomain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim5905425409.- Approved and queued by os-zhuang: the review
5372844359atcab0e1b557is an authorized approval underGOVERNED_APPROVERS, and os-zhuang put the PR in the merge queue. The seat then removedneeds-user-decisionand withdrew the second review request. - Landed: merged at 2026-09-30T23:25Z as
c1602ba429, with one parent (f6ccca4a44, read withgit rev-list --parents). All 5 files have the same per-filegit patch-id --stableascab0e1b557against the merge baseaaad682dbc. - What this card delivered, now all on
main:- the spec layer: PR feat(spec): the
picklistmetadata kind — a shared option list select fields reference by name (#19518) #20823 →addbbf02ab; - the wording follow-up: PR docs(spec): say only what holds before the picklist reference is resolved (#19518) #20878 →
93d4e0ee6e; - this Tier H docs PR.
- The CLI sibling is picklist kind: the
osCLI compile / validate / lint path accepts*.picklist.ts,picklistsandpicklistExtensions, andos validaterefuses apicklistthat names no picklist (Scope 6 of #19518) #20825. The "neitheroptionsnorpicklist" question is decision card Aselect/radiofield with neitheroptionsnorpicklist: refuse it at theFieldSchemadoor (an accept-set narrowing), or keep it at the ADR-0078 completeness gate? (split from #19518) #20827, nowpm:blockedon objectui#11253. The runtime is picklist metadata kind — runtime: resolvepicklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519, which this close unblocks.
- the spec layer: PR feat(spec): the
Path:lines: this card's and picklist metadata kind — runtime: resolvepicklist→ options when serving field metadata, validate writes against the resolved set, apply package-level extensions (phase 1 of objectstack#18164) #19519's now namerecords-forms.picklist-shared-across-objectsandrecords-forms.picklist-org-appendinstead of 清单项待写.- Closing: the seat removes
pm:dispatchedand the assignee, then closes the card (completed).
Generated by Claude Code
- Approved and queued by os-zhuang: the review
- added 5 commits that reference this issue
on Oct 7, 2026
Path: 本地跑起来、看到 — records-forms.picklist-shared-across-objects, records-forms.picklist-org-append | P2
Sub-issue of objectstack#18164 (shared picklist / global value set), filed by the director seat, summon #25 (
session_012GcsUbuqFGBibkEDMRC1eE) under ruling batch #209 item 1 · letter A · maintainer 「18164 同意」 (2026-09-21, chat). ⛔ Not a claim. Position in the road: step ②「本地跑起来、看到」, records/studio; it is taken after the open product P0/P1 checklist items by the road order — ⛔ not dispatched before them. The design of record is the batch #147 item 2 ruling on the parent (comment 5715762696), reproduced here only where this layer needs it.Scope (the spec layer —
packages/spec, thedomain:specseat)picklist(name ruledpickliston the parent, ruling5904864936, batch 🔗 Broken links detected in documentation #251 item 3 · Q2 A):{ name, label, description?, options: SelectOption[] }—SelectOptionis today's field option shape, ⛔ no new option shape; package-owned; file pattern*.picklist.ts; registered beforeobjectin load order; a stack collection like any other metadata (registry row, JSON schema, manifest listing,allowRuntimeCreateper the ADR-0088 rules for authored kinds).Field.select({ picklist: 'industry' }), mutually exclusive withoptions: both on a select type is refused at the schema door with a prescription. (Neither: split to Aselect/radiofield with neitheroptionsnorpicklist: refuse it at theFieldSchemadoor (an accept-set narrowing), or keep it at the ADR-0078 completeness gate? (split from #19518) #20827 for the maintainer, seat ruling on this card, because refusing it narrows stored data.)options(so objectui's renderers, validation and filters are unchanged in phase 1); the spec declares that shape — the resolution itself is the runtime sub-issue.TranslationData.picklists.<name>.{ label?, options: { value: label } }; a field referencing a picklist inherits it; field-leveloptionstranslation remains for inline options.picklistExtensions: [{ extend, options }](theobjectExtensionsidiom), additive only — removal/rename stays with the owning package. The per-organization overlay (ADR-0005,allowOrgOverride) is phase 2 and ⛔ not declared here.osCLI compile / validate path accepts the new kind and refuses the two-or-neither case (CLI isdomain:cli; if the change lands inpackages/cliit is a sibling PR by that seat, filed from this card). Filed as picklist kind: theosCLI compile / validate / lint path accepts*.picklist.ts,picklistsandpicklistExtensions, andos validaterefuses apicklistthat names no picklist (Scope 6 of #19518) #20825; theos i18n extractwalk rides PR feat(spec): thepicklistmetadata kind — a shared option list select fields reference by name (#19518) #20823.Also with this card (Tier H, its own small docs PR, the maintainer merges)
The feature-map line in
docs/NORTH-STAR.md「路上的功能点」 step ② records group —records · 共享选项集:多个对象复用同一份选项,客户按组织追加值而不改应用源码 · records-forms · <the two new item ids>— and the tworecords-formschecklist items (one picklist, two objects; org A adds a value, A writes it, B is refused; locale switch relabels) authored underdocs/qa/platform-checklist/areas/records-forms.json(ADR-0136 D2.4). Until that PR lands the line reads清单项待写.Acceptance
Schema tests: the kind parses;
picklist+optionstogether refused (neither: #20827); the served field shape carries resolvedoptions; translation keys resolve;check:spec-*families green; changesetminor(new published kind). Not in v1: cascading picklists (per-optionvisibleWhen/dependsOnexist), unrestricted mode, per-record-type value restriction.Dedupe words: picklist, global value set, valueSet, shared select options, _picklists.ts, picklistExtensions.
Generated by Claude Code