docs(campaign): define target-like mail evidence
This commit is contained in:
@@ -44,6 +44,57 @@ If the smoke is started immediately after `docker compose up -d`, GreenMail may
|
|||||||
bind the SMTP/IMAP ports before the services are fully ready. The smoke retries
|
bind the SMTP/IMAP ports before the services are fully ready. The smoke retries
|
||||||
login and folder setup for `GOVOPLAN_MAIL_TEST_READY_TIMEOUT_SECONDS`.
|
login and folder setup for `GOVOPLAN_MAIL_TEST_READY_TIMEOUT_SECONDS`.
|
||||||
|
|
||||||
|
## Campaign Acceptance
|
||||||
|
|
||||||
|
The transport smoke proves the Mail adapters. The Campaign acceptance runner
|
||||||
|
proves the public composition: it creates an isolated temporary Core database,
|
||||||
|
creates a Mail-owned encrypted profile through the API, materializes the
|
||||||
|
credential-free [`greenmail-delivery`](../../examples/greenmail-delivery/campaign.json)
|
||||||
|
fixture with only that profile reference, validates/builds it, sends the exact
|
||||||
|
generated EML through Campaign once, appends it once, and cross-checks Campaign
|
||||||
|
report/audit state with one unique-subject message in the GreenMail INBOX and
|
||||||
|
Sent folders. Provider mailbox verification is not a byte-for-byte comparison
|
||||||
|
after provider-side header or storage transformations.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /mnt/DATA/git/govoplan-campaign/dev/mail-testbed
|
||||||
|
set -a
|
||||||
|
. ./.env
|
||||||
|
set +a
|
||||||
|
/mnt/DATA/git/govoplan/.venv/bin/python run_campaign_acceptance.py \
|
||||||
|
--evidence /tmp/govoplan-campaign-greenmail-evidence.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The default run also uses controlled loopback protocol endpoints to prove that
|
||||||
|
an SMTP connection loss before transmission is temporary, an explicit SMTP
|
||||||
|
authentication rejection is permanent, and an IMAP authentication rejection
|
||||||
|
after SMTP acceptance leaves the send accepted while the append fails. A
|
||||||
|
second ordinary send must be rejected before another provider effect.
|
||||||
|
|
||||||
|
The bounded JSON contains no endpoint, account, address, credential, profile,
|
||||||
|
campaign, version, or job identifiers. It records module versions, the fixture
|
||||||
|
hash, normalized classifications/counts, the Mail-profile boundary, required
|
||||||
|
audit actions, provider mailbox increments, and coverage flags. Runtime version
|
||||||
|
declarations identify the exercised composition; they do not claim that the
|
||||||
|
sources are clean, tagged, signed, or release-provenanced. The evidence names
|
||||||
|
them `declared_module_versions` and keeps `source_artifact_provenance` false;
|
||||||
|
exact commit/artifact provenance belongs to the package and release gate.
|
||||||
|
|
||||||
|
This runner is restricted to literal loopback IP addresses and the synchronous
|
||||||
|
Campaign delivery mode. Hostnames such as `localhost` and every non-loopback
|
||||||
|
address fail before profile creation, avoiding a DNS change between validation
|
||||||
|
and connection. It is local target-like evidence, not approval of an
|
||||||
|
institution's SMTP/IMAP service. A post-DATA connection loss
|
||||||
|
with ambiguous SMTP outcome, an explicit temporary SMTP response, partial
|
||||||
|
recipient refusal, and a real worker restart remain separate drills and are
|
||||||
|
explicitly `false` in the coverage projection. Use `--success-only` only when
|
||||||
|
testing the success journey without the local failure endpoints.
|
||||||
|
|
||||||
|
Starting the maintained test bed requires a working Docker CLI, Compose plugin,
|
||||||
|
daemon/socket access, and permission to pull `greenmail/standalone:2.1.9`. The
|
||||||
|
Campaign runner needs only the already-running loopback endpoints; it neither
|
||||||
|
starts Docker nor claims that it did.
|
||||||
|
|
||||||
## Use With A Campaign
|
## Use With A Campaign
|
||||||
|
|
||||||
Use the same settings in a campaign mail profile:
|
Use the same settings in a campaign mail profile:
|
||||||
|
|||||||
@@ -104,6 +104,19 @@ bed where possible:
|
|||||||
- IMAP append failure after SMTP acceptance.
|
- IMAP append failure after SMTP acceptance.
|
||||||
- Worker restart with queued, claimed, and sending jobs.
|
- Worker restart with queued, claimed, and sending jobs.
|
||||||
|
|
||||||
|
For the maintained loopback baseline, run
|
||||||
|
`dev/mail-testbed/run_campaign_acceptance.py`. It proves the public Campaign
|
||||||
|
path for SMTP acceptance, IMAP append, repeat-send blocking, an SMTP connection
|
||||||
|
failure before transmission, an explicit SMTP authentication rejection, and an
|
||||||
|
IMAP authentication rejection after SMTP acceptance. Its evidence is an
|
||||||
|
allowlisted classification/count projection; raw provider diagnostics and
|
||||||
|
transport/account identifiers are deliberately excluded.
|
||||||
|
|
||||||
|
The runner does not simulate a connection loss after SMTP DATA and does not
|
||||||
|
restart a real worker. Keep those two checklist items open until a controlled
|
||||||
|
fault proxy/target provider and supervised worker environment can produce the
|
||||||
|
corresponding `outcome_unknown`, restart, retry, and reconciliation evidence.
|
||||||
|
|
||||||
## Reporting Checks
|
## Reporting Checks
|
||||||
|
|
||||||
- Partial delivery must show accepted, failed, and unknown counts separately.
|
- Partial delivery must show accepted, failed, and unknown counts separately.
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ schema and are safe to run in non-production environments.
|
|||||||
- campaign with blocked recipients or attachment errors that must not be sent
|
- campaign with blocked recipients or attachment errors that must not be sent
|
||||||
- mock delivery campaign that captures SMTP and IMAP append messages in the mail
|
- mock delivery campaign that captures SMTP and IMAP append messages in the mail
|
||||||
development mailbox
|
development mailbox
|
||||||
- real non-production delivery campaign against the GreenMail test bed
|
- [`greenmail-delivery`](../examples/greenmail-delivery/campaign.json), a
|
||||||
|
credential-free real-delivery Campaign materialized with a temporary
|
||||||
|
Mail-owned profile by the loopback acceptance runner
|
||||||
|
|
||||||
## Fixture Rules
|
## Fixture Rules
|
||||||
|
|
||||||
@@ -53,6 +55,13 @@ Before tagging a campaign release:
|
|||||||
- Run the mock delivery example when the mail development mailbox capability is
|
- Run the mock delivery example when the mail development mailbox capability is
|
||||||
enabled.
|
enabled.
|
||||||
- Run the GreenMail SMTP/IMAP smoke for a non-production real delivery path.
|
- Run the GreenMail SMTP/IMAP smoke for a non-production real delivery path.
|
||||||
|
- Run `dev/mail-testbed/run_campaign_acceptance.py` and retain its bounded JSON
|
||||||
|
projection. It must show one SMTP acceptance, one IMAP append, no duplicate
|
||||||
|
effect from a repeated ordinary send, matching Campaign report/audit state,
|
||||||
|
and no resolved transport material in Campaign JSON or its execution
|
||||||
|
snapshot.
|
||||||
|
- Do not interpret the local failure drills as post-DATA ambiguity or worker
|
||||||
|
restart proof; the evidence coverage flags must keep those gaps explicit.
|
||||||
- Confirm reusable mail profile selection is revalidated after campaign owner
|
- Confirm reusable mail profile selection is revalidated after campaign owner
|
||||||
transfer.
|
transfer.
|
||||||
- Confirm every inline SMTP/IMAP field is rejected on import/write, omitted
|
- Confirm every inline SMTP/IMAP field is rejected on import/write, omitted
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ campaign schema and do not require production data.
|
|||||||
| `warnings-review` | core, access, campaigns | Require explicit review before queueing jobs with warnings. |
|
| `warnings-review` | core, access, campaigns | Require explicit review before queueing jobs with warnings. |
|
||||||
| `blocked-send` | core, access, campaigns | Confirm blocked recipients or missing attachments cannot be queued. |
|
| `blocked-send` | core, access, campaigns | Confirm blocked recipients or missing attachments cannot be queued. |
|
||||||
| `mock-delivery` | core, access, campaigns, mail with dev capability | Capture messages in the development mailbox. |
|
| `mock-delivery` | core, access, campaigns, mail with dev capability | Capture messages in the development mailbox. |
|
||||||
| `greenmail-delivery` | core, access, campaigns, mail | Send no-attachment, normal attachment, and ZIP attachment variants through `dev/mail-testbed`. |
|
| [`greenmail-delivery`](greenmail-delivery/campaign.json) | core, access, audit, campaigns, mail | Run a credential-free Campaign through a Mail-owned profile, GreenMail SMTP/IMAP, report/audit checks, repeat-send protection, and bounded failure drills. |
|
||||||
|
|
||||||
## Fixture Rules
|
## Fixture Rules
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@ Before a release tag:
|
|||||||
3. Validate every committed example fixture against the current campaign schema.
|
3. Validate every committed example fixture against the current campaign schema.
|
||||||
4. Build exact messages for each fixture.
|
4. Build exact messages for each fixture.
|
||||||
5. Run the mock-delivery example when the dev mailbox capability is enabled.
|
5. Run the mock-delivery example when the dev mailbox capability is enabled.
|
||||||
6. Run `dev/mail-testbed/run_transport_smoke.py`.
|
6. Run `dev/mail-testbed/run_transport_smoke.py` for low-level transport and attachment variants.
|
||||||
7. Execute the delivery checklist in
|
7. Run `dev/mail-testbed/run_campaign_acceptance.py` for the Campaign journey and bounded evidence.
|
||||||
|
8. Execute the delivery checklist in
|
||||||
`docs/EXAMPLE_CAMPAIGNS_AND_RELEASE_CHECKLIST.md`.
|
`docs/EXAMPLE_CAMPAIGNS_AND_RELEASE_CHECKLIST.md`.
|
||||||
|
|||||||
Reference in New Issue
Block a user