Campaign-final checkpoint¶
campaign-final is a non-sending migration CLI command and a disabled-by-default
chart operation. It closes an approved campaign only after reconciling the mounted
Auth0 export against current PM Investigators and the Identity ledger, running the
existing import verifier, and checking that all eligible deliveries are settled.
Unmatched, duplicate or missing mappings fail closed; this version accepts no
mapping exceptions. Unknown sends anywhere in the ledger, in-flight claims,
missing canary approval and incomplete campaign evidence prevent completion.
Reconciliation compares imported security provenance as well as row mappings: email, identity classification, blocking/deactivation, provider email, mapping origin, last login, and every source identity's provider/subject/email/verification assertion. A same-count export with changed provenance is not interchangeable with the imported export. Reader observation timestamps are excluded because reading the unchanged export again necessarily changes that timestamp. The comparison uses immutable ledger provenance, not mutable local password or email confirmation state that a successful campaign redemption may legitimately change. Every ledger row must also match its live Identity user's exact identity ID, Auth0 source ID and Investigator ID; a merely non-null live mapping is not enough. Live authorization groups must equal the normalized current Investigator roles, and Google/merged accounts must retain the expected imported Google subject. Temporary lockouts leave unfinished recipients in the remaining cohort: only provenance-confirmed blocked/deactivated accounts or reconciled terminal dispositions can remove that delivery obligation.
The control Secret needs a final-evidence key, bound through
SYRF__CampaignFinalEvidence__File. The document is private operator input, never
a GitOps value or command-line argument. Its JSON schema requires every field:
| Field | Required value |
|---|---|
schemaVersion |
1 |
runHandle |
Exact secret-mounted handle of the active campaign |
controlGeneration |
Current durable generation; update after resume |
templateVersion |
Current reviewed campaign template generation |
exportSha256 |
Lowercase SHA-256 of the exact mounted export bytes |
forcedResetGuidanceReady |
true after reviewing forced-reset guidance and synthetic redemption evidence |
optionalMfaPasskeyReenrolmentPlanReady |
true after reviewing native optional MFA/passkey re-enrolment instructions |
rollbackEvidenceReady |
true after reviewing the retained rollback evidence for this campaign |
Unknown JSON properties, absent fields and invalid input fail closed. The three booleans are operator attestations: the command does not pretend to independently prove mailbox receipt, a browser redemption, or a backup restore. Keep their review records with the campaign evidence, and bind them to the same export, run, control generation and template. They do not waive reconciliation or authorize activation. The later readiness percentages and S13 cutover gates still apply.
The Job mounts Identity and PM connection inputs, the export, run handle and final evidence. It has no SES credentials or DataProtection material. Its output sink is writable ephemeral storage; retain the aggregate JSON report and Job completion record before a subsequent GitOps sync prunes that Job. The report includes a schema version, export digest, control/template generations, aggregate imported, eligible, remaining, sent, retired and pending-unknown counts, and the outcome. It excludes handles, addresses, identities, credentials and wall-clock timestamps. Repeating against unchanged state produces the same report and sends no mail. If report writing fails after the durable transition, rerun the same checkpoint to recover the report; do not restart delivery.
S12 now has both catalogue paths: import-rerun invokes import --require-no-writes
with a declared zero-write invariant, and campaign-final invokes the checkpoint
described here. Before importing, the rerun requires a readable declaration with
rerun-writes=0; an absent, malformed, or nonzero declaration is rejected without
database writes. This is an executed idempotence assertion, not a read-only preview
or a transaction that prevents changes: a validly declared rerun still executes
the importer. If it creates users/ledger
rows or repairs lockout eligibility/reservations, it exits nonzero and reports the
aggregate changes. It does not roll those repairs back. Investigate the failed
idempotency evidence and repeat against the corrected, unchanged inventory.
Unacknowledged write concern (w=0) is rejected before importing: an unknown
repair result cannot establish zero writes.
The sequence remains import → verify → import-rerun, followed by canary → approval
→ bounded batches → stop/status → resume → remaining batches → campaign-final →
idempotent-rerun. Each operation is a separate reviewed GitOps commit/sync with
retained evidence. Imports and campaign writes must be quiescent during the final
checkpoint; no final report grants permission to mutate the reconciled inventory.
Automated coverage includes real-Mongo partial/resumed campaigns, stale generation refusal, in-flight and unknown-send refusal, source-to-PM mapping drift, production mounted-input execution, privacy-safe deterministic reports, repeated completion without sends/writes, and Helm argv/declaration/input isolation assertions. Live synthetic rehearsal and production campaign execution remain separate evidence gates; repository tests are not records of those operations.