email-connect/docs/sender-native-adapter-2026-10-31.md
tegwick e795b2970c
Some checks failed
Transactional mail acceptance / mail (push) Failing after 49s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Add attended sender release with sealed sources and recovery
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-31 17:18:52 +01:00

5.1 KiB

Native sender adapter preparation

The native adapter is implemented. scripts/sender_native.py connects the sender transition protocol to the existing Kubernetes, ledger capture and isolated replay tools. It has no CLI; default construction permits reads and server dry-runs only. The attended entry point is now implemented separately; EMAIL-WP-0010-T02 waits for the verified owner return before sealing the final live release packet. No production sender change occurred.

Implemented native checks

The adapter pins cluster, namespace, deployment and ConfigMap identities. It compares complete deployment specifications and ConfigMap data with UID and resource-version preconditions before patches. It preserves caller policy, existing projections, Service and network policies. It verifies the ledger PVC's PV claim UID and derives the single backing node from that PV's node affinity.

Secret requests negotiate Kubernetes PartialObjectMetadata; a full Secret response is refused. The dedicated SMTP projection must match the reviewed foundation contract, have Ready resources, and retain the expected controller ownership. Admission requires the exact successful foundation proposal receipt and its authentication, scope, denial, TTL and workload-token revocation checks. The adapter creates no credential grant. The independent RPF-WP-0068-T04 owner return, including the approved credential lane and cleanup, remains a prerequisite for the final execution packet.

Mutation methods require an execution flag, durable journal and exclusive existing capture lock. Pausing waits for receiver pods to disappear and rejects any other PVC consumer except exact journal-owned helpers. Helper creation records an intent before the API call and the returned UID before use. A lost creation response without a recorded UID stops for identity inspection. Cleanup checks both UID and complete spec and uses a UID deletion precondition; it cannot delete a replacement pod merely because its name matches.

Snapshots reuse the existing read-only SQLite backup path. The quiesced snapshot also runs the existing no-provider replay checks in helper memory. Every snapshot is private, fingerprinted, and checked for unexpected PVC consumers before and after capture. Postflight permits only the independently verified receiver UID as a live writer. Runtime verification checks the actual process sender, username, caller-file mode and password presence, plus health/readiness and unauthenticated request rejection. It prints no credential value and issues no accepted send.

Evidence and its limits

sender-native-preflight-2026-10-31.json records five successful native server dry-runs: pause, paused environment change, resume, sender ConfigMap change and helper creation. The observed production configuration was unchanged after the checks. PVC/PV/node identity and helper egress denial passed. Full proposal preimages remain in the operator's private plan; the public receipt binds their hash. This did not admit credentials, capture production data or alter Kubernetes resources. Dry-run success does not prove a future rollout will succeed.

sender-native-snapshot-rehearsal-2026-10-31.json records the actual snapshot and replay paths running in the pinned receiver image with a synthetic ledger. The container had no network, a read-only root, a read-only source mount, no published ports and UID 10001. All six tables survived both captures. Accepted and unknown invitation/verification outcomes, consumed/canceled links and suppression were retained. The disposable container was removed. No Kubernetes API, production data or SMTP provider was used. This is isolated snapshot integration evidence, not a live writer-fence or end-to-end production transition proof.

Thirty new adapter cases pass, covering identity/spec drift, private exclusive locking, lost helper replies, UID-bound cleanup, unexpected PVC consumers, metadata-only Secret responses and owner projection/admission refusal. The runtime probe is exercised against the actual scoped WSGI application on local loopback with a synthetic provider that records zero sends. Owner default suite: 249 passed, 21 skipped in 23.51s; skips are existing optional mail-harness tests. Ruff passes. Log: /tmp/email-sender-native-check-20261031.log.

Remaining T02 work

Update: the launcher, source binding and assembled protocol/adapter tests are now implemented in the attended entry review. T02 waits for the verified owner receipt before sealing the live proposal and publishing its concrete execution/recovery digest.

Bind the complete executor and dependencies into the final capsule, implement the attended entry point with exact proposal digest and owner-return verification, and prove the assembled forward/recovery path. Prepare the concrete execution and recovery packet against fresh native preimages. Preserve the existing refusal of blind forward replay and configuration-only recovery using the current ledger. Only then can T02 finish; attended execution and independent return remain EMAIL-WP-0010-T03/T04. Productive mail delivery, inbound handling and user verdicts remain CSOC-WP-0015 obligations.