diff --git a/backend/src/test/java/com/danyang/match/platform/auth/MeStatusLocalEligibilityGuardTest.java b/backend/src/test/java/com/danyang/match/platform/auth/MeStatusLocalEligibilityGuardTest.java
new file mode 100644
index 0000000..cae5a84
--- /dev/null
+++ b/backend/src/test/java/com/danyang/match/platform/auth/MeStatusLocalEligibilityGuardTest.java
@@ -0,0 +1,77 @@
+package com.danyang.match.platform.auth;
+
+import com.danyang.match.platform.auth.service.AuthService;
+import com.danyang.match.platform.local_eligibility.entity.LocalEligibility;
+import com.danyang.match.platform.local_eligibility.mapper.LocalEligibilityMapper;
+import com.danyang.match.platform.user.entity.User;
+import com.danyang.match.platform.user.mapper.UserMapper;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Map;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * E2E 场景对账补缺(2026-09-19):`/me/status` 必须返回 `localEligibilityStatus`。
+ *
+ *
原始场景清单(Phase 23 占位文件头,「本地资格 11 项」第 6 项)在对账中发现
+ * 零断言覆盖 —— 实现存在({@code AuthService#getMeStatus} 组装
+ * {@code localEligibilityStatus / localEligibilityType / localEligibilityVerifiedAt},
+ * 未声明时回 {@code not_declared}),但 E2E 与后端测试都从未断言过该字段。
+ * 本守卫把该字段从「碰巧返回」变成「被声明的契约」:
+ * 若后人重构 {@code getMeStatus} 时丢掉本地资格组装,这里会红。
+ */
+@SpringBootTest
+@ActiveProfiles("test")
+@Transactional
+class MeStatusLocalEligibilityGuardTest {
+
+ @MockBean
+ private StringRedisTemplate stringRedisTemplate;
+
+ @Autowired private AuthService authService;
+ @Autowired private UserMapper userMapper;
+ @Autowired private LocalEligibilityMapper localEligibilityMapper;
+
+ private User newUser() {
+ User user = new User();
+ user.setId(UUID.randomUUID().toString());
+ user.setWechatOpenid("openid-" + UUID.randomUUID());
+ user.setAccountStatus("normal");
+ userMapper.insert(user);
+ return user;
+ }
+
+ @Test
+ @DisplayName("未声明本地资格的用户:/me/status 显式返回 not_declared")
+ void notDeclaredUserGetsNotDeclaredStatus() {
+ User user = newUser();
+ Map status = authService.getMeStatus(user.getId());
+ assertEquals("not_declared", status.get("localEligibilityStatus"),
+ "未声明时 /me/status 必须显式返回 not_declared,而不是缺省该键");
+ }
+
+ @Test
+ @DisplayName("已声明本地资格的用户:/me/status 回读真实核验状态与类型")
+ void declaredUserGetsRealStatus() {
+ User user = newUser();
+ LocalEligibility el = new LocalEligibility();
+ el.setUserId(user.getId());
+ el.setEligibilityType("household_registration");
+ el.setVerificationStatus("declared");
+ localEligibilityMapper.insert(el);
+
+ Map status = authService.getMeStatus(user.getId());
+ assertEquals("declared", status.get("localEligibilityStatus"),
+ "/me/status 必须回读 user_local_eligibilities 的真实状态");
+ assertEquals("household_registration", status.get("localEligibilityType"));
+ }
+}
diff --git a/docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md b/docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md
index d22057b..d536d74 100644
--- a/docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md
+++ b/docs/superpowers/plans/2026-09-18-phase23-closeout-and-uat-readiness.md
@@ -136,6 +136,60 @@
- 注入②「把 `user_b_status` 列默认值改成 `accepted`」**无效**:`createMutualConsent`
在 Java 侧**显式写入** `pending`,DB 默认值根本不参与。这条侧面证明了写入路径的权威性。
+### Task 2.1 补充:场景对账表(2026-09-19)
+
+> 原始场景清单取自 Phase 23 占位文件头(commit `ae1bd2b`,此后文件已实现为真实用例)。
+> 对账口径:**场景有真实断言即算覆盖**,层次分 E2E(HTTP 活栈)与后端集成(真实落库)。
+
+**首页 11 项**
+
+| # | 场景 | 覆盖 | 位置 |
+|---|---|---|---|
+| 1 | `GET /home` 返回 userState | ✅ E2E | `run_v11_tests::test_02_home`、`home_v11_test::test_home_returns_fixed_sections` |
+| 2 | Banner 按时间过滤(未开始/已过期不显示) | ✅ 后端 | `BannerOperatorPhase19IntegrationTest` |
+| 3 | Banner 按 `audience_scope` 过滤 | ✅ 后端 | 同上 |
+| 4 | 首页 8 入口顺序固定(INV-017) | ✅ 双层 | 后端 `V11InvariantsTest#inv017`(真实 `getHome`)+ E2E `run_v11_tests::test_03`、`home_v11_test::test_quick_entries_fixed_order` |
+| 5 | 未审核用户不返回真实推荐 | ✅ 后端 | `RecommendationEligibilityPhase06Test`(资格矩阵) |
+| 6 | Paused 用户不返回新推荐 | ✅ 后端 | 同上 |
+| 7 | Successful 用户不返回找对象推荐 | ✅ 后端 | 同上 + `RelationshipProgressPhase12Test` |
+| 8 | 服务站可展示 | ✅ E2E | `run_v11_tests::test_06` + `service_appointment_test`(seed 站点)+ Phase 19 公告守卫 |
+| 9 | Banner 不能外链(INV-016) | ✅ 双层 | 后端 `V11InvariantsTest#inv016`(反射读生产白名单)+ E2E `home_v11_test::test_banner_target_types_are_internal_only` |
+| 10 | `counselingEnabled` flag 控制 `canApplyCounseling` | ⚠️ **场景过时(被取代)** | 该 flag 经产品裁定于 2026-09-19 移除(死配置,见 Task 3.2);入口可见性由 `CapabilityService` 决定(AGENTS.md #26)。原命题不再成立 |
+| 11 | `canReceiveRecommendations` 随账号状态变化 | ✅ 间接 | 资格层 `RecommendationEligibilityPhase06Test` + E2E home 走真实 `/home`(Capability 参与);`CapabilityService` 无独立单测(接受,低风险) |
+
+**本地资格 11 项**
+
+| # | 场景 | 覆盖 | 位置 |
+|---|---|---|---|
+| 1 | 用户可声明丹阳工作/户籍/居住 | ✅ E2E | `local_eligibility_test::test_declaration_is_persisted`、`::test_new_user_is_not_declared` |
+| 2 | 声明不默认要求上传佐证 | ✅ 后端 | `LocalEligibilityServiceTest`(declare 与 evidence 分离) |
+| 3 | 佐证上传需要鉴权 | ✅ 后端 | `LocalEligibilityServiceTest`(userId 自限定)+ `PhotoUploadValidationTest` |
+| 4 | 审核员可访问佐证(INV-011) | ✅ 后端 | `Inv011EvidenceAccessGuardTest`(真实落库 + 审计回查) |
+| 5 | 红娘不可访问佐证(INV-011) | ✅ 后端 | 同上 |
+| 6 | `/me/status` 返回 `localEligibilityStatus` | ✅ **本轮补缺(2026-09-19)** | 对账发现实现存在但**零断言** → 新增 `MeStatusLocalEligibilityGuardTest`(2 用例:not_declared / 真实回读) |
+| 7 | 未核验影响匹配资格 | ✅ 后端 | `RecommendationEligibilityPhase06Test`(`localEligibilityRequired` 接入) |
+| 8 | 审核进入 `local_eligibility` 队列 | ✅ 后端 | `ReviewServicePhase05Test` |
+| 9 | 审核通过更新状态 | ✅ 后端 | 同上 |
+| 10 | 需补充佐证触发用户上传 | ✅ 后端+页面 | `ReviewService` 置 `needs_evidence`、`LocalEligibilityService` 上传后回 `pending_review`(`LocalEligibilityServiceTest` 覆盖分支);用户端承接 `local-eligibility-supplement` 页 + `getStatus.evidenceRequired` |
+| 11 | 查看佐证须记录审计 | ✅ 后端 | `Inv011EvidenceAccessGuardTest`(success/denied 双向审计落库回查) |
+
+**权限 10 项**
+
+| # | 场景 | 覆盖 | 位置 |
+|---|---|---|---|
+| 1 | Counselor 只看 assigned(INV-012) | ✅ 双层 | 后端 `CounselingPhase13ATest` + E2E `counseling_v11_test::test_counselor_assigned_list_is_scoped` |
+| 2 | Counselor 不可看他人服务 | ✅ E2E | `counseling_permission_test::test_counselor_cannot_read_unassigned_service` |
+| 3 | 红娘不可读咨询正文(INV-013) | ✅ 双层 | 后端 `V11InvariantsTest#inv013`(真实 `getDetail` 脱敏)+ E2E `counseling_permission_test::test_matchmaker_has_no_counseling_view` |
+| 4 | 普通管理员不可读敏感备注 | ✅ 后端 | `CounselingPhase13ATest`(脱敏分层:manager 摘要 / 非 assigned 脱敏) |
+| 5 | 咨询管理员可分配 | ✅ 双层 | 后端 `assignIfPending` 守卫 + E2E `run_v11_tests::test_08` |
+| 6 | 咨询可转交风控 | ✅ 后端 | `RiskReferralService` + `ReportAndRiskPhase17IntegrationTest`(`detectCounselingRisk` 来源接入) |
+| 7 | 服务站人员不能浏览全用户(INV-018) | ✅ 双层 | E2E `organization_isolation_test` + `service_station_permission_test` + 后端 `ServiceAppointmentDataScopeTest` |
+| 8 | 服务站人员可处理本站预约 | ✅ E2E | `service_appointment_test::test_operator_can_confirm`(seed 站点范围) |
+| 9 | 内容编辑员不能访问用户档案(INV-019) | ✅ 双层 | 后端 `V11InvariantsTest#inv019` + E2E `content_e2e_test::test_content_editor_cannot_read_user_matching_data` |
+| 10 | 内容编辑员可管理文章 | ✅ E2E | `content_e2e_test::test_article_lifecycle_draft_publish_offline` |
+
+**对账结论**:32 项场景中 **31 项有真实断言覆盖**(E2E 或后端集成),1 项(首页 #10)被产品裁定取代并记录取代关系;发现并补齐 **1 处零断言字段**(`/me/status.localEligibilityStatus`,场景 #6)。无「假覆盖」残留。
+
### Task 2.2: INV-011 显式守卫
**Files:**