# MHI Gateway Delivery Roadmap

## Milestone RC1-9 — Persistent SMPP Runtime and Windows Supervision

Status: implemented and internally verified; awaiting independent review and deployment acceptance.

Scope: one `gateway:smpp:run yas` process owns the database lease, publishes outbox events, maintains one YAS transceiver, submits through approved authorities, records RC1-9A outcomes, polls inbound PDUs, processes DLRs, performs keepalive and bounded reconnect, recovers conservatively, and shuts down cooperatively.

Explicit exclusions: automatic retry, multiple sessions, provider failover, queue-worker substitution, public API or OpenAPI changes, bundled service-wrapper software, and automatic deployment.

## Milestone RC1-9A — Durable SMPP Submission Lifecycle

Status: implemented and internally verified; awaiting independent review.

Scope: extend the existing encrypted SMPP submission handoff with ownership-fenced pending, claimed, accepted, rejected, failed, and acknowledgement-unknown states; durable provider acknowledgement evidence; deterministic idempotency and conflict rejection; safe expired-claim recovery; provider-reference lookup for DLR correlation; and atomic submitted/rejected message projection. Historical claimed rows are preserved as uncertain rather than made eligible for resend.

Explicit exclusions: persistent runtime command, daemon supervision, reconnect scheduling, public API or OpenAPI changes, DLR parsing changes, webhook changes, automatic retry, and deployment.

Dependency and handoff: RC1-9A depends on the existing session lease, submission handoff, runtime executor, message projection, and DLR correlation boundaries. RC1-9 persistent runtime implementation may proceed only after independent approval of this durable lifecycle.

## Milestone 5C-3 — Inbound Handler Boundary

Status: implemented, awaiting approval.

Scope: one pure handler invocation converts mobile-originated, delivery-receipt, and unknown inbound routes into immutable typed handling results. Non-routable protocol results and failures remain unchanged. No persistence, queues, callbacks, tenant or application lookup, business processing, retry, reconnect, metric, HTTP, or future inbound behavior is included. `RuntimeLoop` remains unchanged.

## Milestone 5B-7 — Durable Inbound Envelope Foundation

Status: implemented, awaiting verification and independent approval.

### Objective

Implement the missing durable inbound-envelope recording foundation reserved by the existing `SmppInboundEnvelopeRepositoryInterface`.

### Scope

- Define an immutable inbound-envelope identity.
- Define provider/session transport provenance using existing authoritative runtime and protocol values.
- Add the inbound-envelope persistence model and migration.
- Store sensitive inbound PDU content encrypted at rest using established project encryption conventions.
- Record `AVAILABLE` as the initial inbound-envelope lifecycle state.
- Complete the repository recording operation reserved by `SmppInboundEnvelopeRepositoryInterface`.
- Integrate persistence before acknowledgement at the already approved inbound recording boundary.
- Add only the indexes, constraints, and timestamps required for secure deterministic recording.
- Add focused unit, repository, and dedicated MySQL integration coverage.

### Explicit Out of Scope

- Processing claims, claim ownership fencing, `PROCESSED` or `QUARANTINED` transitions, and stale-claim recovery.
- Classifier, router, or handler changes.
- Tenant resolution, MO message persistence, and DLR correlation or projection.
- Queues, retry workers, callbacks, and webhooks.
- Pricing, wallet, and billing behavior.
- Broad `RuntimeLoop` redesign.
- Milestone 5C-4 or later implementation.

### Expected Production Components

- `SmppInboundEnvelope` model/entity.
- One migration extending the existing schema only as required by the approved inbound-envelope design.
- Immutable envelope identity and provider/session transport-provenance values.
- Encrypted payload representation using established project encryption conventions.
- The completed recording portion of `SmppInboundEnvelopeRepositoryInterface`.
- One inbound-envelope repository implementation.
- Narrowly scoped persist-before-ack composition at the approved inbound receive boundary.

### Testing Requirements

- Construction and constructor-invariant tests for every new immutable value and record.
- Encryption-at-rest tests proving sensitive PDU plaintext is absent from storage and unsafe representations.
- Repository persistence and authorized retrieval tests.
- Envelope identity and transport-provenance retention tests.
- Tests proving every newly recorded envelope begins in `AVAILABLE`.
- Duplicate and idempotency tests matching the separately approved recording architecture.
- Dedicated MySQL transaction tests proving durable persistence completes before a successful acknowledgement is permitted.
- Persistence-failure tests proving a successful acknowledgement is not produced.
- Regression tests proving no processing, tenant, MO, DLR, queue, retry, callback, pricing, wallet, or billing behavior was added.
- Full PHPUnit through its final summary, full Pint, and `git diff --check`.

### Documentation Requirements

- Correct `docs/architecture.md` so it does not claim or imply that the inbound-envelope implementation was previously completed.
- Document the persist-before-ack recording boundary, encryption ownership, transport provenance, and initial `AVAILABLE` state.
- Update `docs/ROADMAP.md` with the corrective prerequisite and its relationship to Phase 5C.
- Update `docs/CHANGELOG.md` only when implementation completes.

### Exit Criteria

- One inbound `deliver_sm` can be durably and securely recorded with immutable identity and provider/session transport provenance.
- Every new record begins in `AVAILABLE`.
- A successful acknowledgement cannot occur before durable persistence succeeds.
- Persistence failure does not produce a successful acknowledgement.
- No processing lifecycle or business projection exists.
- Focused, regression, full-suite, MySQL, Pint, and diff verification pass through final results.
- Self-review and independent review approve the implementation.

### Dependencies

