Skip to content

Harden AgentMail CLI security, delivery recovery, and durable ingress - #10

Merged
sidharth0612 merged 11 commits into
mainfrom
bratislava
Aug 23, 2026
Merged

sidharth0612 merged 11 commits into
mainfrom
bratislava

Conversation

@Haakam21

@Haakam21 Haakam21 commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Consolidates #8 into this PR so the AgentMail CLI/identity work and the durable ingress hardening land as one change. #8 is closed in favour of this branch; its six commits are merged here unchanged.

CLI security and delivery recovery (originally this PR)

Closes the AgentMail identity boundary by resolving CLI credentials from plugin/secret configuration, stripping inherited credential/header/endpoint state, validating restricted options independently of CLI grammar, and aligning the shipped skill and SecretRef documentation with that model. Keeps healthy quiet WebSocket connections alive while preserving stability-gated reconnect backoff, and hardens REST recovery with malformed-page handling, independent normal/deep continuations, retention-safe resume, and monotonic high-water commits. Also fixes canonical multi-account session routing, adds preparation-lock leases and complete cross-platform package validation, normalizes mailbox/media inputs, removes duplicate CLI metadata, and consolidates ingress failure transitions.

Durable ingress edge cases (merged from #8)

Hardens durable AgentMail ingress across deferred media ownership, capacity coordination, tombstone retention, catch-up recovery, reply reconciliation, and reconnect behavior. Admits sender-clock-skewed mail while bounding retention at the shared durable boundary; self-heals cursor baselines without regressing their high-water marks and prevents malformed timestamps from being re-listed forever. Preserves core empty-payload suppression, bases unknown-send 404 recovery on the outbound attempt, and reclaims deferred media after account shutdown settles.

Merge resolution

The two branches conflicted only in src/channel/src/ingress.ts (2 hunks); every other shared file auto-merged. Resolved toward this branch's transitionFailedAgentMailIngress helper, which already consolidates the poison-message failure transition that #8 still open-coded at both call sites. The helper's callers supply the distinct terminal log text and lastError, so the "abandoned deferred turns" and "failed dispatch attempts" paths keep their separate messages.

One fix was needed on top of the mechanical resolution: the helper omitted the failedAt stamp that the open-coded blocks passed to journal.fail, which durable-receive.ts maps to completedAt for failed rows. Restoring it keeps the consolidated path consistent with the two direct journal.fail call sites in the same file, and is covered by the fails repeatedly abandoned deferred turns at the dispatch ceiling test from #8 (which fails without it).

Validation

31 files changed, +1963 −488. npm test 215 passed (14 files), npm run build, and npm run plugin:validate — manifest check plus host load of the AgentMail channel with AgentMail CLI 0.7.14 across all 8 bundled targets — all pass on the merge commit.

Haakam21 and others added 10 commits July 23, 2026 09:21
# Conflicts:
#	README.md
#	src/channel/src/catch-up.test.ts
#	src/channel/src/catch-up.ts
#	src/channel/src/durable-receive.ts
Combines PR #8 (durable ingress edge cases) into PR #10 so both land as a
single change.

Conflict in src/channel/src/ingress.ts resolved toward this branch's
transitionFailedAgentMailIngress helper, which already consolidates the
poison-message failure transition that origin/luanda still open-coded at both
call sites. The helper's callers supply the distinct terminal log text and
lastError, so the "abandoned deferred turns" and "failed dispatch attempts"
paths keep their separate messages.

The helper omitted the failedAt stamp that the open-coded blocks passed to
journal.fail, which durable-receive.ts maps to completedAt for failed rows.
Added it back so the consolidated path matches the two direct journal.fail
call sites in this file.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Haakam21 Haakam21 changed the title Harden AgentMail CLI security and delivery recovery Harden AgentMail CLI security, delivery recovery, and durable ingress Aug 23, 2026
Addresses consolidated review feedback across three rounds.

outbound-route: the "unrelated active session" decline now only fires
when more than one account is configured. With a single account the
inference cannot pick a wrong inbox, and declining dropped routing back
to core's `dmScope ?? "main"`, collapsing every thread into one session.
Account inference is also validated against the configured account list,
so a stale session key for a removed account can no longer skip the
multi-account decline and resolve a synthesized account with an empty
inboxId and no apiKey.

catch-up: retention is filtered on the same effective provider time the
row is admitted with, so a malformed sender date cannot fall through to
the createdAt fallback unfiltered and re-admit mail whose tombstone has
expired. Rows admitted ahead of the sweep clock are remembered by id in
the cursor, so a future-dated row no longer re-enters the admission
chain (and inflates the admitted count) once a minute for up to the full
24h skew horizon. The memo is measured against the run clock rather than
a resumed continuation's rewound bound, and bounded by serialized bytes
as well as entry count so long provider ids cannot push the cursor past
the keyed store's 64KB limit and strand catch-up in its retry loop.

inbound: the abort-path media cleanup is registered with the account
reclaimer before it starts, so shutdown awaits the unlink instead of
exiting with it in flight.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sidharth0612
sidharth0612 merged commit 00c4242 into main Aug 23, 2026
1 check passed
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.

2 participants