Seed catalogue · Marketing

Mango

An approval-first marketing desk that turns one ecommerce store's signals into evidence-backed email and SMS campaigns the owner reviews before anything is sent.

Alternative to
Mailchimp, under MIT
Domain
campaign over an audience
Version
0.1.0
Contract
78 clauses across 11 areas
Maturity
contract-drafted-ui-prototype
Mango screenshot 1: landing desktop
Mango screenshot 2: decision desk desktop
Mango screenshot 3: campaign review desktop
Mango screenshot 4: campaign scheduled desktop
Mango screenshot 5: campaigns desktop
Mango screenshot 6: audience desktop

6 screenshots from the product's own visual and verification artifacts. Its handover records what was exercised.


What you get

Everything below is generated from the seed's own manifest and contract. No rounded-off claims, no numbers we made up.

Operating cost

Runs on your cloud's free tier

The seed declares the free plan as the default deployment. Its own estimate, thresholds and sources are below, unedited.

Assumptions
One store, 10000 contacts, 4 campaigns per month, 20000 email and 5000 SMS recipient-steps, and 500 AI generations. Queue messages are at most 64 KB and dispatch stays below 3334 recipient-steps per UTC day.
Cloudflare Monthly Usd
$0 on the current Workers Free plan while the deployment stays inside every Free quota: at most 100000 dynamic Worker requests per UTC day with 10 ms CPU per invocation; 10000 Queue operations per UTC day (write, read, and delete are each one operation per 64 KB); D1 at 5 million rows read per UTC day, 100000 rows written per UTC day, and 5 GB total storage; and SQLite Durable Objects at 100000 requests and 13000 GB-s per UTC day. Workers Paid starts at $5/month and is required for the declared 100000-contact campaign: its 100000 recipient-step writes plus step and schedule mutations exceed D1 Free's 100000 rows-written-per-UTC-day limit.
External Monthly Usd
Not yet estimated because the reference commerce, email, SMS, and AI adapters have not been selected; required before first release.
Total Monthly Usd
Incomplete until reference adapters and unit prices are selected.
Status
cloudflare-free-plan-assumptions-researched-2026-08-31; external-adapters-unselected

Externals declared

4 externals, each with a reason

Under BASE-DATA-004, user data leaves only through what is declared here.

commerce-store
Mango needs the buyer's real customers, products, carts, browsing signals, orders, refunds, and inventory to identify and recheck opportunities.
ai-provider
A language model turns structured evidence into reviewable campaign content and explanations; Cloudflare primitives do not provide that model capability.
mail-sender
Internet email delivery, domain authentication, bounce handling, and complaint feedback require a delivery provider with established sending infrastructure.
sms-sender
Registered sending numbers, carrier routing, country approval, compliance keywords, and delivery receipts require a telecommunications provider.

Extension points

41 declared integration conveniences

These hooks are optional conveniences. Owners may change any source, including core logic, schema and infrastructure; their agents adapt useful upstream fixes and verify the result.

routes.v1pages.v1navigation.v1settings.sections.v1jobs.v1cron.v1queue.consumers.v1operator.management.v1contact.opt-in.v1contact.soft-bounce.v1proposal.selection.v1audience.exclusions.v1audience.frequency.v1campaign.send-time.v1sms.quiet-hours.v1campaign.attribution.v1store.event-recorded.v1contact.consent-recorded.v1contact.channel-suppressed.v1contact.merged.v1proposal.created.v1proposal.failed.v1campaign.scheduled.v1campaign.dispatch-paused.v1campaign.cancelled.v1campaign.completed.v1delivery.outcome-recorded.v1app.navigation.after.v1decision-desk.header.after.v1proposal.evidence.after.v1proposal.actions.before.v1campaign.review.summary.after.v1campaign.review.audience.after.v1campaign.review.safety.after.v1campaign.detail.tabs.after.v1contact.detail.tabs.after.v1settings.sections.after.v1commerce.store.v1ai.provider.v1mail.sender.v1sms.sender.v1

Declared limits

Capacity, stated up front

Straight from seed.json → limits. Where a value is an estimate the seed says so.

Status
estimated-until-load-tested
Max Contacts
100,000
Max Stored Commerce Events
5,000,000
Max Contact Import Rows
50,000
Max Campaign Steps
10
Max Eligible Contacts Per Campaign
100,000
Max Campaign Asset Bytes
10,485,760
Allowed Campaign Asset Content Types
image/jpeg, image/png, image/gif, image/webp
Max Email Html Bytes
102,400
Max Sms Segments Per Recipient Step
3
Email Handoffs Per Minute
3,000
Sms Handoffs Per Minute
600
Deliverability Reporting Window Days
30
Operator Requests Per Minute
300
Public Requests Per Minute Per Ip
60
Unsubscribe Requests Per Minute Per Token
10
Provider Webhooks Per Minute
5,000
Provider Reconciliation Interval Minutes
15
Unresolved Provider Outcome Hours
24

Non-goals, stated proudly

A product that says what it will never do is a product you can trust to stay small, fast and legible. These are refusals, not gaps.

  • Multiple stores or workspaces
  • Roles and permissions
  • A general CRM
  • Signup-form, landing-page, and website builders
  • Social and advertising campaigns
  • Store transactional messaging (order, shipping, and account notifications)
  • Autonomous sends
  • Visual journey automation
  • A/B and multivariate testing
  • Predictive send-time models
  • Multi-touch attribution
  • Purchased-list prospecting
  • Native mobile apps

The contract

All 78 clauses of Mango, from its own CONTRACT.md. Stable IDs identify requirements; the source handover and verification evidence distinguish implemented, tested and uncovered behavior.

HOME1 clause

HOME-001
Owner front door.

The sessionless landing at / names the configured deployment owner, shows their configured one-line description of Mango, and links to /signin. It contains no vendor pricing, feature tour, testimonials, metrics, cross-store claims, or telemetry. It may show the static credit Powered by Mango · runeditrun.com only when the owner enables it in configuration.

OPER3 clauses

OPER-001
Equal operators.

Every operator can see and act on every proposal, campaign, contact, and setting. There are no roles.

OPER-002
Management.

Operators are invited and removed in settings. The operator configured at setup can be removed only by themselves. Policy: operator.management.v1; default: any operator may invite or remove.

OPER-003
Removal does not rewrite history.

Removing an operator revokes their sessions and leaves every proposal, approval, revision, and audit entry attributed to them intact.

STORE7 clauses

STORE-001
Store connection.

One commerce connection imports customers, products, variants, inventory, orders, refunds, carts, and browsing events through commerce.store.v1, retaining each source record's identifier and occurrence time.

STORE-002
Source identity.

A commerce webhook or scheduled sync carrying a source identifier already stored updates that source record; it never creates a second customer, order, cart, refund, or browsing event.

STORE-003
Freshness.

The Decision Desk shows, per source type, the completion time of the last successful sync and the error of any sync that has failed since it.

STORE-004
Source failure.

If the configured commerce adapter is unavailable, ingestion and proposal generation record a failed operation carrying the adapter's error; saved drafts and already recorded delivery outcomes remain readable and no campaign is sent as a side effect.

STORE-005
Stale sources block approval.

A source type is stale when its last successful sync completed more than 24 hours ago or a sync has failed since it. A proposal or campaign whose inclusion or exclusion rule reads a stale source type is labelled stale and cannot be approved until that source type syncs successfully.

STORE-006
Declared adapter capability.

The commerce connection declares which source types it supplies. An audience rule, exclusion, or proposal that requires a source type the connection does not supply is shown as unavailable and cannot be approved; it never resolves to an empty or partial audience.

STORE-007
Ingestion latency.

A source record from an accepted commerce webhook is readable in the operator app within 60 seconds of the webhook being acknowledged.

CONT13 clauses

CONT-001
Contact identity.

Email addresses are compared case-insensitively after trimming, phone numbers are stored in E.164 form, and one canonical email address or phone number identifies at most one contact.

CONT-002
Channel status.

Each contact has an independent state per channel: pending (consent captured, confirmation outstanding), subscribed, non-subscribed (no consent evidence recorded), unsubscribed (opted out), or suppressed (blocked by CONT-006 or CONT-013). Only subscribed is eligible for a marketing send. Store activity or consent on one channel never changes the other channel's state.

CONT-003
Consent evidence.

Every subscription stores the channel, brand or legal sender, SMS sender or programme where applicable, message subject or category, disclosed frequency, destination jurisdiction, capture method and source, occurrence time, consent text and version, and confirmation evidence. Consent applies only to that recorded scope and current recipient; a capture or import without the evidence creates a non-subscribed contact, and a phone number reported as reassigned or no longer belonging to that recipient becomes non-subscribed until fresh evidence is captured.

CONT-004
Opt-out precedence.

An email unsubscribe, one-click unsubscribe, or SMS opt-out sets that channel to unsubscribed before the request is acknowledged, and excludes it from every draft, scheduled campaign, and queued recipient-step. Later imports, syncs, store events, merges, or operator edits never reverse it.

CONT-005
Resubscription.

A previously unsubscribed channel becomes subscribed only from new affirmative consent evidence recorded after the opt-out and confirmed per CONT-009. A suppressed channel also requires the suppression cause to be resolved. An operator edit alone cannot resubscribe either state.

CONT-006
Email suppression.

A hard bounce, spam complaint, or provider suppression suppresses that email address before the next hand-off to any campaign. Soft bounces are recorded and visible, and suppress the address according to the bounce policy; a later provider-confirmed delivery resets its consecutive-soft-bounce count. Policy: contact.soft-bounce.v1; default: suppress after three consecutive soft bounces.

CONT-007
SMS compliance replies.

A signed inbound SMS webhook consumes the adapter's canonical result for that sender, programme, and destination jurisdiction. STOP, STOPALL, END, QUIT, CANCEL, UNSUBSCRIBE, OPTOUT, and REVOKE always opt out; HELP and INFO request help; START and UNSTOP begin the fresh-consent flow required by CONT-005 and never subscribe by themselves. Mango records each reply once and applies an opt-out before acknowledging the webhook. It returns the configured compliance response only when the provider has not already sent the required reply.

CONT-008
Contact history.

A contact page shows source activity, consent changes, suppressions, campaign eligibility decisions, channel deliveries, and operator actions in time order.

CONT-009
Confirmation.

Where the opt-in policy requires confirmation for a channel, a contact captured with consent on it enters pending and receives one confirmation message on that channel; following its opaque per-contact confirmation link sets the channel to subscribed and stores the confirming request's time. A pending channel receives no marketing send, and a confirmation link stops working 30 days after it is issued. Where the policy does not require confirmation, the captured consent evidence of CONT-003 sets the channel to subscribed directly. Policy: contact.opt-in.v1; default: confirmation is required on both channels.

CONT-010
Import.

An operator imports contacts from a CSV whose rows carry an email address or phone number and, optionally, the consent evidence CONT-003 requires. Each row is validated independently; a row matching an existing canonical identifier updates that contact rather than creating a second; re-running the same file changes nothing further. The import reports created, updated, and rejected row counts with a reason per rejected row, and never sets a channel to subscribed for a contact CONT-004 has unsubscribed.

CONT-011
Merge.

An operator can merge two contacts. The surviving contact keeps the union of source activity, consent records, campaign history, and suppressions, and takes the most restrictive state per channel: suppressed beats unsubscribed, which beats non-subscribed, which beats pending, which beats subscribed. A merge cannot resubscribe a channel.

CONT-012
Dormancy without deletion.

A contact with no recorded click, order, or consent change inside the dormancy window is labelled dormant and excluded by the audience policy (AUD-003). Mango never deletes, unsubscribes, or suppresses a contact for inactivity; BASE-DATA-002 stands, and clearing a dormant list is an operator action.

CONT-013
Erasure and surviving opt-out.

Deleting a contact removes their profile, source activity, consent evidence, message content, and delivery detail within five minutes, confirms completion, and anonymises their actor identity in retained audit entries as BASE-DATA-003 requires. It retains only one opt-out record per unsubscribed or suppressed channel: a salted one-way hash of the email address or phone number, the channel, reason, and time. A later import, sync, or capture matching that hash creates a contact whose channel is already unsubscribed. Supersedes BASE-DATA-003 only for this opt-out dependency; all of that baseline clause's other guarantees and all other personal-data entities remain unchanged.

PROP9 clauses

PROP-001
Decision Desk.

The Decision Desk lists proposals in the proposed state ordered by the proposal policy, highest-ranked first. Policy: proposal.selection.v1; default: rank by expected revenue where this deployment has enough of its own attribution history (RESULT-003) to estimate it, then by the earliest send-by instant; proposals with neither rank last.

PROP-002
Evidence.

A proposal names its triggering source events, lookback window, inclusion rule, exclusion rule, source-data as-of time, send-by instant, proposed channels and step instants, and the method behind every forecast or confidence label.