- Completed SMPP runtime, protocol decoding, and `DeliverSm` reception.
- Existing project encryption and database conventions.
- The reserved `SmppInboundEnvelopeRepositoryInterface`.

## Milestone 5C-4 — Inbound Envelope Processing Contract

Status: implemented, awaiting independent approval.

### Objective

Define immutable, effect-free contracts for processing one existing `AVAILABLE` inbound envelope and returning one deterministic processing outcome.

### Scope

- Define an immutable processing input derived from an existing `AVAILABLE` inbound envelope.
- Carry only safe envelope identity and provider/session transport-provenance references needed to validate processing ownership and trace the source record.
- Define immutable handled, rejected, and quarantined processing outcome types with complete constructor invariants.
- Define one narrow, effect-free processor interface that maps a valid processing input to exactly one deterministic outcome.
- Preserve the completed classifier, router, and handler types as the authoritative interpretation pipeline; do not duplicate their rules.

### Explicit Out of Scope

- Persistence implementation, schema changes, lifecycle mutation, transactions, encryption redesign, decryption infrastructure, or envelope recording.
- Tenant resolution, MO message persistence, DLR status mapping, provider-message-ID correlation, message-state projection, or any business projection.
- Queues, workers, retries, callbacks, webhooks, pricing, wallet, billing, metrics, and operational runtime activation.
- Changes to persist-before-ack recording, protocol decoding, classification, routing, handling, transport, session state, or `RuntimeLoop`.

### Expected Production Components

- One immutable inbound-envelope processing input.
- Safe immutable envelope-identity and provenance-reference values, reusing existing authorities wherever available.
- One closed processing-outcome contract with handled, rejected, and quarantined outcomes.
- One narrow inbound-envelope processor interface with no persistence or framework implementation.
- Dedicated invariant/error categories only where the processing boundary owns the rule.

### Testing Requirements

- Unit tests for processing-input construction, safe identity/provenance retention, and immutability.
- Data-driven invariant tests for missing, malformed, mismatched, or unsafe identity and provenance references.
- Unit tests for handled, rejected, and quarantined outcomes, including wrong-input and wrong-outcome rejection.
- Processor contract tests proving deterministic output and no persistence, decryption, queue, callback, framework, or external-I/O dependency.
- Relevant inbound-envelope and classifier/router/handler regressions; full PHPUnit, Pint, and `git diff --check`.

### Documentation Requirements

- Record the approved processing contract, outcome taxonomy, and dependency direction in `docs/architecture.md`.
- Update `docs/ROADMAP.md` and `docs/CHANGELOG.md` after implementation.
- Document that recording, encryption, and persist-before-ack provenance belong to the completed 5B architecture and are not recreated here.
- Document the absence of lifecycle persistence, tenant resolution, business projection, and runtime activation.

### Exit Criteria

- Architecture has been approved before implementation.
- A valid `AVAILABLE` envelope can be represented as one immutable processing input without exposing unsafe persisted content.
- Handled, rejected, and quarantined outcomes are closed, deterministic, and invariant-safe.
- The processor interface is minimal, effect-free, and has no persistence implementation.
- No business projection or lifecycle mutation exists.
- Required verification and independent approval are complete, with existing recording and protected runtime behavior unchanged.

### Dependencies

- Approved and completed Milestones 5C-1 through 5C-3.
- Approved and completed corrective Milestone 5B-7 — Durable Inbound Envelope Foundation, including its encrypted record, `AVAILABLE` initial state, persist-before-ack flow, and transport-provenance authorities.

## Milestone 5C-5 — Inbound Envelope Lifecycle Repository

Status: implemented, awaiting independent approval.

### Objective

Extend the existing inbound-envelope persistence boundary with safe, ownership-fenced processing lifecycle operations; do not create another store or alter recording and encryption.

### Scope

- Claim exactly one eligible `AVAILABLE` envelope through the existing inbound-envelope repository boundary.
- Prevent concurrent claims with an authoritative database lock and an opaque claim owner or equivalent approved ownership fence.
- Require matching claim ownership for every read and lifecycle mutation after claim.
- Mark a claimed envelope `PROCESSED` after one handled or rejected processing outcome.
- Mark a claimed envelope `QUARANTINED` after one quarantined processing outcome.
- Make terminal transitions idempotent for the same envelope, owner, and outcome while rejecting conflicts and stale owners.
- Define bounded, deterministic recovery rules for stale or interrupted claims using the authoritative database clock.
- Preserve the existing encrypted payload, transport provenance, persist-before-ack order, and original envelope identity.

### Explicit Out of Scope

- A second inbound-envelope table, model, repository, store, or encryption implementation.
- Redesign of envelope recording, sensitive-field encryption, transport provenance, or persist-before-ack acknowledgement behavior.
- Processing orchestration, classification, routing, handling, tenant resolution, MO persistence, DLR correlation, or message-state projection.
- Automatic retry workers, queues, callbacks, webhooks, pricing, wallet, billing, retention/purge automation, metrics, and diagnostics.
- Changes to `SessionExecutor`, protocol components, transport, session state machine, or `RuntimeLoop`.

### Expected Production Components

- Lifecycle operations added to the existing inbound-envelope repository contract.
- Minimal lifecycle fields, indexes, and constraints added to the existing inbound-envelope schema only where the completed 5B schema does not already provide them.
- Immutable claim and lifecycle result values carrying safe identity and ownership references.
- Existing repository implementation extended with claim, authorized read, `PROCESSED`, `QUARANTINED`, and stale-claim recovery operations.
- No additional inbound-envelope persistence adapter or store.

### Testing Requirements

- Repository tests for claiming one `AVAILABLE` envelope and excluding non-available or already-claimed records.
- Two-connection MySQL concurrency tests proving concurrent claim prevention and ownership fencing.
- Tests for authorized read/decryption access and rejection of missing, stale, or mismatched claim owners.
- Transition tests for `PROCESSED` and `QUARANTINED`, including same-outcome idempotency, conflicting terminal outcomes, and immutable terminal state.
- Stale/interrupted claim recovery tests covering exact expiry boundaries, database-clock authority, takeover ownership, and non-stale rejection.
- Regression tests proving ciphertext, provenance, envelope identity, and persist-before-ack recording remain unchanged and no second store exists.
- Full PHPUnit, dedicated MySQL integration coverage, Pint, and `git diff --check`.

### Documentation Requirements

- Update `docs/database.md` with only the lifecycle additions to the existing inbound-envelope schema, indexes, ownership fence, and recovery rules.
- Update `docs/architecture.md`, `docs/ROADMAP.md`, and `docs/CHANGELOG.md` after implementation.
- Reaffirm the existing encryption and persist-before-ack ownership; document that no second store was introduced.
- Document terminal idempotency, stale-claim recovery, and the absence of business processing.

### Exit Criteria

- Architecture and schema are approved before implementation.
- Exactly one eligible `AVAILABLE` envelope can be claimed, and concurrent or stale owners cannot read or mutate it.
- Valid owners can durably finalize `PROCESSED` or `QUARANTINED`; identical terminal repetition is safe and conflicting transitions fail without mutation.
- Stale claims recover only under the approved database-clock and ownership rules.
- Existing encryption, provenance, recording, and acknowledgement ordering are unchanged, with no second inbound-envelope store.
- Required regression verification and independent approval are complete; processing orchestration is not yet active.

### Dependencies

- Approved and completed Milestone 5C-4.
- The completed 5B inbound-envelope schema, repository, encryption, transport provenance, `AVAILABLE` state, and persist-before-ack recording flow.
- Authoritative database time and established row-lock/ownership-fencing conventions.

## Milestone 5C-6 — Inbound Processing Orchestration and Phase Closure

Status: implemented, awaiting independent approval and Phase 5C closure.

### Objective

Complete Phase 5C by composing one existing persisted envelope with the approved processing contract and completed classifier, router, and handler pipeline, then durably recording exactly one lifecycle outcome.

### Scope

- Add one application-level inbound processing orchestrator outside the stable protocol, routing, and handler layers.
- Execute the fixed flow: `AVAILABLE` envelope → claim → authorized read/decryption → processing input → classification → routing → handling → `PROCESSED` or `QUARANTINED`.
- Invoke each processing stage exactly once for one claimed envelope and durably finalize exactly one lifecycle outcome.
- Treat malformed, ambiguous, unsupported, or safely unprocessable envelope content according to the approved rejected/quarantined policy without inventing business semantics.
- Preserve envelope identity and provider/session transport provenance throughout processing.
- Return one immutable orchestration result that exposes safe outcome and lifecycle information only.

### Explicit Out of Scope

- Tenant resolution, MO message persistence, DLR status mapping, provider-message-ID correlation, and message-state projection.
- Callbacks, webhooks, queues, retry workers, pricing, wallet, billing, or any downstream business handoff.
- A second encrypted persistence implementation or redesign of the completed 5B recording, encryption, provenance, and persist-before-ack flow.
- Runtime receive-loop activation, reconnect, supervision, daemon/process commands, scheduling, metrics, and diagnostics.
- Changes to protocol authorities, stable classifier/router/handler semantics, transport, session state machine, acknowledgement ordering, or `RuntimeLoop`.

### Expected Production Components

- One application-level inbound processing orchestrator implementing the approved 5C-4 processor contract or composing behind it as architecture approval specifies.
- Minimal adapters that reconstruct the existing protocol processing input from an authorized decrypted envelope without duplicating decoder or classifier rules.
- Immutable orchestration success, quarantine, ownership-loss, and sanitized failure results only where existing lifecycle results are insufficient.
- Composition wiring to the existing inbound-envelope lifecycle repository, classifier, router, and handler; no hidden service location.
- No second repository, protocol category, route category, handling category, or business projection.

### Testing Requirements

- Unit tests for MO, DLR, and unknown envelope processing through classification, routing, handling, and the correct terminal lifecycle outcome.
- Invocation-count tests proving one claim, one authorized read/decryption, one classification, one route, one handle, and one terminal mutation per applicable envelope.
- Malformed, ambiguous, unsupported, ownership-loss, decryption-failure, and lifecycle-write-failure tests proving deterministic rejection or quarantine, no retry, no duplicate finalization, and no false success.
- Integration tests proving already-terminal envelopes are idempotent, concurrently claimed envelopes are fenced, and interrupted claims follow only the 5C-5 recovery rules.
- Regression tests proving persist-before-ack recording, encryption, transport provenance, session behavior, and `RuntimeLoop` remain unchanged and no business projection occurs.
- Full PHPUnit through its final summary, dedicated MySQL lifecycle/concurrency tests, full Pint, and `git diff --check`.

### Documentation Requirements

- Update `docs/architecture.md` with the final Phase 5C persisted-envelope processing flow and pure/effectful boundaries.
- Update `docs/ROADMAP.md` to mark Phase 5C complete only after independent approval.
- Update `docs/CHANGELOG.md` with implemented behavior and explicit exclusions.
- Reconcile `docs/database.md` with the implemented lifecycle behavior without restating or redesigning the completed 5B store.
- Record the next-phase handoff: terminal processing outcomes may be consumed only by separately approved tenant, MO, DLR, and business-projection use cases.

### Exit Criteria

- Architecture is approved before implementation and all 5C-6 acceptance criteria are verified.
- One eligible `AVAILABLE` envelope follows the approved claim-to-terminal flow with exact invocation counts and ownership enforcement.
- Successfully handled or deterministically rejected input becomes `PROCESSED`; unsafe or unprocessable input becomes `QUARANTINED` according to the approved policy.
- Exactly one terminal lifecycle outcome is durably recorded or one typed failure is returned; no retry or false success occurs.
- Existing encrypted recording, persist-before-ack ordering, transport provenance, and protected runtime behavior remain unchanged.
- No tenant resolution, MO persistence, DLR projection/correlation, callback, queue worker, billing behavior, or second store exists.
- Full verification, self-review, independent approval, and protected-file comparisons pass; Phase 5C is complete and ready to hand off to the next major phase.

### Dependencies

- Approved and completed Milestones 5C-1 through 5C-5.
- The completed 5B encrypted inbound-envelope recording and authorized read/decryption facilities.
- The verified 5C-4 processing contract and 5C-5 lifecycle repository operations.
- The completed classifier, router, and handler pipeline from Milestones 5C-1 through 5C-3.

## Milestone RC1-1 — API Contract & Message Lifecycle Design Freeze

### Status

Completed and committed as the approved API v1 release-candidate contract freeze.

### Deadline Context

RC1 work temporarily takes priority over deferred Phase 6 business-store work. Required sequence: RC1-1 API Contract Freeze; RC1-1A Bulk API Contract Amendment; RC1-2 Send API Hardening; RC1-3 Bulk API; RC1-4 Message Status API; RC1-5 DLR Correlation and Projection; RC1-5A Webhook Contract Amendment; RC1-6 Tenant Delivery Webhooks; RC1-7 Integration Documentation and YAS Acceptance.

Milestone 6A — Durable Mobile-Originated Message Store is deferred, not cancelled. It resumes only after RC1 closure and fresh independent implementation approval.

### Objective

Freeze a coherent, auditable API v1 contract for single and bulk SMS submission, message retrieval, normalized lifecycle status, and delivery-webhook configuration before production implementation changes begin.

### Dependencies

- Existing tenant/application authentication, request context, message creation, message query, and persistence foundations.
- Completed outbound SMPP submission and inbound DLR classification foundations.
- Existing public API behavior documented in `docs/api.md` and implemented routes, requests, controllers, resources, middleware, enums, and database constraints.
- Independent architecture approval for every unresolved contract decision.

### Required Scope

- Audit and classify all six proposed resources as existing-compatible, hardening-required, missing, or superseded.
- Freeze request, response, validation, authentication, authorization, idempotency, correlation, error, and compatibility semantics.
- Freeze one normalized public message lifecycle and its mapping from existing internal message, delivery, dispatch, attempt, and SMPP receipt states.
- Define safe DLR correlation, duplicate, conflict, timestamp, and uncorrelated-receipt behavior.
- Define delivery-webhook configuration, event, signature, replay, deduplication, and delivery-policy boundaries.
- Provide a valid OpenAPI 3.1 representation and record every value that remains an approval blocker.

### Components

- `docs/api/API_V1_CONTRACT.md` as the human-readable audit and contract rationale.
- `docs/api/openapi.yaml` as the normative OpenAPI 3.1 implementation source of truth.
- Architecture, roadmap, and changelog entries describing sequencing, boundaries, and compatibility gaps.
- No runtime component, route, controller, service, repository, migration, model, provider, configuration, or test implementation.

### Explicit Exclusions

- Implementing or changing endpoints, routes, middleware, controllers, requests, resources, services, repositories, models, migrations, providers, jobs, queues, callbacks, webhook senders, SMPP components, or runtime behavior.
- Tenant redesign, billing, wallet, pricing, MO business persistence, keyword processing, reporting, or provider routing changes.
- Inventing numeric retention, timeout, retry, replay, batch, or secret-policy bounds without independent approval.
- Removing or silently reinterpreting existing API behavior.

### Required Audit

- Compare the six proposed resources with current routes and controllers.
- Compare frozen fields and limits with validators, configuration, resources, enums, database indexes, and existing API documentation.
- Verify bearer authentication, tenant/application isolation, correlation, error, and idempotency behavior.
- Identify whether provider correlation, delivery projection, batch identity, webhook configuration, and webhook dispatch exist.
- Record legacy compatibility requirements and explicit unresolved decisions.

### Required Documentation

- Update `docs/ROADMAP.md`, `docs/CHANGELOG.md`, and `docs/architecture.md`.
- Add `docs/api/API_V1_CONTRACT.md` and `docs/api/openapi.yaml`.
- Keep prose and OpenAPI fields, schemas, statuses, headers, errors, and security aligned.
- State prominently that the freeze is proposed and does not implement endpoints.

### Verification

- Prove only the five approved documentation files changed.
- Parse the YAML and validate its OpenAPI 3.1 document shape.
- Run `git diff --check` and a governance self-review.

### Exit Criteria

- All six resources have an evidence-backed implementation classification.
- Request, response, lifecycle, DLR, webhook, security, idempotency, correlation, error, and compatibility contracts are internally consistent.
- OpenAPI and prose agree and unresolved decisions are explicit blockers.
- Independent review approves the freeze before RC1-2 implementation.
- No production behavior changed and Milestone 6A remains deferred rather than cancelled.

## Milestone 6A — Durable Mobile-Originated Message Store

Status: deferred, not cancelled. RC1-1 through RC1-7 temporarily take priority; implementation requires renewed independent approval after RC1 closure.

## Milestone RC1-1A — Bulk API Contract Amendment

Status: completed documentation-only architecture amendment; RC1-3 implementation remains a separate milestone.

Objective: amend the frozen API v1 contract to approve `POST /api/v1/messages/bulk` as an ordered, best-effort, partial-success endpoint with 1–100 items, HTTP `202`, an ephemeral replay-stable UUIDv4 `batch_id`, ordered per-item results, and tenant-scoped durable whole-request idempotency.

Scope: documentation and OpenAPI only. It freezes request-level versus per-item failures, `accepted` and `rejected` counters, one result per input index, `queued` accepted status, current-request correlation headers, replay stability, concurrent request behavior, and explicit exclusions. It introduces no route, controller, service, repository, migration, model, test, configuration, queue, DLR, webhook, status projection, billing, or SMPP/runtime behavior.

Dependencies: committed RC1-1 contract freeze and merged RC1-2 Send API Hardening.

Exit criteria: prose and OpenAPI agree, the five documentation files are the only changes, YAML and schema consistency checks pass, independent review approves the amendment, and RC1-3 remains unimplemented.

## Milestone RC1-2 — Send API Hardening

Status: implemented, verified, committed, and merged.

Scope: harden only `POST /api/v1/messages` with frozen request aliases, normalized `202` result, UUIDv4 request correlation, stable send-boundary errors, tenant-scoped durable replay, conflict fencing, and safe submission logging. On replay, the response header identifies the current HTTP request while the body retains the original message correlation. Existing authentication and rate limiting remain authoritative. Bulk submission, status projection, DLR correlation, webhooks, retries, billing, SMPP behavior, and runtime behavior remain excluded.

## Milestone RC1-3 — Bulk Message Submission API

Status: implemented and verified; awaiting independent review.

Scope: implement only `POST /api/v1/messages/bulk` as the approved authenticated, tenant-isolated, ordered best-effort boundary for 1–100 messages. A thin application orchestrator validates each item independently and delegates accepted items to the unchanged RC1-2 single-message creation service. Tenant-scoped durable replay metadata preserves the original UUIDv4 `batch_id`, counters, ordering, message identities, and safe item errors; concurrent equivalent requests converge and conflicting payloads fail closed. The correlation header identifies the current request. No public batch resource, GET, cancellation, retry, scheduling, template, campaign, DLR, status projection, webhook, billing, wallet, SMPP, session, or runtime behavior is included.

## Milestone RC1-4 — Message Status API

Status: implemented and verified; awaiting independent review.

Scope: normalize only the existing authenticated `GET /api/v1/messages/{message_id}` boundary to the committed `MessageDetails` contract. One tenant- and application-scoped query returns the public message identity, recipient, optional sender and client reference, closed public status, UTC creation time, and current-request correlation. A pure application projector maps existing message and delivery state without adding or mutating lifecycle evidence. Malformed identifiers, absent records, and cross-tenant records fail through the standardized API error boundary. No dedicated `/status` endpoint, DLR ingestion, status transition, callback, webhook, retry, scheduling, batch retrieval, reporting, billing, wallet, SMPP, session, or runtime behavior is included.

## Milestone RC1-4A — Dedicated Message Status Route Correction

Status: implemented and verified; awaiting independent review.

Scope: correct the RC1-4 runtime omission by adding the already frozen authenticated `GET /api/v1/messages/{message_id}/status` resource. The compact response reuses the existing tenant/application-scoped status query and public projector, returns only the contracted normalized status fields and authoritative occurrence time, and preserves the distinct full-message endpoint unchanged. No API-contract, OpenAPI, schema, DLR, webhook, idempotency, SMPP, session, or runtime-loop behavior changes.

## Milestone RC1-5 — Delivery Receipt Correlation and Public Status Projection

Status: implemented and verified; awaiting independent review.

Scope: consume the existing typed inbound delivery-receipt handling outcome after classification, routing, and handling; extract the already validated SMPP receipt identity and state; correlate it deterministically to one acknowledged outbound attempt by provider code and provider reference; and atomically append normalized evidence, update internal delivery state, and append one message event. Exact duplicates are idempotent, ambiguous or unknown references do not mutate messages, and conflicting terminal evidence is retained without rewriting a terminal outcome. RC1-4 reads the resulting state through its existing projector. No public endpoint, webhook, callback, retry, scheduler, campaign, template, report, billing, wallet, reconnect, SessionExecutor, or RuntimeLoop behavior is included.

## Milestone RC1-5A — Webhook Contract Amendment

Status: documentation-only architecture amendment; RC1-6 implementation remains separate and pending independent approval.

Objective: remove the remaining tenant-webhook architecture ambiguities by freezing one tenant configuration, its API, secret lifecycle, signing, replay protection, timeout, failure, retention, terminal-event, payload, and idempotency rules.

Scope: documentation and OpenAPI only. RC1 supports one configuration at `GET /api/v1/webhook` and `PUT /api/v1/webhook`; PUT creates or replaces it. Secrets contain at least 32 random bytes, are write-only, rotate with a 24-hour overlap, and sign exact timestamp/body bytes with HMAC-SHA256. The replay window is five minutes, outbound timeout is 10 seconds, each event gets one attempt with no RC1 retry, attempt retention is 90 days, and failures never roll back delivery persistence. Only delivered, failed, expired, and rejected terminal outcomes emit the approved public-only payload, exactly once.

Dependencies: completed RC1-5 normalized delivery evidence and the committed RC1-1 API contract. RC1-6 depends on independent approval of this amendment; RC1-7 follows RC1-6.

Exit criteria: prose and OpenAPI agree, only the five approved documentation files change, OpenAPI validation and `git diff --check` pass, independent review approves the amendment, and no production or test behavior is introduced.

## Milestone RC1-6 — Tenant Delivery Webhooks

Status: implemented and verified; awaiting independent review.

Scope: implement the approved tenant-scoped `GET /api/v1/webhook` and create-or-replace `PUT /api/v1/webhook` configuration boundary, encrypted current and overlapping secrets, atomically recorded terminal webhook events, and exactly one post-commit outbound delivery attempt. Delivery reuses RC1-5 normalized evidence and the existing public status projector. Only delivered, failed, expired, and rejected outcomes emit public-only HMAC-SHA256 signed payloads. Attempts use a 10-second timeout, persist success or sanitized failure for 90 days, and never roll back committed message delivery.

Explicit exclusions: retries, retry scheduling, exponential backoff, dead-letter queues, dashboards, statistics, billing, wallet, schedules, campaigns, templates, SMPP runtime changes, `SessionExecutor`, and `RuntimeLoop`.

Dependency: completed and independently approved RC1-5A Webhook Contract Amendment and completed RC1-5 normalized delivery evidence.

## Milestone RC1-7 — Integration Documentation and YAS Acceptance

Status: documentation implementation complete and internally verified; staging acceptance, YAS external acceptance, and production approval pending.

Scope: publish the release-candidate handover, implemented API examples, deployment sequence, RC migration/rollback guidance, operations runbook, exact YAS configuration inventory, external-information checklist, 25 executable acceptance scenarios, webhook receiver verification, evidence requirements, security checklist, known limitations, and production go/no-go gate. This milestone documents committed behavior only and changes no API contract, production code, tests, migration, configuration, SMPP component, `SessionExecutor`, or `RuntimeLoop` behavior.

Exit criteria: documentation references and examples agree with the committed contract and repository; OpenAPI parses; commands, configuration keys, and migration names are verified; only documentation files change; independent documentation review approves the handover. RC1 closes only after staging evidence, YAS sign-off, rollback readiness, and production approval are recorded. Milestone 6A remains deferred, not cancelled until that closure.

## Milestone RC1-8 — Staging Deployment, SDKs and Integration Package

Status: integration package implemented and internally verified; deployment, staging execution, external acceptance, and independent review pending.

Scope: provide an operator-led staging deployment runbook for `10.0.0.200`, generic client integration and quick-start guides, a layered staging smoke test, placeholder-only cURL/Postman examples, standalone PHP/Python/Node clients, webhook verification samples, and instructions for producing the ignored `dist/client-integration/` package. The frozen API contract and OpenAPI document remain unchanged. No deployment is performed and no production code, runtime behavior, schema, migration, test, or configuration is changed.

Exit criteria: every sample matches the authoritative contract; supported-language syntax, JSON, OpenAPI, Markdown links, secret safety, documentation-only scope, and diff whitespace pass; all unknown server and operational facts remain explicit; independent review approves the package before any staging action.

## Milestone 5C-2 — Inbound Routing Foundation

Status: implemented, awaiting approval.

Scope: one pure routing step converts the three typed `deliver_sm` protocol results into immutable mobile-originated, delivery-receipt, or unknown routes while preserving every other protocol result unchanged. No application routing, tenant lookup, persistence, database access, queue, callback, event, retry, reconnect, daemon, metric, HTTP, or business behavior is included. `RuntimeLoop` remains unchanged.

## Milestone 5C-1 — `deliver_sm` Reception and Classification

Status: implemented, awaiting approval.

Scope: protocol-only decoding of one `deliver_sm`, raw TLV preservation, classification as mobile-originated, delivery receipt, or unknown, one sequence-matched successful response, and immutable typed results. `RuntimeLoop` is unchanged. No persistence, routing, tenant or business processing, queues, callbacks, retries, reconnects, scheduling, daemon, metrics, diagnostics, webhooks, HTTP endpoints, or database writes are included.

## Milestone 5B-7 — SMPP Runtime Protocol Event Processing

Status: awaiting approval.

Scope: one bound-session receive operation that reads and decodes exactly one SMPP PDU, deterministically classifies the protocol event, automatically emits one `enquire_link_resp`, and returns immutable typed results for `generic_nack`, unsupported requests, unexpected responses, unknown commands, malformed PDUs, transport failures, and illegal session state. `RuntimeLoop` and all runtime actions remain unchanged.

At the 5B-7 baseline, `deliver_sm` remained unsupported. No `deliver_sm` processing, DLR interpretation, inbound routing, persistence, database write, retry, reconnect, throttling, windowing, heartbeat scheduler, daemon, background worker, supervision, metric, or diagnostic behavior was introduced. Milestone 5C-1 supersedes only that protocol-level `deliver_sm` limitation.

## Milestone 5B-6 — SMPP Outbound Execution

Status: awaiting approval.

Scope: execution of the 5B-5 lease, claim, mapping, offline encoding, release, and sleep intents; an immutable claimed-submission-to-session handoff with typed SMSC acceptance/rejection; a bounded, explicitly verified TCP/TLS binary transport; and a synchronous SMPP session lifecycle covering connect, binding, bound enquire-link, `submit_sm`/`submit_sm_resp`, unbinding, close, and fatal failure. The offline 5B-4 codec and protocol-owned factories remain the PDU construction/serialization boundary, and the 5B-5 loop remains a pure intent planner.

Short messages retain the current byte-string/data-coding-zero policy and 254-byte maximum; segmentation is deferred. Tests use persistence, session-port, connector, stream, and sleeper fakes and require no live SMSC. Reconnect, retry, DLR processing, inbound routing, throttling, windowing, metrics, diagnostics, daemon commands, supervision, and persistent processes remain deferred.

## Milestone 5B-5 — Deterministic SMPP Runtime Skeleton

Status: awaiting approval.

Scope: a framework-free single-iteration intent planner with immutable contexts, execution outcomes, actions, failures, and results; explicit acquiring, owned, lease-lost, stopping, and stopped states; validated ownership transitions; injected clock; bounded millisecond poll/idle/lease timing; bounded batch configuration; submission-to-`submit_sm` mapping intent; and offline encoding intent. Mapping or encoding failure preserves valid ownership and sequence deterministically, while durable claimed-submission recovery remains deferred.

The loop executes no repository, mapper, encoder, sleep, socket, TCP/TLS, live bind, live `submit_sm`, transport read or write, reconnect, keepalive, retry, recovery, DLR, inbound routing, diagnostic, metric, service command, persistent process, or Laravel facade operation.

## Milestone 5B-4 — Offline SMPP Protocol Engine

Scope: immutable validated SMPP header, TLV, and command objects with shared body-derived command lengths; closed registry-driven binary encoding and decoding; network-order integer, field-bounded C-Octet, and TLV serialization; exact packet-boundary and response-semantics validation; derived 0–254-octet `submit_sm` payload lengths; byte-for-byte preservation of unknown and duplicate TLVs in wire order; and a deterministic in-memory positive `uint32` sequence generator. The engine requires 64-bit PHP with `PHP_INT_SIZE >= 8`. Supported commands are `bind_transceiver`, `bind_transceiver_resp`, `submit_sm`, `submit_sm_resp`, `enquire_link`, `enquire_link_resp`, `unbind`, `unbind_resp`, and `generic_nack`.

The engine is offline serialization infrastructure only. It adds no socket, TCP, TLS, bind or submission execution, runtime, dispatcher, session lease behavior, reconnect, keepalive, retry, delivery receipt, inbound routing, metric, or diagnostic behavior.

## Milestone 5B-3 — Durable Submission Handoff

Scope: publisher-only enqueue into an encrypted durable SMPP submission queue and atomic claim ownership that locks and validates the active unexpired session lease before deterministically locking submissions. Missing, stale, or expired lease identity is rejected without mutation. Only `pending` and `claimed` states exist. No SMPP protocol, runtime loop, recovery, retry, terminal outcome, inbound, DLR, or diagnostic behavior is implemented.

## Milestone 5B-2 — YAS SMPP Session Lease

Scope: logical lease ownership through a single durable row per provider, opaque owner validation, monotonically increasing generation fencing, authoritative MySQL UTC time, row-locked transactional acquisition and takeover, heartbeat renewal, expiration-based release, immutable snapshots, and dedicated-MySQL concurrency checks. Exactly one live SMPP socket remains a later runtime responsibility.

No runtime process, socket, SMPP protocol engine, event loop, keepalive, reconnect, publisher, submission persistence, inbound persistence, DLR interpretation, or diagnostic behavior is introduced.

## Milestone 5B-1 — YAS SMPP Runtime Foundation

Scope: immutable fail-closed runtime configuration, transport-lifecycle enums, validated non-database value objects, minimal transport and future repository contracts, and dependency registration for configuration only. Provider-dependent timing settings remain explicit and runtime activation remains disabled. Configuration resolution requires a complete valid timing set even while disabled, but its lazy registration does not affect normal application boot.

No database, migration, repository implementation, lease behavior, socket, protocol engine, persistent process, runtime command, submission handoff, inbound envelope, receive loop, keepalive, reconnect, diagnostics, DLR interpretation, or message-state behavior is introduced in this phase.

## Milestone 5A — YAS SMPP Operational Hardening

Scope: one immutable fail-closed YAS configuration shared by operational and diagnostic paths; exact transceiver, `TR`, SMPP 3.4 and TON/NPI enforcement; explicit registered-delivery bytes; bounded endpoint and timeout validation; and the confirmed `max_sessions=1` limitation.

Read and write timeout enforcement is included. The validated `connect_timeout` key is retained as deferred compatibility configuration because the current vendor path has no distinct TCP connect-timeout control.

Delivered without activating long-lived transceiver operation. Session ownership/locking, persistent workers, receive loops, enquire-link processing, reconnection, DLR parsing/persistence, callbacks, webhooks, and message-state updates are deferred to Milestone 5B. Until session coordination exists, manual diagnostics and operational publishing must not run concurrently for the same System ID.

## Milestone 4 — Internal Prepaid Wallet and Ledger Foundation

Scope: tenant/currency wallets, prepaid available and reserved projections, message reservations, balanced immutable ledger transactions and entries, internal credit/reserve/capture/release services, operation-aware HMAC idempotency, tenant isolation, safe audit evidence, and MySQL locking verification.

Explicitly deferred: pricing, dispatcher charging, payment/recharge integration, top-up APIs, refunds, reversals, partial settlement, credit limits, queues, workers, retries, scheduler, DLR, routing, webhooks, invoices, and UI. The dispatcher, providers, outbox, and public API remain unchanged.

## 1. Long-Term Product Vision

MHI Gateway is not an SMS gateway. It is a Communications Platform designed to serve enterprise messaging and engagement use cases across multiple channels and markets.

