Skip to content

Setup → Notification Preferences: Topic and Channel are free-text boxes, so muting one topic means typing its machine name — offer pickers over the topics and channels the platform knows (hotcrm#2194 T2-U15, the remainder) #25346

Closed

Description

@objectstack-fleet

维护者速读

Filing gate ③ a task the maintainer set: the maintainer's ruling on objectstack-ai/hotcrm#2194, recorded there at 6354968262 (the director seat, posting from the maintainer's account): 「25251 B hotcrm B」, 2026-10-23T01:05:47Z. That is letter B for all three rounds, exactly as the seat recommended, and it adopts T2-U15, ruled as a fold into #24775. That card closed completed on 2026-10-20T19:51Z, before the ruling, and its follow-ups landed part of this item but not all, so the remainder is filed here (see Why). Filed by the repo:hotcrm seat 1 (os-elon-musk, session session_014xanhPEmGTMTfVH4UokwJT) under objectstack-ai/hotcrm#2194's After the ruling. ⛔ Not a claim.

Grade: triage's. The seat suggests priority:p3: an adopted suggestion with a measured cost on an existing surface, no wrong data and no contract change.

Reader (who acts): objectstack triage routes and grades it. The landing below is the seat's reading of origin/main; paths under src/ are HotCRM's (objectstack-ai/hotcrm).

Governing text

Why (measured)

Landing

Read on objectstack origin/main 7b047b44:

  • packages/services/service-messaging/src/objects/notification-preference.object.ts: topic: Field.text ("Notification topic, or '' for all topics.", ~:124) and channel: Field.text ("Channel id (inbox/email/push/…), or '' for all channels.", ~:140).
  • Channels are the registered MessagingChannel.ids; topics are the sys_notification.topic values the platform and apps emit. The dev measures whether either set is enumerable today. Where none is, the field's help names where the values come from, and a picker over a set that does not exist is not built here.

Done when

  • New Notification Preference offers Channel as a choice among the registered channels plus "all", and Topic as a choice among the known topics plus "all", wherever the platform can enumerate them.
  • A typed value the platform cannot match stays refused or warned as today.
  • Pins on the field declarations.

Size: M.

Dedupe

Method: every open objectstack-ai/objectstack issue (108) and every issue updated since 2026-10-19 (544, any state), listed through the repo-scoped issues endpoint (paged) at 2026-10-23T01:20Z and matched case-insensitively on their titles. Words: notification preference, topic, channel. 5 hits, all closed: #24775 and #24895 (the carrier and its landed follow-up, above), #25194, #24983 and #24924 (other messaging fields). New.


Generated by Claude Code

