coulomb-social/docs/usecases/platform-communication.md
tegwick cb9301537e
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m57s
Exercise actual communication owner sources through isolated browser flows
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-30 21:51:36 +01:00

13 KiB
Raw Blame History

Platform communication use cases

CSOC-WP-0010-T06, reviewed 2026-10-07. Authentication uses native Authelia SMTP; application invitation/verification delivery uses the existing email-connect service. ReichelAg protocol distribution remains UC-008's manual clipboard/email workflow.

These stable IDs are registered in registry.json with synthetic fixture references, app-side fast checks and established: false. Owner-spanning browser coverage is still required under T06. Personal recovery retains its recorded user acceptance; it is not marked as an established automated journey until its full fast/browser contract can be protected. UC-010–012 remain candidates.

ID Actor, goal and steps Expected outcome / evidence Status and owner
CSOC-UC-009 Existing member requests a new reset on the identity portal, receives email, sets a password privately, then signs into the app Fresh inbox receipt and personal workspace reached; reset URL/password never enter app logs, Git or Hub User-confirmed and accepted 2026-10-06 for the existing personal account; WP-0010-T02/T03 and WP-0008-T11 done
CSOC-UC-010 New member starts approved registration, receives the verification message, then consumes or cancels its link Expiring, single-use, purpose-bound channel evidence; cancellation and consumption invalidate one another; account admission remains user-engine's decision Candidate; implemented service behavior, current personal user workflow not reviewed; T04/T06 with user-engine/NetKingdom/email-connect
CSOC-UC-011 Authorized inviter invites a member; a deliberate resend creates a new event Fixed invitation template, one provider submission per event, suppression respected; provider acceptance does not establish inbox receipt Candidate; implemented service behavior, productive user acceptance pending; T04/T06 with user-engine/email-connect
CSOC-UC-012 Member receives a specifically approved application notification and can obtain help through its reply path Caller/template/recipient authorization, bounded sending, redacted delivery state and monitored reply route Future candidate; no product template/caller admitted; T04/T05/T06

Personal acceptance reference: workspace acceptance. Original Bubble reset/invitation semantics remain unobserved; UC-009 establishes the replacement's accepted recovery path rather than claiming Bubble parity.

Synthetic regression matrix

Only reserved example addresses, synthetic accounts and injected transports are allowed. Native recovery tests need an isolated issuer, directory, mailbox sink and application; never route a regression through the production mail provider. Do not record usable reset/verification URLs in reports. No mailbox scans or live sends are part of the gate.

Layer / contract Existing coverage Remaining gate
App identity boundary tests/test_identity_regressions.py: consumed callback cannot replay; equal email cannot take over another issuer/subject UC-009 real-browser issuer reset → local inbox → app login, expired/replayed reset denial, directory isolation
Registration handoff tests/test_shell.py::test_registration_link_uses_only_configured_destination UC-010 browser request/verify/cancel; preserve tenant/client binding through owner flow
Invitation auth/template/recipient/key/suppression email-connect tests/test_transactional.py: test_rejects_auth_recipient_template_and_key, test_suppression_blocks_send Separate caller identities, caller/template/tenant scope, request limits; no authority from payload source
Invitation retry / uncertain outcome Owner tests test_sends_fixed_template_once, test_resend_is_separate_event_and_sends_again, test_lost_post_send_record_never_resends_after_restart, test_definitive_failure_retries_but_changed_payload_is_rejected, test_disconnect_after_smtp_acceptance_never_releases_reservation Per-caller event namespace, bounded retry schedule and operator handling of unknown outcomes
Verification privacy and replay Owner tests test_registration_verification_is_digest_only_and_single_use, test_registration_cancellation_is_single_use_and_prevents_verification, test_mailbox_evidence_is_not_authorization, plus retry/restart/concurrency functions bound below Expired-handle and binding denials through an isolated owner-spanning browser journey
Provider failure / diagnostic redaction Owner tests test_provider_timeout_temporary_and_permanent_are_redacted, test_status_authenticates_without_sending_and_redacts_errors Diagnostic projections omit bearer values, recipient addresses, message bodies and provider details; caller-scoped status; provider acceptance and inbox receipt shown separately
Reply/bounce operations Offline scanner fixtures exist in email-connect Named monitored inbox, authorized inbound access, correlated bounce → suppression, bounded retention and support escalation

Historical owner baseline (2026-10-07): 27 transactional tests pass at source 73702b7e1a1671948b0545ef32d6e0de9cca9c65, clean checkout. This is local source evidence, not a deployed version or fresh inbox receipt. Reproduction from this repository's installed Python environment:

PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=/home/worsch/email-connect/src \
  .venv/bin/python -m pytest -c /home/worsch/email-connect/pyproject.toml \
  /home/worsch/email-connect/tests/test_transactional.py -p no:cacheprovider \
  --basetemp=/tmp/csoc-email-owner-tests

Reproducible owner regression gate — 2026-10-08

Run make check-communication EMAIL_CONNECT_ROOT=/path/to/email-connect. communication-regressions.json binds 37 module-qualified required test functions covering authorization/template/recipient denial, suppression, provider failure and redaction, invitation uncertainty and verification restart/concurrency safety. The runner copies only Python source and the two declared synthetic test modules to a private temporary tree. It denies socket connects and DNS, strips inherited credentials, disables plugin autoload, and refuses removed or skipped/xfail contract coverage. It leaves the owner checkout untouched. Gate tests in make check prove those failure boundaries. No mailbox, SMTP, issuer or live account is contacted.

The redacted receipt at var/test-results/communication.json binds exact executed source/test/contract hashes and records counts, missing tests and outstanding acceptance. The current owner check passes 66 tests, zero skips. This closes the stale verification-retry baseline above: accepted and uncertain outcomes now retain their reservations across retries/restarts; definitive retryable refusals cancel the failed challenge before retry.

Before marking UC-009–012 as established protected journeys, bind the missing browser node IDs in their owners, arrange the isolated issuer/mailbox/application harness, and record owner admission. As of 2026-10-11 the app checkout binds test_isolated_recovery_registration_and_invitation for UC-009/010/011 against a loopback double only. That node is not established protection and does not replace the real identity portal, email-connect caller, or a productive verdict. make check protects UC-008 and tests the new app UI; check-communication is a separate explicitly selected owner gate. Independent caller scopes, persisted limits and redacted status are implemented in owner source f703bf6 (EMAIL-WP-0008), with148 full tests including the isolated mail harness and scoped-ledger rehearsal. Runtime policy/credential, sender, ledger backup admission, inbox ownership, DNS alignment and productive per-flow user acceptance remain open. Owner review.

Current work ownership — 2026-10-08

WP-0010 is finished at the user's instruction. Existing personal reset acceptance and receiver deployment remain evidenced. Its unfinished T04/T05/T06 scopes are superseded by WP-0015-T01/T03, WP-0015-T02/T03 and WP-0015-T04 respectively. EMAIL-WP-0008-T03, EMAIL-WP-0007 and RPF-WP-0053 retain canonical owner/custody work. WP-0010 references above are historical provenance, not active gates.

Verified owner returns — 2026-10-27

EMAIL-WP-0008 completed scoped caller custody/activation on October 9; EMAIL-WP-0007 completed independent ledger escrow/kit/reader, mirrored daily archives and monitored schedules on October 10. Current receiver policy and user-engine bindings remain deployed/Ready. Today's backup and freshness checks succeeded and its independent versioned mirror is verified. WP-0015-T01/T03 are done; earlier source-only statements above are historical.

The offline gate now declares four recovery Python helpers and the synthetic ledger-backup test module as well as caller/transactional tests. It copies/hashes only those helpers, source and tests and passes 103 tests, zero skips, including real ephemeral age encryption/decryption, all-six-table recovery and scoped quota continuity. No production configuration/ledger/custody is copied.

Actual owner-spanning browser integration, platform sender/inbound/reply/bounce operations and productive UC-010/011 verdicts remain WP-0015-T02/T04. UC-009 personal recovery acceptance is preserved; UC-012 remains deferred. Details: ../release/acceptance-audit-2026-10-27.md.

Owner source browser integration 2026-10-30

UC-010 and UC-011 now have an additional explicit owner-browser gate:

make check-owner-communication \
  USER_ENGINE_ROOT=/path/to/user-engine \
  EMAIL_CONNECT_ROOT=/path/to/email-connect \
  OWNER_BROWSER_RECEIPT=/private/fresh-owner-browser-receipt.json

The exact required node is scripts/owner_communication/test_browser.py::test_real_owner_registration_and_invitation. It is linked by owner_browser_tests in the candidate use-case records. This separate command needs the two owner checkouts; make check continues to protect the established product journeys and tests the owner runner's isolation/failure boundaries. The new check does not mark a candidate established or accepted.

The runner copies and hashes only the owners' Python sources and packaged public custody schemas into a fresh private tree. It strips inherited configuration and credentials, disables pytest plugin autoload, and confirms both imported packages come from that snapshot. Existing owner configuration, databases and tests are not loaded. Locked development dependencies include user-engine's jsonschema dependency. The receipt binds the runner, Python lock, Playwright package lock, owner source and both browser harness files. Per-file hashes live in the adjacent .sources.txt filename/digest manifest, whose hash is bound in the JSON receipt. Retain both files together. This is the receive scanner's approved content-digest shape; it adds no scanner exception.

Chromium submits user-engine's actual registration/confirmation forms. The real registration HTTP adapter calls email-connect's actual scoped receiver and SQLite ledger. A synthetic local mail sink exposes the verification/cancellation links; the directory and preauthenticated administrative session are fixtures. The authorization adapter is explicitly the owner's standalone test double, not a production PDP. The password setup handoff is shown but not followed. No native Authelia reset, directory password change, app sign-in or MFA ceremony is proved by this node; UC-009 retains its separate personal acceptance and isolated-double test.

The browser verifies that mailbox delivery alone creates no applicant User or directory identity; correct confirmation creates one identity. A second caller cannot consume a fresh valid handle that the correct caller can subsequently consume. Reused, cancelled and expired handles refuse, as do wrong tenant/client bindings and an invalid caller token. The administrative form refuses another tenant. Real invitation forms and the actual outbox HTTP adapter prove one local provider call per invitation event, a distinct resend, repeated delivery without another send, and recipient suppression. The event sink asserts that recipient addresses are removed from the activity envelope.

Python connections are restricted to the exact admitted loopback service ports, with external-connect and DNS refusal probes. Browser routing permits only the three fixture origins, blocks service workers and rejects other origins. Browser API requests also validate their origin and disable redirects. The mail provider is an injected in-memory sink; no SMTP provider or live mailbox is contacted. Failed check diagnostics stay in a private temporary file. Receipts require the exact unskipped node and contain hashes/counts/verdicts, not usable handles or message bodies. Safety tests prove inherited credentials, runtime databases and .env files are excluded, and skipped/wrong-node reports and symlinked sources cannot pass.

Evidence: ../release/owner-communication-browser-2026-10-30.json. Productive UC-010/011 verdicts and platform sender/reply/bounce operations remain WP-0015. UC-012 remains deferred pending a selected template/caller; UC-008 manual mail distribution is unchanged.