For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 将银歌 AI 插件、初始化、强制升级和真实激活状态统一收口,在 AI 业务放行前完成可靠检查,并按已确认规则引导未激活用户进入设置或返回主页。
Architecture: AiSdkManager 维护单例 SDK 会话和统一就绪状态,提供“服务就绪”和“业务就绪”两层门禁;业务页面通过可复用的 AiReadinessGuard 获得一致弹框与导航行为。设置页激活复用服务门禁,激活成功后重新查询真实状态。
Tech Stack: Android Java、银歌 AI SDK AAR、AndroidX AppCompat、JUnit 4、Gradle 7.4。
Files:
Create: app/src/main/java/com/cpt/aidishrecognition/ai/AiReadyState.java
Create: app/src/main/java/com/cpt/aidishrecognition/ai/AiReadinessPolicy.java
Create: app/src/test/java/com/cpt/aidishrecognition/ai/AiReadinessPolicyTest.java
Step 1: 编写失败测试
覆盖 SUCCESS -> READY、NOT_ACTIVE -> NOT_ACTIVE、插件缺失、强制升级以及未知错误映射。
Run: ./gradlew :app:testDebugUnitTest --tests com.cpt.aidishrecognition.ai.AiReadinessPolicyTest
Expected: 因目标类型尚未创建而编译失败。
AiReadinessPolicy 只负责将 SDK code 映射到 AiReadyState,不持有 Android Context 或页面引用。
Run: ./gradlew :app:testDebugUnitTest --tests com.cpt.aidishrecognition.ai.AiReadinessPolicyTest
Expected: BUILD SUCCESSFUL。
AiSdkManager 为统一门禁Files:
Modify: app/src/main/java/com/cpt/aidishrecognition/ai/AiSdkManager.java
Step 1: 增加服务门禁与业务门禁接口
提供 ensureServiceReady()、ensureAiReady()、cancelReadyRequests()、invalidateReadyState() 和 markNotActive()。
同一时刻只执行一次初始化/查询;请求排队,回调前检查 Activity 生命周期;插件安装交互期间不触发普通初始化超时。
onInitSuccess() 后短暂等待 SDK 的强制升级消息,再放行服务请求或查询激活状态,避免先弹未激活、随后又收到 1010。
在后台线程调用 queryAiActiveStatus(),主线程分发结果;NOT_ACTIVE 同步清除本地激活展示缓存。
Run: ./gradlew :app:compileDebugJavaWithJavac
Expected: BUILD SUCCESSFUL。
Files:
Modify: app/src/main/java/com/cpt/aidishrecognition/ai/AiDishActivationManager.java
Modify: app/src/main/java/com/cpt/aidishrecognition/activity/SettingActivity.java
Modify: app/src/main/java/com/cpt/aidishrecognition/fragment/SettingsBasicFragment.java
Modify: app/src/main/res/layout/fragment_setting_basic.xml
Step 1: 移除激活管理器的独立 SDK 初始化回调
激活前调用 ensureServiceReady();插件未安装或必须升级时返回明确状态;激活成功后调用 ensureAiReady() 二次确认。
SettingActivity 增加来源和目标项参数,基础设置页定位并短暂高亮 AI 激活行。
从 AI 业务页进入设置时,激活成功回传 RESULT_OK;取消或返回时回传 RESULT_CANCELED。
Run: ./gradlew :app:compileDebugJavaWithJavac
Expected: BUILD SUCCESSFUL。
Files:
Create: app/src/main/java/com/cpt/aidishrecognition/ai/AiReadinessGuard.java
Modify: app/src/main/res/values/strings.xml
Step 1: 实现统一检查入口
守卫调用 ensureAiReady(),处理进度提示、重复请求和 Activity 销毁。
未激活:前往设置/返回主页;插件未安装:安装插件/返回主页;必须升级:立即升级/返回主页;其他错误:重试/返回主页。
前往设置携带目标项参数;拒绝处理使用 CLEAR_TOP | SINGLE_TOP 返回 MainActivity。
Run: ./gradlew :app:compileDebugJavaWithJavac
Expected: BUILD SUCCESSFUL。
Files:
Modify: app/src/main/java/com/cpt/aidishrecognition/activity/DishManagementActivity.java
Modify: app/src/main/java/com/cpt/aidishrecognition/activity/NewDishLearningActivity.java
Modify: app/src/main/java/com/cpt/aidishrecognition/activity/DishRecognitionActivity.java
Step 1: 接入菜品管理页
页面创建后先检查门禁,READY 后才同步菜品与学习数据;设置返回后重新查询;learnDateRivise() 返回 NOT_ACTIVE 时使状态失效并重新提示。
门禁通过前不启动相机识别和学习请求;删除页面内重复的插件、升级和自动激活处理。
门禁通过前不提交识别帧;运行中返回 NOT_ACTIVE 时交给统一守卫,不在页面自动提交激活码。
Run: ./gradlew :app:compileDebugJavaWithJavac
Expected: BUILD SUCCESSFUL。
Files:
Modify: app/src/main/java/com/cpt/aidishrecognition/utils/DishLearningStore.java
Modify: app/src/main/java/com/cpt/aidishrecognition/activity/DishManagementActivity.java
Step 1: 增加临时同步目录支持
远端图片先写入独立临时目录,不提前删除正式目录。
SDK 校正成功后再切换正式目录;下载、保存或 SDK 校正失败时清理临时目录并保留原数据。
Run: ./gradlew :app:compileDebugJavaWithJavac && git diff --check
Expected: BUILD SUCCESSFUL 且无空白错误。
Files:
Modify: docs/superpowers/specs/2026-07-21-ai-sdk-readiness-gate-design.md
Modify: docs/superpowers/specs/2026-07-21-ai-sdk-readiness-gate-design.html
Create: /Users/liang/AndroidStudioProjects/zhct/zhctprompt/work_android/AIDishRecognition/change_records/2026-07-21-ai-sdk-readiness-gate.md
Create: /Users/liang/AndroidStudioProjects/zhct/zhctprompt/work_android/AIDishRecognition/change_records/2026-07-21-ai-sdk-readiness-gate.html
Step 1: 运行单元测试和构建
Run: ./gradlew :app:testDebugUnitTest :app:assembleDebug
Expected: BUILD SUCCESSFUL。
验证插件未安装、必须升级、未激活、激活成功及运行中 1004 五类路径;日志不得包含激活码。
同步 Markdown/HTML 文档,记录具体文件、行为、验证命令和遗留的设备侧前置条件。
Run: git diff --check && git status --short
Expected: 仅包含本次实现文件和用户原有未相关改动,不执行暂存、提交或推送。
NewSingleTipPop。NewSingleTipPop,等待期间隐藏操作区。NewSingleTipPop 与插件更新弹框统一使用白色标题栏和黑色标题文字。