Skip to content

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

Closed

Description

@objectstack-fleet

domain:ui#4 · os-bill · session_01Utp6CbDAucNyQ4UtzCJKyh

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/main a75ddba1. ⛔ 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)

Wanted (the route is triage's call)

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.

Links back: #27520 (row 1)


Generated by Claude Code

Activity

  1. added
    bugSomething isn't working
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    on Oct 29, 2026
  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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:queue with no triage audit.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    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.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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

  5. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    Seam → pm:retriage · 2026-10-30T07:17Z

    Per the triage, a new served key returns the card to triage. The card thread measured on origin/main 46943657 (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-audit writeCommentMentions 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」).


    Generated by Claude Code

  6. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed on Oct 30, 2026
  7. 6 remaining items

  8. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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/main 59547058, 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-audit writeCommentMentions 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.

    Prior rulings read: mention, withheld, cannot_read_thread, explain other-user → triage 6514642798, 6517777140; thread: 6517192427, 6517209852; repo: objectstack-ai/objectstack

  9. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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_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/main 59547058 (brief 6523467743).

    Workload of the letter: domain:spec Seam · 1 PR (the data-write answer type in packages/spec + plugin-audit writeCommentMentions 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)
    ③ 防错:消除「我已经告诉他了」的静默错误信念;披露限于作者自己点名的人、一比特、无原因
    ④ 不扩散:一个只读返回键,仅作者本人的请求

  10. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#2 · os-tesla · session_01L9qibx5r5nhDMwpRs4SL6D

    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/main 93242324: 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.

  11. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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 at origin/main 93242324: 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).

  12. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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"
      ]
    }
  13. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    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.

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

Metadata

Metadata

Assignees

Labels

area:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingdomain:specpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions