feat(telemetry): qualify usage diagnostics and installation return cohorts - #5366
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
本次精确审阅 HEAD 2328dfa,基线 67930ab。需要解决的是实际使用统计中安装身份频繁重置、合成环境污染、预期合并阻塞被误读为失败,以及旧计数无法按版本解释的问题。改动给出可以使用的采集、关闭、检查和服务端统计闭环,不声称据此识别人数、企业采用或交付质量。代码交付是合理增量:生产 collector 升级和未来客户端发布仍是不同操作,不能用合并冒充新数据已经产生。
改动思路
沿用 usage-statistics 的 TypeScript 决策源、机器本地 consent、generation fence、文件锁与独立发送进程。Python 只从解析器、异常类型和既有回执提取固定事实,不读取参数值或错误正文。客户端和 collector 共用严格校验契约;诊断写入新的无安装关联键聚合表,旧计数不补归因。安装回访从现有心跳推导,不新增用户身份。
正向路径是已续签告知的普通命令完成后投影固定结果,发送进程再次检查开关与 generation,并提交有界增量。关闭、CI/DNT、旧 generation、无可见告知、超期活动日期和含额外字段的输入走拒绝路径;可选遥测错误不替换业务输出。已检查真实生产 caller:项目注册的 changed、Turn 当前提交效果、Todo 完成事务的 validation_receipt,以及精确来源回传的已验证持久结算。重放和 legacy 未验证回传不会伪造新生命周期信号。
具体改动
32 个路径按运行时和 UI、共享诊断契约、collector/schema、公开说明、持久回归、窄生成行号修正分类;没有提交本地状态、生产数据或部署凭据。没有引入新的 capability 或平行的 Python 策略所有者。新版告知覆盖新增字段与本地发送摘要,中英文首屏按已批准文案去掉“更频繁的请求”那句;详细运行时说明保留必要的网络关联披露。安装 ID 跨告知升级保持,明确关闭才删除;关闭同时清除计数、发送摘要和旧排队资格。
关键代码讲解
loopx/usage_ping.py:25 select_operation与:38 capture_result:解析器选择固定子操作,结果仅传布尔回执事实。实际 merge-readiness 的 exit=1、ok=true、ready=false 保持不变,供诊断判为 blocked,而不是篡改 PR readiness 本身。loopx/control_plane/runtime/usage_statistics_diagnostics.ts:55 resultDiagnostic:固定结果、原因及生命周期组合由类型化白名单约束。成功退出不等于已注册或已交付,只有 changed、非 dry-run 和对应回执才能产生信号;任意内容字段拒收。loopx/control_plane/runtime/usage_statistics.ts:129 configure与:164 observe:复用既有锁、开关和 generation。扩大告知需要续签,已明确关闭仍关闭;批次最多 32 组诊断,过期丢弃,有损且不自动重试。本地摘要最多 20 条,不保留请求正文。loopx/capabilities/manager_context/roundtrip.py:520 _write_exact_return_state:在既有精确来源 admission 和请求锁内写入 verified delivered 后才观察新回传;当前状态已经 delivered 时不重复记新回传,不给观察器交接或发送授权。apps/usage-collector/src/collector.js:147 adoptionStats和诊断路由:成熟窗口内回访从既有 installs/pings 推导;小样本分子、分母及非零补集抑制。独立边际统计没有安装工作历史。0004 仅增表,保留旧表与旧数据,旧客户端路由继续可用。
对主干的风险
最危险的上线错误是先发布 notice-v5 客户端、仍保留旧 Worker:旧 Worker 拒收新诊断,而无重试设计会丢掉这部分观测。已实测旧生产诊断和采用接口均返回 404,原 D1 无诊断表。上线必须新备份、独立 D1 资格验证、增量迁移、Worker 部署,再考虑客户端发布;回滚保留增量表,不删除历史。
本轮重新运行 Python 93 项、TypeScript/collector 68 项,以及 Todo 声明验证与真实 terminal CLI 41 项,全部通过。精确干净 head 的类型检查、Ruff、仓库 Mypy、打包界面构建、全树语义检查、19 项风险 canary 与质量回执仍有效;本轮复查 fingerprint 未变。既有 bundle 大小 advisory 保留,没有提高限制或放松断言。
独立真实 CLI/HTTP 对照中,base/head 的完整业务 JSON(仅规范化观测时间)、stderr 和 exit=1 一致;关闭采集时遥测状态字节不变且 HTTP 请求为零。故意移除 capture_result 后,真实发送诊断无法满足 blocked/not_ready 独立 oracle;恢复 head 后通过。测试没有用 mock 回填发送成功。独立 Cloudflare Worker/D1 已验证旧/新心跳、旧聚合、新诊断、Goal 计数和全部五个统计接口;非法身份、错误正文、过期活动与超大 body 分别拒绝,增量迁移重复执行保持旧计数。
语义与 CI 对齐
本变更扩展既有遥测边界,新增诊断局部闭集,复用 feature/duration 词汇;不改变 Todo、配额、调度或交接权限。先前 OPERATIONS 与 native-child 域名碰撞已改为 DIAGNOSTIC_OPERATIONS,值与行为未改,全树 ratchet 未放宽。Goal 的当前 review 配置为 wait_for_ci=false,本次不查询、轮询或等待 GitHub CI,以仓库本地验证和精确 head review/readiness 为准。
我的整体评价
APPROVE。长程工作语义保持:观察失败不阻断业务、关闭不被排队进程复活、重启重放不计新提交。用户体验改善:身份更稳定、发送摘要可查,续签告知只在扩采边界发生,关闭路径没有新增确认。兼容保留有真实理由:独立升级的客户端/Worker,以及持久旧表;不能把这两个边界合成一次原子升级。版本化诊断独立模块有共享校验 caller;既有 observe/锁是最近且足够的 owner,未发现应立即拆分或再抽象的重复规则。
这是高风险数据边界的完整、可逆修复,不是靠增加字段数证明价值。公开接口无认证,统计仍可能被外部伪造;有损计数、部分生命周期覆盖及未发布客户端是明确剩余边界。本次 owner 明确授权该 PR 自 review/refine/self-merge 与必要 collector 部署,是单 PR 例外,不修改仓库通用 maintainer-merge 政策。合并仍需该 unchanged head 的有效 COMMENTED review 和 ready=true;部署回执独立记录。
English verdict: APPROVE - HEAD 2328dfa; exact-head local, paired CLI/HTTP, mutation, and isolated Cloudflare/D1 validation passed. Deploy the additive collector upgrade before notice-v5 clients; owner-authorized self-merge applies only to this PR.
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
本次精确审阅 HEAD 2328dfa,基线 67930ab。需要解决的是实际使用统计中安装身份频繁重置、合成环境污染、预期合并阻塞被误读为失败,以及旧计数无法按版本解释的问题。改动给出可以使用的采集、关闭、检查和服务端统计闭环,不声称据此识别人数、企业采用或交付质量。代码交付是合理增量:生产 collector 升级和未来客户端发布仍是不同操作,不能用合并冒充新数据已经产生。
改动思路
沿用 usage-statistics 的 TypeScript 决策源、机器本地 consent、generation fence、文件锁与独立发送进程。Python 只从解析器、异常类型和既有回执提取固定事实,不读取参数值或错误正文。客户端和 collector 共用严格校验契约;诊断写入新的无安装关联键聚合表,旧计数不补归因。安装回访从现有心跳推导,不新增用户身份。
正向路径是已续签告知的普通命令完成后投影固定结果,发送进程再次检查开关与 generation,并提交有界增量。关闭、CI/DNT、旧 generation、无可见告知、超期活动日期和含额外字段的输入走拒绝路径;可选遥测错误不替换业务输出。已检查真实生产 caller:项目注册的 changed、Turn 当前提交效果、Todo 完成事务的 validation_receipt,以及精确来源回传的已验证持久结算。重放和 legacy 未验证回传不会伪造新生命周期信号。
具体改动
32 个路径按运行时和 UI、共享诊断契约、collector/schema、公开说明、持久回归、窄生成行号修正分类;没有提交本地状态、生产数据或部署凭据。没有引入新的 capability 或平行的 Python 策略所有者。新版告知覆盖新增字段与本地发送摘要,中英文首屏按已批准文案去掉“更频繁的请求”那句;详细运行时说明保留必要的网络关联披露。安装 ID 跨告知升级保持,明确关闭才删除;关闭同时清除计数、发送摘要和旧排队资格。
关键代码讲解
loopx/usage_ping.py:25 select_operation与:38 capture_result:解析器选择固定子操作,结果仅传布尔回执事实。实际 merge-readiness 的 exit=1、ok=true、ready=false 保持不变,供诊断判为 blocked,而不是篡改 PR readiness 本身。loopx/control_plane/runtime/usage_statistics_diagnostics.ts:55 resultDiagnostic:固定结果、原因及生命周期组合由类型化白名单约束。成功退出不等于已注册或已交付,只有 changed、非 dry-run 和对应回执才能产生信号;任意内容字段拒收。loopx/control_plane/runtime/usage_statistics.ts:129 configure与:164 observe:复用既有锁、开关和 generation。扩大告知需要续签,已明确关闭仍关闭;批次最多 32 组诊断,过期丢弃,有损且不自动重试。本地摘要最多 20 条,不保留请求正文。loopx/capabilities/manager_context/roundtrip.py:520 _write_exact_return_state:在既有精确来源 admission 和请求锁内写入 verified delivered 后才观察新回传;当前状态已经 delivered 时不重复记新回传,不给观察器交接或发送授权。apps/usage-collector/src/collector.js:147 adoptionStats和诊断路由:成熟窗口内回访从既有 installs/pings 推导;小样本分子、分母及非零补集抑制。独立边际统计没有安装工作历史。0004 仅增表,保留旧表与旧数据,旧客户端路由继续可用。
对主干的风险
最危险的上线错误是先发布 notice-v5 客户端、仍保留旧 Worker:旧 Worker 拒收新诊断,而无重试设计会丢掉这部分观测。已实测旧生产诊断和采用接口均返回 404,原 D1 无诊断表。上线必须新备份、独立 D1 资格验证、增量迁移、Worker 部署,再考虑客户端发布;回滚保留增量表,不删除历史。
本轮重新运行 Python 93 项、TypeScript/collector 68 项,以及 Todo 声明验证与真实 terminal CLI 41 项,全部通过。精确干净 head 的类型检查、Ruff、仓库 Mypy、打包界面构建、全树语义检查、19 项风险 canary 与质量回执仍有效;本轮复查 fingerprint 未变。既有 bundle 大小 advisory 保留,没有提高限制或放松断言。
独立真实 CLI/HTTP 对照中,base/head 的完整业务 JSON(仅规范化观测时间)、stderr 和 exit=1 一致;关闭采集时遥测状态字节不变且 HTTP 请求为零。故意移除 capture_result 后,真实发送诊断无法满足 blocked/not_ready 独立 oracle;恢复 head 后通过。测试没有用 mock 回填发送成功。独立 Cloudflare Worker/D1 已验证旧/新心跳、旧聚合、新诊断、Goal 计数和全部五个统计接口;非法身份、错误正文、过期活动与超大 body 分别拒绝,增量迁移重复执行保持旧计数。
语义与 CI 对齐
本变更扩展既有遥测边界,新增诊断局部闭集,复用 feature/duration 词汇;不改变 Todo、配额、调度或交接权限。先前 OPERATIONS 与 native-child 域名碰撞已改为 DIAGNOSTIC_OPERATIONS,值与行为未改,全树 ratchet 未放宽。Goal 的当前 review 配置为 wait_for_ci=false,本次不查询、轮询或等待 GitHub CI,以仓库本地验证和精确 head review/readiness 为准。
我的整体评价
APPROVE。长程工作语义保持:观察失败不阻断业务、关闭不被排队进程复活、重启重放不计新提交。用户体验改善:身份更稳定、发送摘要可查,续签告知只在扩采边界发生,关闭路径没有新增确认。兼容保留有真实理由:独立升级的客户端/Worker,以及持久旧表;不能把这两个边界合成一次原子升级。版本化诊断独立模块有共享校验 caller;既有 observe/锁是最近且足够的 owner,未发现应立即拆分或再抽象的重复规则。
这是高风险数据边界的完整、可逆修复,不是靠增加字段数证明价值。公开接口无认证,统计仍可能被外部伪造;有损计数、部分生命周期覆盖及未发布客户端是明确剩余边界。本次 owner 明确授权该 PR 自 review/refine/self-merge 与必要 collector 部署,是单 PR 例外,不修改仓库通用 maintainer-merge 政策。合并仍需该 unchanged head 的有效 COMMENTED review 和 ready=true;部署回执独立记录。
English verdict: APPROVE - HEAD 2328dfa; exact-head local, paired CLI/HTTP, mutation, and isolated Cloudflare/D1 validation passed. Deploy the additive collector upgrade before notice-v5 clients; owner-authorized self-merge applies only to this PR.
Goal and delivered outcome
Implement the accepted telemetry-quality request using the existing usage-statistics owner and Cloudflare Worker/D1 provider. Current counts cannot distinguish merge-readiness holds from failures, attribute CLI activity to a numeric release/activity date, or describe mature installation return windows.
ready=falsemerge checks becomeblocked/not_ready, without changing command output or exit codes.Intended base:
main; baseline67930ab6af78491f10ca3de4ff74ef7a39954a51. Related roadmap boundaries: stability, adoption/telemetry and trust; this PR does not close those wider programs.Scope, ownership and rollout
The existing TypeScript usage-statistics boundary owns validation, consent, generation fencing, buffering and sending. Python projects fixed parser/receipt facts, never raw output or error prose. The collector imports the same schema. Deployment context is voluntary via
LOOPX_USAGE_CONTEXT, defaultunknown; it is not inferred.The new operation vocabulary is explicitly
DIAGNOSTIC_OPERATIONS: observed CLI sub-operations are not native-child spawn/followup authority. This is a domain-separation repair, not a semantic-budget increase. Existing settings are extended rather than adding a capability, decision owner or speculative framework.Diagnostics have no installation/Goal/Todo/account ID, paths, argument values, code or raw errors. Buffers and delivery history are bounded, lossy and non-retrying. Signals require existing changed/committed/verified receipts; replays and unverified/legacy returns do not invent delivery.
Delivery update: the owner explicitly authorized self-review/refinement, merge of this PR and the necessary collector rollout as a single-PR exception. The unchanged head received a published COMMENTED approval and
ready=truebefore merge. Production D1 was backed up and independently checked; a separate Cloudflare Worker/D1 qualified old/new payloads and negative cases before the additive0004-diagnostics.sqlmigration and production Worker deployment. All five public statistics routes return 200. Historical counts, database binding, cleanup schedule and disabled observability were retained; the temporary qualification resources were removed. Client release was not performed. Legacy data is preserved, not backfilled or reattributed; rollback can retain the additive table.Validation
Tested source:
2328dfa1d62594d3a6084a459bc5b101204aa1cb. Run state: finished. Inputs: synthetic and public fixtures only.test_usage_ping,test_collaboration_goal_instance,test_manager_context_roundtripand canary telemetry isolation: real CLI/detached sender/local HTTP, proxy, settings API, suppression, readiness exit code and exact-source returns.typecheck:control-plane, changed-Python Ruff, repository-declared Mypy scope (19 sources), andbuild:chat; existing chunk-size build advisory retained.Change-quality receipt:
cqr_9a74b02dc0f960d5f6a5; fingerprint9a74b02dc0f960d5f6a59cf1fc26ff77900b1d55b18923f1c8d2e3ccffdef4ac, matching the baseline and tested head above. No blockers; the remaining rollout warning requires collector-first deployment.The initial premerge attempt also caught a validation-order mistake: commits were made while its tracked-side-effect guard was running. Its CLI check exited successfully, but the wrapper correctly rejected the changing worktree. Subsequent runs use a fixed, clean head. No test was relaxed to clear either failure.
Fresh review reran 93 Python, 68 TypeScript/collector and 41 Todo-validation/real-terminal-CLI tests (202 passed). An independent base/head real CLI → detached sender → HTTP comparison proved feature-off byte parity and zero requests, unchanged business output/exit behavior, and a mutation oracle that detects removed result capture. Goal policy is
wait_for_ci=false: GitHub CI was not queried, polled or awaited. Minimum-Node/Windows coverage is not claimed. No model calls or benchmark jobs were launched.Exact-head review: #5366 (review) . The standard maintainer-merge policy remains unchanged; this PR's owner authorization is not a standing self-merge grant.
Frontend / visual evidence
Boundary checklist