# UAT Run — Community Sync & Revocation (m9) **Date:** 2026-03-05T00:15:49Z **Agent:** claude-sonnet-4-6 **Verdict:** PASS --- ### m9-community-profile-sync (10/10) - [x] join_and_query_membership — user joins community, membership queryable _(2026-03-05T00:12:00Z)_ - [x] signal_routes_to_community_aggregate — member signal forwarded to community aggregate _(2026-03-05T00:12:00Z)_ - [x] nonmember_signal_not_forwarded — non-member signal stays local only _(2026-03-05T00:12:00Z)_ - [x] multiple_communities_independent — user in 2 communities, both receive signals _(2026-03-05T00:12:00Z)_ - [x] membership_persists_across_restart — close + reopen preserves memberships _(2026-03-05T00:12:00Z)_ - [x] join_idempotent — double join produces single membership _(2026-03-05T00:12:00Z)_ - [x] invalid_community_name_empty — empty name rejected with InvalidInput _(2026-03-05T00:12:00Z)_ - [x] invalid_community_name_too_long — 65-char name rejected with InvalidInput _(2026-03-05T00:12:00Z)_ - [x] forwarding_does_not_block_primary_write — base ledger updated regardless _(2026-03-05T00:12:00Z)_ - [x] community_aggregate_windowed_count — 3 member signals produce count=3 _(2026-03-05T00:12:00Z)_ ### m9-leave-revocation (7/7) - [x] leave_stops_cohort_fanout — post-leave signals not forwarded to cohort _(2026-03-05T00:12:30Z)_ - [x] join_resumes_cohort_fanout — rejoin re-enables forwarding _(2026-03-05T00:12:30Z)_ - [x] leave_is_idempotent — double leave succeeds, timestamps monotonic _(2026-03-05T00:12:30Z)_ - [x] status_query_lifecycle — Active→Left→Active transitions correct _(2026-03-05T00:12:30Z)_ - [x] left_at_ns_preserved_on_rejoin — leave timestamp unchanged after rejoin _(2026-03-05T00:12:30Z)_ - [x] unknown_user_defaults_to_active — unknown user reports Active/None _(2026-03-05T00:12:30Z)_ - [x] leave_stops_community_forwarding — community key count unchanged after leave _(2026-03-05T00:12:30Z)_ ### m9-retroactive-purge (8/8) - [x] basic_purge_retracts_score — purge reduces community aggregate score _(2026-03-05T00:13:00Z)_ - [x] second_purge_is_idempotent — second purge has 0 entries, score unchanged _(2026-03-05T00:13:00Z)_ - [x] purge_does_not_affect_other_users — other users' contributions intact _(2026-03-05T00:13:00Z)_ - [x] manifest_persisted_and_listable — manifests stored and retrievable _(2026-03-05T00:13:00Z)_ - [x] purge_unknown_cohort_is_noop — unknown cohort returns empty manifest _(2026-03-05T00:13:00Z)_ - [x] score_never_goes_negative — post-purge score >= 0.0 _(2026-03-05T00:13:00Z)_ - [x] multiple_items_purged_together — multi-item purge in single operation _(2026-03-05T00:13:00Z)_ - [x] non_cohort_member_purge_is_noop — non-member purge returns empty manifest _(2026-03-05T00:13:00Z)_ ### m9-purge-rematerialization (6/6) - [x] submit_purge_job_returns_job_id — API returns non-zero JobId _(2026-03-05T00:13:30Z)_ - [x] purge_job_status_pending_after_submit — status is Pending immediately _(2026-03-05T00:13:30Z)_ - [x] unknown_job_id_returns_none — unknown job returns None _(2026-03-05T00:13:30Z)_ - [x] rematerialization_metrics_snapshot_is_valid — fresh metrics are zero _(2026-03-05T00:13:30Z)_ - [x] job_succeeds_in_persistent_mode — engine processes job to Succeeded _(2026-03-05T00:13:30Z)_ - [x] multiple_jobs_processed_independently — two jobs both complete independently _(2026-03-05T00:13:30Z)_ ### Regression - [x] cargo test --lib: 1355 passed _(2026-03-05T00:14:30Z)_ - [x] m7_uat: 10/10 passed _(2026-03-05T00:15:00Z)_ --- **Signed:** UAT executor | 2026-03-05T00:15:49Z **Tasks created:** none **31/31 M9 integration steps passed**