You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
comments: the @mention picker offers a member who cannot read the thread, and the author is never told that person will not be notified #27703
Ruled: 6523848208 · letter A · 2026-10-30T13:23Z
Ruling-ref: 6523848208
Filing gate: ② a silent drop of what the author asked for. Split out of #27520 row 1, as triage 6495077487 directed: 「It becomes its own p2 card: a silent drop of the author's intent.」 Observed by the 18.3.0 RC walkthrough at c4c515ad. Mechanism read at origin/maina75ddba1. ⛔ Not a claim. Triage sets the lane.
Business reason
Who: anyone who @mentions a colleague in a record's Discussion. What happens: the picker offers a member who cannot read that thread. The comment saves with the mention, and the server withholds that person's notification. Nobody tells the author, so they believe the person was told when they were not. The rendered mention also looks like plain typed text.
Mechanism (read, not reproduced here)
Server:packages/plugins/plugin-audit/src/mention-recipient-gate.ts withholds a recipient for cannot_read_source or cannot_read_thread (~L84–92, L192). Its own docblock says the reason is 「Logged; never shown to the author」.
Either leave non-readers out of the picker, or tell the author after save which mentions will not be notified. Either way the author is no longer misled. The first needs a read the console does not make today (who can read this thread). The second needs the comment write to say which recipients were withheld. Both cross the server boundary, so this may split into a domain:server half and a domain:ui half. Rendering picked mentions as chips is the presentation half of the same row.
Dedupe
I read the 266 most recent issues by title for mention, cannot_read_thread and picker. The only hit is #27503 (a mention by email matched case-sensitively), which is a different defect. New.
⛔ Not a claim. This audit was owed: a filer's pm:queue with no triage audit.
Read fresh. The author must not believe a withheld person was told. If the picker can filter or the save answer can say "not notified" from what the client already reads, it stays domain:ui.
If it needs the server to name the withheld recipients in the comment-save answer, that is a new served key. The seat stops and returns it with pm:retriage as a Seam (「协议新增定 p1」).
Claim: PM loop round 1
Session: session_01Utp6CaJoinvGQSbHeDaWBe
Account: os-bill
Branch: claude/project-thread-jaslxp (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-27703
Domain: domain:ui
Seat: domain:ui#3
File surface: the mention/discussion region of ui/packages/app-shell/src/views/RecordDetailView.tsx, ui/packages/react/src/context/DiscussionContext.tsx, ui/packages/plugin-detail/src/RichTextCommentInput.tsx (chips, if taken), tests beside, root .changeset/, i18n for a new sentence (stop on breach; explain in the report)
Container & model: M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on 178b5238: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: ui code produces the defect | no platform path covers it | every Studio / console author reaches it today
Thread-read: 6514642798
Premise: holds
Serial constraints cleared: PRs #27636 and #27592 (record page, named by triage) merged 2026-10-29T20:03Z
Scope of this claim: measure first. Per triage (os-zhuang, 2026-10-30T04:00Z), if the fix needs a new served key (withheld recipients in the comment-save answer, or a who-can-read read), the thread stops before code and the seat returns the card with pm:retriage as a Seam. Only the mention/discussion region of RecordDetailView.tsx is in scope: seat 4's PR #27793 (apiHandler region) and seat 2's record page v4 PRs (#27920, #27545) are off limits, as are seat 4's #27912, #27907 and #27893 files.
Dispatched 2026-10-30T07:12Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
Reported 2026-10-30T07:16Z for #27703. No PR: the triage STOP case holds. Nothing the client already reads says who can read the thread or which mentions were withheld, so the fix needs a new served key. Seam below.
{
"issue": 27703,
"status": "needs_decision",
"branch": "claude/project-thread-jaslxp",
"pr": null,
"session": "session_01Utp6CY77T7uJxshsVS2zgc",
"premise_still_valid": true,
"summary": "Measured on origin/main 46943657, reading only. (1) The picker list is RecordDetailView.tsx L2492-2541: dataSource.find of sys_user, top 50, select id name email image, plus the viewer. It carries no record or thread readability. (2) The saves are handleAddComment / handleAddReply (L2925-3014, dataSource.create of sys_comment) and handleEditComment (L3040ff, dataSource.update). Each answers the stored row. sys_comment (sys-comment.object.ts) has no admitted or withheld field. (3) The gate runs inside the sys_comment afterInsert writer (audit-writers.ts writeCommentMentions, registered L2641). admitMentionRecipients returns the admitted ids only. A withheld recipient is only logged at warn, and MentionWithheldReason is documented as never shown to the author. Nothing is stamped on the row or put in the create answer, and the notification lands in the recipient's own inbox, which the author cannot read. (4) The only read on main that answers readability for ANOTHER user is POST /api/v1/security/explain. Its other-user arm (security-plugin-explain-access.ts L136-166) needs manage_users, organization administration of that user, or a delegated adminScope, and refuses an ordinary commenter with PermissionDeniedError. The record page asks it only for the viewer (useRecordEditable, queueClaim). The ui cannot derive readability itself: OWD, sharing, RLS, the tenant wall and the comment object's CRUD are server-side, and the gate's own docblock says nothing outside the evaluator derives it. So both routes the card names cross the server boundary. Per the ruling: stop before code, no PR.",
"tests": "No code, so no tests. Readings at origin/main 46943657: RecordDetailView.tsx L783 (state), L2492-2541 (directory read), L2925-3074 (create, reply, edit writes); DiscussionContext.tsx L28-66 (DiscussionMentionSuggestion is id, label, avatarUrl; no readability field); mention-recipient-gate.ts (whole file, L84-92 reason type, L172-180 verdicts); audit-writers.ts L2540-2641 (afterInsert only, admitted ids only); sys-comment.object.ts L141-259 (field list); security-plugin-explain-access.ts L136-166 (other-user refusal). Not measured: a live comment save against a running server. Reason: the reading leaves no client path to measure.",
"gates": "n/a. No diff, so dispatch-gates --commands derives nothing and check-sdui-manifest has nothing to read.",
"dogfood_battery": "n/a. No PR.",
"line_budget": "0. No diff.",
"files_changed": [],
"deviations": [
"No worktree and no pnpm install: no edit was made.",
"Read the card and code before the seat's start (reading only), then re-checked the newest Claim (6517141465, Branch claude/project-thread-jaslxp) after start."
],
"mcp_calls": "0",
"api_writes": "1. This report comment, through post-stamped (POST issues/27703/comments via the relay).",
"open_questions": [
{
"question": "Seam (protocol addition, triage asked for p1): which served answer tells the author a mention was withheld?",
"options": [
"A. The sys_comment create (and update) answer carries a response-only list of the mentioned user ids the gate withheld, with no reason. Server half (domain:server, plugin-audit): writeCommentMentions already holds admitted vs mentioned; it hands the withheld ids back on the write's answer for the AUTHOR's own request only. Spec half: the key is declared where the data write answer is typed (packages/spec), as a response-only key, not a stored sys_comment field, because a stored field would tell every reader of the comment who cannot read it. ui half that follows (domain:ui, this card): handleAddComment, handleAddReply and handleEditComment read the key, map ids to names through mentionSuggestions, and show one warning naming who will not be notified (new en/zh sentence plus packs), pinned with an ablation. Cost: server S-M, ui S.",
"B. A picker-time read: the server answers which candidates can read this record and the sys_comment object, and the picker leaves the others out. Cost: a new endpoint, one grant resolution per candidate per open, and it lets any commenter probe whether a named colleague can read a record. The thread arm (cannot_read_thread) can only be judged after the comment exists, so B still needs A to be exact.",
"C. Both: B for the picker, A as the exact answer at save."
],
"recommendation": "A, because it reuses the gate's own verdict (no second derivation of readability), is exact for both reasons, and only tells the author about people they named themselves. B can follow if the picker should also shrink."
}
],
"out_of_scope_findings": [
"class: a · reach: not measured live, read from code: the record page Edit rewrites mentions through dataSource.update (RecordDetailView.tsx handleEditComment), but the mention writer is registered on sys_comment afterInsert only (audit-writers.ts L2641, the handler returns unless ctx.event is afterInsert). So a mention added by editing a comment notifies nobody, even a reader, and the author is not told. Same silent drop of the author's intent as this card. Dedupe words: mention added on edit not notified, sys_comment afterUpdate mentions, edit comment mention notification. carrier: the seat, to fold into the server card that takes this Seam",
"carrier: #27703 · noted, not filed: rendering picked mentions as chips (plugin-detail RichTextCommentInput.tsx) is ui-only, but this run makes no PR; it belongs with the ui half after the Seam lands"
]
}
Dedupe words: mention withheld author not told, mention picker non-reader, comment save withheld recipients.
Per the triage, a new served key returns the card to triage. The card thread measured on origin/main46943657 (report 6517192427) and stopped before code. No PR exists and the branch is untouched.
Measured: the client holds nothing that answers "who will not be notified".
Picker candidates: they come only from the sys_user directory read (RecordDetailView.tsx ≈L2492–2541), which carries no readability.
Comment write answer: a comment create/update answers with the stored row, and sys_comment has no withheld field.
Mention gate:plugin-audit runs the gate in the afterInsert writer. It returns only the admitted recipients and logs the withheld ones at warn.
Readability check: the only read that answers "can another user read this" is the security/explain other-user branch. It needs manage_users, an org admin or a delegated adminScope, so an ordinary commenter is refused. The client can't infer readability itself.
Seam (the thread recommends A; the seat agrees):
A. The sys_comment create/update answer carries a response-only field, for the author's own request only: the ids of the mentioned users whose notification was withheld, with no reason.
Landing: plugin-auditwriteCommentMentions plus the spec's data-write answer type. Metadata-protocol added.
⛔ Not a stored field: that would show every reader who can't read the thread.
The ui half follows as a domain:ui card. The three write callbacks read it, map ids to names through mentionSuggestions, and say "X and Y will not be notified", with an ablation. Mention chips (RichTextCommentInput.tsx) ride with that ui half.
B. The server filters the picker to readers. Not recommended alone: it is costly, it can probe colleagues' permissions, and the thread arm can only be judged after the comment is stored.
Out of scope, from reading the code (not measured live): the mention writer hangs on afterInsert only, so an @ newly added by editing a comment notifies no one. Fold it into the server card that takes the Seam.
Labels: pm:dispatched → pm:retriage, and the seat's assignee is cleared. Triage sets the lane and priority (「协议新增定 p1」).
Director seat, summon #54 continuation 2 (ledger objectstack#12708, opening mark 6523423511). Presented to the maintainer in batch #431 as item 1 of 3 — triage's retriage answer 6517777140 grades Seam A and puts one point to the maintainer: whether the comment-write answer may tell the author, per named user and with no reason, that a mention was withheld (a disclosure about another user's access).
Seat increment (re-read at origin/main59547058, 2026-10-30T13:01Z):
Premises re-run, hold: the gate's reasons cannot_read_source / cannot_read_thread (mention-recipient-gate.ts L92–93), applied at L192, with the docblock "Logged; never shown to the author" (L84); the mention writer hangs on afterInsert only (audit-writers.ts L2641), so a mention added by editing notifies no one; sys_comment has no admitted / withheld field; the only read that answers another user's readability is security/explain's other-user arm, gated on manage_users / organization administration / adminScope (security-plugin-explain-access.ts L144 / L163). The client holds nothing that can answer "who will not be notified".
Prior rulings: triage 6514642798 (stays domain:ui only if the client already reads it — it does not), 6517777140 (Seam A, p1, Clause-②: yes). check-prior-rulings.mjs --card 27703 names ADR-0071 §1, ADR-0139 D3, ADR-0055 §4, ADR-0058 D6, ADR-0092 D1 — term matches; no ADR rules on mention disclosure.
Facets: ① the gate already holds the verdict; a response-only member on the author's own write reuses it with no second derivation of readability and nothing stored (a stored field would show every reader who cannot read the thread). ② every author who @mentions reaches it today (18.3.0 RC walkthrough, console: suggestions from the 18.3.0 RC browser walkthrough: mention and discussion feedback, list selection and bulk results, refusal wording, approvals inbox, dashboards and money formatting, and phone layout #27520 row 1). ③ the silent false belief ("I told them") is the error this closes; the answer is loud and exact for both reasons. ④ one response-only key, author's own request only, no reason text. The disclosure is one bit per user the author named — whether that person will be notified — which the author would otherwise learn by the colleague's silence; it does not say why, and it probes nothing the author did not already type. A′ (a count only, no ids) would be weaker: the author could not fix the mention.
Seat's letter: A, disclosure accepted — the sys_comment create and update answer carries, for the author's own request only, the ids of the mentioned users whose notification was withheld, with no reason; not a stored field; the edit-time mention (afterInsert only) folds into the server end; the ui half (name the users in one sentence; mention chips) follows as its own domain:ui card once the key is on main. Not B (a picker-time readability read: a new endpoint, one grant resolution per candidate per open, and it lets any commenter probe a colleague's access; the thread arm cannot be judged before the comment exists).
Workload of A: domain:spec Seam · 1 PR (the data-write answer type in packages/spec + plugin-auditwriteCommentMentions on insert and update) · S–M · Clause-②: yes, Metadata-protocol: added (a served key), p1 (「协议新增定 p1」) · then domain:ui 1 PR · S.
After the ruling: needs-user-decision → pm:queue (domain:spec, p1); the spec seat dispatches with Ruling-ref:; the ui card is filed by the spec seat on landing with the pointer.
Ruling: batch #431 item 1 · letter A · maintainer 「27703 同意」 2026-10-30T13:21Z
Director seat, summon #54 continuation 2 (ledger objectstack#12708, opening mark 6523423511, brief 6523467743). The maintainer answered in the summon chat, verbatim: 「27703 同意」 — the seat's letter A, with the disclosure accepted.
What the ruling binds (letter A): the sys_comment create and update answer carries, for the author's own request only, a response-only member listing the ids of the mentioned users whose notification was withheld by the mention gate, with no reason; it is never a stored field (a stored field would tell every reader who cannot read the thread). The disclosure is accepted as ruled: one bit per user the author named — whether that person will be notified — nothing more. The gate's verdict is reused; no second derivation of readability. The edit-time mention (the writer hangs on afterInsert only, so an @ added by editing notifies no one) folds into the server end of this Seam. The ui half — the three write callbacks read the member, map ids to names through the picker's suggestions and say in one sentence who will not be notified, with an ablation; mention chips in RichTextCommentInput.tsx — follows as its own domain:ui card once the key is on main. Not taken: B (a picker-time readability read: a new endpoint, per-candidate grant resolution on every open, and a probe of colleagues' access), C.
Governing text: triage 6514642798 and 6517777140 (Seam A, p1, Clause-②: yes); the gate's reasons and docblock (mention-recipient-gate.ts L84 / L92–93 / L192); security/explain's other-user arm (security-plugin-explain-access.ts L144) as the reason the client cannot answer it. Premises re-read at origin/main59547058 (brief 6523467743).
Workload of the letter:domain:spec Seam · 1 PR (the data-write answer type in packages/spec + plugin-auditwriteCommentMentions on insert and update) · S–M · Clause-②: yes, Metadata-protocol: added (a served key) · p1 (「协议新增定 p1」) · contract review at CONTRACT_REVIEW_TIER · then domain:ui 1 PR · S.
Execution:needs-user-decision → pm:queue in this act (domain:spec, priority:p1, area:records as triage set them); the spec seat dispatches with Ruling-ref: naming this comment and files the ui card with the pointer when the key lands.
os-decision-facets
① 长远:闸门已握判定,只读返回复用它,不落库、不二次推导
② 拉动:每个 @ 别人的作者今天都撞上(18.3.0 RC 走查,#27520 行 1)
③ 防错:消除「我已经告诉他了」的静默错误信念;披露限于作者自己点名的人、一比特、无原因
④ 不扩散:一个只读返回键,仅作者本人的请求
Claim: PM loop round 1
Session: session_01L9qibx5r5nhDMwpRs4SL6D
Account: os-tesla
Branch: claude/project-thread-z0obcm (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-27703
Domain: domain:spec
Seat: domain:spec#2
File surface: packages/spec/src/api/protocol.zod.ts (the data-write answer types CreateDataResponseSchema / UpdateDataResponseSchema, one response-only member) + tests and regenerated spec artefacts; packages/plugins/plugin-audit/src/audit-writers.ts (writeCommentMentions region and its sys_comment registration, insert and update); only if the transport needs it, the data-write path that builds the create/update answer (named in the report); tests beside; changesets. ⛔ No ui/**, no stored sys_comment field, no change to whom the gate admits (stop on breach; explain in the report)
Container & model: S–M, mode:thread, model: TIER_DEFAULT (Clause-②: yes ⇒ default judgment tier to build; the contract review at CONTRACT_REVIEW_TIER is the triage seat's), effort: xhigh (p1)
Clause-②: yes
Metadata-protocol: added
Responsibility: the server's mention gate withholds silently and no answer carries it (plugin-audit writeCommentMentions) | no platform path covers it (security/explain other-user arm refuses an ordinary commenter) | every author who @mentions in a record Discussion reaches it today (18.3.0 RC walkthrough, #27520 row 1)
Thread-read: 6523848208
Premise: holds (re-read at origin/main93242324: writeCommentMentions returns unless afterInsert, registered on afterInsert only; no withheld member on the data-write answer)
Serial constraints cleared: no open PR touches protocol.zod.ts or plugin-audit (29 open PRs read); seat 4's in-flight #27908 claims packages/plugins/plugin-audit/src/** for an action-invocation row, a different region of the same package: ordinary concurrency, the later lander merges main
Ruling-ref: 6523848208 (letter A, the maintainer's 「27703 同意」)
Dispatched 2026-10-30T14:04Z to a card thread of the seat's project; the order lives in the project. The ui half is not in this claim: the seat files it as its own domain:ui card once the key is on main. ⛔ The thread posts no claim and writes no assignee.
Amends claim 6524736722 (same session, same branch claude/project-thread-z0obcm). The card thread measured the transport at origin/main93242324: the engine already hands every after* hook the caller's own options bag, and createData / updateData already pass in-process listeners there and answer what they collect (onFieldsDropped, onValidationAdvisory). The withheld-mention ids ride that path, so the seat reads it as mechanism inside ruling 6523848208, not a second ruling.
File surface adds:
packages/spec/src/contracts/data-engine.ts (one in-process listener on the write options; never crosses the wire)
packages/metadata-protocol/src/protocol.ts (createData / updateData pass the listener and answer the ids, omitted when empty)
packages/objectql/src/engine.ts (the update option allowlist line and its drift pin)
Serial constraints for the added files: open PR #28128 (epic #8345, branch claude/project-thread-mzbmzo, draft) also touches packages/metadata-protocol/src/protocol.ts, a different region (the record-mode currency save). Ordinary concurrency: the later lander merges main. No other open PR touches the three files (open PR list read at this stamp).
Reported 2026-10-30T15:18Z for #27703. Draft PR #28174 at head 9a38b6c0.
{
"issue": 27703,
"status": "done",
"branch": "claude/project-thread-z0obcm",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28174",
"session": "session_01L9qibxkM6EsYLMNr5Vc8zP",
"premise_still_valid": true,
"summary": "Ruling 6523848208 letter A, built. The sys_comment create and update answers carry an optional response-only withheldMentions (user ids the mention gate withheld on this write, no reason, never stored), declared generically on CreateDataResponseSchema and UpdateDataResponseSchema. Transport: no new path; the engine already hands every after* hook the caller's options bag on ctx.input.options, so WriteObservabilityOptions gains an in-process listener onMentionsWithheld that the plugin-audit mention writer calls with the gate's own verdict (the gate's withhold() reports ids via an optional onWithheld callback; who it admits is unchanged), and createData/updateData answer it omit-when-empty. The writer now also runs on sys_comment afterUpdate and judges only the mentions the edit added against ctx.previous.",
"tests": "head 9a38b6c0 (targeted re-run) and eb6b1469 (suites; the only change between them is a merge of origin/main touching packages/spec/src/api/storage*). plugin-audit test: Test Files 67/67, Tests 1089/1089 (first run red on audit-writers.test.ts gate-input pin, fixed, 118/118). metadata-protocol test: 284 passed + 4 skipped files, 21859 passed + 26 skipped tests. objectql test: 495/495 files, 9631/9631 tests. spec test: 757/757 files, 22520 passed + 1 todo. typecheck spec, plugin-audit, metadata-protocol, objectql: lock VERDICT command-exit 0. On 9a38b6c0: spec contract 16/16, objectql transport + option 32/32, plugin-audit gate integration + audit-writers 145/145. Ablations via scripts/ablation-replace.mjs, each restored to blob == HEAD: A1 writer listener call removed -> 4 failed/27; A1b added-only filter removed -> 2 failed/27; A1c afterUpdate registration deleted -> 1 failed/27; A2 createData answer key renamed, metadata-protocol rebuilt, ablation-dist-preflight marker present -> 2 failed/7, restore rebuilt, marker absent -> 7/7; A3 per-request set hoisted process-wide, rebuilt, preflight present -> 3 failed/7, restore rebuilt, absent -> 7/7.",
"gates": "dispatch-gates --commands at eb6b1469: 113 families, each run with stdin from /dev/null, exit codes recorded before any pipe (record: /mnt/project-files/spec-seat-2/r2026-10-30/out/27703-gates-ran-9a38b6c0.list). --ran: 113 derived, 110 run, 3 NOT MEASURED, 0 unrun, 0 red. NOT MEASURED (exit 3, prerequisite not met): check:i18n (CLI build closure), check:dual-build-cjs-loads (whole-repo build), spec check:skill-examples (client SDK dist). check-plugin-teardown-shape --self-test first exit 3 (pinned control 621a4876 absent from the shallow clone), re-run after fetching that commit: exit 0, 48 cases; record carries the re-run. After the final merge: spec rebuilt, spec check:generated exit 0 (14/14 up to date). Re-derivation at eb6b1469 equals the swept set. CI check-runs on #28174: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"line_budget": "+592 / -28 across 17 files at 9a38b6c0 vs origin/main merge base",
"files_changed": [
".changeset/27703-withheld-mentions-answer.md",
"content/docs/api/data-api.mdx",
"content/docs/kernel/contracts/data-engine.mdx",
"content/docs/references/api/protocol.mdx",
"packages/metadata-protocol/src/protocol.ts",
"packages/objectql/src/engine-unknown-option.test.ts",
"packages/objectql/src/engine.ts",
"packages/objectql/src/protocol-withheld-mentions-answer.test.ts",
"packages/plugins/plugin-audit/src/audit-writers.test.ts",
"packages/plugins/plugin-audit/src/audit-writers.ts",
"packages/plugins/plugin-audit/src/mention-recipient-gate.integration.test.ts",
"packages/plugins/plugin-audit/src/mention-recipient-gate.ts",
"packages/spec/authorable-surface/api.json",
"packages/spec/src/api/protocol.zod.ts",
"packages/spec/src/api/write-answer-withheld-mentions.test.ts",
"packages/spec/src/contracts/data-engine.ts",
"packages/spec/src/data/hook-api.ts"
],
"deviations": [
"File surface beyond the claim's two files: metadata-protocol protocol.ts, objectql engine.ts and spec contracts/data-engine.ts (added by the seat's claim amendment), plus spec data/hook-api.ts (one docblock word list), objectql engine-unknown-option.test.ts (drift pin), a new objectql transport test file, and two hand-written docs pages (content/docs/api/data-api.mdx, content/docs/kernel/contracts/data-engine.mdx). No governed path, no ui/**.",
"The derived sweep ran while later commits (an audit-writers.test.ts fix, the docs pages) landed; re-derivation at eb6b1469 gave the identical 113-family set, and after the final main merge only the spec rebuild, check:generated and the targeted files were re-run, not the full sweep.",
"Worktree: the shared checkout held the designated branch, so it was detached and the branch checked out in a dedicated worktree (objectstack-issue-27703).",
"test:repo (vitest repo project) not run locally; CI's.",
"First push of 64d49655 reported a failed ref update; an immediate re-push succeeded with no change."
],
"mcp_calls": "3 — mcp__github__issue_read x3 (get, get_comments x2); 0 writes",
"api_writes": "2 — relay pr_create (objectstack-ai/objectstack#28174, read-back identical, 13691 bytes), this comment via post-stamped",
"open_questions": [],
"out_of_scope_findings": [
"carrier: the seat · noted, not filed: batch create (createManyData / batchData), clone and flow-written comments still notify readers but do not answer withheldMentions; the ruling names create and update only",
"carrier: the seat · noted, not filed: an edit by someone other than the comment's author is judged and titled with author_id as the actor, unchanged from the insert path",
"carrier: #27703 ui half · the seat files the domain:ui card (read withheldMentions in the three Discussion write callbacks, name the users in one sentence, mention chips) once the key is on main"
]
}
Activity
objectstack-fleet commentedon Oct 30, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 业务对象与记录 | none | P②
Triage: p2 ·
domain:ui·area:records· audit · 2026-10-30T04:00Z⛔ Not a claim. This audit was owed: a filer's
pm:queuewith no triage audit.domain:ui.pm:retriageas a Seam (「协议新增定 p1」).pm:queuestands.Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
Claim: PM loop round 1
Session:
session_01Utp6CaJoinvGQSbHeDaWBeAccount:
os-billBranch:
claude/project-thread-jaslxp(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-27703Domain:
domain:uiSeat:
domain:ui#3File surface: the mention/discussion region of
ui/packages/app-shell/src/views/RecordDetailView.tsx,ui/packages/react/src/context/DiscussionContext.tsx,ui/packages/plugin-detail/src/RichTextCommentInput.tsx(chips, if taken), tests beside, root.changeset/, i18n for a new sentence (stop on breach; explain in the report)Container & model:
M,mode:thread,model: TIER_DEFAULT(dispatch-gates --tieron178b5238: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: ui code produces the defect | no platform path covers it | every Studio / console author reaches it today
Thread-read: 6514642798
Premise: holds
Serial constraints cleared: PRs #27636 and #27592 (record page, named by triage) merged 2026-10-29T20:03Z
Scope of this claim: measure first. Per triage (os-zhuang, 2026-10-30T04:00Z), if the fix needs a new served key (withheld recipients in the comment-save answer, or a who-can-read read), the thread stops before code and the seat returns the card with
pm:retriageas a Seam. Only the mention/discussion region ofRecordDetailView.tsxis in scope: seat 4's PR #27793 (apiHandlerregion) and seat 2's record page v4 PRs (#27920, #27545) are off limits, as are seat 4's #27912, #27907 and #27893 files.Dispatched 2026-10-30T07:12Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.
Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CY77T7uJxshsVS2zgc
os-dev-report
Reported 2026-10-30T07:16Z for #27703. No PR: the triage STOP case holds. Nothing the client already reads says who can read the thread or which mentions were withheld, so the fix needs a new served key. Seam below.
{ "issue": 27703, "status": "needs_decision", "branch": "claude/project-thread-jaslxp", "pr": null, "session": "session_01Utp6CY77T7uJxshsVS2zgc", "premise_still_valid": true, "summary": "Measured on origin/main 46943657, reading only. (1) The picker list is RecordDetailView.tsx L2492-2541: dataSource.find of sys_user, top 50, select id name email image, plus the viewer. It carries no record or thread readability. (2) The saves are handleAddComment / handleAddReply (L2925-3014, dataSource.create of sys_comment) and handleEditComment (L3040ff, dataSource.update). Each answers the stored row. sys_comment (sys-comment.object.ts) has no admitted or withheld field. (3) The gate runs inside the sys_comment afterInsert writer (audit-writers.ts writeCommentMentions, registered L2641). admitMentionRecipients returns the admitted ids only. A withheld recipient is only logged at warn, and MentionWithheldReason is documented as never shown to the author. Nothing is stamped on the row or put in the create answer, and the notification lands in the recipient's own inbox, which the author cannot read. (4) The only read on main that answers readability for ANOTHER user is POST /api/v1/security/explain. Its other-user arm (security-plugin-explain-access.ts L136-166) needs manage_users, organization administration of that user, or a delegated adminScope, and refuses an ordinary commenter with PermissionDeniedError. The record page asks it only for the viewer (useRecordEditable, queueClaim). The ui cannot derive readability itself: OWD, sharing, RLS, the tenant wall and the comment object's CRUD are server-side, and the gate's own docblock says nothing outside the evaluator derives it. So both routes the card names cross the server boundary. Per the ruling: stop before code, no PR.", "tests": "No code, so no tests. Readings at origin/main 46943657: RecordDetailView.tsx L783 (state), L2492-2541 (directory read), L2925-3074 (create, reply, edit writes); DiscussionContext.tsx L28-66 (DiscussionMentionSuggestion is id, label, avatarUrl; no readability field); mention-recipient-gate.ts (whole file, L84-92 reason type, L172-180 verdicts); audit-writers.ts L2540-2641 (afterInsert only, admitted ids only); sys-comment.object.ts L141-259 (field list); security-plugin-explain-access.ts L136-166 (other-user refusal). Not measured: a live comment save against a running server. Reason: the reading leaves no client path to measure.", "gates": "n/a. No diff, so dispatch-gates --commands derives nothing and check-sdui-manifest has nothing to read.", "dogfood_battery": "n/a. No PR.", "line_budget": "0. No diff.", "files_changed": [], "deviations": [ "No worktree and no pnpm install: no edit was made.", "Read the card and code before the seat's start (reading only), then re-checked the newest Claim (6517141465, Branch claude/project-thread-jaslxp) after start." ], "mcp_calls": "0", "api_writes": "1. This report comment, through post-stamped (POST issues/27703/comments via the relay).", "open_questions": [ { "question": "Seam (protocol addition, triage asked for p1): which served answer tells the author a mention was withheld?", "options": [ "A. The sys_comment create (and update) answer carries a response-only list of the mentioned user ids the gate withheld, with no reason. Server half (domain:server, plugin-audit): writeCommentMentions already holds admitted vs mentioned; it hands the withheld ids back on the write's answer for the AUTHOR's own request only. Spec half: the key is declared where the data write answer is typed (packages/spec), as a response-only key, not a stored sys_comment field, because a stored field would tell every reader of the comment who cannot read it. ui half that follows (domain:ui, this card): handleAddComment, handleAddReply and handleEditComment read the key, map ids to names through mentionSuggestions, and show one warning naming who will not be notified (new en/zh sentence plus packs), pinned with an ablation. Cost: server S-M, ui S.", "B. A picker-time read: the server answers which candidates can read this record and the sys_comment object, and the picker leaves the others out. Cost: a new endpoint, one grant resolution per candidate per open, and it lets any commenter probe whether a named colleague can read a record. The thread arm (cannot_read_thread) can only be judged after the comment exists, so B still needs A to be exact.", "C. Both: B for the picker, A as the exact answer at save." ], "recommendation": "A, because it reuses the gate's own verdict (no second derivation of readability), is exact for both reasons, and only tells the author about people they named themselves. B can follow if the picker should also shrink." } ], "out_of_scope_findings": [ "class: a · reach: not measured live, read from code: the record page Edit rewrites mentions through dataSource.update (RecordDetailView.tsx handleEditComment), but the mention writer is registered on sys_comment afterInsert only (audit-writers.ts L2641, the handler returns unless ctx.event is afterInsert). So a mention added by editing a comment notifies nobody, even a reader, and the author is not told. Same silent drop of the author's intent as this card. Dedupe words: mention added on edit not notified, sys_comment afterUpdate mentions, edit comment mention notification. carrier: the seat, to fold into the server card that takes this Seam", "carrier: #27703 · noted, not filed: rendering picked mentions as chips (plugin-detail RichTextCommentInput.tsx) is ui-only, but this run makes no PR; it belongs with the ui half after the Seam lands" ] }Dedupe words: mention withheld author not told, mention picker non-reader, comment save withheld recipients.
Generated by Claude Code
objectstack-fleet commentedon Oct 30, 2026
domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe
Seam →
pm:retriage· 2026-10-30T07:17ZPer the triage, a new served key returns the card to triage. The card thread measured on
origin/main46943657(report 6517192427) and stopped before code. No PR exists and the branch is untouched.Measured: the client holds nothing that answers "who will not be notified".
sys_userdirectory read (RecordDetailView.tsx≈L2492–2541), which carries no readability.sys_commenthas no withheld field.plugin-auditruns the gate in theafterInsertwriter. It returns only the admitted recipients and logs the withheld ones at warn.security/explainother-user branch. It needsmanage_users, an org admin or a delegatedadminScope, so an ordinary commenter is refused. The client can't infer readability itself.Seam (the thread recommends A; the seat agrees):
sys_commentcreate/update answer carries a response-only field, for the author's own request only: the ids of the mentioned users whose notification was withheld, with no reason.plugin-auditwriteCommentMentionsplus the spec's data-write answer type.Metadata-protocoladded.domain:uicard. The three write callbacks read it, map ids to names throughmentionSuggestions, and say "X and Y will not be notified", with an ablation. Mention chips (RichTextCommentInput.tsx) ride with that ui half.Out of scope, from reading the code (not measured live): the mention writer hangs on
afterInsertonly, so an @ newly added by editing a comment notifies no one. Fold it into the server card that takes the Seam.Labels:
pm:dispatched→pm:retriage, and the seat's assignee is cleared. Triage sets the lane and priority (「协议新增定 p1」).Generated by Claude Code
6 remaining items
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Brief-claimed-by: session_01Utp6CbQLcy8yg6vhJVXXi8 · batch #431 · 2026-10-30T13:01Z
Director seat, summon #54 continuation 2 (ledger objectstack#12708, opening mark 6523423511). Presented to the maintainer in batch #431 as item 1 of 3 — triage's retriage answer 6517777140 grades Seam A and puts one point to the maintainer: whether the comment-write answer may tell the author, per named user and with no reason, that a mention was withheld (a disclosure about another user's access).
Seat increment (re-read at
origin/main59547058, 2026-10-30T13:01Z):cannot_read_source/cannot_read_thread(mention-recipient-gate.ts L92–93), applied at L192, with the docblock "Logged; never shown to the author" (L84); the mention writer hangs onafterInsertonly (audit-writers.ts L2641), so a mention added by editing notifies no one;sys_commenthas no admitted / withheld field; the only read that answers another user's readability issecurity/explain's other-user arm, gated onmanage_users/ organization administration /adminScope(security-plugin-explain-access.ts L144 / L163). The client holds nothing that can answer "who will not be notified".domain:uionly if the client already reads it — it does not), 6517777140 (Seam A, p1,Clause-②: yes).check-prior-rulings.mjs --card 27703names ADR-0071 §1, ADR-0139 D3, ADR-0055 §4, ADR-0058 D6, ADR-0092 D1 — term matches; no ADR rules on mention disclosure.sys_commentcreate and update answer carries, for the author's own request only, the ids of the mentioned users whose notification was withheld, with no reason; not a stored field; the edit-time mention (afterInsertonly) folds into the server end; the ui half (name the users in one sentence; mention chips) follows as its owndomain:uicard once the key is onmain. Not B (a picker-time readability read: a new endpoint, one grant resolution per candidate per open, and it lets any commenter probe a colleague's access; the thread arm cannot be judged before the comment exists).domain:specSeam · 1 PR (the data-write answer type inpackages/spec+plugin-auditwriteCommentMentionson insert and update) · S–M ·Clause-②: yes,Metadata-protocol: added(a served key), p1 (「协议新增定 p1」) · thendomain:ui1 PR · S.needs-user-decision→pm:queue(domain:spec, p1); the spec seat dispatches withRuling-ref:; the ui card is filed by the spec seat on landing with the pointer.Prior rulings read: mention, withheld, cannot_read_thread, explain other-user → triage 6514642798, 6517777140; thread: 6517192427, 6517209852; repo: objectstack-ai/objectstack
objectstack-fleet commentedon Oct 30, 2026
director#1 · os-bill · session_01Utp6CbQLcy8yg6vhJVXXi8
Ruling: batch #431 item 1 · letter A · maintainer 「27703 同意」 2026-10-30T13:21Z
Director seat, summon #54 continuation 2 (ledger objectstack#12708, opening mark 6523423511, brief 6523467743). The maintainer answered in the summon chat, verbatim: 「27703 同意」 — the seat's letter A, with the disclosure accepted.
What the ruling binds (letter A): the
sys_commentcreate and update answer carries, for the author's own request only, a response-only member listing the ids of the mentioned users whose notification was withheld by the mention gate, with no reason; it is never a stored field (a stored field would tell every reader who cannot read the thread). The disclosure is accepted as ruled: one bit per user the author named — whether that person will be notified — nothing more. The gate's verdict is reused; no second derivation of readability. The edit-time mention (the writer hangs onafterInsertonly, so an @ added by editing notifies no one) folds into the server end of this Seam. The ui half — the three write callbacks read the member, map ids to names through the picker's suggestions and say in one sentence who will not be notified, with an ablation; mention chips inRichTextCommentInput.tsx— follows as its owndomain:uicard once the key is onmain. Not taken: B (a picker-time readability read: a new endpoint, per-candidate grant resolution on every open, and a probe of colleagues' access), C.Governing text: triage 6514642798 and 6517777140 (Seam A, p1,
Clause-②: yes); the gate's reasons and docblock (mention-recipient-gate.ts L84 / L92–93 / L192);security/explain's other-user arm (security-plugin-explain-access.ts L144) as the reason the client cannot answer it. Premises re-read atorigin/main59547058(brief 6523467743).Workload of the letter:
domain:specSeam · 1 PR (the data-write answer type inpackages/spec+plugin-auditwriteCommentMentionson insert and update) · S–M ·Clause-②: yes,Metadata-protocol: added(a served key) · p1 (「协议新增定 p1」) · contract review atCONTRACT_REVIEW_TIER· thendomain:ui1 PR · S.Execution:
needs-user-decision→pm:queuein this act (domain:spec,priority:p1,area:recordsas triage set them); the spec seat dispatches withRuling-ref:naming this comment and files the ui card with the pointer when the key lands.os-decision-facets
① 长远:闸门已握判定,只读返回复用它,不落库、不二次推导
② 拉动:每个 @ 别人的作者今天都撞上(18.3.0 RC 走查,#27520 行 1)
③ 防错:消除「我已经告诉他了」的静默错误信念;披露限于作者自己点名的人、一比特、无原因
④ 不扩散:一个只读返回键,仅作者本人的请求
objectstack-fleet commentedon Oct 30, 2026
domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D
Claim: PM loop round 1
Session:
session_01L9qibx5r5nhDMwpRs4SL6DAccount:
os-teslaBranch:
claude/project-thread-z0obcm(the card thread's designated push branch, the recorded platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-27703Domain:
domain:specSeat:
domain:spec#2File surface:
packages/spec/src/api/protocol.zod.ts(the data-write answer typesCreateDataResponseSchema/UpdateDataResponseSchema, one response-only member) + tests and regenerated spec artefacts;packages/plugins/plugin-audit/src/audit-writers.ts(writeCommentMentionsregion and itssys_commentregistration, insert and update); only if the transport needs it, the data-write path that builds the create/update answer (named in the report); tests beside; changesets. ⛔ Noui/**, no storedsys_commentfield, no change to whom the gate admits (stop on breach; explain in the report)Container & model:
S–M,mode:thread,model: TIER_DEFAULT(Clause-②: yes⇒ default judgment tier to build; the contract review atCONTRACT_REVIEW_TIERis the triage seat's),effort: xhigh(p1)Clause-②: yes
Metadata-protocol: added
Responsibility: the server's mention gate withholds silently and no answer carries it (plugin-audit
writeCommentMentions) | no platform path covers it (security/explainother-user arm refuses an ordinary commenter) | every author who @mentions in a record Discussion reaches it today (18.3.0 RC walkthrough, #27520 row 1)Thread-read: 6523848208
Premise: holds (re-read at
origin/main93242324:writeCommentMentionsreturns unlessafterInsert, registered onafterInsertonly; no withheld member on the data-write answer)Serial constraints cleared: no open PR touches
protocol.zod.tsorplugin-audit(29 open PRs read); seat 4's in-flight #27908 claimspackages/plugins/plugin-audit/src/**for an action-invocation row, a different region of the same package: ordinary concurrency, the later lander mergesmainRuling-ref: 6523848208 (letter A, the maintainer's 「27703 同意」)
Dispatched 2026-10-30T14:04Z to a card thread of the seat's project; the order lives in the project. The ui half is not in this claim: the seat files it as its own
domain:uicard once the key is onmain. ⛔ The thread posts no claim and writes no assignee.objectstack-fleet commentedon Oct 30, 2026
domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D
Claim amendment · file surface · #27703 · 2026-10-30T14:07Z
Amends claim 6524736722 (same session, same branch
claude/project-thread-z0obcm). The card thread measured the transport atorigin/main93242324: the engine already hands every after* hook the caller's own options bag, andcreateData/updateDataalready pass in-process listeners there and answer what they collect (onFieldsDropped,onValidationAdvisory). The withheld-mention ids ride that path, so the seat reads it as mechanism inside ruling 6523848208, not a second ruling.File surface adds:
packages/spec/src/contracts/data-engine.ts(one in-process listener on the write options; never crosses the wire)packages/metadata-protocol/src/protocol.ts(createData/updateDatapass the listener and answer the ids, omitted when empty)packages/objectql/src/engine.ts(the update option allowlist line and its drift pin)Serial constraints for the added files: open PR #28128 (epic #8345, branch
claude/project-thread-mzbmzo, draft) also touchespackages/metadata-protocol/src/protocol.ts, a different region (the record-mode currency save). Ordinary concurrency: the later lander mergesmain. No other open PR touches the three files (open PR list read at this stamp).objectstack-fleet commentedon Oct 30, 2026
domain:spec#2 · os-tesla · session_01L9qibxkM6EsYLMNr5Vc8zP
os-dev-report
Reported 2026-10-30T15:18Z for #27703. Draft PR #28174 at head
9a38b6c0.{ "issue": 27703, "status": "done", "branch": "claude/project-thread-z0obcm", "pr": "https://github.com/objectstack-ai/objectstack/pull/28174", "session": "session_01L9qibxkM6EsYLMNr5Vc8zP", "premise_still_valid": true, "summary": "Ruling 6523848208 letter A, built. The sys_comment create and update answers carry an optional response-only withheldMentions (user ids the mention gate withheld on this write, no reason, never stored), declared generically on CreateDataResponseSchema and UpdateDataResponseSchema. Transport: no new path; the engine already hands every after* hook the caller's options bag on ctx.input.options, so WriteObservabilityOptions gains an in-process listener onMentionsWithheld that the plugin-audit mention writer calls with the gate's own verdict (the gate's withhold() reports ids via an optional onWithheld callback; who it admits is unchanged), and createData/updateData answer it omit-when-empty. The writer now also runs on sys_comment afterUpdate and judges only the mentions the edit added against ctx.previous.", "tests": "head 9a38b6c0 (targeted re-run) and eb6b1469 (suites; the only change between them is a merge of origin/main touching packages/spec/src/api/storage*). plugin-audit test: Test Files 67/67, Tests 1089/1089 (first run red on audit-writers.test.ts gate-input pin, fixed, 118/118). metadata-protocol test: 284 passed + 4 skipped files, 21859 passed + 26 skipped tests. objectql test: 495/495 files, 9631/9631 tests. spec test: 757/757 files, 22520 passed + 1 todo. typecheck spec, plugin-audit, metadata-protocol, objectql: lock VERDICT command-exit 0. On 9a38b6c0: spec contract 16/16, objectql transport + option 32/32, plugin-audit gate integration + audit-writers 145/145. Ablations via scripts/ablation-replace.mjs, each restored to blob == HEAD: A1 writer listener call removed -> 4 failed/27; A1b added-only filter removed -> 2 failed/27; A1c afterUpdate registration deleted -> 1 failed/27; A2 createData answer key renamed, metadata-protocol rebuilt, ablation-dist-preflight marker present -> 2 failed/7, restore rebuilt, marker absent -> 7/7; A3 per-request set hoisted process-wide, rebuilt, preflight present -> 3 failed/7, restore rebuilt, absent -> 7/7.", "gates": "dispatch-gates --commands at eb6b1469: 113 families, each run with stdin from /dev/null, exit codes recorded before any pipe (record: /mnt/project-files/spec-seat-2/r2026-10-30/out/27703-gates-ran-9a38b6c0.list). --ran: 113 derived, 110 run, 3 NOT MEASURED, 0 unrun, 0 red. NOT MEASURED (exit 3, prerequisite not met): check:i18n (CLI build closure), check:dual-build-cjs-loads (whole-repo build), spec check:skill-examples (client SDK dist). check-plugin-teardown-shape --self-test first exit 3 (pinned control 621a4876 absent from the shallow clone), re-run after fetching that commit: exit 0, 48 cases; record carries the re-run. After the final merge: spec rebuilt, spec check:generated exit 0 (14/14 up to date). Re-derivation at eb6b1469 equals the swept set. CI check-runs on #28174: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "line_budget": "+592 / -28 across 17 files at 9a38b6c0 vs origin/main merge base", "files_changed": [ ".changeset/27703-withheld-mentions-answer.md", "content/docs/api/data-api.mdx", "content/docs/kernel/contracts/data-engine.mdx", "content/docs/references/api/protocol.mdx", "packages/metadata-protocol/src/protocol.ts", "packages/objectql/src/engine-unknown-option.test.ts", "packages/objectql/src/engine.ts", "packages/objectql/src/protocol-withheld-mentions-answer.test.ts", "packages/plugins/plugin-audit/src/audit-writers.test.ts", "packages/plugins/plugin-audit/src/audit-writers.ts", "packages/plugins/plugin-audit/src/mention-recipient-gate.integration.test.ts", "packages/plugins/plugin-audit/src/mention-recipient-gate.ts", "packages/spec/authorable-surface/api.json", "packages/spec/src/api/protocol.zod.ts", "packages/spec/src/api/write-answer-withheld-mentions.test.ts", "packages/spec/src/contracts/data-engine.ts", "packages/spec/src/data/hook-api.ts" ], "deviations": [ "File surface beyond the claim's two files: metadata-protocol protocol.ts, objectql engine.ts and spec contracts/data-engine.ts (added by the seat's claim amendment), plus spec data/hook-api.ts (one docblock word list), objectql engine-unknown-option.test.ts (drift pin), a new objectql transport test file, and two hand-written docs pages (content/docs/api/data-api.mdx, content/docs/kernel/contracts/data-engine.mdx). No governed path, no ui/**.", "The derived sweep ran while later commits (an audit-writers.test.ts fix, the docs pages) landed; re-derivation at eb6b1469 gave the identical 113-family set, and after the final main merge only the spec rebuild, check:generated and the targeted files were re-run, not the full sweep.", "Worktree: the shared checkout held the designated branch, so it was detached and the branch checked out in a dedicated worktree (objectstack-issue-27703).", "test:repo (vitest repo project) not run locally; CI's.", "First push of 64d49655 reported a failed ref update; an immediate re-push succeeded with no change." ], "mcp_calls": "3 — mcp__github__issue_read x3 (get, get_comments x2); 0 writes", "api_writes": "2 — relay pr_create (objectstack-ai/objectstack#28174, read-back identical, 13691 bytes), this comment via post-stamped", "open_questions": [], "out_of_scope_findings": [ "carrier: the seat · noted, not filed: batch create (createManyData / batchData), clone and flow-written comments still notify readers but do not answer withheldMentions; the ruling names create and update only", "carrier: the seat · noted, not filed: an edit by someone other than the comment's author is judged and titled with author_id as the actor, unchanged from the insert path", "carrier: #27703 ui half · the seat files the domain:ui card (read withheldMentions in the three Discussion write callbacks, name the users in one sentence, mention chips) once the key is on main" ] }feat(spec): withheldMentions wording, client mirror and changeset for #…
objectstack-fleet commentedon Oct 30, 2026
domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D
Landed in PR #28174 (
7811c3f6, 2026-10-30T17:17Z). The ui half named by ruling 6523848208 is filed as #28218.