PROP-003
Counts.

A proposal distinguishes candidates, excluded contacts, eligible contacts, and per-channel recipient-steps. No count is labelled recipients until exclusions have been applied.

PROP-004
Content.

A proposal contains an editable campaign name, email subject and body, SMS body when SMS is proposed, sender identity, destination links, and a preview for every selected channel.

PROP-005
Owner control.

A generated proposal is a draft and cannot schedule or send anything until an operator explicitly approves a particular saved revision.

PROP-006
Grounded generation.

AI-generated audience explanations, timing claims, and forecasts use only this deployment's imported store data and configured knowledge, supplied to ai.provider.v1. A generation containing a claim not derivable from that evidence is rejected and the proposal is marked failed per PROP-007; no generic marketing copy is substituted.

PROP-007
Generation failure.

If the configured AI adapter returns invalid output or does not complete within 60 seconds, the proposal is marked failed carrying the provider error, no semantic fallback is created, and existing proposals and campaigns are unaffected.

PROP-008
Forecast provenance.

Every revenue, recovery-rate, or confidence figure names the deployment's own campaigns and store events it was computed from and the number of them. Mango never presents a benchmark drawn from other stores, and where its own history is too thin to compute a figure it says so instead of showing a range.

PROP-009
Proposal states.

A proposal is proposed, approved (an operator approved a revision and a campaign exists), dismissed (an operator rejected it, with the reason recorded), expired (its send-by instant passed), or failed (PROP-007). Only a proposed proposal can be approved or dismissed, and every transition records its actor and time.

AUD7 clauses

AUD-001
Review snapshot.

Campaign review shows the audience rule and as-of time, candidate count, each exclusion reason with its count, eligible contact count, and the recipient-step count per channel.

AUD-002
Consent and suppression.

Contacts whose state on a channel is pending, non-subscribed, unsubscribed, or suppressed are excluded from that channel regardless of segment membership or an operator-authored inclusion rule.

AUD-003
Commerce and dormancy exclusions.

Contacts excluded by the audience policy are listed in review with their reason and count. Policy: audience.exclusions.v1; default: exclude a contact from a product campaign for seven days after purchasing that product, while a refund or return of it is unresolved, and while the contact is dormant under a twelve-month dormancy window (CONT-012).

AUD-004
Frequency protection.

A contact inside the channel's frequency window is excluded from that step and recorded with the reason frequency-window, never silently deferred to a later time. Policy: audience.frequency.v1; default: 24 hours since the contact's last marketing email and 72 hours since their last marketing SMS.

AUD-005
Dispatch recheck.

Eligibility is recalculated when a step's dispatch begins and again immediately before each provider hand-off, so a purchase, refund, opt-out, bounce, complaint, consent change, merge, or frequency-window change after approval prevents that delivery and is recorded as the exclusion reason. Every source type used by the audience must still satisfy STORE-005; if refresh fails or the source becomes stale, the affected channel pauses before any further hand-off and resumes only after a successful refresh.

AUD-006
Multi-step exit.

Each later step re-applies its audience and exclusion rules; a contact who converts or becomes ineligible after an earlier step receives no later step.

AUD-007
Frozen candidate set.

Approval freezes the candidate set resolved at that instant. A contact who first matches the inclusion rule after approval is never added to the approved campaign, and each contact yields at most one recipient-step per channel per step even when they match the rule more than once. Exclusions still apply at dispatch (AUD-005).

CAMP11 clauses

CAMP-001
States.

A campaign is draft (editable, nothing scheduled), scheduled (an approved revision with a future step instant), dispatching (a step has begun handing off), paused (dispatch stopped by SEND-009), completed (SEND-007), cancelled (CAMP-009), or failed (its first step could not begin before its deadline because a required adapter or sender registration was unavailable). Every transition records its actor or the feature that acted, and its time; an invalid transition is rejected.

CAMP-002
Draft editing.

Operators can edit and persist the campaign name, selected channels, audience rule, message content, sender identity, links, and schedule while a campaign is a draft.

CAMP-003
Revision preview.

Desktop, mobile, and plain-text previews render from the saved revision that will be approved, including resolved personalisation examples and the compliance footer or SMS opt-out text that will be sent.

CAMP-004
Approval checks.

Approval atomically validates the audience, consent, source freshness (STORE-005), sender registration, email authentication, sending reputation (MSG-011), compliance content, personalisation, links, schedule, and adapter configuration. A sender adapter must provide effective deduplication and provider reconciliation as required by SEND-001 and SEND-008. Any failure leaves the campaign a draft and names every blocking check.

CAMP-005
Idempotent approval.

Repeated approval requests carrying the same campaign and revision identifier produce one scheduled campaign and one set of steps and recipient-steps, whatever the number of requests.

CAMP-006
Schedule.

Each step stores an IANA time zone and the resolved UTC instant. A local time that does not exist or is ambiguous under daylight saving is rejected until the operator chooses an unambiguous instant. Policy: campaign.send-time.v1; default: resolve every step against the store time zone and the operator-selected local time.

CAMP-007
Scheduled edits.

Editing a scheduled campaign creates a new draft revision and leaves the approved revision active until the replacement passes approval. Replacement approval atomically makes the new revision the campaign's only active schedule and cancels every pending recipient-step of the prior revision. Once any step has begun dispatching, edits can only create a new campaign; the original campaign and its later steps remain active until the operator explicitly cancels them.

CAMP-008
Test send.

A test sends only to the configured operator test addresses or phone numbers, is visibly marked as a test in its content and in campaign history, and changes no contact activity, reporting, attribution, or frequency protection.

CAMP-009
Cancellation.

Cancelling a scheduled, dispatching, or paused campaign stops every step and every recipient-step confirmed not handed to a provider within 30 seconds, records provider-confirmed hand-offs separately, and leaves an in-flight request in handoff-unknown until SEND-008 reconciles it. It never claims to recall a delivered message. Campaign detail shows the time remaining until the next step dispatches.

CAMP-010
Step deadline.

Each step carries a send-by instant, defaulting to the end of that step's scheduled local day. Recipient-steps not handed to a provider by then are skipped and recorded as deadline-passed; a step whose deadline passes before dispatch begins does not send.

CAMP-011
Dispatch punctuality.

Dispatch of a scheduled step begins within 60 seconds of its resolved UTC instant, and each step's instant dispatches exactly once even if the scheduler runs twice.

MSG11 clauses

MSG-001
Sender identity.

Every email uses the configured business display name, From address, reply-to address, and physical postal address; every SMS uses a sender registered for the recipient's country.

MSG-002
Email authentication.

A marketing email cannot be scheduled unless the mail adapter reports SPF, DKIM, and DMARC passing for the sending domain and the visible From domain aligns with an authenticated domain.

MSG-003
Email unsubscribe.

Every marketing email carries a visible unsubscribe link and an opaque per-recipient HTTPS List-Unsubscribe URL with List-Unsubscribe-Post: List-Unsubscribe=One-Click; DKIM covers both headers. The one-click URL accepts a context-free HTTPS POST body of List-Unsubscribe=One-Click, does not redirect, and applies CONT-004 before returning success. The visible link opens a page that applies CONT-004 on a single confirming action and never on page load, so a mailbox scanner or link prefetcher cannot unsubscribe anyone. Both paths are idempotent under repeats, need no session or cookie, and reveal no contact other than their own.

MSG-004
SMS permission.

An SMS is eligible only when its phone number is subscribed for the recorded consent scope and the SMS adapter confirms an approved sender for that recipient's country. For every permitted sender and jurisdiction, the adapter must be able to receive and enforce the standard opt-out and help keywords in CONT-007; otherwise SMS is blocked for that recipient.

MSG-005
SMS opt-out.

Every marketing SMS carries the configured programme identity and Reply STOP to unsubscribe, or the jurisdiction's required equivalent, and the configured frequency disclosure where required. An opaque unsubscribe URL may be additional but never replaces reply-based opt-out. Review shows the exact compliance text and resulting segment count.

MSG-006
Links.

Scheduling is blocked when a destination link is malformed, is not HTTPS, or resolves to a host outside the allowed link hosts configured in settings. Review names every blocked link.

MSG-007
Content checks.

Review names blocking and advisory content findings per channel. An operator can acknowledge an advisory finding; the consent, sender registration, opt-out, authentication, link, personalisation, and reputation checks are blocking and cannot be overridden.

MSG-008
Personalisation.

Every personalisation token carries a fallback value. Scheduling is blocked when a token has no fallback and cannot be resolved for any one eligible contact; otherwise the fallback is rendered and the count of contacts using it is shown in review.

MSG-009
Email body.

Every marketing email is sent as multipart/alternative with an HTML part and a plain-text part carrying the same offer, links, and unsubscribe link, plus the preheader text set on the revision. Operator-authored HTML is transmitted as authored within the allowed tag and attribute set, which admits no script, form, or remote stylesheet; the preview renders it sanitised per BASE-INPUT-002.

MSG-010
Unsubscribe availability.

The unsubscribe path answers within 2 seconds and is rate-limited per unsubscribe token at the limit in seed.json, not per client IP address. The token is the rate-limit key declared for this public path under BASE-ACCESS-003, so mailbox-provider requests for unrelated recipients cannot consume one another's allowance; an exceeded token allowance returns 429 without affecting other tokens.

MSG-011
Sending reputation.

Once a sending domain has at least 1,000 marketing deliveries in the reporting window, scheduling a marketing email from it is blocked while provider-reported complaints divided by delivered marketing emails are at or above 0.3%, or hard bounces divided by attempted marketing hand-offs are at or above 5% (RESULT-006). A provider's stricter block applies at any volume. The block names each numerator, denominator, reporting window, and provider rule, cannot be acknowledged away, recomputes when late facts arrive, and clears only when every applicable threshold is below its limit.

SEND9 clauses

SEND-001
Provider hand-off.

Email uses mail.sender.v1 and SMS uses sms.sender.v1. Every recipient-step carries a provider-effective idempotency key derived from the campaign, revision, step, and contact. Mango stores the provider message identifier before treating it as handed off. A timeout or lost response becomes handoff-unknown and is reconciled by provider lookup before any retry; an adapter whose deduplication retention cannot cover the campaign deadline and reconciliation window cannot pass CAMP-004. A retried job, redelivered queue message, or resumed dispatch therefore never produces a second provider message.

SEND-002
Quiet hours.

SMS is handed off only inside the recipient-local legal and provider-required windows. The recipient time zone is resolved from recorded location evidence with its source and freshness, never substituted with the store time zone; an unknown or stale zone blocks hand-off. Legal and provider windows are mandatory minima that a policy cannot weaken. Policy: sms.quiet-hours.v1; default: defer until the next allowed instant at or before the step's send-by instant (CAMP-010), otherwise skip and record quiet-hours-deadline.

SEND-003
Throttling and progress.

Dispatch paces hand-offs to the provider and carrier rate limits in seed.json. Campaign status shows the estimated completion instant and updates the handed-off, delivered, skipped, and failed counts within 30 seconds of each change.

SEND-004
Transport failure.

A transient provider or network failure on a recipient-step is retried up to 5 times over 1 hour with increasing delay, except that handoff-unknown is reconciled rather than retried. A permanent rejection or exhausted retry budget marks that recipient-step failed with the provider's error and campaign detail shows it; a hard rejection, complaint, or provider suppression also updates CONT-006 atomically before another hand-off.

SEND-005
Provider-event identity.

Every signed provider webhook is stored once as an immutable fact using the strongest identity that adapter declares: provider event identifier where supplied, otherwise provider message identifier, event kind, provider event time or version, and a stable payload digest. Replaying or reordering delivery, bounce, complaint, suppression, and SMS reply facts produces the same derived delivery disposition and contact state, and an older fact never downgrades a later provider disposition.

SEND-006
Delivery truth.

A recipient-step has a transport disposition of queued, handoff-unknown, handed-off, accepted, delivered, bounced, skipped, or failed, plus independent complaint and suppression facts. Delivered is recorded only from a provider fact asserting delivery; provider acceptance is never reported as delivery. A later complaint remains visible without erasing the earlier delivery fact, and a skipped disposition carries its reason.

SEND-007
Partial completion.

A campaign becomes completed only once every recipient-step has a terminal transport disposition; handoff-unknown is not terminal. Its summary keeps delivered, skipped, failed, bounced, complained, and suppressed totals separate and never sums them into a single success figure. Later complaint or suppression facts update the completed campaign's summary and the contact ledger.

SEND-008
Resumable dispatch and reconciliation.

Dispatch survives worker eviction, redeployment, and restart: it resumes from recipient-steps without a terminal transport disposition, sends nothing twice (SEND-001), and needs no operator action. At the reconciliation interval in seed.json, it queries the provider for handoff-unknown and other unresolved messages and imports missed provider facts. After the provider's declared lookup window expires, an unresolved message becomes failed with outcome-unconfirmed; it is never counted as delivered or retried blindly. A campaign never remains dispatching with no work or reconciliation in progress.

SEND-009
Provider outage.

When hand-offs to a provider fail transiently for 5 continuous minutes, or the adapter reports the provider unavailable, the affected campaign channel moves to paused and no recipient hand-offs are attempted on it. The adapter runs a bounded health probe or non-recipient canary at the reconciliation interval in seed.json; a successful probe resumes dispatch automatically, subject to CAMP-010 and AUD-005. The pause and provider error are shown on campaign detail, and each operator is emailed once as soon as the mail provider is available.

RESULT6 clauses

RESULT-001
Campaign history.

Operators can list campaigns by state and channel, open the approved revision, and inspect its audience snapshot, delivery timeline, cancellation, and per-channel outcome totals.

RESULT-002
Engagement.

Clicks and store conversions are shown as observed events. Open tracking is off by default; when an operator enables it, opens are labelled privacy-sensitive estimates and never support a confidence, deliverability, or attribution figure.

RESULT-003
Attribution.

Revenue attributed to a campaign names the qualifying store event and attribution window, is reported separately from any forecast, and is assigned at most once per order. Policy: campaign.attribution.v1; default: the most recent non-automated tracked click in the seven days before purchase wins; a cancellation or refund subtracts the corresponding attributed amount.

RESULT-004
Cost.

Each AI call and provider hand-off records the external provider, model or channel, billable units, and reported cost; totals are visible by campaign and by day.

RESULT-005
Link tracking.

A tracked link is rewritten to an opaque per-recipient-step redirect on this deployment that records the request and forwards to the original URL. The redirect sets no cookie, loads nothing, and carries no contact identifier in the destination URL. Known mailbox security scanners and bot requests are retained as automated events but excluded from engagement and attribution. An operator can disable tracking per campaign, which sends the original URLs and records no clicks.

RESULT-006
Deliverability reporting.

Per sending domain and SMS sender, Mango shows the delivered, bounced, complained, and failed counts and the resulting hard-bounce and spam-complaint rates over the reporting window in seed.json, and the rates MSG-011 is currently evaluating.

DATA1 clause

DATA-001
Export contents.

The export contains every contact, source record, consent record, suppression and surviving opt-out record (CONT-013), proposal, campaign, revision, audience decision, message, recipient-step outcome, attribution event, setting, and audit entry as JSON, and every uploaded campaign asset as its original file.


Baseline guarantees

22 declared clauses from this product's BASELINE.md. Selected ownership guarantees are shown below; execution evidence is separate.

BASE-DATA-005
Independence.

The deployment makes no request to the marketplace or the seed author. There is no telemetry, phone-home, licence check, or kill switch.

Declared guarantee
BASE-DATA-001
Export and import.

pnpm export produces every record and attachment; pnpm import restores it into an empty deployment; export, import, export yields an archive with equivalent contents.

Declared guarantee
BASE-DATA-004
Outbound flows.

User data leaves the deployment only through externals declared in seed.json → externals. No other outbound request carries user data.

Declared guarantee
BASE-PUBLIC-001
Privacy.

Public surfaces (widgets, booking pages, forms, status pages) set no cookies, load nothing from third-party domains, and send no visitor data before the visitor's first interaction.

Declared guarantee
BASE-SECRET-001
No leakage.

No secret appears in the client bundle, in logs, or in an error response.

Declared guarantee

BASELINE.md for Mango


Release history

Honest version: there is one release line so far, and we will not invent the rest.

v0.1.0
Current — contract-drafted-ui-prototype

The manifest states this version and maturity. Consult the source verification evidence before deployment.


DIY quickstart

The code is MIT and the deployment is yours. Nothing below talks to us; optional management remains planned.

This edition has not published a source README yet; use its manifest and contract for current scope and status.


View as agent

Everything on this page exists as machine-readable files. If you are an agent evaluating Mango for someone, read these instead of the prose.

No catalogue install command or source README is declared for this edition.

Catalogue endpoint

/agents/catalogue.json

Every seed with its id, category, version, clause count, install command and links to the files on the left. Generated from the seeds' own artifacts on every build, so it cannot drift from what ships.

The machine face

Mango landing screenshot

Run Mango on your own cloud.

MIT code, your data, your infrastructure. Leave whenever you like and it keeps running.