The platform will eventually support:

- SMS
- WhatsApp
- Email
- Push Notifications
- Voice
- USSD
- OTP
- Templates
- Campaigns
- Customer Journeys
- Analytics
- AI-assisted routing
- Multi-country providers

The architecture will remain channel-neutral so that messaging, workflow orchestration, billing, routing and observability are reusable across all channels.

## 2. Milestone-Driven Delivery Plan

The roadmap below is organized by delivery milestones rather than abstract technology phases. Each milestone is an engineering release train that produces a working and releasable capability.

### Milestone 0 — Foundation & SMPP Core

Release: v0.1.0

Objectives
- Preserve the already-working YAS SMPP implementation
- Build reusable SMPP services
- Implement ProviderConnection management
- Add health checks for provider connectivity
- Support persistent SMPP workers
- Establish configuration management and structured logging
- Create the queue skeleton
- Add automated tests for SMPP core behavior

Definition of Done
- YAS bind works
- Health checks work
- Tests pass
- Logging works

### Milestone 1 — Multi-Tenant Core

Release: v0.2.0

Objectives
- Implement Tenants
- Implement Applications
- Implement API Credentials
- Deliver authentication and authorization
- Add RBAC
- Add tenant-aware middleware
- Establish audit base models and logging

Definition of Done
- Multiple tenants are supported
- API authentication works
- Tenant isolation is verified

### Milestone 2 — Messaging Engine

Release: v0.3.0

Objectives
- Implement the Message model
- Implement SMS-specific message handling
- Build the routing engine
- Add message attempts and delivery receipts
- Implement retry logic
- Add queue-based message processing

Definition of Done
- POST /messages/send works
- SMS can be delivered
- Delivery receipt processing works
- Retry works

### Milestone 3 — Wallet & Billing

Release: v0.4.0

Objectives
- Implement Wallets
- Implement the immutable ledger
- Add reservation, capture, release and reversal flows
- Build the pricing engine
- Support charges, refunds and topups

Definition of Done
- The ledger is accurate
- Reserve/Capture/Release workflow is complete
- Pricing engine is complete

### Milestone 4 — Public API

Release: v0.5.0

Objectives
- Deliver a REST API surface
- Support bulk messaging
- Add OTP APIs
- Add webhook support
- Publish OpenAPI documentation
- Prepare SDK integration readiness

Definition of Done
- The public API is stable
- OpenAPI documentation is complete

### Milestone 5 — Administration Dashboard

Release: v0.6.0

Objectives
- Deliver a Filament-based admin experience
- Manage users, providers, wallets and reports
- Add monitoring and operational tools
- Support tenant management workflows

Definition of Done
- The operational dashboard is complete

### Milestone 6 — Additional Channels

Release: v0.7.0

Objectives
- Add WhatsApp support
- Add Email support
- Add Push Notifications support
- Add Voice support
- Add USSD support

Definition of Done
- Multi-channel messaging is operational

### Milestone 7 — High Availability & Enterprise Readiness

Release: v1.0.0

Objectives
- Optimize Redis usage
- Scale queue processing
- Run multiple SMPP workers
- Add provider failover
- Improve monitoring and metrics
- Add backup and disaster recovery
- Perform performance tuning and production hardening

Definition of Done
- Production-ready deployment is available
- High availability is validated

## 3. Branch Strategy

The implementation workflow should use a disciplined branching strategy.

Recommended branches:

- main
- develop
- feature/m0-smpp-core
- feature/m1-tenancy
- feature/m2-messaging
- feature/m3-wallet
- feature/m4-api
- feature/m5-dashboard
- feature/m6-channels
- feature/m7-ha
- bugfix/*
- hotfix/*

## 4. Versioning Strategy

The platform should use Semantic Versioning.

- v0.1.0 — Foundation & SMPP
- v0.2.0 — Tenancy
- v0.3.0 — Messaging
- v0.4.0 — Billing
- v0.5.0 — Public API
- v0.6.0 — Dashboard
- v0.7.0 — Additional Channels
- v1.0.0 — Enterprise Production Release

## 5. Definition of Done

No milestone is complete until all of the following are satisfied:

- Architecture updated
- Database updated
- API updated
- Documentation updated
- Unit tests
- Feature tests
- Integration tests
- Code review
- Security review
- Deployment verification

## 6. Development Workflow

The delivery workflow should follow this order:

Architecture
↓
Documentation
↓
Database Design
↓
API Design
↓
Security Review
↓
Codex Implementation
↓
Code Review
↓
Unit Tests
↓
Feature Tests
↓
Integration Tests
↓
Deploy to Test Server
↓
User Acceptance Testing
↓
Merge into develop
↓
Release

## 7. CI/CD

A future CI/CD pipeline should automate validation and deployment.

Pipeline:

Git Push
↓
Bitbucket
↓
Composer Install
↓
Laravel Pint
↓
PHPStan
↓
PHPUnit/Pest
↓
Build
↓
Deploy to Test Server
↓
Smoke Tests

## 8. Documentation Policy

Every completed milestone must update:

- architecture.md
- database.md
- api.md
- security.md
- ROADMAP.md
- CHANGELOG.md

No feature is considered complete without documentation updates.

## 9. Success Criteria

Project success will be measured by the following outcomes:

- Clean architecture maintained
- Tenant isolation guaranteed
- Immutable billing
- Provider abstraction
- High observability
- Security by default
- Horizontal scalability
- Multi-channel extensibility
- Zero breaking API changes inside the same API version
- Enterprise-grade maintainability
