Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

The page-editor palette offers the legacy record:chatter and (as of the 17.1.0 pin) explicitly excludes the canonical record:discussion — the pair is advertised under the alias #5495

Closed

Description

@os-support-ai

Observation filed unassigned by the dev seat implementing the @objectstack/spec 17.1.0 pin bump (#5328). Not a defect that breaks anything today — the palette works — but the naming is inverted and someone should decide which way it points.

What was measured

record:chatter and record:discussion are the same renderer under two names — packages/plugin-detail/src/index.tsx:589 says so directly, and packages/core/src/registry/public-blocks.ts:57 records the direction:

record:chatter … as record:discussion under a Salesforce-familiar name, kept for schemas

So record:discussion is the canonical spelling and record:chatter is the compatibility alias. objectui has emitted the canonical one all along — packages/plugin-detail/src/synth/buildDefaultPageSchema.ts:731 is componentNode('record:discussion').

The metadata-admin palette, however, offers record:chatter (BLOCK_TYPE_META, labelled "Chatter feed") and had no entry for record:discussion at all, because spec 17.0.0's PageComponentType did not declare the canonical name. 17.1.0 added it (34 members before and after — element:filter left as record:discussion arrived, so the member count is unchanged and hides the swap).

That made block-config.test.ts's "every spec block type is either offered or explicitly excluded" fail on the pin bump, and #5328 resolved it the no-UX-change way: a PALETTE_EXCLUSIONS entry for record:discussion reading "same renderer as the offered record:chatter — one palette entry per renderer".

Why that resolution deserves a follow-up

It is correct as a pin-bump edit — offering both would put two identical blocks in the palette, and flipping which one is offered changes what authors drag — but it leaves the tree in a slightly odd state: the palette now explicitly excludes the canonical name and advertises the alias.

The decision

Either:

  • offer record:discussion, exclude record:chatter — palette matches the canonical spec name and the schema objectui itself emits; the alias stays renderable for existing schemas, just not advertised. Author-visible label probably stays "Discussion". Changes what new pages get authored with, which is the point.
  • keep it as is and record that "Chatter feed" is the deliberate author-facing name for the pair, in which case the exclusion comment is the whole story and this card closes as won't-fix.

Refs: #5328 (where it surfaced) · #4935 (the sibling element:filter residue in the same file).

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Aug 21, 2026
  2. added theissue type on Aug 21, 2026
  3. os-zhuang commented on Aug 21, 2026

    @os-zhuang
    Contributor

    Triage (first-touch): routed to the decision inbox (needs-user-decision, domain:ui, type Task). The palette currently advertises the compatibility alias and explicitly excludes the canonical name — which way it points changes what authors see and what new pages get authored with, an author-facing naming call on the manual floor (small, one-letter answer). Chinese four-facet analysis below.

    os-decision-facets(四棱卡面块;标记按字面文本写入)

    一句话问题:同一个「讨论/动态」组件有两个名字,官方正名是 discussion,兼容旧名是 chatter —— 而组件面板上架的偏偏是旧名,正名反被明示排除;新页面从此都用旧名写成。

    选项与真实代价:

    • A. 面板上架正名 discussion,排除旧名 chatter:业务上 = 作者拖出来的和平台自己生成的(buildDefaultPageSchema 一直发 discussion)终于一致;旧 schema 照常渲染,只是不再被推荐。真实代价:面板里的名字换了一次,老作者要适应一次;label 文案(「Chatter feed」→「Discussion」)同步换。
    • B. 维持现状,并把「Chatter feed 是刻意的作者面命名」记为裁决:业务上 = 沿用 Salesforce 熟悉感获客。真实代价:平台自产 schema 用正名、作者手拖用旧名,两套拼写长期并存;每个新读代码的人都要再问一遍这卡问的问题。
    • 四棱:① 长远合理性:A 收敛到单一正名,B 把别名永久化;② 业务拉动:今天无用户报障,但 17.1.0 起 spec 已声明正名 —— 方向已定,面板是最后一块没跟上的;③ 防 AI 犯错:A 让生成器与面板输出同一拼写,B 维持两套拼写并存,AI 学样本时各学一半;④ 不扩散:A 是一次性小改,B 零改但债续期。
    • 推荐:A(回退:B + 在排除注释里写明是刻意命名裁决)。回一个字母即可。

    置信缺口(本分析看不见什么):「Salesforce 熟悉感」对当前目标客户的实际获客价值无法从代码测得 —— 这正是要你裁的原因;存量用户页面里手拖 chatter 块的数量未测。裁后执行:A 则一张 S 卡(BLOCK_TYPE_META 换名 + PALETTE_EXCLUSIONS 反转 + block-config.test 断言随动 + 4935 姊妹残留顺检),B 则本卡关 won't-fix 并把裁决写进排除注释。


    Generated by Claude Code

  4. huangyiirene commented on Aug 22, 2026

    @huangyiirene
    Collaborator

    Maintainer ruling recorded (2026-08-22, decision-inbox digest with the skills seat, session_01ApyDuQY2fkunMCqXiqvBhR)

    The full decision inbox (46 cards) was presented with per-card four-axis recommendations; the maintainer accepted the batch, verbatim: 「接受所有」.

    Ruled: Option A — the palette offers the canonical name. record:discussion is offered in the page-editor palette and record:chatter becomes the explicitly excluded compatibility alias, inverting the current PALETTE_EXCLUSIONS state. The author-facing label changes from "Chatter feed" to "Discussion"; the alias stays renderable for existing schemas, just no longer advertised. Per the triage execution note this is an S-size card: BLOCK_TYPE_META rename, PALETTE_EXCLUSIONS inversion, the block-config.test.ts assertion following along, and a check of the #4935 sibling element:filter residue in the same file.

    State: needs-user-decision removed → pm:queue (ready for dispatch).


    Generated by Claude Code

  5. claude commented on Aug 23, 2026

    @claude
    Contributor

    Claim — domain:ui execution seat. PM round 29, session session_01EuPCi56cnGyykygi3z9w4m, branch claude/issue-5495-palette-canonical-discussion. Default tier.

    Executing the 2026-08-22 maintainer ruling: Option A — the palette offers the canonical name. record:discussion is offered; record:chatter becomes the explicitly excluded compatibility alias, inverting the current PALETTE_EXCLUSIONS state. The label moves "Chatter feed" → "Discussion". ⛔ The alias stays renderable for existing schemas — this changes what is advertised, not what works.

    S-size scope as the triage execution note records it: BLOCK_TYPE_META rename · PALETTE_EXCLUSIONS inversion · the block-config.test.ts assertion following along · and a check of the #4935 sibling element:filter residue in the same file.

    ⚠️ On that last item, read #4935's 2026-08-22 unlock comment before touching it: residue 1 no longer exists — PALETTE_EXCLUSIONS['element:filter'] was already deleted by #5529, which had to touch this same file once the enum member disappeared. So the check is to confirm that and report what (if anything) is left, ⛔ not to re-delete something already gone.

    Hot-file serialisation: #4935 is held behind this card — both land in packages/app-shell/src/views/metadata-admin/previews/block-types.ts.


    Generated by Claude Code

  6. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    os-dev-report

    {
      "issue": 5495,
      "status": "done",
      "branch": "claude/issue-5495-palette-canonical-discussion",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5838",
      "premise_still_valid": true,
      "summary": "Executed the 2026-08-22 maintainer ruling (Option A) in packages/app-shell/src/views/metadata-admin/previews/block-types.ts: BLOCK_TYPE_META now offers the canonical 'record:discussion' labelled \"Discussion\" (was 'record:chatter' / \"Chatter feed\"), and PALETTE_EXCLUSIONS now excludes 'record:chatter' as the compatibility alias — inverting the pair. Icon and category are unchanged. The alias stays fully renderable: nothing in plugin-detail was touched, and a new test (previews/__tests__/palette-discussion-alias.test.tsx) pins that the registry still resolves 'record:chatter' to the SAME renderer function object as the canonical name and that an alias schema still renders the discussion panel — so 'no longer offered' cannot drift into 'no longer rendered'. block-config.test.ts needed no edit and that is the point: it derives palette coverage from PageComponentType and is satisfied by either direction of this pair, which is why the direction now has a test of its own. Scope item 4 confirmed without acting: 'element:filter' has zero hits in block-types.ts on current main — #5529 already deleted PALETTE_EXCLUSIONS['element:filter'], exactly as #4935's 2026-08-22 unlock comment records; nothing re-deleted, #4935's remaining elements.tsx residue left alone. Changeset added (minor, @object-ui/app-shell) declaring the label change, the offered-block change, and the one knock-on below.",
      "tests": "All from repo root; gate union re-run on the FINAL commit 85c289455 with a clean tree. (1) SPEC PIN, counter-probed before relying on it — resolved @objectstack/spec = 17.2.0, PageComponentType.options = 34 members; 'record:discussion' -> true, 'record:chatter' -> true, 'record:details' -> true (known-present), 'element:filter' -> false (genuinely retired), 'zzNotARealType' -> false (never existed). Two trues and two falses from one probe, so a broken probe cannot read as passing. (2) TESTS: `pnpm exec vitest run <palette-discussion-alias.test.tsx> <block-config.test.ts>` -> 'Test Files 2 passed (2) / Tests 35 passed (35)', exit 0. Broader: `pnpm exec vitest run packages/app-shell/src/views/metadata-admin/previews apps/console/src/__tests__/public-contract.test.ts packages/app-shell/src/utils/__tests__/pageSchemaIntrospect.test.ts` -> 'Test Files 40 passed (40) / Tests 481 passed (481)', exit 0. (3) TYPECHECK: `pnpm --filter @object-ui/app-shell type-check` exit 0, with the script name echoed in the output ('> tsc --noEmit && tsc -p tsconfig.test.json') so it was not a zero-match no-op. First attempt exited 2 on TS2307/TS6305 unbuilt-closure errors only; fixed by `pnpm --filter '@object-ui/app-shell^...' build` (exit 0) — not a defect in this change. (4) REVERSE VERIFICATION on a real commit, never against uncommitted edits: committed 85c289455, then `git checkout origin/main -- block-types.ts`; mutation confirmed on disk by grepping BOTH the injected and the removed text (injected line count 0, reverted line count 1 — not a bare diff --stat), re-ran -> 'Tests 2 failed | 33 passed (35)', exit 1. Predicted direction was plain red and that is what happened. Restored with `git checkout HEAD -- block-types.ts`, re-confirmed on disk (injected 1, removed 0), `git diff HEAD --stat` EMPTY, re-ran -> 35 passed, exit 0. LEGS THAT DO NOT DISCRIMINATE, named: all 30 cases of block-config.test.ts stay green in both states (derived coverage, either direction satisfies it); the new file's 'both spellings are real members of the pinned spec enum' case (a fact about the spec, not about this change); and BOTH alias-renderability cases, deliberately — they assert the registry and renderer this PR does not touch, so they must be green before and after, and the day they go red the cause is a deleted registration. (5) GATES, each quoting its own verdict line, exit codes captured before any pipe: check:control-bytes 'OK (scanned 4855 tracked text file(s); skipped 85 binary)'; check:spec-symbols 'spec symbol derivation: 1298 files scanned against 4959 spec export names'; check:phantom-deps 'Every in-scope import is declared by the package that publishes it'; check:i18n-keys 'every in-scope call-site key resolves against the en pack (2928 keys)'; check:i18n-dead-keys (a REPORT, not a gate, per its own footer) exit 0; node scripts/check-changeset-presence.mjs '1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)' exit 0. (6) LINT: the touched package's own gate ran IN FULL, not narrowed — `eslint .` in @object-ui/app-shell, measured from --format json output: 939 files linted, 0 errors, 2599 warnings (the repo-wide un-capped baseline .github/workflows/lint.yml documents). One new warning, an `any` type-argument on a React.ComponentType annotation in the new test. DECLARED NARROWING: the other 39 packages' lint was not run locally. Invariance evidence rather than assumption — the root eslint.config.js enables no type-aware linting (tseslint.configs.recommended, no project/projectService in languageOptions), so an edit confined to packages/app-shell cannot move the verdict on any untouched file in another package. CI runs the whole farm regardless.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5837 (label `finding`, unassigned, no pm:queue): the page-block canvas draws a node's icon and colour tone from BLOCK_TYPE_META, so a type that renders fine but is excluded from the palette shows the generic UnknownBlockIcon and the neutral misc tone in the outline. Pre-existing, not introduced here — before this card it was the CANONICAL record:discussion that read this way, i.e. every page the platform generates for itself; this change moves it onto the rarer legacy alias, reducing how often it is seen without closing it. Not folded in: a fix needs a new alias-display mechanism, since a second BLOCK_TYPE_META entry would break block-config.test.ts's 'no type is both offered and excluded'. Disclosed in the changeset and the PR body.",
        "NOT FILED, reported here instead: block-types.ts carries a pre-existing unused import (`Bot`, line 33) — verified unchanged on origin/main, so not introduced by this PR. Left alone and deliberately not filed: it is one of 53 @typescript-eslint/no-unused-vars warnings in @object-ui/app-shell alone, part of the repo-wide warning baseline .github/workflows/lint.yml explicitly declines to cap ('--max-warnings is deliberately not set'). An issue for this single instance would duplicate a known and deliberately accepted stance rather than report anything new. Flagging it so the judgement is PM's, not silently mine."
      ]
    }

    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

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions