feat(app): 独立本地 OPC App 控制平面#27
Conversation
|
Addressed all four review findings in
Validation on the pushed tree:
No merge or self-approval performed. |
|
Addressed the remaining P2 launcher-transaction finding in Launcher artifact contract
Recoverable activation semanticsActivation is a recoverable directory transaction: This does not claim that Windows directory replacement is atomic. If activation fails, the old complete launcher set is restored. If restoration itself fails, Failure-injection evidence
Validation on the pushed tree:
The final full suite passed on its first run for this revision. No test relaxation, self-approval, or merge was performed. |
coconilu
left a comment
There was a problem hiding this comment.
Review(Kimi Code CLI 代为审查)
总体评价:质量不错,可以合并。issue #25 的核心不变量在代码层面均有落实且有测试佐证:
- 单一语义来源:
opc_dashboard.py缩为薄 shim,聚合/脱敏/DTO 全部移入opc_snapshot_service.py,opc_app.py不 import dashboard(AST 断言强制),不存在两份业务规则实现; - 只读脱敏边界:写路由仅 projects/selection 三条,只写 App 自有
settings.json;_assert_redacted三重断言;测试断言响应字节流不含接入路径; - 网络安全:仅 loopback bind、Host 精确匹配、Origin 白名单、每进程 CSRF token、CSP
default-src 'self'、资产路由白名单 + 防链接替换; - 状态隔离与生命周期:state root 双向重叠检查、release 哈希 ID + 原子 pointer、uninstall 仅删 owned runtime。
本地实测(Windows):validate_repo.py PASS;python -m unittest discover -s tests → 392 tests, OK (skipped=6);手动冒烟 install → launcher 启动 → rollback 拒绝(无 previous)→ uninstall 保留 state 链路正常。
发现的问题(均为 minor/nit,不阻塞合并)
-
minor —
opc_app.py:60-63、scripts/opc_app_admin.py:51-61:OPC_APP_HOME为相对路径时用os.path.abspath()解析,状态根会随启动 cwd 漂移(不同目录启动同一 App 得到不同接入清单)。与add_project要求绝对路径(ABSOLUTE_PROJECT_ROOT_REQUIRED)的严格度不一致。建议非绝对的OPC_APP_HOME直接报错,或在docs/opc-app.md明确说明按 cwd 解析。 -
nit —
opc_app.py:398-440:AppSettingsStore的 read-modify-write 只有进程内threading.RLock保护;两个 App 实例共享同一 state root 时后写静默覆盖先写(文件本身原子写不会损坏,只丢一次操作)。单机单用户场景风险低,但 ADR-0017 未提及多实例取舍,建议明确说明。 -
nit — PR 描述计数:PR 声称 "378 tests, 6 expected skips",本分支实测为 392 tests, skipped=6(全部通过)。仅计数口径不一致,建议核对。
无法在本环境复核、依赖 PR 声明的部分
- 浏览器 QA(多分辨率、键盘导航、零横向溢出、零 console error)与官方 Plugin Validator、独立安装 QA;
- Linux/macOS launcher 与 XDG 状态目录未实测(仅 Windows 验证,POSIX 路径有 6 个预期 skip 的测试兜底);
- Host 严格校验下浏览器手动输入
http://localhost:port会得到 400 —— 是有意的反 DNS-rebinding 设计且文档已写明默认 URL 为127.0.0.1,可考虑返回更可读的错误页。
Closes #25
Scope
.opc, File/Git knowledge, Git history, user configuration, App state, and optional Mem0 dataopc_dashboard.pycompatible; no feat(adapters): 管理 Codex、Claude 与 Kimi 的本地 OPC 集成生命周期 #26 Adapter work is includedValidation
python scripts/validate_repo.py? PASSpython -m unittest discover -s tests -p "test_*.py" -v? PASS, 393 tests, 6 expected platform/disposable-environment skipspython scripts/privacy_scan.py? PASSThe existing v0.2 public synthetic evidence was reproducibly regenerated because
docs/installation-and-distribution.mdis a hash-bound delivery artifact. The only evidence change is that document's SHA-256.Risk and rollback
OPC_APP_HOME; relative overrides are rejected to prevent working-directory driftpython scripts/opc_app_admin.py rollbackpreviews, androllback --applyswitches back to the previous complete releaseuninstallpreviews, anduninstall --applyremoves only the owned runtimeData and configuration impact
%LOCALAPPDATA%\OPC\Appon Windows or${XDG_STATE_HOME:-$HOME/.local/state}/opc-appon Linux.opc, File/Git knowledge, Git history, existing user configuration, or Mem0 dataReview boundary
This PR is ready for independent UI/install QA and review. It is intentionally not merged.