Activity

  1. added
    area:workflowApprovals and automation — the work that runs without a person driving it
    bugSomething isn't working
    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed
    and removed on Oct 23, 2026
  2. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: card thread · domain:services seat 1 (seat post #6021, project run by the Sales account) · p2 · the whole card · 2026-10-23T12:51Z
    Session: session_01GsN1y3qWPdkVLasbhDB2Fy
    Account: os-sales (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-8hqiya (the harness-pinned branch for this session; it names no issue, so the Duplicate Fix Guard's branch-name hint will not match — this claim is the identity record)
    Worktree: objectstack-issue-25346
    Domain: domain:services
    Seat: domain:services#1 (seat post #6021)
    File surface (read on origin/main f0fdd45b; stop on a breach and explain it in the report):

    • packages/services/service-messaging/src/objects/notification-preference.object.ts: the topic and channel field declarations (the card's landing). The first act is the card's own measurement: whether either value set is enumerable today, and whether any field shape the platform declares can offer it as a picker. Where the shape of the answer is a public-contract choice (field type, stored wildcard spelling, an open channel seam), the dev stops and returns needs_decision instead of writing code.
    • packages/services/service-messaging/src/translations/: regenerated with node scripts/check-i18n-bundles.mjs --write when field help changes; zh-CN hand-translated.
    • Tests: pins on the two field declarations in the package.
    • One patch changeset for @objectstack/service-messaging if code lands.
    • Not packages/spec, not packages/metadata-protocol (the identity-index migration), not objectui.
      Container & model: M, card thread (in-session executor), model: default tier, effort: high
      Clause-②: no
      Metadata-protocol: none
      Basis for the Clause-② line: provisional, for the help-text landing the card allows where no set is enumerable; if the ruling picks a closed picker it becomes no (narrowing) and a superseding claim says so.
      Responsibility: n/a — not a defect card (an adopted UX suggestion, filing gate ③)
      Thread-read: none
      Serial constraints cleared: none (no open PR or in-flight claim declares notification-preference.object.ts)
      Resume-from: none

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25346,
      "status": "needs_decision",
      "branch": "claude/project-thread-8hqiya",
      "pr": null,
      "session": "session_01GsN1y3qWPdkVLasbhDB2Fy",
      "premise_still_valid": true,
      "summary": "Measured on origin/main f0fdd45b, before any code. Topic: no enumerable set exists. Topics are free strings at each emit site (14 in platform code: ten approval.* in plugin-approvals, collab.mention, security.access_upgrade, auth.phone_otp, auth.phone_invite; plus any string an app's notify step writes), so per the card the help names where values come from. Channel: a runtime set exists (service-messaging registers inbox always, email and sms while their transport is resolvable; nobody registers push), but no declarable field shape offers it as a picker without a contract change: a select option value is a SystemIdentifierSchema (lowercase, 2+ chars), so the stored wildcard '*' cannot be an option; a select is closed on the write path, while the channel seam is open by contract (MessagingChannel is exported from the package index and MessagingService.registerChannel is public). Whether Channel counts as enumerable, and whether to change the contract for it, is the fork.",
      "tests": "none — no code written (needs_decision before code, per os-dev)",
      "gates": "none run — no diff",
      "dogfood_battery": "n/a — no diff",
      "mcp_calls": "4 — read tools only: issue_read get, issue_read get_comments (25346, 25280), search_pull_requests",
      "api_writes": "2 — via the fleet-write relay: label-write (assign os-sales, pm:queue replaced by pm:dispatched), post-stamped claim comment",
      "open_questions": [
        {
          "question": "Channel: the platform knows its channels at runtime, but a picker needs a select, which cannot hold the '*' wildcard and would close the open MessagingChannel seam. Land help text, a closed select, or a spec-level suggestion list?",
          "options": [
            "A — both fields stay text; the help names the sources (channel: inbox always, email with an email service, sms with an SMS service, '*' for all; drop the unimplemented push. topic: the topic a notify step or platform feature sends, e.g. approval.requested, '*' for all); pins on both declarations; bundles regenerated. Clause-② no, Metadata-protocol none, patch, about S.",
            "B — channel becomes a closed select over inbox/email/sms with the wildcard re-spelled (e.g. all): boot conversion of stored '*' rows, resolver and digest/quiet-hours help follow (B2: a service-owned notification_channel picklist that channel plugins extend). Clause-② no (narrowing), BREAKING, full dogfood, M to L. Closes the public channel seam for preferences and leaves two wildcard spellings in one row.",
            "C — a spec-lane decision to carry suggestion options on text fields (field.zod.ts notes importing the settings specifier's demote-to-suggestions semantics onto fields is a second ruling), rendered by objectui as a combobox; then service-messaging declares suggestions. Not this card's lane."
          ],
          "recommendation": "A, because the channel seam is open by contract and '*' cannot be a select value, so B trades a 3-value dropdown for a breaking migration and a second wildcard spelling; the long-term shape for open vocabularies is C, which is a spec decision with no other measured pull. The card itself provides for A where the platform cannot enumerate. If a real dropdown is wanted, file C on the spec lane rather than doing B here."
        }
      ],
      "out_of_scope_findings": []
    }

    The four-axis analysis (Chinese) is with the services seat and the coordinator for the maintainer's batch.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: human (Sales) · letter A on the needs_decision in os-dev-report 6365345478 · 2026-10-23T13:08Z
    Ruled-by: Sales (os-sales, the owner of the project that runs this lane), in the project chat at 2026-10-23T13:07:33Z, answering the coordinator's A/B/C summary of the report above. Verbatim: 「A」
    Recorded by: the card thread (session session_01GsN1y3qWPdkVLasbhDB2Fy), via the fleet-write relay.

    What A means for this card (the report's option A, unchanged):

    1. topic and channel on sys_notification_preference stay text; no picker, no select, no stored-data change, nothing newly refused.
    2. The channel help names the channel ids this deployment can send on: inbox always, email when an email service is configured, sms when an SMS service is configured, and * for all channels. The unimplemented push is dropped from the help.
    3. The topic help names where topics come from: the topic a notify step or a platform feature sends (for example approval.requested), and * for all topics.
    4. Pins on both field declarations; translation bundles regenerated; one patch changeset for @objectstack/service-messaging. Clause-②: no, Metadata-protocol: none, as claim 6365308855 declared.
    5. A real dropdown over open vocabularies (option C, a spec-lane suggestion list on text fields) is not part of this card and is not filed by it.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 23, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:services seat 1 (seat post #6021) · os-sales · session_016g7nYP9wdNx1GDa5XDr7Uy · 2026-10-23T15:01Z

    reading value
    PR #25449 MERGED through the queue (ACCEPT 6367059213), head ad7975f4e5
    origin/main carries 8878c36a58

    State: the card was closed by Fixes #25346. pm:dispatched is off and the assignee is cleared. The card thread's slot is free.


    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:workflowApprovals and automation — the work that runs without a person driving itbugSomething isn't workingdomain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions