Skip to content

Show sender titles in operator inbox - #288

Merged
pixexid merged 2 commits into
mainfrom
bb/gh-258-item-8-thr_7dmhnghr7f
Aug 19, 2026
Merged

pixexid merged 2 commits into
mainfrom
bb/gh-258-item-8-thr_7dmhnghr7f

Conversation

@pixexid

@pixexid pixexid commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Related GH-258
Review tier: A

@pixexid
pixexid marked this pull request as ready for review August 19, 2026 03:18
@pixexid
pixexid merged commit 42fadcf into main Aug 19, 2026
1 check passed
@pixexid
pixexid deleted the bb/gh-258-item-8-thr_7dmhnghr7f branch August 19, 2026 03:18
pixexid added a commit that referenced this pull request Aug 19, 2026
Rebase resolution onto 42fadcf. #288 landed withSenderTitles and sender-title
resolution on the same function this PR reshaped, so three files conflicted.

server.ts and tests/server.test.ts were resolved by hand. listOperatorMessages
keeps #288's async signature, `bb` parameter and default-off withSenderTitles,
and gains the outcome envelope around it; the unregistered early return sits
before the title resolution, which is correct because an unregistered project
has no rows to title. dist/server.js was regenerated by the builder, never
hand-resolved.

Two #288 tests merged without conflict but still assumed the bare array:
the RPC assertion in "keeps inbox messages readable when a sender title cannot
be resolved", and a sidebar mock, which now goes through the existing
okMessages wrapper like its siblings.

#288's own property is preserved and still asserted: the plain list performs no
threads.get, only withSenderTitles does, and the unread poll still does not
request titles.
pixexid added a commit that referenced this pull request Aug 19, 2026
…289)

* Answer the unregistered inbox with a foundation code, not a sentence

Closes #280

`operatorMessages` now answers `{ outcome, message?, messages }`, where
`outcome` is drawn from the repo's existing `FoundationCode` vocabulary
and `satisfies readonly FoundationCode[]` is the standing proof that no
parallel error scheme was invented at the app boundary. The condition is
the one foundation already refuses as PROJECT_CONFIG_REQUIRED: no row in
`project_config_heads`.

It travels in the result rather than on a thrown error because the SDK
reduces every handler rejection to `{ code: "handler_error", message }`,
so a code carried on the error would not survive the boundary.

Both consumers migrate. The panel branches on the code; the unread poll
stops branching at all, because an answered read is a proven count and
the unregistered outcome carries no rows. The exact registered-project
check, its timing, and the CLI's output and refusal are unchanged.

* Prove the CLI still refuses an unregistered inbox

Review P2 on #289. Moving the refusal into the reader's result meant the CLI
had to refuse on its own account, and that new line had no test — deleting it
left the suite identically green. The mutant returned exit 0 and `[]` for an
unregistered project: #280's own defect class, a refused read presenting as an
empty inbox, on the surface where a seat reads its durable inbox.

The behaviour was already correct; nothing proved it stayed correct. The test
asserts both halves — a registered project lists exit 0 as a bare array with
the seeded row in it, an unregistered one exits 2 with a refusal — because a
green on the refusal alone is also compatible with the verb not existing, the
flag being ignored, or the seeding never having run.

Deleting the refusal fails it (expected +0 to be 2); making the CLI refuse
unconditionally fails it too. Filtered: 1 failed | 175 skipped (176).

Also review P3, same line: `message` is optional on the result, so
`new Error(listed.message)` could construct an empty error. Returning
invalidCli directly with the outcome code as fallback drops the throw and
catch round trip in the same block and gives a future messageless outcome
something to print.

* Reshape #288's inbox tests onto the result envelope

Rebase resolution onto 42fadcf. #288 landed withSenderTitles and sender-title
resolution on the same function this PR reshaped, so three files conflicted.

server.ts and tests/server.test.ts were resolved by hand. listOperatorMessages
keeps #288's async signature, `bb` parameter and default-off withSenderTitles,
and gains the outcome envelope around it; the unregistered early return sits
before the title resolution, which is correct because an unregistered project
has no rows to title. dist/server.js was regenerated by the builder, never
hand-resolved.

Two #288 tests merged without conflict but still assumed the bare array:
the RPC assertion in "keeps inbox messages readable when a sender title cannot
be resolved", and a sidebar mock, which now goes through the existing
okMessages wrapper like its siblings.

#288's own property is preserved and still asserted: the plain list performs no
threads.get, only withSenderTitles does, and the unread poll still does not
request titles.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant