docs: execute the provider-neutral HayaSend direction - #84
Merged
Conversation
Turn the accepted customer-owned, provider-neutral direction into evidence-gated production semantics, Cloudflare, FolioMCP, and agent-policy work. Define the transactional outbox and recipient ledger targets, fault and conformance evidence, commercial data boundary, and disposition of every post-v0.1 draft. Closes #83 Relates to #81 Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
yhay81
force-pushed
the
agent/production-cloudflare-execution-plan
branch
from
July 26, 2026 14:54
ecab25e to
34b3e19
Compare
yhay81
marked this pull request as ready for review
July 26, 2026 14:54
yhay81
added a commit
that referenced
this pull request
Jul 26, 2026
## Summary - re-dispatch stored `queued` and `scheduled` emails when an identical idempotent request is replayed - preserve the original email ID and stored schedule during recovery - rely on the existing atomic send lease and final-state checks to collapse duplicate SQS deliveries - document the ambiguous-acceptance recovery procedure and at-least-once boundary ## Root cause Email persistence and SQS/EventBridge dispatch are separate operations. If persistence succeeded and dispatch then failed, the API returned an error but retained the email and idempotency claim. An identical retry returned that stored record without restoring an immediate or short-delay job, so the email could remain queued forever. ## Impact Clients can safely retry the identical payload with the same idempotency key after an ambiguous API failure. HayaSend returns the same ID and restores dispatch for eligible non-final records. Replays never re-dispatch `sending`, canceled, suppressed, or terminal records. This remains an immediate risk-reduction bridge. The accepted #81/#84 direction replaces client-triggered repair with durable outbox reconciliation in the provider-neutral semantics series. ## Validation - `npm ci` - `npm run check` - `npm test` — 22 files, 170 tests - `npm run build` - `npm run lint:openapi` - `npm audit --omit=dev --audit-level=high` — 0 vulnerabilities - `npm outdated --json` — no direct dependency updates available - `git diff --check` Closes #50 Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
This was referenced Jul 26, 2026
yhay81
added a commit
that referenced
this pull request
Jul 26, 2026
## Outcome Publish the first Gate 1 contract from #81/#84: versioned provider capabilities, generated conformance schemas, and a provider-neutral fault catalog. ## What changed - define strict Zod contracts for capability documents, conformance cases, and evidence reports - publish the current AWS SES adapter document with effective HayaSend limits and explicit unsupported capabilities - generate JSON Schema 2020-12 artifacts and fail CI/release validation on any drift - require complete case coverage, consistent totals, matching provider/version/digest, chronological runs, HTTPS evidence, and evidence-backed `unsupported` - include the machine-readable capability and case files in the future npm package boundary - document official AWS sources checked on 2026-07-26 ## Current truth - HayaSend limits: 9 MiB serialized request, conservative 39 MiB MIME estimate, 50 combined recipients, 20 attachments, 25 MiB decoded attachments, 100 strict batch items, 30-day scheduling - provider event ID persistence: unsupported until #99 - provider-side send idempotency: unsupported - message content, addresses, raw provider errors, and credentials remain outside default evidence ## Validation - `npm run check` - `npm run check:conformance` - `npm test` — 23 files, 175 tests - `npm run build` - `npm run lint:openapi` - `npm audit --omit=dev --audit-level=high` — 0 vulnerabilities - `npm outdated --json` — no direct updates available - `actionlint .github/workflows/*.yml` - `npm pack --dry-run --json` — conformance documents and schemas included - `gitleaks protect --staged --redact --no-banner` - `git diff --check` Closes #95 Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
yhay81
added a commit
that referenced
this pull request
Jul 26, 2026
## Outcome Adds the provider-neutral Gate 1 domain contract from #96 without changing the public API, current stores, or AWS runtime behavior. - versioned message, recipient, attempt, provider-event, and outbox records - opaque recipient and attempt IDs; normalized To/Cc/Bcc roles - deterministic outbox and provider-event identities with no address-derived keys - fixed privacy-safe diagnostic categories and explicit provider/capability versions - generated JSON Schema with reproducible generation and CI drift checks - lifecycle, ambiguity, immutability, and privacy documentation Closes #96 Parent direction: #81 Execution plan: #84 ## Local evidence - `npm run check` - `npm run check:conformance` - `npm test` (24 files, 180 tests) - `npm run build` - `npm run lint:openapi` - `sam validate --lint --template-file template.yaml --region us-east-1` - `actionlint` - `npm audit --audit-level=low` (0 vulnerabilities) - `npm outdated --json` (`{}`) - `npm pack --dry-run --json` - `gitleaks git --staged` (no leaks) - `git diff --check` Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
yhay81
added a commit
that referenced
this pull request
Jul 26, 2026
## Outcome Implements the memory-adapter reference semantics for the transactional outbox in #97, without changing AWS persistence yet. - atomically copy-on-write commits the sendable email, provider-neutral message, recipients, optional idempotency claim, and deterministic outbox item - validates linkage, pristine state, schedule/due time, unique envelope recipients, and unexpired idempotency - conditionally leases due items with exact expiry recovery and one active owner - publishes stable `job_id` values, acknowledges dispatch, and safely retries queue failures - preserves the same job identity after queue-acceptance ambiguity - supports continuous sweeps with AbortSignal shutdown - exposes privacy-safe due, leased, undispatched, oldest-age, and failure counters - injects failures at every staged commit/write and queue boundary Closes #97 Parent direction: #81 Execution plan: #84 ## Local evidence - `npm run check` - `npm run check:conformance` - `npm test` (25 files, 201 tests; 21 focused outbox tests) - `npm run build` - `npm run lint:openapi` - `sam validate --lint --template-file template.yaml --region us-east-1` - `actionlint` - `npm audit --audit-level=low` (0 vulnerabilities) - `npm outdated --json` (`{}`) - `npm pack --dry-run --json` (new port and reconciler included) - `gitleaks git --staged` (no leaks) - `git diff --check` Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
This was referenced Jul 26, 2026
This was referenced Jul 26, 2026
yhay81
added a commit
that referenced
this pull request
Jul 27, 2026
Implements #100 under the accepted direction in #81 and the execution order in #84. ## What changes - adds `GET /emails/{id}/recipients` and `hayasend emails recipients ID` with opaque IDs, stable pagination, deterministic recipient-derived aggregate status, attempt state, ambiguity/retry state, and allowlisted output - adds `GET /diagnostics/recovery`, protected by the new `diagnostics:read` scope, for outbox age/stuck leases, SQS and DLQ depth, provider-event lag, and provider capability digest - makes `doctor` report recovery availability and compare the running AWS capability digest to the installed CLI without breaking keys that lack `diagnostics:read` - records the latest provider-event timestamp in MemoryStore and DynamoDB without allowing older out-of-order evidence to regress it - grants the API Lambda only `sqs:GetQueueAttributes` on its stack-owned queues - documents the privacy and authorization boundary in OpenAPI, CLI, operations, README, changelog, and the conformance catalog - updates `@redocly/cli` from 2.40.0 to 2.41.0 Default API and CLI output never includes addresses, subjects, bodies, credentials, signed URLs, provider message IDs, raw provider errors, queue URLs, or unrecognized fields. ## Current-head local evidence Rebased signed head: `c7c493603e70002a567ff9c0e66e448baa9dad7e` - `npm test` — 39 files / 361 tests passed - `npm run check` - `npm run check:conformance` - `npm run build` - `npm audit --audit-level=low` — 0 vulnerabilities - `npm outdated --json` — empty - `git diff --check` - both rebased commits have valid GPG signatures and Signed-off-by trailers The only tree changes introduced by refreshing the previously AWS-tested head onto current `main` are the independently merged npm release-recovery workflow and its tests (`.github/workflows/release.yml`, `tests/npm-package.test.ts`). ## AWS product evidence Application head `e9514d4dc4f636425a8a9db8327331c519fe2915`: - [AWS integration run 30256105349](https://github.com/haya-inc/hayasend/actions/runs/30256105349) passed in the dedicated empty `hayainc-test` account with `retain_stack=false` - proved scoped 403 boundaries, two-recipient opaque pagination, privacy allowlists, outbox metrics, SQS and delivery/scheduler DLQ depths, disabled inbound DLQ, AWS SES capability digest, durable outbox recovery, and complete stack/resource cleanup - temporary exact-branch environment allowance was removed; `aws-integration` again permits only `main` ## Release gate [v0.2.0](https://github.com/haya-inc/hayasend/releases/tag/v0.2.0) is fully published and verified, so the former post-release Draft gate is satisfied. No review or work is requested from `nurazon59`. --------- Signed-off-by: Yusuke Hayashi <yusuke8h@gmail.com>
This was referenced Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Outcome
Turn the accepted direction in #81 into a stage-gated implementation plan: production semantics first, then a provider-neutral Cloudflare proof, controlled FolioMCP dogfood, and only then agent-safe policy.
What changed
Draft disposition
The plan preserves production-focused work, combines #49/#51/#53 into an ordered semantics series, and parks #33/#55/#77/#82. Existing stacks #59→#61 and #73→#75 remain ordered.
Post-release refresh
main.main.README.md,ROADMAP.md,SUPPORT.md,docs/commercial.md, and the newdocs/execution-plan.md.Validation
npm cinpm run checknpm test— 22 files / 146 testsnpm run buildnpm audit --omit=dev --audit-level=high— 0 vulnerabilitiesnpm outdated --depth=0 --json— no direct updatesgit diff --checkCloses #83
Relates to #81