Record and pin verified account journey release
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
This commit is contained in:
parent
502a8e01d7
commit
62d6f8b0c7
7 changed files with 413 additions and 4 deletions
66
docs/evidence/2026-09-13-journey-release.md
Normal file
66
docs/evidence/2026-09-13-journey-release.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Account journey release — 2026-09-13
|
||||
|
||||
Implemented and deployed user feedback/retry, tenant-scoped identity lifecycle,
|
||||
last-admin protection, administrator succession, confirmation/stale-state handling,
|
||||
actual login-name/onboarding/delivery guidance, scoped audit, platform delivery
|
||||
retry and atomic/retryable first-admin bootstrap.
|
||||
|
||||
## Reproducible validation
|
||||
|
||||
- `PYTHONDONTWRITEBYTECODE=1 make test`: 210 tests, seven opt-in PostgreSQL skips;
|
||||
layer conformance passed.
|
||||
- Disposable PostgreSQL 16 on local loopback, tmpfs, no production records:
|
||||
`USER_ENGINE_POSTGRES_TEST_DSN=postgresql://postgres@127.0.0.1:25432/postgres USER_ENGINE_POSTGRES_TEST_RESET=1 PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src:tests uv run --no-project --with 'psycopg[binary]>=3.2,<4' python -m unittest discover -s tests`
|
||||
passed all 210 with zero skips. Covers independent-connection concurrent
|
||||
last-admin changes, advisory-lock cleanup, caller-transaction preservation and
|
||||
nested bootstrap rollback. Disposable container stopped after validation.
|
||||
- `make test-journeys JOURNEY_ARGS="--report /tmp/user-engine-journeys.json"`:
|
||||
41 tests passed. Durable report: `2026-09-13-journey-report.json`.
|
||||
- `make test-journeys JOURNEY_ARGS=--require-complete`: tests pass, command fails
|
||||
intentionally because 15 of 29 journeys retain named gaps.
|
||||
- `make test-browser-journeys`: 13 isolated Chromium checks passed against the
|
||||
synthetic loopback fixture (user, tenant admin, platform operator).
|
||||
- Identity provisioner regression: 20 tests passed.
|
||||
- rapp-user-engine `make check`: four packaging checks passed.
|
||||
- Portal CI commit 502a8e0: smoke run 141 and journey run 142 succeeded.
|
||||
Provider CI commit 84f7635: smoke run 227 and journey run 228 succeeded.
|
||||
CI uses pinned Python containers; browser and PostgreSQL acceptance were run
|
||||
separately, not claimed as part of dependency-free CI.
|
||||
|
||||
## Deployed artifacts
|
||||
|
||||
Portal source 1127f852dde8b247bcc7a7f0caff805f25c5f37e, image CI run 138:
|
||||
`forgejo.coulomb.social/coulomb/user-engine@sha256:b3df548acd23860c2bca3af123ea542d07784ff21340ea2cb0a406e6e7d9c29d`.
|
||||
Provider source a0cc947bf65241ac93280d1d7c00d8fc8b7a7740, built from exact git archive:
|
||||
`forgejo.coulomb.social/coulomb/identity-provisioner@sha256:698620e25cabccd746c10c332030e436428d184baab0f8270936494d285216a6`.
|
||||
|
||||
Provider deployed first, portal second. Image-only patches tested cluster UID,
|
||||
deployment UID/resource version and predecessor image. Both deployments Ready 1/1.
|
||||
Canonical provider manifests and portal package pins updated; unrelated hostname
|
||||
work preserved. In-pod provider inspection confirms tenant_access is present.
|
||||
Ten live HTTP checks passed (public account/recovery/security, readiness, API denial,
|
||||
and browser denial with recovery for platform operations and tenant activity).
|
||||
Twelve fresh live Chromium checks passed, including expired callback recovery,
|
||||
390px layout, shared sign-out confirmation/POST and final sign-in-only state.
|
||||
No real user's directory groups or factors were mutated for these checks.
|
||||
The Recreate portal rollout briefly returned 503 while replacing its single pod;
|
||||
checks passed after readiness. In-memory sessions and unused provider password
|
||||
setup grants are reset by restarts.
|
||||
|
||||
Rollback images (retain all other deployment configuration):
|
||||
- Portal: `sha256:558e489f0b6e0b7160ab0d370560a66497e12488b95531bbccca122b46331a6f`.
|
||||
- Provider: `sha256:55f744cc9bc2ec3fe23eb7175fa4b7bfcc7a29469d9b9a1a8eaefc75d790dfc6`.
|
||||
Rollback portal first if removing the new provider contract; rollback was not needed.
|
||||
|
||||
## Live work retained
|
||||
|
||||
This is not complete acceptance of all 29 journeys. USER-WP-0028-T02 and
|
||||
USER-WP-0026-T03 retain authoritative application catalogue/admission integration;
|
||||
current membership records cannot prove effective access. USER-WP-0028-T03 and
|
||||
USER-WP-0030-T03 depend on KEY-WP-0035/NK-WP-0033 factor credential custody and
|
||||
verified enrollment/cancel/replacement/recovery/policy behavior. MFA handoff stays
|
||||
unavailable; optional OTP enforcement has not been deployed. The coverage report
|
||||
also names mail delivery/receipt and real identity-switching acceptance gaps.
|
||||
USER-WP-0027-T06 remains open for complete integrated acceptance, including
|
||||
VERGABE-WP-0019. Local provider calls and local persistence are not one atomic
|
||||
transaction: desired-state retry/readback recovers an interruption between them.
|
||||
323
docs/evidence/2026-09-13-journey-report.json
Normal file
323
docs/evidence/2026-09-13-journey-report.json
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
{
|
||||
"tests_run": 41,
|
||||
"test_success": true,
|
||||
"skipped": 0,
|
||||
"journeys": [
|
||||
{
|
||||
"id": "U01",
|
||||
"role": "user",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_anonymous_and_expired_sessions_have_login_without_logout",
|
||||
"test_account_clarity.AccountClarityTests.test_authenticated_roles_have_logout_without_login"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U02",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_web.PortalApplicationTests.test_expired_browser_session_and_provider_outage_fail_closed",
|
||||
"test_account_recovery.AccountRecoveryTests.test_failed_callback_has_clean_recovery_and_no_loop"
|
||||
],
|
||||
"remaining": "KEY-WP-0035: actual no-factor/enrolled login needs provider credential and policy rollout.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U03",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_web.PortalApplicationTests.test_browser_invitation_acceptance_and_onboarding_status",
|
||||
"test_web.PortalApplicationTests.test_invitation_lifecycle_is_versioned_and_replay_safe"
|
||||
],
|
||||
"remaining": "Live notification delivery and invited-person acceptance remain unverified.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U04",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_journey_roles.UserJourneys.test_password_handoff_names_actual_login_and_failure_can_retry"
|
||||
],
|
||||
"remaining": "Provider password reset is separately tested in net-kingdom; live email recovery remains unresolved.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U05",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_otp_help_is_available_without_portal_login_and_never_claims_activation"
|
||||
],
|
||||
"remaining": "Portal boundary only. KEY-WP-0035 owns factor presence/AAL2 enforcement; live enrollment, cancel, replacement and lost-factor recovery await approved provider credential/contract.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U06",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_otp_help_is_available_without_portal_login_and_never_claims_activation"
|
||||
],
|
||||
"remaining": "Portal boundary only. KEY-WP-0035 owns factor presence/AAL2 enforcement; live enrollment, cancel, replacement and lost-factor recovery await approved provider credential/contract.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U07",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_otp_help_is_available_without_portal_login_and_never_claims_activation"
|
||||
],
|
||||
"remaining": "Portal boundary only. KEY-WP-0035 owns factor presence/AAL2 enforcement; live enrollment, cancel, replacement and lost-factor recovery await approved provider credential/contract.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U08",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_otp_help_is_available_without_portal_login_and_never_claims_activation"
|
||||
],
|
||||
"remaining": "Portal boundary only. KEY-WP-0035 owns factor presence/AAL2 enforcement; live enrollment, cancel, replacement and lost-factor recovery await approved provider credential/contract.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U09",
|
||||
"role": "user",
|
||||
"implementation": "partial",
|
||||
"tests": [
|
||||
"test_account_recovery.AccountRecoveryTests.test_account_workload_list_is_scoped_to_current_user"
|
||||
],
|
||||
"remaining": "USER-WP-0028-T02/USER-WP-0026-T03: authoritative application catalogue and access requests not implemented.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U10",
|
||||
"role": "user",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_wrong_shared_identity_recovery_does_not_claim_a_known_session",
|
||||
"test_portal_navigation.PortalNavigationTests.test_navigation_does_not_leak_between_operator_member_and_anonymous"
|
||||
],
|
||||
"remaining": "Authenticated multi-identity/tenant switching must be verified against live issuer.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U11",
|
||||
"role": "user",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_account_recovery.AccountRecoveryTests.test_shared_logout_clears_portal_then_uses_provider_confirmation",
|
||||
"test_portal_navigation.PortalNavigationTests.test_get_logout_only_confirms_and_bad_csrf_does_not_end_session",
|
||||
"test_portal_navigation.PortalNavigationTests.test_expired_session_logout_clears_stale_cookie"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U12",
|
||||
"role": "user",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_browser_denial_is_recoverable_while_api_remains_json",
|
||||
"test_account_recovery.AccountRecoveryTests.test_recovery_is_public_and_never_trusts_query_identity"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "U13",
|
||||
"role": "user",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.UserJourneys.test_profile_validation_keeps_safe_input_and_retry_saves",
|
||||
"test_web.PortalApplicationTests.test_browser_invitation_acceptance_and_onboarding_status"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T01",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.TenantAdminJourneys.test_wrong_role_or_tenant_never_calls_provider",
|
||||
"test_journey_roles.TenantAdminJourneys.test_audit_is_tenant_scoped_and_never_dumps_payload"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T02",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_web.PortalApplicationTests.test_invitation_lifecycle_is_versioned_and_replay_safe",
|
||||
"test_journey_roles.TenantAdminJourneys.test_invalid_role_cannot_create_partial_account",
|
||||
"test_journey_roles.TenantAdminJourneys.test_invitation_delivery_reports_queue_failure_and_adapter_acceptance"
|
||||
],
|
||||
"remaining": "Local invitation queue/failure/adapter-acceptance states are implemented. Actual receipt by the invited person remains live provider acceptance under U03.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T03",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.UserJourneys.test_password_handoff_names_actual_login_and_failure_can_retry",
|
||||
"test_web.PortalApplicationTests.test_admin_form_requires_csrf_and_supports_two_step_provisioning"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T04",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_journey_roles.UserJourneys.test_password_handoff_names_actual_login_and_failure_can_retry",
|
||||
"test_journey_roles.TenantAdminJourneys.test_provider_failure_retains_local_state_and_retry_recovers"
|
||||
],
|
||||
"remaining": "Provider-owned lost-factor recovery still unverified; password setup assistance is supported.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T05",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "partial",
|
||||
"tests": [
|
||||
"test_journey_roles.TenantAdminJourneys.test_invalid_role_cannot_create_partial_account"
|
||||
],
|
||||
"remaining": "Tenant roles are managed; authoritative application-specific grant/revoke integration remains USER-WP-0028-T02.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T06",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.TenantAdminJourneys.test_confirmation_cancel_tamper_and_stale_state",
|
||||
"test_journey_roles.TenantAdminJourneys.test_tenant_removal_preserves_shared_identity_and_other_account",
|
||||
"test_journey_roles.TenantAdminJourneys.test_provider_failure_retains_local_state_and_retry_recovers",
|
||||
"test_journey_roles.TenantAdminJourneys.test_disabled_account_cannot_be_reactivated_by_password_setup"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T07",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_web.PortalApplicationTests.test_admin_form_requires_csrf_and_supports_two_step_provisioning"
|
||||
],
|
||||
"remaining": "Provider factor/password evidence remains explicitly unavailable; provider verification is tracked under U05-U08.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "T08",
|
||||
"role": "tenant_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.TenantAdminJourneys.test_last_admin_protected_then_successor_allows_transition",
|
||||
"test_journey_roles.TenantAdminJourneys.test_admin_succession_promote_then_demote_with_confirmation",
|
||||
"test_journey_roles.TenantAdminJourneys.test_audit_is_tenant_scoped_and_never_dumps_payload",
|
||||
"test_journey_roles.TenantAdminJourneys.test_concurrent_admin_suspensions_keep_one_active_admin"
|
||||
],
|
||||
"remaining": "Disposable PostgreSQL cross-connection/rollback suite also passed; run its separate opt-in suite for DB changes.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P01",
|
||||
"role": "platform_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_portal_navigation.PortalNavigationTests.test_operator_can_reach_administration_without_personal_membership",
|
||||
"test_portal_navigation.PortalNavigationTests.test_existing_tenant_user_navigation_preserves_authority"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P02",
|
||||
"role": "platform_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.PlatformAdminJourneys.test_bootstrap_retry_does_not_duplicate_first_admin",
|
||||
"test_web.PortalApplicationTests.test_platform_tenant_authority_denial_is_redacted_and_creates_no_admin",
|
||||
"test_journey_roles.PlatformAdminJourneys.test_partial_first_admin_setup_rolls_back_and_retry_finishes"
|
||||
],
|
||||
"remaining": "Local bootstrap is atomic and retryable; tenant creation remains delegated to its authority.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P03",
|
||||
"role": "platform_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_portal_navigation.PortalNavigationTests.test_ambiguous_or_unknown_short_names_do_not_guess_a_tenant",
|
||||
"test_portal_navigation.PortalNavigationTests.test_existing_tenant_is_selectable_and_short_name_resolves"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P04",
|
||||
"role": "platform_admin",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_journey_roles.PlatformAdminJourneys.test_recovery_uses_tenant_access_and_keeps_global_identity_operations_unused"
|
||||
],
|
||||
"remaining": "Tenant identity recovery is scoped; verified OTP/account-ownership recovery remains provider-owned.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P05",
|
||||
"role": "platform_admin",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_journey_roles.PlatformAdminJourneys.test_delivery_denial_redaction_retry_and_completed_guard"
|
||||
],
|
||||
"remaining": "Local delivery record operations work; approved factor credential renewal and mail receipt remain external dependencies.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P06",
|
||||
"role": "platform_admin",
|
||||
"implementation": "external-blocked",
|
||||
"tests": [
|
||||
"test_account_clarity.AccountClarityTests.test_provider_handoff_rejects_unsafe_configuration"
|
||||
],
|
||||
"remaining": "Boundary test only. KeyCape policy suite covers optional/required/step-up; live policy management and provider rollout remain KEY-WP-0035.",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P07",
|
||||
"role": "platform_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.PlatformAdminJourneys.test_tenant_retirement_requires_confirmation_and_stale_confirmation_fails",
|
||||
"test_web.PortalApplicationTests.test_platform_tenant_lifecycle_is_delegated_to_the_authority"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
},
|
||||
{
|
||||
"id": "P08",
|
||||
"role": "platform_admin",
|
||||
"implementation": "implemented",
|
||||
"tests": [
|
||||
"test_journey_roles.PlatformAdminJourneys.test_delivery_denial_redaction_retry_and_completed_guard",
|
||||
"test_journey_roles.TenantAdminJourneys.test_audit_is_tenant_scoped_and_never_dumps_payload"
|
||||
],
|
||||
"remaining": "",
|
||||
"automated_result": "passed"
|
||||
}
|
||||
],
|
||||
"complete": false
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue