Commit Graph

25 Commits

Author SHA1 Message Date
aleiby
08cee416a4 fix(handoff): normalize identity in sendHandoffMail (#780)
The handoff mail bead was created with un-normalized assignee
(e.g., gastown/crew/holden) but mailbox queries use normalized identity
(gastown/holden), causing self-mail to be invisible to the inbox.

Export addressToIdentity as AddressToIdentity and call it in
sendHandoffMail() to normalize the agent identity before storing,
matching the normalization performed in Router.sendToSingle().

Fix handoff mail delivery (hq-snp8)
2026-01-20 14:09:54 -08:00
gastown/crew/jack
8eafcc8a16 feat(mail): extend message bead for queues/channels
Add queue/channel routing fields to message beads:
- queue: string (queue name, mutually exclusive with to/channel)
- channel: string (channel name, mutually exclusive with to/queue)
- claimed_by: string (who claimed queue message)
- claimed_at: timestamp (when claimed)

Messages can now be direct (To), queued (Queue), or broadcast (Channel).
Added constructors NewQueueMessage/NewChannelMessage, type helpers
IsQueueMessage/IsChannelMessage/IsDirectMessage/IsClaimed, and
Validate() for mutual exclusivity checks.

Also fixes build error in mail_queue.go (QueueConfig struct nil comparison).

Closes gt-xfqh1e.4

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:14:36 -08:00
beads/crew/fang
1418b1123a feat: add gt mail mark-read command for desire path (bd-rjuu6)
Adds mark-read and mark-unread commands that allow marking messages
as read without archiving them. Uses a "read" label to track status.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 00:03:40 -08:00
Cong
6e4f2bea29 fix: replace panic with fallback in ID generation (#213)
Replace panic calls in generateID() and generateThreadID() with
time-based fallback when crypto/rand.Read fails. This is an extremely
rare error case, but panicking is not the right behavior for ID
generation functions.

🤝 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 21:33:40 -08:00
george
117e6a1852 fix: handle crypto/rand.Read error in ID generation (gt-qysj9)
Panic if crypto/rand.Read fails rather than silently returning
zero IDs which could cause message collisions.
2026-01-04 23:58:37 -08:00
Steve Yegge
a09027043d feat: Add overseer identity for human operator mail support
Adds first-class support for the human overseer in Gas Town mail:

- New OverseerConfig in internal/config/overseer.go with identity
  detection (git config, gh cli, environment)
- Overseer detected/saved on town install (mayor/overseer.json)
- Simplified detectSender(): GT_ROLE set = agent, else = overseer
- New overseer address alongside mayor/ and deacon/
- Added --cc flag to mail send for CC recipients
- Inbox now includes CC'd messages via label query
- gt status shows overseer identity and unread mail count
- New gt whoami command shows current mail identity

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 18:02:49 -08:00
Steve Yegge
34b5a3bb8d Document intentional error suppressions with comments (gt-zn9m)
All 156 instances of _ = error suppression in non-test code now have
explanatory comments documenting why the error is intentionally ignored.

Categories of intentional suppressions:
- non-fatal: session works without these - tmux environment setup
- non-fatal: theming failure does not affect operation - visual styling
- best-effort cleanup - defer cleanup on failure paths
- best-effort notification - mail/notifications that should not block
- best-effort interrupt - graceful shutdown attempts
- crypto/rand.Read only fails on broken system - random ID generation
- output errors non-actionable - fmt.Fprint to io.Writer

This addresses the silent failure and debugging concerns raised in the
issue by making the intentionality explicit in the code.

Generated with Claude Code https://claude.com/claude-code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 23:14:29 -08:00
Steve Yegge
4801a98793 feat: simplify mail wisps - single DB with --wisp flag (gt-fgms)
Removed dual-routing architecture that used separate .beads-wisp/ directory.
Now uses single .beads/ with --wisp flag passed to bd create.

Changes:
- router.go: Remove resolveWispDir(), simplify shouldBeWisp()
- mailbox.go: Remove wispDir field and dual-source query logic
- types.go: Rename Ephemeral to Wisp, remove MessageSource
- mail.go: Rename --ephemeral to --wisp flag
- spawn.go: Use Wisp field for lifecycle messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 20:16:14 -08:00
Steve Yegge
200a09a02d feat: mail uses wisps for ephemeral orchestration messages (gt-lg66)
Add dual-inbox architecture where ephemeral messages go to
.beads-wisp/.beads/ instead of .beads/. Lifecycle messages
(POLECAT_STARTED, NUDGE, etc.) auto-detect as ephemeral.

Changes:
- Add Ephemeral and Source fields to mail.Message
- Add --ephemeral flag to gt mail send
- Router auto-detects lifecycle message patterns
- Mailbox merges messages from both persistent and wisp storage
- Inbox displays (ephemeral) indicator for wisp messages
- Delete/archive works for both message types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-24 20:03:58 -08:00
Steve Yegge
ebbe886d81 Fix crew worker mail identity mismatch (gt-2xiv)
Normalize crew/ and polecats/ to canonical form in addressToIdentity():
- gastown/crew/dave -> gastown/dave
- gastown/polecats/Toast -> gastown/Toast

Follows Postels Law: be liberal in what you accept.
2025-12-22 00:40:43 -08:00
Steve Yegge
a3da3302a3 fix(mail): use slash-based identity format for addresses
Changes mail identity format from hyphenated (gastown-Toast) to
slash-based (gastown/polecats/Toast) to:
- Match directory structure (REST-like)
- Distinguish from hyphenated bead IDs (gt-xyz) and molecule names

Updated:
- addressToIdentity(): preserve slashes instead of replacing with dashes
- identityToAddress(): simplified, identity == address now
- detectSender(): include /polecats/ in polecat addresses
- Tests updated for new format

Closes gt-cxtu: shared beads architecture verified working.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 14:28:14 -08:00
Steve Yegge
9a631b9195 fix(mail): normalize crew/polecats paths in addressToIdentity
Strip crew/ and polecats/ from addresses before identity conversion.
This ensures beads/crew/dave and beads/dave both resolve to beads-dave,
fixing the inbox mismatch bug (hq-0ol).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 10:06:13 -08:00
Steve Yegge
7e16ac4800 fix: recover orphaned mail migration to bd v0.32.0
The merge at 96c773f lost changes from 5791752 (beads-sync branch).
Re-implementing:
- router.go: Use bd create --type=message with labels
- mailbox.go: Use bd list/show/close instead of bd mail commands
- types.go: Add Pinned field to Message struct

Original work was in commits 5791752 and 4c060f4 on beads-sync.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 22:01:16 -08:00
Steve Yegge
f6ff533891 feat(mail): Sort pinned messages first in inbox (gt-ngu1)
Add Pinned field to BeadsMessage and sort pinned messages before
unpinned ones in listBeads(). Within each group, sort by newest first.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 17:53:52 -08:00
Steve Yegge
4c060f4aaa refactor(mail): Remove bd mail dependency, use bd create/list/show (gt-9xg)
Replace `bd mail send/inbox/read/ack` commands with `bd create/list/show/close`.
This separates the orchestration layer (gt) from the data plane (beads).

Changes:
- router.go: Use `bd create --type=message` instead of `bd mail send`
- mailbox.go: Use `bd list --type=message` and `bd show` for inbox/read
- types.go: Parse metadata from labels (from:, thread:, reply-to:)
- mail.go: Fix findBeadsWorkDir to prefer rig-level beads, fix crew address format

Messages are now stored as beads issues with type=message. Metadata (sender,
thread, reply-to) is stored in labels for retrieval.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 17:52:15 -08:00
Steve Yegge
bae097cb35 fix(mail): Align gt mail send --priority with bd mail send (gt-kspu)
Changed --priority flag from string values (low/normal/high/urgent) to
numeric values (0-4) to match bd mail send interface:
- 0 = urgent/critical
- 1 = high
- 2 = normal (default)
- 3 = low
- 4 = backlog

Also added --urgent flag as shortcut for --priority 0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 07:59:02 -08:00
Steve Yegge
6e0f1a96d1 Merge remote-tracking branch 'origin/polecat/Nux' 2025-12-19 18:28:02 -08:00
Steve Yegge
89520a5854 Merge remote-tracking branch 'origin/polecat/Scabrous'
# Conflicts:
#	docs/architecture.md
#	docs/harness.md
#	internal/beads/builtin_molecules.go
#	internal/cmd/mail.go
#	internal/cmd/molecule.go
#	internal/cmd/mq.go
#	internal/git/git.go
#	internal/mail/router.go
2025-12-19 17:59:36 -08:00
Steve Yegge
50accc9cb2 feat(mail): add deacon/ identity support
Add deacon/ as a town-level mail identity alongside mayor/.
Both addressToIdentity() and identityToAddress() now handle
deacon/deacon/ consistently with trailing slash preservation.

Tested with bd mail send deacon/ and bd mail inbox --identity deacon/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 17:26:54 -08:00
Steve Yegge
6479dddb9b feat(mail): add interrupt vs queue delivery semantics (gt-6k8)
Add delivery modes to mail messages:
- queue (default): message stored for periodic checking
- interrupt: inject system-reminder directly into session

New features:
- --interrupt flag on gt mail send for urgent/lifecycle messages
- --quiet flag on gt mail check for silent non-blocking checks
- gt mail wait command to block until mail arrives (with optional timeout)

Interrupt delivery injects a system-reminder via tmux send-keys,
useful for stuck detection, nudges, and urgent notifications.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 16:30:53 -08:00
Steve Yegge
4048cdc373 fix(lint): resolve all errcheck warnings
Fix ~50 errcheck warnings across the codebase:

- Add explicit `_ =` for intentionally ignored error returns (cleanup,
  best-effort operations, etc.)
- Use `defer func() { _ = ... }()` pattern for defer statements
- Handle tmux SetEnvironment, KillSession, SendKeysRaw returns
- Handle mail router.Send returns
- Handle os.RemoveAll, os.Rename in cleanup paths
- Handle rand.Read returns for ID generation
- Handle fmt.Fprint* returns when writing to io.Writer
- Fix for-select with single case to use for-range
- Handle cobra MarkFlagRequired returns

All tests pass. Code compiles without errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 12:44:42 -08:00
Steve Yegge
e799fe5491 fix: normalize mayor identity to 'mayor/' for mail routing
The addressToIdentity function was stripping the trailing slash from
'mayor/' addresses, causing a mismatch with beads messages that have
assignee 'mayor/'. This fix ensures mayor addresses always use 'mayor/'
for consistent mail routing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 23:30:24 -08:00
Steve Yegge
96902092fd feat(mail): add message types and threading support
- Add MessageType enum (task, scavenge, notification, reply)
- Expand Priority from 2 to 4 levels (low, normal, high, urgent)
- Add ThreadID and ReplyTo fields to Message struct
- Add --type and --reply-to flags to 'gt mail send'
- Add 'gt mail thread <id>' command to view conversation threads
- Update inbox/read display to show type and threading info
- Auto-generate thread IDs for new messages
- Reply messages inherit thread from original

Closes: gt-hgk

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-18 20:14:13 -08:00
Steve Yegge
59921d52c8 feat: refactor mail system to use bd mail backend
- Mail commands (send/inbox/read/delete) now wrap bd mail CLI
- Address translation: mayor/ → mayor, rig/polecat → rig-polecat
- Beads stores messages as type=message issues
- Legacy JSONL mode retained for crew workers (local mail)
- Refinery notifications use new mail interface
- Swarm landing notifications use new mail interface

Closes gt-u1j.6, gt-u1j.12

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-16 21:45:42 -08:00
Steve Yegge
e984a55fe5 feat: add mail system and CLI commands
- internal/mail: Message types with priority support
- internal/mail: Mailbox JSONL operations (list, get, append, delete)
- internal/mail: Router for address resolution and delivery
- gt mail send: Send messages to agents
- gt mail inbox: List messages (--unread, --json)
- gt mail read: Read and mark messages as read
- Address formats: mayor/, rig/, rig/polecat, rig/refinery
- High priority messages trigger tmux notification
- Auto-detect sender from GT_RIG/GT_POLECAT env vars

Closes gt-u1j.6, gt-u1j.12

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 14:19:15 -08:00