Skip to content

plugin-approvals: approval notifications name the record by its id — "Your Contract C8Mp7TjRYta8mOWx was approved." #26181

Closed

Description

@objectstack-fleet

Ruled: 6429362190 · letter A′ · 2026-10-26T23:01Z

Filing class: ② needs a maintainer re-ruling — it revisits ruling B of #23556 / #23594 ({{object}} {{record}} = object label + record id). Reach: public door, measured on 18.1.0 with objectstack-ai/hotclm main (pnpm demo:zh). Reader: the maintainer, then the approvals lane (plugin-approvals/src/translations/messages.ts, approval-notification-text.ts).

维护者速读

审批通知现在用记录 id 指代记录:「Approval requested — A decision on Contract C8Mp7TjRYta8mOWx is waiting on you.」「Your Contract C8Mp7TjRYta8mOWx was approved.」。收件人看不出是哪份合同,要点进去才知道。这是平台之前的裁决(#23556/#23594 方案 B)定下的写法,要改需要重新裁决。

Measured

All 11 notifications of one hotclm regression pass, read back from sys_notification: the four approval.requested, two approval.approved and one approval.rejected name the record as Contract <16-char id>. The app's own notifications in the same bell name it by title ("Contract approved: 回归测试 订单 25万(审批阶梯)").

Options

  • A — name the record by its display title (the object's title field, ADR-0079), id only when the title is empty or unreadable to the recipient.
  • B — title plus id ("Contract 回归测试 订单 25万 (C8Mp…)").
  • C — keep the id (current ruling).

Dedupe: objectstack issues (2,000 most recently updated, all states) grepped for {{record}}, record by its id, 23594 — neighbours #24375 / #24501 (object API name on the request page), none revisits this.


Filed from the hotclm browser regression thread (2026-10-26); maintainer: 「平台的问题应该提交issue到平台」.

Activity

  1. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · priority:p2 · domain:server · area:workflow · needs-user-decision · pm:awaiting-maintainer · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-26T15:56Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #402 · 2026-10-26T17:39Z

    Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #402 as item 2 of 2 (the two approvals cards filed from the hotclm browser regression thread). Seat increment (re-verified on origin/main cdd4eea9; the card and the triage leaning 6420598906 / 6420611091 are not restated):

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #402 item 2 · letter A′ · maintainer 「同意」 2026-10-26T23:00Z

    Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708). The maintainer answered batch #402 with 「同意」 — both seat letters. Brief 6423124361. Letter A′, the record's title per recipient: an approval notification (the in-app bell row and the email body — every surface rendered for one named recipient) names the record by its display title (ADR-0079 nameField, resolved as that recipient and narrowed by their field-level security), falling back to the record id when the title is empty or unreadable to them. The token-bearing action-link pages (action-link-pages.ts:54–62, read under the system context with no reader to narrow for) keep naming the record by object label and id — the #23594 reason stands there. This re-rules #23556 / #23594 letter B for the notification surfaces only; the maintainer's acceptance is the re-ruling. Not B (title plus id on every line; the id is the fallback, not a suffix) and not C.

    Workload of the chosen letter (card column): approvals lane · S — subjectParams / approval-notification-text.ts:64–84 gains a per-recipient title read reusing the request page's existing title resolution (ctx.title() / nameField), the message templates keep their {{object}} {{record}} shape, one test per fallback (empty title; title field unreadable to the recipient), and a dated note beside the #23594 comment in action-link-pages.ts saying the notification surfaces were re-ruled here.

    Execution: needs-user-decision → pm:queue in this act (domain:server, p2, area:workflow); pm:awaiting-maintainer removed in the same stroke. Ruling-ref: names this comment; Clause-②: no, Metadata-protocol: none.

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 8 · card thread
    Session: session_01R1q2xdtYgU6FKrZ7LgjPCC (the seat); the card thread is session_01Kfr6fhXWwYppMd27Z6fPM8
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-tlbu2c (the card thread's harness-pinned branch; it names no issue, so this claim is the identity record)
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#1
    Ruling-ref: 6429362190 (batch #402 item 2, letter A′, maintainer 「同意」 2026-10-26T23:01Z): an approval notification (bell row and email body) names the record by its display title, resolved as that recipient and narrowed by their field-level security, falling back to the record id when the title is empty or unreadable. The token-bearing action-link pages keep object label and id. The templates keep {{object}} {{record}}; no title-plus-id suffix.
    File surface: packages/plugins/plugin-approvals/** (the notification subject/body text, a dated note at action-link-pages.ts beside the #23594 comment, tests), and a patch changeset. ⛔ No packages/spec/**. ⛔ No ui/**.
    Container & model: S, mode:thread, default model and effort (set at thread open)
    Clause-②: no — template shape unchanged; the dev measures it on the diff
    Metadata-protocol: none
    Responsibility: approval notifications name the record by a bare id the recipient cannot recognise (triage 6420611091)
    Thread-read: 6429362190
    Premise: holds (read 2026-10-27T00:46Z at origin/main 6390fe52ce: card open, unassigned, pm:queue, no claim)
    Serial constraints cleared: #26180 (seat 1, same round) also works in packages/plugins/plugin-approvals/. Each dev re-measures open PRs on the files it touches and runs git merge-tree against any overlap before pr_create.

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 26181,
    "status": "done",
    "branch": "claude/project-thread-tlbu2c",
    "pr": "#26389",
    "session": "session_01Kfr6fhXWwYppMd27Z6fPM8",
    "premise_still_valid": true,
    "summary": "Ruling A′ implemented at head 6cc01b7. notify() takes a notice about a record as {about, text}: it resolves the name each recipient reads (subjectNamesFor: the record read once under the system context, the title (ADR-0079 nameField) picked from it as served to the recipient, titleAsServed over their servedFields answer, the inbox's own rule) and emits once per distinct name, so no recipient gets another's title. The recipient envelope (recipientContext) is resolveUserAuthzGrants in the request's organization vetted by vetOrganizationClaim, as plugin-audit's mention gate builds it. The id stands for an empty title, an unreadable or masked title field, and any failure. Templates keep their object-and-record holes unchanged; action-link pages keep the id with a dated #26181 note beside the #23594 comment; approvals.mdx, which said Deal D_123, was corrected (a file outside the claim's surface, made false by this change).",
    "tests": "New notification-subject-title-per-recipient.integration.test.ts, 4 cases (title for a reader; empty title -> id; FLS unreadable and masked -> id; two recipients with different FLS on one request -> different bodies, per-approver emits and one split SLA-breach emit). Red on main: approval-service.ts + approval-notification-text.ts at 6390fe5 -> (a) and (d) fail ('Received: A decision on Contract C1 is waiting on you.'), (b) and (c) pass as fallback controls; restored, git diff HEAD empty, blob fbf728e7 == HEAD. Ablation via scripts/ablation-replace.mjs (titleAsServed(record, displayField, readable) -> undefined; anchor 1 -> 0, blob fbf728e7 -> 05af8607; restored == HEAD) turns (c) and (d) red; tests import src, no dist leg. Updated 4 suites that pinned ruling B's id on titled fixtures. Package suite at 6cc01b7 under the lock: Test Files 100/100, Tests 1284/1284; typecheck (tsc + scripts + check:test-typecheck OK) VERDICT command-exit 0.",
    "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 6cc01b7: 98 commands, each run with exit captured before any pipe; --ran: 98 derived, 98 run, 0 NOT-MEASURED (derived zero, all codes recorded). First pass had 4 exit 3 (prerequisite): check-plugin-teardown-shape --self-test (re-run 0 after fetching pinned control 621a487), check:i18n (re-run 0 after the named build closure: OK, 10 packages in sync), check:skill-examples (re-run 0), check:dual-build-cjs-loads (re-run 0). eslint --no-inline-config packages/plugins/plugin-approvals/src exit 0. CI families: PR check-runs in_progress at report time, the seat reads them. Overlap: only #26337 shares files; git merge-tree HEAD e451337 exit 0; #26180 has no open PR.",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "mcp_calls": "0 — no MCP GitHub calls; card, comments and open-PR files read with gh api REST reads",
    "api_writes": "2 relay writes + 1 git push — fleet-write pr_create (POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/26389/assignees, read back identical, 9360 bytes) and this os-dev-report comment (POST /issues/26181/comments via post-stamped.mjs); write budget spent 3 of 3 (push, pr_create, report)",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · two copies of the named-user envelope builder now exist (plugin-audit mention-recipient-gate contextForMentionedUser and plugin-approvals recipientContext); lifting one into @objectstack/core is outside this card's file surface · noted in the PR's Acceptance notes, not filed",
    "carrier: seat · claim file surface addition: content/docs/automation/approvals.mdx (one paragraph that named the outcome notification's record as Deal D_123, made false by this change)"
    ]
    }


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed

    PR #26389 merged at 2026-10-27T02:31Z by the merge queue as c51aed4f9d on main (Fixes #26181; ACCEPT 6431995136).

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-26389-*' 0 refs
    origin/main by content git cat-file -e origin/main:packages/plugins/plugin-approvals/src/notification-subject-title-per-recipient.integration.test.ts present
    Ancestry git merge-base --is-ancestor c51aed4f9d origin/main holds

    State: this card closed by Fixes (completed); pm:dispatched removed.


    Generated by Claude Code

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

Metadata

Metadata

Labels

area:workflowApprovals and automation — the work that runs without a person driving itbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions