Add push full agent mail - #10340
Conversation
|
✅ Nitro CLI E2E snapshots: no flow recordings changed vs |
Patch coverage94.1% of changed lines covered (846/899) +26 more changed files; see the JSON below for uncovered lines. Uncovered changed lines (JSON){
"sha": "ec42ce00519f852cacecee828bb06f02bf2c3791",
"files": [
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Mail/IMailStore.cs", "ranges": [[87, 87]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Tasks/ITaskStore.cs", "ranges": [[207, 210], [213, 221], [223, 230], [232, 233]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentRole.cs", "ranges": [[15, 22]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/ISessionDeliveryLedger.cs", "ranges": [[22, 22]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverItem.cs", "ranges": [[6, 6]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverHistoryLimitOption.cs", "ranges": [[14, 16]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverRecordCreation.cs", "ranges": [[6, 6]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Notify/MailNudge.cs", "ranges": [[65, 66], [94, 95], [97, 97]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverFilter.cs", "ranges": [[6, 6]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverReferenceResult.cs", "ranges": [[6, 6]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentDatabase.cs", "ranges": [[129, 129], [641, 641]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Notify/PingSessionExecutor.cs", "ranges": [[160, 161]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Tasks/TaskStore.cs", "ranges": [[1035, 1036]] },
{ "path": "src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverLedger.cs", "ranges": [[227, 227], [229, 229]] }
]
}Project coverage: 58.0% (289985/499691 lines) |
There was a problem hiding this comment.
🟡 Changes recommended
The new takeover command composes multiple state-changing operations across separate transactions, which can leave the workspace in a partially-updated state (and lose audit fidelity) if a later step fails.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR extends Nitro’s agent workflow by (1) introducing an actor takeover feature (moving mail + reassigning active tasks and recording an immutable audit trail), and (2) upgrading the agent mail “nudge” to push a bounded JSON digest (with delivery de-duplication across channels), alongside a few related CLI/TUI improvements.
Changes:
- Add
nitro agent takeover(plustakeover history) and a v12 workspace schema “takeover ledger” to audit mail/task movement. - Switch mail nudges/digests (hook + ping + nudge paths) to render bounded JSON digests and avoid re-delivery using the session delivery ledger.
- Add task reassignment support and task
--typefiltering for list/ready, plus show/read outputs enriched with takeover references.
File summaries
| File | Description |
|---|---|
| src/Nitro/CommandLine/test/CommandLine.Tests/Tui/Agents/AgentsModeTests.cs | Adds coverage for researcher role styling token usage in the TUI list. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Workspace/TakeoverLedgerTests.cs | New tests validating takeover header+items recording, querying filters, limits, rollback/cancellation behavior. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Workspace/AgentDatabaseTests.cs | Extends DB initialization/upgrade assertions (WAL, foreign keys, takeover tables, unknown-version journal-mode behavior). |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/PingSessionExecutorTests.cs | Updates executor wiring and asserts digest JSON shape via parsing rather than string contains. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/NotifierTests.cs | Updates end-to-end notify test to validate JSON digest content. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/MailDigestTests.cs | New tests covering digest rendering, ordering, truncation, and total byte cap behavior. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/ActorWakeDispatcherTests.cs | Updates assertions to validate JSON digest payload content. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Mail/MailStoreTests.cs | Adds coverage for transferring mail participation (read state preservation, conflict handling, thread/search visibility). |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/SessionDeliveryLedgerTests.cs | Adds tests for cross-channel “already delivered” detection and session scoping. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/CodexHookHandlerTests.cs | Adds durable-role resolution tests and updates digest expectations to JSON digest output. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/ClaudeHookHandlerTests.cs | Adds durable-role resolution tests and updates stop/digest behavior and message cap assertions. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/ClaudeHookExecutorTests.cs | Updates constructor wiring for new handler dependency set. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/AgentEffectiveRoleTests.cs | New unit tests for resolving effective role with registry fallback and error/cancellation behavior. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Tasks/TaskStoreTests.cs | Adds reassignment behavior tests and expands seeding helpers for assignee. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Tasks/ShowTaskCommandTests.cs | Adds takeover rendering coverage and validates JSON output remains parseable for long descriptions. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Tasks/ReadyTaskCommandTests.cs | Adds --type filtering coverage (human + JSON). |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Tasks/ListTaskCommandTests.cs | Adds --type filtering coverage and updates option help text. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/TakeoverAgentCommandTests.cs | New command tests for takeover behavior, JSON shape, forced/live-session behavior, and history output. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/RegisterAgentCommandTests.cs | Updates help output to include known-role list and example. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Mail/SendMailCommandTests.cs | Adds nudge error-handling test, validates exact digest JSON per session, and covers duplicate push -> pointer behavior. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Mail/ReplyMailCommandTests.cs | Adds coverage that replies nudge recipients with correct id/body. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Mail/ReadMailCommandTests.cs | Updates JSON contract expectations (adds takeovers) and adds takeover-hop display tests. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Mail/MailCommandTestBase.cs | Adds helpers to parse digest calls and to construct MailNudge with delivery ledger. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/Mail/BroadcastMailCommandTests.cs | Updates assertions to validate digest JSON. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/ListAgentCommandTests.cs | Updates --role help text to include known roles. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/CodexHookCommandTests.cs | Updates hook notify output expectation to JSON digest. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/ClaudeHookCommandTests.cs | Updates hook outputs to JSON digest and adds helper to seed mail directly. |
| src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/AgentCommandTests.cs | Updates help/usage snapshots to include takeover subcommand. |
| src/Nitro/CommandLine/src/CommandLine/Tui/Theming/DefaultTheme.cs | Adds dedicated theme token for researcher role. |
| src/Nitro/CommandLine/src/CommandLine/ThrowHelper.cs | Adds a shared out-of-range helper for negative limits. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverReferenceResult.cs | New compact DTO for embedding takeover references in results. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverRecordCreation.cs | New creation record for takeover audit header fields. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverRecord.cs | New takeover audit model (header + attached items). |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverLedgerSchema.cs | New SQL schema for takeover audit tables + indices. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverLedger.cs | Implements recording/querying takeover audit trail with atomic header+item inserts. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverItemKinds.cs | Defines allowed takeover item kinds (message sender/recipient, task). |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverItem.cs | New model for takeover-attached items. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/TakeoverFilter.cs | New filter type for querying takeovers with limit validation. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/SessionDeliveryLedger.cs | Adds FindDeliveredAsync to detect cross-channel deliveries for de-duplication. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/ITakeoverLedger.cs | New ledger abstraction for audit recording/querying. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/ISessionDeliveryLedger.cs | Adds default interface method for delivered lookup. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentRole.cs | Adds well-known role constants/list including researcher. |
| src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentDatabase.cs | Bumps schema to v12, adds takeover schema creation, and adjusts when WAL/fk pragmas are applied. |
| src/Nitro/CommandLine/src/CommandLine/Services/Tasks/TaskStore.cs | Adds atomic ReassignAsync and refactors comment insertion to support reuse inside a transaction. |
| src/Nitro/CommandLine/src/CommandLine/Services/Tasks/TaskDetailResult.cs | Adds Takeovers to task detail result shape. |
| src/Nitro/CommandLine/src/CommandLine/Services/Tasks/ITaskStore.cs | Adds default interface implementation for ReassignAsync. |
| src/Nitro/CommandLine/src/CommandLine/Services/Results/JsonSourceGenerationContext.cs | Registers new JSON-serializable shapes for takeover + references. |
| src/Nitro/CommandLine/src/CommandLine/Services/Results/JsonResultFormatter.cs | Writes JSON via WriteRawLine to avoid formatting side-effects. |
| src/Nitro/CommandLine/src/CommandLine/Services/Notify/PingSessionExecutor.cs | Builds digests using ledger delivery tracking + new digest policy. |
| src/Nitro/CommandLine/src/CommandLine/Services/Notify/PingPolicy.cs | Removes digest-message cap constant (moved to digest policy). |
| src/Nitro/CommandLine/src/CommandLine/Services/Notify/MailNudge.cs | Implements best-effort digest sending with delivery de-duplication + time provider usage. |
| src/Nitro/CommandLine/src/CommandLine/Services/Notify/MailDigestPolicy.cs | New policy constants for digest message cap/body cap/total bytes. |
| src/Nitro/CommandLine/src/CommandLine/Services/Notify/MailDigest.cs | New digest renderer producing bounded JSON payloads plus instruction banner. |
| src/Nitro/CommandLine/src/CommandLine/Services/Mail/MailTransferResult.cs | New detailed transfer result including moved ids for auditing. |
| src/Nitro/CommandLine/src/CommandLine/Services/Mail/MailStore.cs | Adds TransferParticipationAsync for moving senders/recipients between actors. |
| src/Nitro/CommandLine/src/CommandLine/Services/Mail/MailMessageDetailResult.cs | Moves result type into Services.Mail and adds takeover references field. |
| src/Nitro/CommandLine/src/CommandLine/Services/Mail/IMailStore.cs | Adds default interface method for transferring mail participation. |
| src/Nitro/CommandLine/src/CommandLine/Services/Hook/CodexHookHandler.cs | Adds effective-role resolution and switches to digest JSON w/ delivery tracking. |
| src/Nitro/CommandLine/src/CommandLine/Services/Hook/ClaudeHookHandler.cs | Adds effective-role resolution, digest JSON + block preamble logic, and delivery tracking. |
| src/Nitro/CommandLine/src/CommandLine/Services/Hook/AgentEffectiveRole.cs | New helper to resolve role from session or durable agent registry with safe fallback semantics. |
| src/Nitro/CommandLine/src/CommandLine/Services/Console/NitroConsole.cs | Adds WriteRawLine to emit raw output (used for JSON). |
| src/Nitro/CommandLine/src/CommandLine/Services/Console/INitroConsole.cs | Adds WriteRawLine contract. |
| src/Nitro/CommandLine/src/CommandLine/Extensions/ServiceCollectionExtensions.cs | Registers ITakeoverLedger implementation in DI. |
| src/Nitro/CommandLine/src/CommandLine/Extensions/RootCommandExtensions.cs | Uses WriteRawLine for JSON empty-object output. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Tasks/ShowTaskCommand.cs | Enriches task show (human + JSON) with takeover references. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Tasks/ReadyTaskCommand.cs | Adds --type filter support for ready listing. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Tasks/Options/TaskTypeFilterOption.cs | New --type filter option description for list/ready commands. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Tasks/ListTaskCommand.cs | Switches to TaskTypeFilterOption for list filtering. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/TakeoverHistoryAgentCommand.cs | New takeover history subcommand with actor/limit filters and JSON output. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/TakeoverAgentCommand.cs | New command implementing takeover flow (role inheritance + mail/task moves + audit record). |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/RegisterAgentCommand.cs | Updates example to use researcher role. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverReasonOption.cs | New --reason option for takeover audit metadata. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverHistoryLimitOption.cs | New --limit option with positive-only validation for history. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverHistoryActorOption.cs | New --actor filter option for history. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverFromActorOption.cs | New required --from option for takeover. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/TakeoverActorOption.cs | New required --actor option for takeover. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/RoleAgentOption.cs | Updates role option help text to list known roles. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Options/ForceActorTakeoverOption.cs | Adjusts --force help text to match takeover semantics. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Mail/WatchMailCommand.cs | Updates detail creation call site for new MailMessageDetailResult.Create signature. |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Mail/ReadMailCommand.cs | Enriches mail read output with takeover hops (human + JSON). |
| src/Nitro/CommandLine/src/CommandLine/Commands/Agent/AgentCommand.cs | Wires takeover into the agent command tree. |
Review details
- Files reviewed: 81/81 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| var mailTransfer = await mail.TransferParticipationAsync(from, to, cancellationToken); | ||
| var taskIds = await tasks.ReassignAsync( | ||
| from, | ||
| to, | ||
| to, | ||
| $"Taken over from '{from}' by '{to}'.", | ||
| cancellationToken); | ||
| var items = CreateItems(mailTransfer, taskIds); | ||
| var takeover = await ledger.RecordAsync( | ||
| new TakeoverRecordCreation | ||
| { | ||
| FromActor = from, | ||
| ToActor = to, | ||
| Actor = to, | ||
| Forced = force, | ||
| Role = role.Length > 0 ? role : null, | ||
| Reason = reason | ||
| }, | ||
| items, | ||
| cancellationToken); |
| private static async Task<IReadOnlyList<TakeoverReferenceResult>[]> GetTakeoversAsync( | ||
| ITakeoverLedger ledger, | ||
| IReadOnlyList<MailMessage> messages, | ||
| CancellationToken cancellationToken) | ||
| { | ||
| var takeovers = new IReadOnlyList<TakeoverReferenceResult>[messages.Count]; | ||
|
|
||
| for (var index = 0; index < messages.Count; index++) | ||
| { | ||
| var records = await ledger.QueryAsync( | ||
| new TakeoverFilter { MessageId = messages[index].Id }, | ||
| cancellationToken); | ||
| takeovers[index] = records.Select(TakeoverReferenceResult.FromRecord).ToArray(); | ||
| } |
No description provided.