Skip to content

[Decision] ADR-0142 D3: inject the queue column on every ownership: 'user' object (the default, so every business object today) or only where an object opts in (Salesforce "Allow queues") #26359

Closed

Description

@objectstack-fleet

Ruled: 6429748166 · letter A · 2026-10-26T23:28Z

Filing gate: ② a decision only the maintainer can make. Filed by the director seat (session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708) after the maintainer asked, on 2026-10-26 in the director summon chat, 「帮我评估26337,是不是大部分业务对象都要加个字段?」 and 「salesforce也是这么设计的吗?」, then 「立决策卡」. ⛔ Not a claim. Reader: the lane that carries PR #26337 (#25769) — the ruling changes what that PR injects, or confirms it. Dedupe: REST list of the 124 newest open + closed issues, grep queue.*(column|inject|opt-in|allow queues|per-object) → 0 (control queue → 8); objectstack-ai/hotcrm#2395 and PR #26337 are the carrier, not duplicates. New.

维护者速读

ADR-0142 D3(已接受)规定:queue 列由 applySystemFields 注入到所有 ownership: 'user' 的对象上,与 owner_id 同一批。ownership 省略即为 user(object.zod.ts 的枚举默认),实测本仓 app-crm 6 个、app-showcase 19 个对象文件没有一个显式声明 ownership,sys_ 命名空间按既有规则跳过。所以 PR #26337 落地后,每一个业务对象都会多一列 queue(文本列,存队列机器名,系统列、可写、非 lookup)。这是 ServiceNow 的形状(assignment_group 在每张任务表上)。Salesforce 不是:它的 OwnerId 可以指向 User 或 Queue(多态 owner),而且队列按对象开关——队列只对「Allow queues」里勾选的对象(Lead、Case、Custom Object 等)可用,Account/Contact/Opportunity 不能进队列。本卡只裁一件事:列是「默认全注入」还是「对象显式打开才注入」。不裁 owner 多态(ADR Alternatives 2 已否,维护者接受合并问题 1 时已裁)。

One-sentence problem

After PR #26337 every business object in every app gets a queue column whether or not that object will ever sit in a queue; the alternative is an explicit per-object switch, which is one more permanent key and one more way for a queue to silently not apply.

Governing text

  • ADR-0142 D3 (docs/adr/0142-ownership-queue-membership-claim-and-assignment-rules.md): "applySystemFields injects queue … on exactly the objects it injects owner_id on (ownership: 'user'), and withholds it under the other three tiers." An eligible object declaring its own queue field is refused at registration (merge question 15).
  • ADR-0142 D1: "A queue is a named, organization-scoped set of people that records of any ownership: 'user' object can sit in." Queues are not bound to objects; assignment rules (D5) are declared per object.
  • ADR-0142 Alternatives 2 (owner points at the queue, Salesforce) and 3 (queue-item join, Dataverse): both rejected; merge question 1 restates the cost and was accepted by the maintainer when the ADR merged. This card does not reopen placement.
  • packages/spec/src/data/object.zod.ts ownership: z.enum(['user', 'business_unit', 'org', 'none']) — user is the default; the description says user "injects reassignable owner_id plus owning_business_unit_id".
  • ADR-0117 D1: the precedent — owning_business_unit_id is injected by the same ownership axis, default tier included, with no per-object opt-in. ADR-0078 forbids an inert column; ADR-0049 enforce-or-remove applies to any new switch.

Premises (re-check before ruling)

Options × real cost × effort

What Customer-visible consequence Effort
A — keep D3 as accepted: inject queue on every ownership: 'user' object Nothing changes; PR #26337 lands as designed. Every business object shows a system queue column in Studio field lists, exports and /meta; empty on objects nobody routes. One text column per table; no join, no extra read cost. An object that wants no queue column leaves the user tier (losing owner_id too) — the only escape, and a blunt one. None beyond PR #26337; one sentence added to ADR-0142 Open items recording this ruling.
B — Salesforce-style per-object switch: a new object key (e.g. queues: true) and queue is injected only where it is set ADR-0142 amendment (Tier H, maintainer approval) adding the key; object.zod.ts key + generated baselines + docs; applySystemFields condition; PR #26337 changes; the two example apps opt their routed objects in. Objects stay lean by default; a queue, assignment rule, move or claim targeting an object that did not opt in must be refused loudly at registration (a rule on a non-queueable object is a registration error), otherwise the switch is a silent no-op. Authors learn one more key; AI authors will forget it. Lane spec + objectql + sharing · 1 ADR amendment PR + 1 code PR (or one revision of #26337). No measured precedent for "new object-level boolean that gates an injected column"; the nearest is ADR-0117's tier extension, which landed as an enum value, not a switch. Estimate M.
C — inject only on objects a declared queue or assignment rule names (derived, no new author key) ADR-0142 amendment giving queue an objects: list (D1 today binds a queue to no object); injection becomes registration-order dependent (object registered before its queue gets the column later). Fewer columns, but whether an object has queue now depends on which packages are installed; moving a record into a queue whose object list does not cover it fails; a queue added in Setup at runtime cannot add a column to a live table without a schema migration. Lane spec + objectql + sharing + metadata registry · ADR amendment + code PR; touches registration ordering, which ADR-0142 deliberately avoided. Estimate L. No precedent for install-time-derived column injection.

Business meaning

  • A = ServiceNow: every task table has an assignment group field; routing is a property of the platform's work model, not of each table.
  • B = Salesforce: "Allow queues" is a per-object setting; most objects cannot be queued, and that is a deliberate product choice an admin makes once per object.
  • C = a column that appears when a package that routes the object is installed — closest to Dataverse's "enable queues for this table" but derived rather than declared.

Four axes (business standpoint)

os-decision-facets

  • ① 项目长远合理性:两年后平台的工作模型里,队列和责任人是同一轴上的两个落位(坐在队列里 / 由某人负责),任何有责任人的对象都应能进队列——这是 A。B 把「能否进队列」做成对象级特例,契约多一个永久键、注入规则多一条分支;C 把列的存在交给安装顺序,是最大的特例增生。参照:ServiceNow 任务表全带 assignment_group;Salesforce 的按对象开关是其多态 owner 时代的产物,而本仓已否定多态 owner(Alternatives 2)。
  • ② 实际业务拉动:今天撞上的是 HotCRM 的 case/lead 分流(#25769 的拉动方);没有任何客户要求「某对象不得进队列」。B/C 的拉动为零,是对列数的观感担忧。
  • ③ 防 AI 犯错:A 下出错只有一种形态——对象自己声明了 queue 字段,注册时响亮拒绝(D3 已定)。B 下 AI 写了分配规则却忘了开开关,若不加注册拒绝就是静默不生效;加了拒绝则多一条门。C 下错误形态是「换个安装顺序列就没了」,最难排查。
  • ④ 创业阶段不扩散:A 不新增任何声明键;B 新增一个必须永久维护、文档、校验、生成基线的键(ADR-0049 enforce-or-remove 立刻适用);C 新增 objects: 列表与注册序依赖。新增门禁默认否。

Prior rulings read: queue, ownership, owner_id, Allow queues → 8 hits (none on per-object opt-in); ADR-0142 D1/D3 + merge question 1 accepted; thread: objectstack-ai/hotcrm#2395, PR #26337.

Recommendation + confidence gap

A. ① alone picks A: the two-year platform shape is "any owned object can sit in a queue", and the maintainer already accepted D3 and merge question 1. B is not taken because its only gain is fewer empty columns, paid for with a permanent key and a new silent-failure face. C is not taken because it makes a system column's existence depend on install order.
Self-check: 只看①选 A;②③④ 是否翻转:否。
Gap: the seat has not measured what the empty queue column costs in Studio field lists and CSV exports (one extra system column alongside owner_id, created_by, owning_business_unit_id); if the maintainer's concern is that visible clutter rather than the schema, the remedy is a presentation rule for system columns, not an injection switch, and would be a separate card.

After the ruling

  • A: no code change. The lane carrying PR feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 adds one line to ADR-0142 "Open items" citing this ruling (Ruling-ref:) and lands it inside that PR (the ADR is Tier H; the PR is already a governed draft and lands by maintainer approval). Card closes completed on the PR's merge.
  • B: the lane opens an ADR-0142 amendment PR (Tier H) naming the key, the registration refusal for rules/queues on non-opted objects, and the example-app opt-ins; PR feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 is revised after the amendment merges. This card stays pm:queue as the amendment's carrier.
  • C: as B, plus a registration-ordering design in the amendment; the seat recommends against it and would ask for a second reading before any code.

Size: A: XS · B: M · C: L. Clause-②: no. Metadata-protocol: A none · B/C yes (new authorable key or list on object).

Related

objectstack-ai/hotcrm#2395 (parent, pm:dispatched); PR #26337 (draft implementing ADR-0142); ADR-0142 D1/D3/D5, Alternatives 2–3, merge question 1; ADR-0117 D1 (owning_business_unit_id injection, same axis); ADR-0078 (no inert column); ADR-0049 (enforce-or-remove).

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #403 · 2026-10-26T23:16Z

    Director seat, summon #51 continuation (ledger objectstack#12708). Filed by this seat at the maintainer's 「立决策卡」 and presented in batch #403 as item 1 of 2, beside PR #26337's governed-draft line (the PR that implements the clause this card asks about). The card body carries the six items and the facets block; nothing is restated here. Seat increment since filing:

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #403 item 1 · letter A · maintainer 「同意」 2026-10-26T23:25Z

    Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #403 with 「同意」 — the seat letter. Brief 6429607539. Letter A, ADR-0142 D3 stands as accepted: applySystemFields injects the queue column on every ownership: 'user' object (the default tier, so every business object in app-crm and app-showcase today), beside owner_id and owning_business_unit_id, and withholds it under the other three tiers; no per-object switch (Salesforce "Allow queues", the card's B) and no injection derived from queue or rule declarations (C). The maintainer's question that opened this card — 「是不是大部分业务对象都要加个字段?」 — is answered yes, by design, the ServiceNow shape the ADR's merge question 1 already chose. Not B (a permanent object key whose only gain is fewer empty columns, plus a silent-no-op face when an author forgets it) and not C (a system column whose existence would depend on install order).

    Workload of the chosen letter (card column): none beyond PR #26337 as it stands; one sentence in ADR-0142 "Open items" recording this ruling, carried inside PR #26337 (Tier H; the PR is a governed draft and lands by the maintainer's approval).

    Execution: the only act this ruling needs rides PR #26337, so this card closes completed in this act and the pointer goes on that PR; needs-user-decision leaves in the same stroke. Ruling-ref: names this comment — the lane cites it in the ADR line. Clause-②: no, Metadata-protocol: none.

  3. removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Oct 26, 2026
  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Closed completed by the director seat · 2026-10-26T23:29Z

    Ruled A by the maintainer (ruling 6429748166, 「同意」 to batch #403): ADR-0142 D3 stands, the queue column is injected on every ownership: 'user' object, no per-object switch. The one act the ruling needs — a sentence in ADR-0142 "Open items" citing the ruling — rides PR #26337 (pointer left on that PR). Nothing else to carry here.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions