Skip to content

Distinguish HEY World posts from email - #185

Open
code-monger-givenall wants to merge 1 commit into
basecamp:mainfrom
code-monger-givenall:agent/world-post-safety
Open

Distinguish HEY World posts from email#185
code-monger-givenall wants to merge 1 commit into
basecamp:mainfrom
code-monger-givenall:agent/world-post-safety

Conversation

@code-monger-givenall

@code-monger-givenall code-monger-givenall commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

What changed

This rebases and narrows the HEY World safety change to the two requested boundaries:

  • hey box view --json preserves each row's kind
  • box responses report posting_count, email_count, and world_post_count
  • mixed boxes summarize email and HEY World counts separately
  • the TUI refuses open, move, Trash, Spam, and ignore on a world/post row before any request

The seven caller-supplied --kind flags and hey world delete have been removed. CLI actions still take bare IDs, so the listing now exposes the information callers need and the TUI performs the local guard backed by actual row state.

Validation

  • GOWORK=off TMPDIR=/tmp mise exec -- make check
  • the smoke-test module compiles
  • no live mailbox or HEY World mutation was run

Copilot AI balanced review requested due to automatic review settings August 19, 2026 18:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Distinguishes HEY World posts from email across the CLI and TUI, preventing inappropriate email actions and adding a dedicated deletion command.

Changes:

  • Preserves posting kinds and reports separate email and World-post counts.
  • Blocks email-only actions for world/post items.
  • Adds confirmed HEY World deletion through the SDK.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
.surface Registers new commands and flags.
API-COVERAGE.md Documents the World deletion endpoint.
README.md Documents posting kinds and World deletion.
skills/hey/SKILL.md Adds agent guidance for World posts.
internal/cmd/box.go Counts and summarizes posting kinds.
internal/cmd/box_test.go Tests mixed-kind JSON output and counts.
internal/cmd/help.go Adds World commands to help.
internal/cmd/help_test.go Updates help expectations.
internal/cmd/ignore.go Adds World-post validation.
internal/cmd/move.go Adds World-post validation.
internal/cmd/posting_kind.go Implements shared kind validation.
internal/cmd/posting_kind_test.go Tests rejection across email actions.
internal/cmd/root.go Registers the World command.
internal/cmd/seen.go Adds validation to seen/unseen.
internal/cmd/spam.go Adds World-post validation.
internal/cmd/stop_ignoring.go Adds World-post validation.
internal/cmd/trash.go Adds World-post validation.
internal/cmd/trash_test.go Tests trash/spam rejection.
internal/cmd/world.go Implements confirmed World deletion.
internal/cmd/world_test.go Tests confirmation and endpoint routing.
internal/tui/mail.go Blocks email actions on World posts.
internal/tui/mail_test.go Tests TUI action rejection.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/cmd/box.go Outdated
Comment thread README.md Outdated
Comment thread skills/hey/SKILL.md Outdated
Comment thread internal/cmd/posting_kind.go Outdated
Copilot AI review requested due to automatic review settings August 19, 2026 18:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (2)

internal/cmd/help.go:20

  • world is still rendered under the EMAIL heading even though this change establishes that HEY World posts are published content and that their actions are separate from email. Put this command in a non-email/HEY World category so root help communicates the same boundary as the command validation.
		names:   []string{"boxes", "box", "search", "contacts", "threads", "attachments", "compose", "reply", "forward", "drafts", "seen", "unseen", "move", "trash", "spam", "ignore", "stop-ignoring", "world"},

internal/cmd/box.go:30

  • The detailed description now says this command returns both email and World items, but its Short text and --limit help still call every result a thread. Those strings drive root/subcommand help and preserve the misleading email-only description this PR is intended to remove; update them to use “items” or explicitly mention both kinds, along with the help expectation.
		Long:  "List email threads and HEY World posts in a box. Each kind is counted separately. Accepts a box name (imbox, feedbox, etc.) or numeric ID.",

Copilot AI review requested due to automatic review settings August 19, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (1)

internal/cmd/box.go:137

  • The new Item column still renders resolvePostingTopicID(posting), so email rows show the topic ID while World rows fall back to the box item ID. These IDs can differ, and the newly documented seen/move/trash commands require the box item ID, so copying an email's displayed “Item” value can target the wrong resource. Render posting.Id consistently and expose the topic ID in a separately labeled column if the read workflow still needs it.
		fmt.Sprintf("%d", resolvePostingTopicID(posting)),

Copilot AI review requested due to automatic review settings August 19, 2026 19:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (7)

internal/cmd/seen.go:77

  • The new guard only works when --kind is supplied, but the built-in unseen help examples still omit it. Update these examples so copied commands preserve the item-kind boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each email thread as unseen/unread.",

internal/cmd/seen.go:23

  • The new guard only works when --kind is supplied, but the built-in seen help examples still demonstrate calls without it. This can lead users to copy the compatibility form and bypass the World-post boundary; align these examples with the README by passing --kind topic.

This issue also appears on line 77 of the same file.

			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each email thread as seen/read.",

internal/cmd/trash.go:23

  • The new guard only works when --kind is supplied, but hey trash --help still demonstrates commands without it. Add --kind topic so the built-in examples do not teach callers to bypass the World-post check.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Shared threads lose your access rather than being deleted for everyone.",

internal/cmd/spam.go:23

  • The new guard only works when --kind is supplied, but hey spam --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Marks each thread as spam and removes it from the current box.",

internal/cmd/ignore.go:23

  • The new guard only works when --kind is supplied, but hey ignore --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Ignored threads remain in their box and can be restored with hey stop-ignoring.",

internal/cmd/stop_ignoring.go:23

  • The new guard only works when --kind is supplied, but hey stop-ignoring --help still demonstrates commands without it. Add --kind topic so copied examples enforce the World-post boundary.
			"agent_notes": "Accepts one or more box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. Reverses hey ignore for each thread.",

internal/cmd/move.go:33

  • The built-in move examples still omit --kind, even though this new annotation says callers should preserve it and the README examples now do so. Since omission bypasses the World-post guard, include --kind topic in all three help examples.
			"agent_notes": "Accepts box item IDs from hey box output. Pass --kind exactly as returned by hey box --json. HEY World posts are rejected before any email action is requested. --to accepts a box name, kind, or ID. Use HEY's scheduled Bubble Up flow for Bubble Up.",

@jeremy

jeremy commented Sep 9, 2026

Copy link
Copy Markdown
Member

Thanks for this. The premise checks out against HEY itself: a box's postings carry kind, published HEY World posts show up in a box as world/post rows next to email topics, and the bulk email actions answer 2xx for one of those IDs without doing anything. Current main renders every row as an email and drops the kind, so a reader has no way to tell. I'd like to take this, narrowed.

Keep:

  1. Preserving kind on each row of hey box view --json and in the box metadata, with the mixed summary line (2,944 emails and 21 HEY World posts). That is the change that lets a caller or an agent tell the rows apart, and it costs nothing.
  2. The TUI refusing move, trash, spam, ignore and open on a world/post row. The TUI already holds the row's kind, so that guard is a real check rather than a promise.

Drop:

  1. The --kind flag on the seven CLI verbs. The verbs take bare IDs and cannot see the kind, so an optional caller-supplied assertion protects only callers who already know, and it pushes --kind topic into every example and every skill snippet for the rest. The honest fix for the blind spot on the CLI side is the listing change in (1); the fix for the misleading 2xx is on the server, and I'll carry that as an API note rather than a CLI flag.
  2. hey world delete. That is a new destructive surface for a different part of the product, and it deserves its own PR after a maintainer says HEY World belongs in this CLI at all. Bundling it into a safety change makes both harder to review.

Rebase notes: main has moved since this branch. hey box is now hey box view, the row model and rendering live in internal/cmd/postings_listing.go on top of internal/mail.Source, and rows already show both the box item ID and the topic ID as separate columns, which resolves the Item-column concern from the earlier review on its own. With (3) and (4) gone the diff should shrink to the listing, the TUI and their tests.

Preserve each box row's kind and report separate email and HEY World counts in box output. Carry the kind into the TUI so published World posts cannot be opened or passed to email filing actions.\n\nKeep the CLI action verbs ID-only, with no caller-supplied kind flags or World deletion surface.
@code-monger-givenall

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and narrowed as requested in 3b21789.

Kept the box-row kind, the three box metadata counts, the mixed email/HEY World summary, and TUI guards for open, move, Trash, Spam, and ignore. Removed all seven caller-supplied --kind flags and the complete hey world delete surface. The mutating smoke fixtures now explicitly select only kind == "topic" rows.

Validation: GOWORK=off TMPDIR=/tmp mise exec -- make check passes, and the separate smoke module compiles. No live mailbox or HEY World mutation was run.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants