完成40%
This commit is contained in:
+68
-13
@@ -1,8 +1,8 @@
|
||||
# 项目当前总览
|
||||
|
||||
> 当前阶段:导航任务 1—10、TAC 认证客户端、领域上下文基础与 M07 反馈客户端已经完成;T01、认证、家谱工作区、G03 原子创建、M06 帮助、个人资料读写、通知读写、M10 服务端退出、M04 登录态改密和 M05 手机号换绑后端接口门禁均为红灯,继续逐域关闭真实接口
|
||||
> 当前状态:A01/A04/A05 已接入统一 TAC、真实短信和认证请求代码,M07 已接真实反馈提交 owner;G01/G05、G03、M06、M01/M02/M03 个人资料读写、N01/N02/M01/G01 通知域、M10 退出域、M04 密码凭证域与 M05 换绑域已完成三人接口审查和失败门禁,均未猜测接线;`runtimeConfig.mode` 仍为 `mock`,MuMu 原生矩阵和真实环境联调待执行
|
||||
> 当前基准 HEAD:`9b0ad62df467f4e2c58b7689087683c77755e07b`(`main`,工作区有本轮未提交变更)
|
||||
> 当前阶段:导航任务 1—10、TAC 认证客户端、领域上下文基础与 M07 反馈客户端已经完成;任务 36 普通加入、任务 37 邀请码直入、任务 38 G11 设置和任务 39 G12 字辈集合合同已完成三人审查与失败门禁;任务 40 F01/F03 家族动态读取已完成三方接口定案并建立专项失败门禁,正在收口门禁对抗评审与文档;T01、认证、家谱工作区、G03、加入/邀请/G11/G12、F01/F03 读取、M06、个人资料读写、通知读写、M10、M04 和 M05 后端接口门禁均为红灯,继续逐域关闭真实接口
|
||||
> 当前状态:A01/A04/A05 已接入统一 TAC、真实短信和认证请求代码,M07 已接真实反馈提交 owner;G01/G05、G03、普通加入、邀请码直入、G11、G12、F01/F03 读取、M06、个人资料读写、通知域、退出、密码与换绑域均已完成接口审查并建立失败门禁,均未猜测接线;`runtimeConfig.mode` 仍为 `mock`,MuMu 原生矩阵和真实环境联调待执行
|
||||
> 当前基准 HEAD:`f1edc6b53320755a8638c99d492250153a8dcb17`(`main`,工作区有任务 36/37/38/39 未提交变更)
|
||||
> 更新日期:2026-07-23
|
||||
|
||||
## 2026-07-23 换机续作断点
|
||||
@@ -11,15 +11,15 @@
|
||||
|
||||
本项目的总目标不可缩减为“只写规划”或“只让静态测试通过”:必须在 `main` 工作区内持续推进整个 UniApp 家谱项目,按测试先行和三人交叉评审完成导航、T01 长世代世系树、TAC/认证、家谱领域数据、G/T/F/R/N/M 全量页面与接口、异常恢复、无障碍、构建及上线验证,最终交付能够正常上线使用的项目。若本地可完成的工作全部完成后只剩后端合同重导、有效测试账号、应用签名、发布凭证或 MuMu 人工操作等外部状态,才允许停在明确硬阻塞;每项阻塞必须有失败门禁、复现证据、唯一所有者、解除条件和继续步骤,不能用 mock、fixture、定时器或宽松兼容伪装完成。
|
||||
|
||||
协作固定为当前主代理加两位评审者,共三人。三人都必须独立检查接口/字段、页面/业务闭环、交互/异常/视觉,再交叉质询并统一结论;主代理是唯一写入者,不再创建旧专家身份或增加并发评审者。普通技术取舍由三人自行收敛,不反复交给用户。系统保存的目标记录仍存在,但在 2026-07-23 读取时状态为 `paused`;换机后的执行者不得据此把任务视为取消,应以上述总目标和本节断点继续。只有项目真实达到完成定义时才能标记完成。
|
||||
协作固定为当前主代理加两位评审者,共三人。三人都必须独立检查接口/字段、页面/业务闭环、交互/异常/视觉,再交叉质询并统一结论;主代理是唯一写入者,不再创建旧专家身份或增加并发评审者。普通技术取舍由三人自行收敛,不反复交给用户。系统目标已经重新固定为整个项目的可上线闭环并处于 active;只有项目真实达到完成定义时才能标记完成。
|
||||
|
||||
### 仓库与保护基线
|
||||
|
||||
- 当前分支为 `main`,HEAD 为 `9b0ad62df467f4e2c58b7689087683c77755e07b`,上游显示 `main...origin/main`。工作区含大量本轮未提交的修改、删除和新增文件,均属于当前连续治理成果;换机后先运行 `git status -sb` 和 `git rev-parse HEAD` 核对,禁止用 `restore/checkout/reset` 清理,也禁止自行改分支或 worktree。
|
||||
- 当前分支为 `main`,HEAD 为 `f1edc6b53320755a8638c99d492250153a8dcb17`,上游显示 `main...origin/main`。工作区含任务 36/37/38/39 未提交修改和新增门禁,均属于当前连续治理成果;禁止用 `restore/checkout/reset` 清理,也禁止自行改分支或 worktree。
|
||||
- 本节仅记录断点,没有执行 `git add/commit/push`。由用户自行上传;换机后必须保留当前完整工作区,而不能只依赖旧远端基线。
|
||||
- 后端唯一目标地址是 `https://backend-api.ddxcjp.cn/`。受保护 `APP.openapi.yaml` 的 SHA-256 为 `8964CD583CE172425B63BBFD802F7EB587EB3641EADFD6F9D3B264FAA8090C6C`,`APP.openapi.json` 为 `87DB1DC148C5E6E877815AFF7B3A7FC7C7ECA95A2CEC50A88B42F3908961F31A`;两文件相对 HEAD 无差异。不得修改、格式化、覆盖或删除,只接受后端同一版本重新导出的双文件。
|
||||
- 不得启动、关闭或调整 MuMu。浏览器截图和源码检查不能冒充 Android 原生视觉、TalkBack、系统字号、软键盘或返回键验收。
|
||||
- 当前物理测试库存仍是 PowerShell `140`、Node `47`。最近一次完整记录为 PowerShell `126/140`,14 项均是预期发布红灯;Node 语法 `47/47`、纯 Node `19/19`、活动 Vue 脚本 `64/64` 通过。G03 最后一次布尔类型加固后又单独通过聚焦合同;换机后应先重跑完整套件,不能把这些历史数字冒充新机器证据。
|
||||
- 换机后 fresh 基线已重跑:任务 36 门禁前为 PowerShell `126/140`、14 项预期发布红灯;任务 36 后为 `126/141`。任务 37 新增 `tests/invite-ticket-openapi-contract.ps1` 后物理库存为 PowerShell `142`、Node `47`,全量 fresh 为 `126/142`,16 项均为明确发布红灯;任务 38 新增 `tests/g11-settings-openapi-contract.ps1` 后当前物理库存为 PowerShell `143`、Node `47`,全量 fresh 为 `126/143`,17 项均为明确发布红灯。任务 39 新增 G12 主门禁、对抗合同和 Unicode Node 冒烟后,物理库存为 PowerShell `145`、Node `48`,全量 fresh 为 `127/145`,18 项均为明确发布红灯。任务 40 新增家族动态读取主门禁与对抗合同后,当前物理库存为 PowerShell `147`、Node `48`,全量 fresh 为 `128/147`,19 项均为明确发布红灯;Node 语法 `48/48`、纯 Node `20/20`、活动 Vue 脚本 `64/64` 和编译审计均 fresh 通过。
|
||||
|
||||
### 已完成到哪里
|
||||
|
||||
@@ -33,16 +33,61 @@
|
||||
|
||||
- 搜索、我的申请和待审列表使用各自专用最小投影与稳定 cursor 分页,不返回 `total`,所有 `genealogyId/applyId` 都是有界词法字符串。搜索项只暴露识别家谱所需字段和当前查看者状态;我的申请完整表达 `PENDING/APPROVED/REJECTED/WITHDRAWN`;待审项只含 `applyId/applicantName/relationDesc/applyReason?/submittedAt`,不得泄漏手机号、用户 ID、邀请人或审核人内部字段。
|
||||
- 申请 body 闭合为 `applicantName/relationDesc/applyReason?`,前两项必填;删除 `phone/inviterUserId`。同账号、租户、家谱最多一个活动 `PENDING`,由数据库唯一约束而非先查后插保证。
|
||||
- 申请 POST 必须带无 PII 的 `Idempotency-Key`。同 key、同 canonical body 重放同一结果;同 key、不同 body 返回 409。客户端只持久 `{sessionEpoch,requestKey,startedAt}`,不持久姓名、关系和理由。
|
||||
- 申请 POST 必须带无 PII 的 `Idempotency-Key`,并与状态查询的 requestKey 共用唯一 `GenealogyJoinApplicationRequestKey`:`gja.{13 位毫秒时间}.{22—43 位 base64url CSPRNG}`,随机量至少 128 位;`acceptUntil=issuedAt+10 分钟`、未来偏差最多 5 分钟、`resolveBy<=claimedAt+2 分钟`。canonical digest 唯一覆盖 method、规范 path、genealogyId、tenant、account、client 与规范 body;正文统一执行 NFC、去边界空白、CRLF/CR→LF且不折叠内部空白。同 key、同 canonical request 重放同一结果;同 key、不同 digest 返回 409。客户端只持久 `{sessionEpoch,requestKey,startedAt}`,不持久姓名、关系和理由。
|
||||
- 冷启动恢复不复用 `mine` 查询,也不持久表单 PII;新增唯一只读 owner `GET /genealogy/app/genealogies/join-apply-requests/{requestKey}`,以显式 discriminator 返回 `PENDING {resolveBy,retryAfterSeconds}`、`SUCCEEDED {applyId/genealogyId/...无 PII 回执}` 或 `FAILED_NO_COMMIT`。只允许 `ABSENT→PENDING→SUCCEEDED/FAILED_NO_COMMIT`,两个终态不可变;GET 纯读,跨账号/租户/client 统一非泄漏 404,PENDING 必须有收敛期限,从未到达的 key 也必须在可计算时间边界后成为零写 `FAILED_NO_COMMIT`。
|
||||
- 不引入 `applicationVersion`、`If-Match` 或审核详情端点。申请在 PENDING 时不可编辑,撤回、通过和拒绝都以 `WHERE status=PENDING` 的数据库 CAS 决定唯一赢家。重复相同撤回返回同一 200;重复相同审核决定返回原 200,拒绝时只有规范化后理由相同才算相同动作;相反决定、不同拒绝理由或撤回/审核竞态败方返回 typed 409 和当前最小状态。终态不可改,重新申请创建新 `applyId`。
|
||||
- 审核 body 只允许 `APPROVE`,或 `REJECT+必填申请人可见 rejectionReason`。批准必须在同一事务完成唯一成员关系和申请终态;G05 的 `canReviewJoinApplications` 只是入口 capability,服务端在事务/CAS 时仍重新验证权限、家谱状态和 `PUBLIC_APPLY`。
|
||||
- 所有操作 required SaToken 和非空 `clientid`,仅使用 `application/json`、`Cache-Control: private, no-store`,429 带 `Retry-After`。线上三个匿名 GET 当前实测为 HTTP 200 加业务 `code=401`,却与文档 HTTP 401 string 冲突;发布合同必须统一为真实 HTTP 状态与 typed JSON,禁止 `*/*`、200 包装认证错误、`default` 响应和 int64 JSON 身份。
|
||||
- 客户端结果未知时禁止乐观改列表:申请查专用 operation;撤回刷新 mine 并可安全重放同一 DELETE;审核刷新 pending,行消失只能说“状态已变化/已被处理”,不能冒充本次审核成功。首版不承诺消息中心通知;G09 的 `onShow` 与手动刷新是当前业务真相。
|
||||
|
||||
**尚未实施的边界必须原样保留:** `tests/join-application-openapi-contract.ps1` 还没有创建,任务 36 尚未写入实施计划和接口映射,测试计数仍为 140/47;G06/G08/G09/G10 业务代码也没有在本任务中修改。换机后的第一项写操作应是用 `apply_patch` 新增该 OpenAPI 失败门禁,先运行并取得精确 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`,再把 `API-JOIN-001`—`006`、七个 operation、状态机、隐私投影、竞态和部署反例同步写入现有四份中文权威文档及文档合同。后端门禁通过前页面继续保持诚实本地预览,不写只适配当前宽松线上模型的临时代码。
|
||||
**当前实施边界:** `tests/join-application-openapi-contract.ps1` 已创建并取得精确 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`;它成为七个 operation 与 APP 加入 schema 的唯一 owner,旧 `g-series-openapi-contract.ps1` 和 `core-flow-contract.ps1` 不再锁定 `phone/inviterUserId`、数字状态和 `auditRemark`。任务 36 只建立后端合同、权威文档和发布反例,不修改 G06/G08/G09/G10 业务代码;后端门禁通过前页面继续保持诚实本地预览,不写只适配当前宽松线上模型的临时代码。后续客户端批次必须删除 G10 手机号、三处消息中心承诺、`LOCAL_WITHDRAWN` 与遗留 adapter,并以状态机测试和 MuMu 证据完成原子迁移。
|
||||
|
||||
完成任务 36 的本地门禁、全量回归和三人终审后,继续按独立批次推进邀请码直入、G11 设置写入、G12 字辈真实保存,以及其余 G/T/F/R/N/M 业务域;不得一次混合导航、验证码、领域持久化和无障碍多个阶段。最终仍须完成真实后端联调、构建、签名/隐私配置、MuMu 全流程矩阵和发布终审。
|
||||
任务 36 已完成本地门禁、`126/141` 全量回归和三人终审,后端缺口继续以发布红灯保留。当前已进入独立任务 37;完成后继续 G11 设置写入、G12 字辈真实保存,以及其余 G/T/F/R/N/M 业务域。不得一次混合导航、验证码、领域持久化和无障碍多个阶段;最终仍须完成真实后端联调、构建、签名/隐私配置、MuMu 全流程矩阵和发布终审。
|
||||
|
||||
### 当前精确断点:任务 37 邀请码签发与直接加入
|
||||
|
||||
三人已对 G06/G08/M08、受保护双导出和 2026-07-23 当前线上 OpenAPI 完成只读审查并交叉反驳。线上 722 条路径中只有通用 promotions 与礼仪邀请,没有家谱邀请码签发、解析、撤销或直接加入 owner。统一结论为六个专用 operation:活动票据列表、无 body 幂等签发、撤销、JSON body 安全解析、无 body 直接兑换、兑换 request-status。
|
||||
|
||||
- 真实流程只在 G06 完成“输入原码→resolve(不消费票据、不建立成员,仅允许轮换短时 grant 摘要)→展示无邀请人 PII 的可信目标→明确确认直接加入且不经审核→redeem→status 收敛→刷新 `/mine`→安装 context→G01/G05”。邀请不再进入 G08;真实接线时删除 G06→G08 invite 导航和 G08 全部 invite source,G08 只归普通申请所有。
|
||||
- 首版票据固定单次、24 小时和至少 128 位随机量;HMAC 查找,隔离 KMS 密文只保留 600 秒同 key 秘密恢复窗。签发 unknown 只重放原 `gii` POST/key,窗后返回 `ISSUED_SECRET_UNAVAILABLE` 且不新签;客户端不持久原码。
|
||||
- resolve 原码只在 JSON body,统一非枚举错误和多维限流;最多五分钟的 redemption token 绑定 tenant/account/client/ticket/version/genealogy/authorizationEpoch,只驻内存。列表、URL/query、导航、storage、日志/APM/分析、错误和除指定成功分支外的响应闭包禁止原码/token。
|
||||
- redeem 不提交姓名、关系或理由,不创建申请、审核记录、人物或亲属关系;事务内原子完成 ACTIVE→CONSUMED、唯一 MEMBER 和成功回执。已有普通 PENDING 引导先去 G09 撤回,不由邀请流程暗改任务 36。
|
||||
- 兑换 unknown 使用 `gir` key 和 PENDING/SUCCEEDED/FAILED_NO_COMMIT 纯读状态收敛;客户端只持久 `{sessionEpoch,requestKey,startedAt}`。FAILED 保证票据未消费、成员未建,成功后的 workspace/context/导航失败只重试本地收口。
|
||||
|
||||
`tests/invite-ticket-openapi-contract.ps1` 已测试先行创建,初次取得 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`,经两位评审指出错误 envelope、撤销 CAS、秘密递归闭包、幂等时限、普通申请反向隔离等假绿后已加固到稳定 81 项后端缺口。文档合同、`126/142` 全量 PowerShell、Node `47/47`、纯 Node `19/19`、Vue 脚本 `64/64` 和编译审计均已 fresh 通过预期边界;当前门禁仍保持后端红灯,任务 37 已完成三人终审。后端门禁通过前不修改 M08/G06/G08 业务接线,不用 fixture、定时器或兼容分支伪装邀请码生产闭环。
|
||||
|
||||
### 当前精确断点:任务 38 G11 家谱设置版本化写入
|
||||
|
||||
三人已核对 G11、任务 26 workspace、任务 35 共享 accessPreset、受保护双导出与 2026-07-23 线上 OpenAPI。当前页面仍从 fixture 读取,保存只更新本页 baseline 并用 1800ms timer 显示“尚未提交服务器”;旧双导出 PUT 是宽 `GenealogyUpdateBody → RObject`,线上仍是含十个字段和 `visibility/joinMode` 的宽 `AppGenealogyUpdateBody`,两者都缺版本 CAS、typed 错误与严格权限/媒体合同。
|
||||
|
||||
- 全局唯一写 owner 保留 `PUT /genealogy/app/genealogies/{genealogyId}`,operationId 固定且全局唯一 `appUpdateGenealogySettings`;递归拒绝 PATCH、`/settings` 旁路、任一单字段设置 body/字段写入口,以及用外部或错分区同名 `$ref` 冒充 owner,并删除重复 generic GET。`/genealogy/app/genealogies...` 写 body 根层的 `intro` 明确保留给家谱设置,其他子域必须使用 `albumDesc/articleSummary` 等自身字段名,避免把设置第二写入口伪装成通用简介。workspace 同时递归扫描成功响应闭包,拒绝任何返回 `RAppGenealogyVo/AppGenealogyVo`、allOf 合成或等价实体的旁路详情 GET。G11 只消费 workspace 门禁的 PASS 结论,每次进入 fresh 读取唯一 `/overview` baseline,不信任路由、mine、旧 G05 内存、roleType 或 fixture。
|
||||
- 共享 `GenealogyName` 统一 G03/G11/读取为非 null、NFC、无边界空白、无换行/控制字符的 1—24 Unicode code point;`GenealogyIntro` 精确为空串或规范 1—80,正文只允许内部 LF,拒绝 CR/tab/其他控制字符,空串清空、省略保持。body 关闭额外字段且只允许 1—3 个 `genealogyName/intro/accessPreset` 脏属性,事务内原子 merge;canonical no-op 保留版本且无领域副作用。
|
||||
- 并发与 T01/M02 统一:`AppGenealogyVo.settingsVersion` 与 required `If-Match` 引用同一 opaque owner,以 `x-version-scope-fields` 锁定只随三个 canonical 设置实际变化,body 不重复版本,不另用强 ETag/412。409 根层只含 discriminator/oneOf 且分支为 exact local ref,精确分为版本变化+current、未 READY、活动待审;冲突优先级为 version→READY→active PENDING。
|
||||
- 活动 PENDING 只阻断实际 `PUBLIC_APPLY→MEMBER_ONLY`,整笔零写并引导 G10;不自动处理普通申请,不影响邀请码。设置 PUT 与任务 36 新申请 POST 都在事务内重验准入并共享 `ATOMIC_SINGLE_WINNER`,竞态只能一方提交。
|
||||
- 200 与 overview 共用关闭额外字段的 canonical `RAppGenealogyVo`;所有 component 解析只接受 exact local ref,标量、envelope、引用字段和错误字段以 allowed-key 集拒绝 `format/min/max/readOnly/writeOnly` 等额外约束、冲突组合关键字与 `nullable` 漂移。每个响应必须包含单值 enum 的 `Cache-Control: private, no-store`,429 另含 Retry-After;只允许 `traceparent/tracestate/x-request-id/x-correlation-id` 四种非语义 tracing header,禁止 ETag 与其他语义 header,避免产生第二套并发或缓存 owner。四种 tracing header 使用 component 时同样只能 exact local;内联时必须是 allowed-key 关闭、带非 null 的 string schema 的 Header Object。任务 36 的幂等、cursor、状态迁移、事务与重验扩展必须是真实 JSON 数组,不能用逗号字符串冒充。网络、超时、408、取消、5xx 和畸形 2xx 都是 outcome unknown;fresh overview 对账只陈述当前事实,不自动 PUT 或冒充本次成功。成功失效 mine/overview/search/preview 并重验 context。
|
||||
|
||||
`tests/g11-settings-openapi-contract.ps1` 已测试先行建立,吸收两位评审的全局 owner、workspace 前置、准入反向协调、字符、nullable、exact local ref、固定 header 与纯 discriminator 伪绿反例后稳定输出 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`、`Issues: 48`。它接管 PUT、body、settingsVersion/If-Match、409 与响应;workspace/join/G03 门禁分别只保留读取基础、申请准入协调、bootstrap/accessPreset/旧 DTO 删除。本批不创建无法执行生产 coordinator 的占位 client gate;后端同版双导出绿后,客户端第一项写操作必须先建立实际执行生产模块的纯 Node 失败测试,再实现 adapter/page,OpenAPI 绿不等于允许接线。任务 38 完成全量回归与三人终审后继续独立任务 39:G12 字辈真实保存。
|
||||
|
||||
### 当前精确断点:任务 39 G12 字辈集合版本化保存
|
||||
|
||||
三人已完成 G12 页面、共享字辈夹具/Node 冒烟、受保护双导出及现有 G-series 门禁的只读核对,并统一为唯一 `GET/PUT /genealogy/app/genealogies/{genealogyId}/generation-poems`,operationId 分别为 `appGetGenerationPoemSet`、`appUpdateGenerationPoemSet`。旧 collection POST、逐行 PUT、batch preview/save、management 旁路必须同版删除;不引入 preview token、preview/status 接口或第二写 owner。GET/PUT 200 共用 ACTIVE-only `GenerationPoemSetSnapshot {genealogyId,poemSetVersion,items}`,稳定词法 `poemId` 可随 `generationNo` 移动,重复字辈文字允许,排序只由 1—2147483647 的 generationNo 拥有。
|
||||
|
||||
- body 唯一为精确 `{items,disableMissing}` 的 `AppGenerationPoemSetUpdateBody`。声明 items 必须严格递增且最多 500;已有行的 poemId 必须引用 baseline ACTIVE,新行省略 ID。`disableMissing=false` 保留未声明 baseline,`true` 软停用遗漏项;空 false 是 no-op,空 true 停用全部。服务端先构造完整候选集合,再按 generationNo 排序并执行唯一 ID/世代、slot collision、连续性与最终 ACTIVE 容量检查;swap 必须显式提交所有受影响行并原子成功或零写,绝不物理删除历史。候选流程包含 `VALIDATE_FINAL_ACTIVE_CAPACITY`、`ALLOCATE_UNIQUE_NEW_IDS` 及新 ID 非空、唯一、非 baseline 校验,碰撞返回 `GENERATION_SLOT_CONFLICT`。
|
||||
- 并发唯一使用 opaque `GenerationPoemSetVersion` 与 required `If-Match`;body 不复制版本,不引入 ETag/412。canonical no-op 保留版本,语义变化生成永不复用的新版本。GET 重验 canView,PUT 在事务内重验 tenant、canEdit、版本与 READY;响应严格 typed JSON、private/no-store,429 带 Retry-After。正式 CORS 唯一声明 owner 为 `x-app-gateway-policies.APP_GATEWAY_PREFLIGHT`,精确允许 Authorization/Content-Type/If-Match/clientid 和 GET/PUT/OPTIONS;最终仍须用真实 gateway OPTIONS/preflight 证明部署 allowlist,导出声明不能冒充运行证据。
|
||||
- unknown 恢复采用 `FRESH_GET_THREE_WAY_NO_AUTO_PUT`:以 baseline/version、声明项与 disableMissing 构造 effective target;已有项按 ID+generation+NFC 文本匹配,新项按 generation+文本匹配且服务端 ID 必须新鲜。当前集合与 target 相等时执行 `CURRENT_EQUALS_TARGET_FIRST_NO_ATTRIBUTION`,只确认事实而不归因本次请求;仍等于 old 才允许用户明确重试,其他情况进入分歧处理。比较要求同基数、无额外行,语义等价忽略版本,但已变化 target 必须得到新且未复用版本;任何 unknown 后都不自动 PUT。
|
||||
- 字辈文本按 NFC、1—50 Unicode code point、完整 UTF-16 且拒绝边界空白、控制字符、bidi/zero-width 类字符。客户端在后端门禁转绿前继续诚实本地预览,禁止把 fixture、timer 或本地成功接到当前宽松接口。转绿后的第一项客户端写操作必须是直接执行生产 normalizer/coordinator 的失败测试,再原子删除旧 fixture/timer/本地成功和旧合同;随后补 saving/unknown/conflict、清空确认、live region、焦点、44dp 与 MuMu 320/360/412、1.3 倍字号、TalkBack、软键盘、0/1/500×50、swap、断网/杀进程、权限撤销、READY 和账号切换矩阵。
|
||||
|
||||
测试先行证据为 `tests/g12-generation-poem-openapi-contract.ps1` 输出 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`;72 项只指向受保护旧导出的真实路径/schema/header/CORS 缺口。完整 zero issues 合法种子及多跳 ref、callback、HTTP 方法、typed error、候选/unknown/CORS 变异由 `tests/g12-generation-poem-openapi-adversarial-contract.ps1` 证明为 `G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS`;ECMAScript Unicode 边界由 `tests/g12-generation-poem-unicode-contract-runtime-smoke.js` 证明为 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS`。G-series 已删除旧 G12 owner,三人第三轮终审无 P0/P1;受保护 OpenAPI 和页面均未修改。
|
||||
|
||||
### 当前精确断点:任务 40 F01/F03 家族动态读取
|
||||
|
||||
本批只治理 F01 动态列表、F03 动态详情和正常一级评论读取,明确排除 F02 发布、点赞、评论/回复写、回复读取和媒体文件读取。三方已统一唯一 owner 为 `GET /genealogy/app/genealogies/{genealogyId}/feeds`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}`、`GET /genealogy/app/genealogies/{genealogyId}/feeds/{feedId}/comments`,operationId 分别为 `appListFamilyFeeds`、`appGetFamilyFeed`、`appListFamilyFeedRootComments`;同版本删除两个 `/page` GET,保留谱上下文嵌套身份,不引入全局 feed 路由。受保护双导出当前仍有 feed list/page 与 comments list/page 双 owner、无 operationId、int64 ID、通用 RList/RObject/PageResult 和开放评论 DTO;2026-07-23 线上 OpenAPI 3.1.0 还显示 `AppFamilyFeedVo/FamilyFeedCommentVo` 无 required,评论投影含手机号和内部审核字段,因此两者都不能接页面。
|
||||
|
||||
`API-FEED-READ-001`—`006` 固定词法 `GenealogyId/FamilyFeedId/FamilyFeedCommentId` 与 closed required 最小投影。`AppFamilyFeedReadItem` 只含 `feedId/feedContent/authorDisplayName/publishedAt/hasMedia`;`hasMedia=true` 时,在媒体读取合同落地前客户端必须诚实展示附件暂不可用占位,不能静默伪装为完整纯文字动态。`AppFamilyFeedRootCommentReadItem` 只含 `commentId/commentContent/authorDisplayName/publishedAt`,只返回正常可见一级评论,不返回删除占位、reply、手机号、账号/业务用户 ID、状态或审核字段。标题、标签、点赞数、总评论数和 fixture 展示时间都不是本批服务端合同,adapter 不得猜值。
|
||||
|
||||
两个 collection GET 使用 opaque cursor,`limit` 默认 20、范围 1—50,不返回 total/pageNum;feed 按 `publishedAt DESC + feedId DESC_ORDINAL`,评论按 `publishedAt ASC + commentId ASC_ORDINAL`。读取窗口精确为 `UPPER_BOUND_KEYSET_LATEST_VISIBLE`:新插入项等刷新后再出现,删除或变为不可见的项在后续页省略,编辑内容按该页读取时的最新可见版本返回,不能宣传为严格 MVCC snapshot。cursor 绑定 tenant/account/authSession/client、谱/动态、projection/order/limit、windowUpperBound 与 lastTuple;每页重新鉴权,篡改或过期为 typed 400,跨主体、错谱、feed 不属于 path 谱、删除/隐藏、撤权或不可见统一 `404 FAMILY_FEED_NOT_AVAILABLE`,不以 403 泄露存在性。
|
||||
|
||||
`tests/family-feed-read-openapi-contract.ps1` 已测试先行取得 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85`。85 项全部对应受保护旧导出的双 owner、参数、词法身份、closed projection、cursor、安全、typed JSON、private/no-store、Retry-After、严格 Reference Object 与无 PII 缺口;`tests/family-feed-read-openapi-adversarial-contract.ps1` 以完整 zero issues 合法种子和 58 个独立变异取得 `FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58`,覆盖旧 owner、大小写、security owner/数组、int64、PII/审核字段、offset/total、cursor scope/order、403 分流、wildcard、缓存头、外部/多跳 ref、HEAD/OPTIONS/callback 与 schema 关键字旁路。受保护 OpenAPI、F01/F03 和 dormant `appApi.getFeeds` 均未修改。后端绿前 F01/F03 继续使用按 `genealogyId + feedId` 失败关闭的 fixture,禁止接当前宽接口或在远端失败后回退 fixture。后端同版本 JSON/YAML/live 文档全部通过后,客户端第一项写操作必须先建立直接执行生产 read normalizer/coordinator 的纯 Node 失败测试,再原子迁移列表、详情和评论分页,删除 fixture 锁、伪重试与旧“必须 fixture”断言,并补 sessionEpoch、切谱/切账号迟到响应、局部评论错误、诚实媒体占位、焦点恢复和 MuMu/无障碍矩阵。
|
||||
|
||||
## 当前目标
|
||||
|
||||
@@ -72,11 +117,11 @@
|
||||
|
||||
后端在 2026-07-22 新提供 `https://backend-api.ddxcjp.cn/`。同日 21:52(Asia/Shanghai)只读获取其 `/v3/api-docs`,线上为 OpenAPI `3.1.0`、`722` 条路径、`858` 个操作和 `507` 个模型;本地 112 条路径中有 109 条仍在线,`/genealogy/app/files/reference`、`/genealogy/app/files/upload`、`/genealogy/pc/files/upload` 三条不在当前线上文档,线上另有 613 条路径。线上模型已把部分 `Genealogy*Body` 重命名为 `AppGenealogy*Body`,`GenerationPoemBatchBody` 也新增了由路径写入的 `genealogyId` 字段,因此本地双导出是明确的旧快照,不能再代表当前部署的完整合同。`utils/config.js` 的唯一 `baseUrl` 已更新为无尾斜杠的 HTTPS 地址;`mode` 仍保持 `mock`,在页面接口和安全合同逐批闭合前不得提前切换远端。
|
||||
|
||||
线上文档已经提供 `/captcha/require`、`/captcha/challenge`、`/captcha/verify`:挑战与校验绑定 `tenantId/clientId/sceneCode/subject`,校验成功响应可返回 `validToken`,而发送短信的 `AppSmsCodeBody` 已把 `validToken` 列为必填。客户端已按 `APP_SMS_LOGIN/APP_REGISTER/APP_FORGOT_PASSWORD` 三个精确场景实现“查询要求→取得挑战→供应商完成→服务端校验→携票发送短信”,注册和找回提交不重复执行 TAC;认证请求只接受 HTTP 200 的严格 JSON envelope,统一 15 秒超时,离页或返回会中止当前 RequestTask。密码登录体尚无 `validToken`,因此 A01 以短信登录为默认且密码登录入口保持不可用,绝不以客户端先滑动冒充服务端强制校验。
|
||||
线上文档已经提供 `/captcha/require`、`/captcha/challenge`、`/captcha/verify`:挑战与校验绑定 `tenantId/clientId/sceneCode/subject`,校验成功响应可返回 `validToken`,而发送短信的 `AppSmsCodeBody` 已把 `validToken` 列为必填。客户端已按 `APP_SMS_LOGIN/APP_REGISTER/APP_FORGOT_PASSWORD` 三个精确场景实现“查询要求→取得挑战→供应商完成→服务端校验→携票发送短信”,注册和找回提交不重复执行 TAC;认证请求只接受 HTTP 200 的严格 JSON envelope,统一 15 秒超时,离页或返回会中止当前 RequestTask。A01 现以密码登录为默认并接通线上 MD5 wire、`access_token` 持久化与 G01 跳转;默认 mode 仍为 mock。密码联调入口的 static TAC 票据尚未由登录接口消费,因此只是测试性前置,不能冒充服务端强制校验,`API-AUTH-TAC-001` 继续保持发布红灯。
|
||||
|
||||
认证后端门禁仍有四组问题:`API-AUTH-TAC-001` 要求密码登录加入服务端可消费的同语义票据;`API-AUTH-TAC-002` 记录线上 `/captcha/challenge` 在 `APP_REGISTER` 实测返回 HTTP 500 且空响应;`API-AUTH-TAC-003` 要求验证请求以 provider discriminator/`oneOf` 严格关闭根对象和各 payload 的额外字段,并补齐必填 `providerCode/captchaType/payload`;`API-AUTH-TAC-004` 要求同一验证中心返回服务端绑定的 verification session、可验证方法和同一类短时单次 `validToken`,`required=false` 也必须直接签发可供短信接口消费的票据,不得形成无障碍绕过。`tests/auth-tac-openapi-contract.ps1` 当前输出 `AUTH-TAC-OPENAPI-CONTRACT BLOCKED`。密码登录、短信登录和注册的线上成功响应已统一为 `RAppLoginVo → AppLoginVo.access_token`,客户端旧令牌字段读取已删除。线上文档自身仍发布 `http://backend-api.ddxcjp.cn` server URL,与已验证可用的 HTTPS 地址不一致;客户端只能使用显式 HTTPS,后端还需修正文档 server 声明。对 `http://localhost:5173` 的预检已返回允许 `content-type/clientid`,这不能替代正式 H5 域名的 CORS 验证。
|
||||
|
||||
家谱工作区只读审查已固定 `/genealogy/app/genealogies/mine` 为可访问集合 owner、`/genealogy/app/genealogies/{genealogyId}/overview` 为 G05 唯一详情 owner;首批不同时请求语义重复的 `/{genealogyId}`。线上 `AppGenealogyVo.genealogyId` 仍是 JSON `integer/int64`,最大合法值进入 JavaScript 后会不可逆失真;三个相关模型均无 `required`,也没有必填 `canView`,`roleType` 无枚举。无令牌实测三条读取均返回 HTTP 200、`application/json;charset=UTF-8` 与 `{code:401,msg,data:null}`,但文档只列 200/401 且 401 为字符串,尚不能稳定区分登录失效、对象无权、已删除和服务故障。问题单 `API-GENEALOGY-WORKSPACE-001`—`003` 与 `tests/genealogy-workspace-openapi-contract.ps1` 已建立;同版本双导出通过前不写 G01/G05 专属 adapter,不用本地字段猜测替代服务端 owner。
|
||||
家谱工作区只读审查已固定 `/mine`/`appListMyGenealogies` 为可访问集合 owner、`/{genealogyId}/overview`/`appGetGenealogyOverview` 为 G05 唯一详情 owner;首批不同时请求语义重复的 `/{genealogyId}`。门禁已收紧为 GET-only/no-body、required SaToken/clientid、词法 `GenealogyId`、关闭的成功 envelope、typed HTTP、exact local ref 和固定 private/no-store;`/mine` 以 `OMIT_ONLY_AFTER_CONFIRMED_ACCESS_LOSS` 约束失权省略,overview 以 `NON_DISCLOSING_GENEALOGY_NOT_AVAILABLE` 统一对象无权/撤权/不存在,非法 ID 为 `GENEALOGY_ID_INVALID`。线上 `AppGenealogyVo.genealogyId` 仍是 JSON `integer/int64`,相关模型无 required/canView/角色 enum,无令牌部署又使用 HTTP 200+业务 401,均不能通过。问题单 `API-GENEALOGY-WORKSPACE-001`—`003` 与 `tests/genealogy-workspace-openapi-contract.ps1` 是唯一读取门禁;同版本双导出通过前不写 G01/G05 专属 adapter,不用本地字段猜测替代服务端 owner。
|
||||
|
||||
M06 三人审查选择 `GET /genealogy/app/help-articles` 的完整列表作为唯一远端 owner;线上列表模型已经包含 `helpContent`,因此页面不调用详情端点、不消费 `helpId`,也不让 JSON `int64` 进入页面模型。每次响应只允许显式投影 `helpCategory/helpTitle/helpContent`,分类从当前列表动态派生,展开键只在当前响应生命周期内使用并在搜索、分类、刷新前清空。当前受保护双导出仍返回通用 `ListResult/RList`,线上 `RListHelpArticleVo/HelpArticleVo` 又没有 `required`,正文格式、仅发布内容、展示顺序和认证失败承载也未形成一致合同;匿名实测列表与详情均为 HTTP 200+业务 `code=401`,而线上文档声明 HTTP 401 string。问题单 `API-M06-001`—`003` 与 `tests/help-center-openapi-contract.ps1` 已建立;门禁通过前保留明确本地 FAQ,不写 live-only adapter。
|
||||
|
||||
@@ -134,10 +179,20 @@ G03 创建链路三人反向质询后否决“先建空谱、再写始祖”的
|
||||
- 浏览器截图链已把 G03、G06、G08—G12、T06、F02、N01 的有效状态断言迁回各自现有运行时合同;G01、T03—T08、T07 三个有价值的浏览器测试只剥离截图写盘,继续验证状态、滚动、溢出与交互。
|
||||
- 已删除固定 Chrome 截图助手、联系表、8 个只保护截图助手的合同,以及迁移后重复的 N01/A02 合同;`tests/mumu-visual-acceptance-boundary-contract.ps1` 现在唯一约束“仓库不维护自动截图证据链、最终视觉通过只来自 MuMu”。
|
||||
|
||||
当前物理库存为 `140` 个 PowerShell 合同、`47` 个 Node 文件和 `4` 个 JSON 合同数据文件。最新 fresh 结果为 PowerShell `126/140` 通过;其余 14 项不是可删除的普通回归,而是保留真实外部或发布阻塞的 `tests/lineage-openapi-contract.ps1`、`tests/auth-tac-openapi-contract.ps1`、`tests/genealogy-workspace-openapi-contract.ps1`、`tests/g03-bootstrap-openapi-contract.ps1`、`tests/g03-bootstrap-client-release-gate.ps1`、`tests/help-center-openapi-contract.ps1`、`tests/profile-openapi-contract.ps1`、`tests/profile-update-openapi-contract.ps1`、`tests/notification-read-openapi-contract.ps1`、`tests/notification-read-state-openapi-contract.ps1`、`tests/logout-openapi-contract.ps1`、`tests/password-change-openapi-contract.ps1`、`tests/phone-change-openapi-contract.ps1` 和缺少 MuMu 人工证据时必须失败的 `tests/auth-android-accessibility-release-gate.ps1`。十四个输出分别为 `LINEAGE-OPENAPI-CONTRACT BLOCKED`、`AUTH-TAC-OPENAPI-CONTRACT BLOCKED`、`GENEALOGY-WORKSPACE-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-CLIENT-RELEASE BLOCKED`、`HELP-CENTER-OPENAPI-CONTRACT BLOCKED`、`PROFILE-OPENAPI-CONTRACT BLOCKED`、`PROFILE-UPDATE-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-STATE-OPENAPI-CONTRACT BLOCKED`、`LOGOUT-OPENAPI-CONTRACT BLOCKED`、`PASSWORD-CHANGE-OPENAPI-CONTRACT BLOCKED`、`PHONE-CHANGE-OPENAPI-CONTRACT BLOCKED` 和 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。Node 语法 `47/47` 通过,纯 Node 冒烟 `19/19` 通过,活动 Vue 脚本模块语法 `64/64` 通过;导航源码扫描保持 `MIGRATION-DEBT=0`。依赖 `127.0.0.1:9222` 调试页的浏览器运行时文件本轮只做语法检查,没有执行;这不能冒充浏览器行为或 MuMu 原生视觉通过。
|
||||
当前物理库存为 `147` 个 PowerShell 合同、`48` 个 Node 文件和 `4` 个 JSON 合同数据文件。最新 fresh 结果为 PowerShell `128/147` 通过;其余 19 项不是可删除的普通回归,而是保留真实外部或发布阻塞的 `tests/lineage-openapi-contract.ps1`、`tests/auth-tac-openapi-contract.ps1`、`tests/genealogy-workspace-openapi-contract.ps1`、`tests/g03-bootstrap-openapi-contract.ps1`、`tests/g03-bootstrap-client-release-gate.ps1`、`tests/help-center-openapi-contract.ps1`、`tests/profile-openapi-contract.ps1`、`tests/profile-update-openapi-contract.ps1`、`tests/notification-read-openapi-contract.ps1`、`tests/notification-read-state-openapi-contract.ps1`、`tests/logout-openapi-contract.ps1`、`tests/password-change-openapi-contract.ps1`、`tests/phone-change-openapi-contract.ps1`、`tests/join-application-openapi-contract.ps1`、`tests/invite-ticket-openapi-contract.ps1`、`tests/g11-settings-openapi-contract.ps1`、`tests/g12-generation-poem-openapi-contract.ps1`、`tests/family-feed-read-openapi-contract.ps1` 和缺少 MuMu 人工证据时必须失败的 `tests/auth-android-accessibility-release-gate.ps1`。十九个输出分别为 `LINEAGE-OPENAPI-CONTRACT BLOCKED`、`AUTH-TAC-OPENAPI-CONTRACT BLOCKED`、`GENEALOGY-WORKSPACE-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-OPENAPI-CONTRACT BLOCKED`、`G03-BOOTSTRAP-CLIENT-RELEASE BLOCKED`、`HELP-CENTER-OPENAPI-CONTRACT BLOCKED`、`PROFILE-OPENAPI-CONTRACT BLOCKED`、`PROFILE-UPDATE-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-OPENAPI-CONTRACT BLOCKED`、`NOTIFICATION-READ-STATE-OPENAPI-CONTRACT BLOCKED`、`LOGOUT-OPENAPI-CONTRACT BLOCKED`、`PASSWORD-CHANGE-OPENAPI-CONTRACT BLOCKED`、`PHONE-CHANGE-OPENAPI-CONTRACT BLOCKED`、`JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`、`INVITE-TICKET-OPENAPI-CONTRACT BLOCKED`、`G11-SETTINGS-OPENAPI-CONTRACT BLOCKED`、`G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED` 和 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。Node 语法 `48/48` 通过,纯 Node 冒烟 `20/20` 通过,活动 Vue 脚本模块语法 `64/64` 通过;导航源码扫描保持 `MIGRATION-DEBT=0`。依赖 `127.0.0.1:9222` 调试页的浏览器运行时文件本轮只做语法检查,没有执行;这不能冒充浏览器行为或 MuMu 原生视觉通过。
|
||||
|
||||
阶段 0 清理结束时,`static/` 的正式基线为 `79` 个文件、共 `70,414,397` 字节。任务 3 退役两张孤立通知 frame 后,正式 `static/assets` 为 `77` 个文件、共 `69,093,742` 字节;`static/tac/` 当前 5 个文件、共 `68,190` 字节,因而当前 `static/` 物理库存为 `82` 个文件、共 `69,161,932` 字节。4 个供应商文件保持原字节并由哈希合同保护,新增适配器是唯一项目映射层;TAC 已进入 A01/A04/A05 业务运行时,但不属于可重建视觉资产注册表。`tmp/`、`unpackage/` 和 `design-pipeline/generated/` 均不存在;正式生成资产仍由清单和构建器恢复,质量报告不作为长期资料保留。
|
||||
|
||||
任务 36 新增门禁后,当前物理库存更新为 PowerShell `141`、Node `47`、JSON 合同数据 `4`;新增门禁已独立验证为 `JOIN-APPLICATION-OPENAPI-CONTRACT BLOCKED`。全量 fresh 复核为 `126/141`,新增加入申请红灯与原 14 项共同构成 15 项明确发布阻塞;上文 `140/47` 与 `126/140` 仅是新增门禁前的换机 fresh 基线,不能把两个时点混写为全部通过。
|
||||
|
||||
任务 37 新增邀请码门禁后,当前物理库存为 PowerShell `142`、Node `47`、JSON 合同数据 `4`;全量 fresh 为 `126/142`,新增 `INVITE-TICKET-OPENAPI-CONTRACT BLOCKED` 后共有 16 项明确发布阻塞。任务 36 的 `126/141` 是上一时点证据,不得冒充当前库存。
|
||||
|
||||
任务 38 新增设置门禁后,当前物理库存为 PowerShell `143`、Node `47`、JSON 合同数据 `4`;全量 fresh 为 `126/143`,新增 `G11-SETTINGS-OPENAPI-CONTRACT BLOCKED` 后共有 17 项明确发布阻塞,专项门禁稳定为 `Issues: 48`。
|
||||
|
||||
任务 39 新增 G12 主门禁、对抗合同和 Unicode 冒烟后,当前物理库存为 PowerShell `145`、Node `48`、JSON 合同数据 `4`;全量 fresh 为 `127/145`,对抗合同转绿而主门禁新增第 18 项发布阻塞。专项结果为 `G12-GENERATION-POEM-OPENAPI-CONTRACT BLOCKED`、`Issues: 72`、`G12-GENERATION-POEM-OPENAPI-ADVERSARIAL-CONTRACT PASS` 和 `G12-GENERATION-POEM-UNICODE-RUNTIME-SMOKE PASS`。
|
||||
|
||||
任务 40 新增家族动态读取主门禁与对抗合同后,当前物理库存为 PowerShell `147`、Node `48`、JSON 合同数据 `4`;全量 fresh 为 `128/147`,主门禁新增第 19 项发布阻塞,对抗合同本身通过。专项结果为 `FAMILY-FEED-READ-OPENAPI-CONTRACT BLOCKED`、`Issues: 85` 和 `FAMILY-FEED-READ-OPENAPI-ADVERSARIAL-CONTRACT PASS MUTANTS=58`;它没有修改受保护 OpenAPI 或页面,也没有把线上宽松 DTO 当作可用合同。
|
||||
|
||||
## 当前规划结论
|
||||
|
||||
### 导航栈
|
||||
@@ -160,7 +215,7 @@ G03 创建链路三人反向质询后否决“先建空谱、再写始祖”的
|
||||
### TAC 认证与无障碍安全边界
|
||||
|
||||
- `utils/auth-verification.js` 是当前认证场景、4 位短信码和服务端票据形状的唯一客户端 owner;生产目标由后端 `SmsCodeSecret` 和 `tests/phone-change-openapi-contract.ps1` 锁定为严格 6 位,门禁通过时必须一次替换所有活动消费者并删除旧 owner 的四位规则。`components/TacVerification.vue` 是验证浮层与 renderjs 生命周期 owner;`static/tac/js/jiapu-tac-adapter.js` 是 TianAi challenge/proof/verify 映射 owner;`utils/api.js` 是严格 HTTP 200 envelope、15 秒超时、离页中止、认证会话写入和反馈 wire payload 的唯一 owner。旧认证专用请求控制器入口、占位验证、伪验证码、宽松令牌兼容和 M07 假提交均已删除。
|
||||
- A01 默认短信登录;密码登录因 `API-AUTH-TAC-001` 保持可见但不可用。A04/A05 都只在发送短信前验证一次,并在手机号改变后使旧验证码上下文失效;成功、失败、取消、重复回调、空响应、非 JSON、超时、离页和返回键均有静态或纯运行时合同。短信发送与重设密码的 `RVoid` 没有声明 `data` 必填,客户端因此只要求合法 HTTP 200 与整数成功 `code`,并把“省略 data”或 `data:null` 都精确归一为 `null`;登录、注册和 challenge 等有实体响应仍强制 `data`。
|
||||
- A01 默认密码登录,线上 wire、TAC 前置、token 保存和 G01 跳转已有可执行纯 Node 状态机证据;默认 mode 仍为 mock,且密码登录未消费 `validToken`,故 `API-AUTH-TAC-001` 仍是生产发布阻塞。A04/A05 都只在发送短信前验证一次,并在手机号改变后使旧验证码上下文失效;成功、失败、取消、重复回调、空响应、非 JSON、超时、离页和返回键均有静态或纯运行时合同。短信发送与重设密码的 `RVoid` 没有声明 `data` 必填,客户端因此只要求合法 HTTP 200 与整数成功 `code`,并把“省略 data”或 `data:null` 都精确归一为 `null`;登录、注册和 challenge 等有实体响应仍强制 `data`。
|
||||
- 当前客户端浮层已补齐对话框命名、说明关联、初始聚焦、Tab 圈定、Escape/Android 返回、焦点恢复、原生刷新与关闭按钮、48px 目标及小视口内部滚动;这只是客户端壳层预检,不代表第三方滑块本身可由 TalkBack 或键盘完成。`tests/auth-android-accessibility-release-gate.ps1` 要求 MuMu 原生证据与非拖动等价验证方式,证据缺失时固定输出 `ANDROID-AUTH-ACCESSIBILITY-RELEASE BLOCKED`。
|
||||
- 三人交叉质询后的唯一方向是“同一验证中心、同一短时单次 `validToken`、供应商无关的服务端决策”,永久禁止 `accessibility=true`、跳过 TAC 或无票据发短信。中国大陆非交互风控供应商只进入限时 POC,必须在真实 UniApp Android WebView 中证明 TalkBack、外接键盘和 Switch Access 无焦点陷阱且误杀、防刷、弱网与故障指标达标,不能预先写成无障碍完成。已安全绑定设备只能作为加权信号;供应商不确定或不可用时进入支持文字/中继的可审计人工兜底或稍后重试,绝不 fail-open;音频验证码仅为后续独立 POC 候选,不能作为 P0 或唯一替代。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user