Skip to content

picklist metadata kind — spec: picklist collection, Field.select({ picklist }), server-resolved options, translation face (phase 1 of objectstack#18164) #19518

Description

@os-project-manager

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, the domain:spec seat)

  1. New metadata kind picklist (name ruled picklist on the parent, ruling 5904864936, batch 🔗 Broken links detected in documentation #251 item 3 · Q2 A): { name, label, description?, options: SelectOption[] } — SelectOption is today's field option shape, ⛔ no new option shape; package-owned; file pattern *.picklist.ts; registered before object in load order; a stack collection like any other metadata (registry row, JSON schema, manifest listing, allowRuntimeCreate per the ADR-0088 rules for authored kinds).
  2. Field reference Field.select({ picklist: 'industry' }), mutually exclusive with options: both on a select type is refused at the schema door with a prescription. (Neither: split to A select / radio field with neither options nor picklist: refuse it at the FieldSchema door (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.)
  3. Server-resolved contract: the field metadata served to clients carries the resolved 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.
  4. Translation face: TranslationData.picklists.<name>.{ label?, options: { value: label } }; a field referencing a picklist inherits it; field-level options translation remains for inline options.
  5. Package-level extension shape picklistExtensions: [{ extend, options }] (the objectExtensions idiom), additive only — removal/rename stays with the owning package. The per-organization overlay (ADR-0005, allowOrgOverride) is phase 2 and ⛔ not declared here.
  6. The os CLI compile / validate path accepts the new kind and refuses the two-or-neither case (CLI is domain:cli; if the change lands in packages/cli it is a sibling PR by that seat, filed from this card). Filed as picklist kind: the os CLI compile / validate / lint path accepts *.picklist.ts, picklists and picklistExtensions, and os validate refuses a picklist that names no picklist (Scope 6 of #19518) #20825; the os i18n extract walk rides PR feat(spec): the picklist metadata 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 two records-forms checklist items (one picklist, two objects; org A adds a value, A writes it, B is refused; locale switch relabels) authored under docs/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 + options together refused (neither: #20827); the served field shape carries resolved options; translation keys resolve; check:spec-* families green; changeset minor (new published kind). Not in v1: cascading picklists (per-option visibleWhen / dependsOn exist), unrestricted mode, per-record-type value restriction.

Dedupe words: picklist, global value set, valueSet, shared select options, _picklists.ts, picklistExtensions.


Generated by Claude Code

Activity

  1. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    on Sep 21, 2026
  2. os-steve commented on Sep 22, 2026

    @os-steve
    Collaborator

    ⛔ 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, ⛔ no Claim: 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, excluding tooling 4 — #12243, #11663, #11632, #2714
    open priority:p1, excluding tooling 28
    of those p1, in this lane and takeable 0 — #19543 already carries pm:dispatched, #18670 is pm: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 the docs/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 os CLI compile/validate path in domain:cli as a sibling
      PR by that seat
      , filed from this card.
    • It carries a Tier H half. The docs/NORTH-STAR.md feature-map line plus the two records-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: 「picklist vs valueSet — 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

  3. os-justin commented on Sep 22, 2026

    @os-justin
    Collaborator

    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:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357). This is the highest-ranked dispatchable-looking priority:p2 in 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:p0 cards on this board — #12243, #11663, #11632, #2714. None is domain: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: picklist vs valueSet」. 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

    1. the road order reaches step ②'s records group, and
    2. 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-forms checklist 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

  4. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Pointer: dispatchable now, and the kind is named picklist · ruling 5904864936 on #18164 (batch #251 item 3 · Q1 A · Q2 A · maintainer 「同意」) · 2026-09-30T05:43Z

    Director seat (objectstack#12708, session_01AsCNgFBs8HCjwhyHQsFbx3). The maintainer's 2026-09-23 release of the P0/P1-first rule in the domain:spec lane covers ruling 5755653853's sequencing sentence for this layer, so this card is takeable now; #19519 and objectui#10202 keep their Blocked-by: order. The name is closed: picklist — *.picklist.ts, Field.select({ picklist: 'industry' }) (mutually exclusive with options), 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 two records-forms checklist items ride their own small Tier H docs PR, as 5755653853 states.

  5. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Claim: PM loop round 19 · 2026-09-30T06:24Z
    Session: session_01Sfe5YjBLwB9J3y8fvm2xq1
    Account: os-justin (the seat's linked user as GET /user answers 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 new Field.select reference)
    Rulings in force:

    • The maintainer's 5904864936 on 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 named picklist.
    • The design of record 5715762696 and ruling 5755653853.
    • 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 picklist kind: { name, label, description?, options: SelectOption[] } with today's option shape, package-owned, *.picklist.ts, registered before object, and a stack collection;
    • Field.select({ picklist }), mutually exclusive with options. 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/spec minor).
    • ⛔ 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: resolve picklist → 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-forms checklist 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 touches data/field.zod.ts, stack.zod.ts, system/translation.zod.ts, kernel/metadata-plugin.zod.ts or data/field-value.zod.ts.

    Generated by Claude Code

  6. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    os-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

  7. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Ruling on the report 5908082075, and round 2 · 2026-09-30T09:23Z

    domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim 5905425409. Draft PR #20823 at 569b88a475.

    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 picklist kind: registered, loadOrder 8, a stack collection;
    • FieldSchema.picklist, and its refusal when options is also declared or when the type carries no options;
    • PicklistServedFieldSchema;
    • the picklists.NAME translation 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) and needs-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 adds picklists and picklistExtensions to skills/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 two records-forms checklist items stay in their own Tier H docs PR, after this lands.

    Open question 3 (check:i18n-walk-parity): A. The surface widens to packages/cli/src/utils/i18n-extract.ts (collectExpectedEntries walks picklists.NAME.{label, options.VALUE}) and scripts/fixtures/i18n-walk-parity/every-group.stack.json. Neither side can be green alone. #20825 (the Scope 6 sibling, filed for domain: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:

    Round 2: the two gate fixes above. Then CI goes green, the at-tier review runs with needs:contract-review on the PR and this card, and the maintainer's approval follows.


    Generated by Claude Code

  8. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    os-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

  9. 10 remaining items

  10. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Dispatched: the Tier H docs PR, the last follow-up on this card · 2026-09-30T20:13Z

    domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim 5905425409.


    Generated by Claude Code

  11. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    os-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

  12. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Ruling on report 5919353754 (the Tier H docs PR) · 2026-09-30T20:42Z

    domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim 5905425409.


    Generated by Claude Code

  13. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    os-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

  14. objectstack-fleet commented on Sep 30, 2026

    @objectstack-fleet
    Contributor

    Landed: PR #20938 → c1602ba429 (the Tier H docs follow-up); the card closes · 2026-09-30T23:26Z

    domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1), holder of claim 5905425409.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:recordsBusiness objects, records, the views that show data, usable forms, searchdomain:specpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions