Repository navigation
fix(service-messaging): Notification Preferences says which topics and channels can be entered - #25449
Conversation
… channels come from Claude-Session: https://claude.ai/code/session_01GsN1y3qWPdkVLasbhDB2Fy Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GsN1y3qWPdkVLasbhDB2Fy Co-authored-by: Claude <noreply@anthropic.com>
…ES and ja-JP Claude-Session: https://claude.ai/code/session_01GsN1y3qWPdkVLasbhDB2Fy Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check4 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 5 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin d4e7fe7c735011ed9e2449da7d997705a1037326 && git checkout d4e7fe7c735011ed9e2449da7d997705a1037326
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d0a1361bdabc153b2fb927b8f7ef6f024ecc6891 ad7975f4e55cdee5f29f38b0fd172556ee765587 && git checkout -B drift-repro d0a1361bdabc153b2fb927b8f7ef6f024ecc6891 && git merge --no-ff ad7975f4e55cdee5f29f38b0fd172556ee765587
node scripts/docs-audit/affected-docs.mjs --json d0a1361bdabc153b2fb927b8f7ef6f024ecc6891 |
|
os-dev-report {
"issue": 25346,
"status": "done",
"branch": "claude/project-thread-8hqiya",
"pr": "https://github.com/objectstack-ai/objectstack/pull/25449",
"session": "session_01GsN1y3qWPdkVLasbhDB2Fy",
"premise_still_valid": true,
"summary": "Ruling A (6365616409, Sales) on the needs_decision in 6365345478. topic and channel on sys_notification_preference stay text with default '*'. Their help now names where values come from: channel lists inbox (always), email and sms (once their service is configured) or a plugin's own channel id, and drops the unimplemented push; topic names a flow's notify step or a platform topic such as approval.requested. Both say '*' means all and that an unused value matches nothing. Bundles: en regenerated; zh-CN, es-ES and ja-JP translated by hand (es-ES and ja-JP were stale byte copies, which check:i18n-stale-fill reds on). One patch changeset.",
"tests": "New pin file notification-preference-topic-channel-help.test.ts, 3 cases. Ablation: the object file restored from base f0fdd45b gives 3 failed, HEAD gives 3 passed; restore proven with git diff --quiet HEAD. Package suite pnpm --filter @objectstack/service-messaging test: Test Files 61 passed (61), Tests 729 passed (729). typecheck exit 0; eslint on the two changed source files exit 0.",
"gates": "dispatch-gates --commands derived 68, all 68 exit 0. Prerequisites first: check-plugin-teardown-shape --self-test after fetching its pinned fixture; check:dual-build-cjs-loads after building the 8 dists it named; check:i18n-stale-fill after the es-ES and ja-JP re-translation. --ran: 68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN. Read on 2d1b522b; main then merged in, giving head ad7975f4 (the 7 incoming commits touch no service-messaging path). CI on the PR is pending at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "7 — read tools only: issue_read get, issue_read get_comments x4, search_pull_requests, pull_request_read get",
"api_writes": "6 — all via the fleet-write relay: label-write (assign, pm:queue to pm:dispatched), post-stamped x3 (claim, needs_decision report, ruling record), pr_create (draft, assignee os-sales), pr_request_reviewers (os-sales)",
"open_questions": [],
"out_of_scope_findings": []
}Generated by Claude Code |
席位核对 · ACCEPT · 2026-10-23T14:19Z
Generated by Claude Code |
Requested by Sales · project thread
Fixes #25346
Clause-②: no
Metadata-protocol: none
Claim of record:
6365308855on the card (card thread,domain:servicesseat 1). Ruling of record:6365616409(letter A, Sales, on the needs_decision in os-dev-report6365345478). Branchclaude/project-thread-8hqiyais the harness-pinned branch for this session. It names no issue, so the Duplicate Fix Guard's branch-name hint will not match, and the claim is the identity record.What changes
Setup → Notification Preferences showed Topic and Channel as bare text boxes. Their help only said "Notification topic" and "Channel id (inbox/email/push/…)", and no
pushchannel exists. The card asked for pickers wherever the platform can enumerate the values. The measurement in the report found that neither field can be a picker without a contract change:MessagingChannelis exported, andregisterChannelis public. Aselectdoes not fit:SystemIdentifierSchema, so the stored*wildcard cannot be an option.Ruling A keeps both fields as
textand makes the help say what to type.packages/services/service-messaging/src/objects/notification-preference.object.ts:inbox(always available),email(once an email service is configured),sms(once an SMS service is configured), or the id of a channel an installed plugin adds. Enter*for all channels. An id no channel uses matches nothing.pushis gone.approval.requestedorcollab.mention. Enter*for all topics. A topic nothing sends matches nothing.The type, default (
*),maxLength, index and resolver are unchanged. No stored row changes meaning and no write is newly refused.The comments beside both declarations record why the field is not a picker.
Translation bundles:
enwas regenerated bynode scripts/check-i18n-bundles.mjs --write.zh-CN,es-ESandja-JPwere translated by hand. The es-ES and ja-JP leaves were byte copies of the old English source, whichcheck:i18n-stale-fillreds on. Re-translating them dropped their two entries from each*.source-hashes.generated.ts, as the tool writes it.Pins
New file
packages/services/service-messaging/src/objects/notification-preference-topic-channel-help.test.ts, 3 cases:textwith default*, and its help saysEnter * for all.ids read from the three channel factories this package builds (createInboxChannel,createEmailChannel,createSmsChannel). So a channel added or renamed here fails until the help says so. The help names none of the spec vocabulary's ids that no channel implements (push,webhook,slack,teams,in-app), and it says a plugin's own channel is valid.Ablation leg: the object file was restored from
f0fdd45b(base) and the pin file run: 3 failed. HEAD: 3 passed. The file was restored withgit checkout HEAD --, andgit diff --quiet HEADpassed. Nodist/leg is needed, because the pin imports source.Tests and gates
Read on
2d1b522b. Thenmainwas merged in, giving headad7975f4. None of the 7 incoming commits touches aservice-messagingpath, so nothing was re-run.pnpm --filter @objectstack/service-messaging test:Test Files 61 passed (61),Tests 729 passed (729).pnpm --filter @objectstack/service-messaging typecheck: exit 0.eslinton the two changed source files: exit 0.node scripts/pm/dispatch-gates.mjs --commandsderived 68 commands, and all 68 exit 0. Three needed a prerequisite first:check-plugin-teardown-shape --self-testran after its pinned fixture commit was fetched;check:dual-build-cjs-loadsran after the 8 dists it named were built;check:i18n-stale-fillran after the es-ES and ja-JP re-translation.--ranreconcile:68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN.!in the title and no(narrowing)arm.Acceptance notes
Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01GsN1y3qWPdkVLasbhDB2Fy