Prepare glob-scoped callers and prove offsite ledger recovery
Some checks failed
Transactional mail acceptance / mail (push) Failing after 32s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 57s

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a11fd9-caf6-7a63-b578-9daaaa134ff2
This commit is contained in:
tegwick 2026-10-09 11:43:11 +02:00
parent 6fb206b359
commit 93b6ba2aae
21 changed files with 1080 additions and 19 deletions

View file

@ -1,5 +1,8 @@
# User-engine caller policy draft — 2026-10-08
This is the historical draft review. The compatible rollout preparation below
updates its scope and resolves the source compatibility gap; activation remains open.
This file proposes the only caller that exists today. It is not mounted,
`EMAIL_CONNECT_CALLERS_FILE` is not set, and no token file was created.
EMAIL-WP-0008-T03 stays waiting until the bindings, quotas and token custody
@ -40,3 +43,46 @@ admitted tenant/client pair, or a separate reviewed contract change.
The token path in the draft does not exist. Selecting this file on the
running receiver would fail startup before serving traffic. Do not copy the
shared ingest token into that path as part of this draft.
## Compatible rollout preparation — 2026-10-09
User selected the proposed limits and requested glob or regex support. The draft
now admits exact tenant:coulomb/coulomb-social plus the proposed case-sensitive
tenant:*-family and tenant:family-* globs with literal client coulomb-social.
Only * and ? glob operators are supported; all patterns and actual identifiers
are bounded to 128 characters, with at most 128 total exact/pattern pairs.
These family naming patterns are proposals rather than a complete tenant inventory.
They apply to verification creation and handle consumption/cancellation as well
as invitation sends. Suppression remains excluded.
User-engine source accepts opt-in USER_ENGINE_MAIL_CLIENT_BINDINGS, a JSON list
matching config/mail-client-bindings.user-engine.draft.json. It resolves one
literal client for the actual tenant; missing or ambiguous matches refuse before
any HTTP delivery. Only the mail transport gains client_id: audit envelopes and
stored outbox payloads retain their original shape. Default unset configuration
retains current live behavior. The reviewed patch is retained in
deploy/caller-rollout/user-engine-mail-bindings.patch.
adopt_legacy_invitations explicitly reserves original invitation ids for this
user-engine caller. A matching old fingerprint can tolerate the added transport
client_id, preserving accepted evidence and terminal unknown/permanent outcomes.
Other immutable changes still refuse; admission checks precede legacy matching.
New events bind the full payload. Other callers cannot opt into this adoption.
The immutable ConfigMap and strategic deployment patch in deploy/caller-rollout
pass server dry-run; packaged-evidence-2026-10-09.json binds the local candidate
image to the exact caller module under UID10001 and disabled networking.
Before activation, deliver a caller-specific token to the separately admitted
Secret email-connect-caller-user-engine (key token) and corresponding user-engine
custody lane. Do not copy the legacy shared ingest token into that projection.
Publish/admit the new receiver image, retain the current ledger/recovery receipt,
fence outbox dispatch during coordinated token/policy transition, and set both
the receiver policy and user-engine binding configuration. Pending outbox tenants
must match the admitted scope before traffic resumes; narrow or add explicit
bindings when their names do not match these proposed globs.
The live receiver remains eb3e7b68 in single-caller mode. Capture and rehearsal
must be repinned together only when a new receiver image is actually deployed.
Policy narrowing/removal preserves ledger evidence but can deny existing links;
review rollback with the compatible image and both caller credentials before
releasing traffic. Source preparation does not issue a token or select this policy.

View file

@ -1,5 +1,8 @@
# Email ledger backup/recovery candidate — 2026-10-08
Historical candidate review. The admitted first run and monitoring proof on
2026-10-09 are recorded below; scheduling and independent custody remain open.
EMAIL-WP-0007 implements the independent transactional SQLite recovery scope
requested by CSOC-WP-0010-T04/T05. The verification retry release remains live;
this candidate does not change that deployment, SMTP/caller credentials or inbox
@ -147,3 +150,38 @@ T01/T02 implementation/rehearsal can close on this evidence; T03/T04 remain open
for actual custody, offsite capture/recovery, post-capture reconciliation contract,
monitored operation and founder activation. CSOC-WP-0010 remains active for those
and caller/sender/rate-limit, reply/bounce/inbox and cross-owner journey acceptance.
## Admitted first run — 2026-10-09
The user authorized one first capture/upload/retrieval/isolated recovery with
schedules disabled (decision 0dfcdd94-50ee-4219-9659-5c4c445721f0).
Installed source and hash-locked SDK pass hardened node preflight. The receiver
resumed after 56.41 seconds; primary version 1791537739370570 passed size/hash
readback. A separate version-pinned GET and workstation decrypt/application
rehearsal preserve all six tables, two accepted deliveries and one suppression,
under UID10001/network-none with no provider calls. Other state tables are empty
in this live snapshot; their invariants retain synthetic recovery evidence.
The isolated drill interval was 636.29 seconds including intervening operator
work, rather than a production restore/RTO measurement.
Public transfer/recovery evidence is docs/ledger-first-backup-2026-10-09.json.
The existing mode-0600 workstation identity matches the configured public age
recipient; separate escrow admission is still open. The admitted node publisher
credential performed retrieval and was not copied to the workstation. This does
not prove a separately scoped recovery caller or node/workstation-loss custody.
User selected the platform-root operations inbox. OnFailure hooks now deliver
redacted notices to its State Hub inbox. A synthetic failed unit delivered
adcebf95-26c4-4adb-99b0-4446c8505a42, verified by an independent inbox read.
Failures to deliver retain private pending records for at-least-once replay with
stable event ids; duplicates are possible if acceptance succeeded but its reply
was lost. Successful freshness checks replay pending notices, while failures
invoke the same delivery hook. No notification includes journal output,
credentials, message contents or ledger rows. Human response is not claimed.
Both timers are installed and disabled; one attended freshness check passed.
Full email regression after caller/notification changes: 178 passed, zero skips
using the loopback GreenMail harness; focused syntax checks pass. Retention,
capacity, independent receipt/key/image custody, separate recovery caller and
recurring schedule/RPO admission retain EMAIL-WP-0007-T03/T04. Production restore
still requires fencing and post-capture reconciliation before traffic release.

View file

@ -0,0 +1,131 @@
{
"schema": "email-connect.first-primary-ledger-recovery.v1",
"decision_id": "0dfcdd94-50ee-4219-9659-5c4c445721f0",
"publication": {
"schema": "platform.application-primary-archive.v1",
"status": "offsite_fetched_verified",
"application": "email-connect",
"captured_at": "2026-10-09T09:21:20Z",
"object_key": "platform-pg/application-archives/email-connect/2026/10/09/20261009T092120Z-004a5e182fd57e5005787bb8.tar.age",
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/email-connect/2026/10/09/20261009T092120Z-004a5e182fd57e5005787bb8.tar.age",
"ciphertext_sha256": "8053f6dfd9763fbcdef4e9a005c79c2cab3d43ff31d37e8decd690ad07b4f5eb",
"ciphertext_bytes": 71896,
"remote_retrieval_verified": true,
"stage": "transfer_verified",
"multipart_completed": true,
"version_id": "1791537739370570",
"immutable_create": true,
"image": "forgejo.coulomb.social/coulomb/email-connect@sha256:eb3e7b68d21209e9eb71b928a5b0bc987e8e3164f21dca4ff712f946d0c103f2",
"database_sha256": "b6020ffa13a097f0e4f24ce3a273cdf7a3eac5ab6b8c0770af8971ce3c951d58",
"database_bytes": 57344,
"ledger_fingerprint": {
"schema_sha256": "13148e5a9c6e01cc593bb07278a8649b13e43b26c30b0ed1a6e15995f7b00732",
"user_version": 0,
"tables": {
"caller_buckets": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"deliveries": {
"rows": 2,
"sha256": "a0387716815b2ec191187cb34bb3252b9cf51f5fb15a2019918a9cf1737c061e"
},
"send_attempts": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"suppressions": {
"rows": 1,
"sha256": "ae26d10dfec16f1b626292b342a5e86afd1858fcaed7c29d4e68e7cf821183d7"
},
"verification_attempts": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"verifications": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
},
"pause_and_capture_seconds": 56.41,
"local_archive": "20261009T092120Z-004a5e182fd57e5005787bb8.tar.age",
"application_restore_verified": false,
"completed_at": "2026-10-09T09:22:20.500704+00:00"
},
"application_recovery": {
"status": "application_restored_verified",
"application": "email-connect",
"object_key": "platform-pg/application-archives/email-connect/2026/10/09/20261009T092120Z-004a5e182fd57e5005787bb8.tar.age",
"version_id": "1791537739370570",
"ciphertext_sha256": "8053f6dfd9763fbcdef4e9a005c79c2cab3d43ff31d37e8decd690ad07b4f5eb",
"database_sha256": "b6020ffa13a097f0e4f24ce3a273cdf7a3eac5ab6b8c0770af8971ce3c951d58",
"ledger_fingerprint": {
"schema_sha256": "13148e5a9c6e01cc593bb07278a8649b13e43b26c30b0ed1a6e15995f7b00732",
"user_version": 0,
"tables": {
"caller_buckets": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"deliveries": {
"rows": 2,
"sha256": "a0387716815b2ec191187cb34bb3252b9cf51f5fb15a2019918a9cf1737c061e"
},
"send_attempts": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"suppressions": {
"rows": 1,
"sha256": "ae26d10dfec16f1b626292b342a5e86afd1858fcaed7c29d4e68e7cf821183d7"
},
"verification_attempts": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"verifications": {
"rows": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
},
"mail_sent": false,
"production_restored": false,
"application_restore_verified": true,
"recovery_image": "forgejo.coulomb.social/coulomb/email-connect@sha256:eb3e7b68d21209e9eb71b928a5b0bc987e8e3164f21dca4ff712f946d0c103f2",
"network": "disabled",
"checks": {
"accepted_verifications": 0,
"unknown_verifications": 0,
"invalidated_handles": 0,
"suppressions": 1,
"accepted_deliveries": 2,
"unknown_sends": 0
},
"uid": 10001,
"evidence_ceiling": "isolated_ledger_rehearsal",
"elapsed_seconds": 0.93
},
"independent_retrieval": {
"separate_provider_GET": true,
"version_and_hash_verified": true,
"publisher_credential_used_on_node": true,
"credential_copied_to_workstation": false,
"separate_recovery_caller_proved": false
},
"isolated_drill_wall_seconds": 636.29,
"interval_includes_operator_work": true,
"recovery_proof_at": "2026-10-09T09:31:56.290620+00:00",
"production_rto_measured": false,
"independent_identity_escrow_admitted": false,
"schedules_enabled": false,
"failure_notification": [
{
"id": "adcebf95-26c4-4adb-99b0-4446c8505a42",
"to_agent": "platform-root",
"subject": "email-connect ledger notification test",
"read": null
}
]
}