opencodex Providers 工作区账户与导航 Rail 集成审计:从 A-gate 合成到 GO-WITH-FIXES 的修复闭环

发布时间:2026/9/27 2:07:02
opencodex Providers 工作区账户与导航 Rail 集成审计:从 A-gate 合成到 GO-WITH-FIXES 的修复闭环 【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载导读本文以 opencodex 仓库中devlog/_fin/260718_provider_workspace_accounts_rail/031_integration_audit.md为骨架系统剖析该次“Providers 工作区账户与 Rail 导航”集成审计的全过程范围与测试完整性核查、安全与状态所有权审计、UX/无障碍审计、路由审计、独立终审以及最终 GO-WITH-FIXES 判定。读者将掌握一套可复用的前端集成审计方法论以及 opencodex 工作区中多账户切换、Provider Rail 导航、路由哈希同步与无凭据泄露no raw-id等关键实现的源码级细节与修复清单。审计背景与范围边界该次集成审计位于260718_provider_workspace_accounts_rail工作单元roadmap 见 000_plan.md是对两个依赖有序切片——账户切换010_account_switcher.md与 Provider Rail 打磨020_provider_rail.md——合并后的最终交叉回归审计。整合阶段规范见 030_integration_qa.md。审计的核心理念是“production edits are default-out”任何修复都必须由可复现的证据驱动且必须以 P 阶段修正案amendment形式命名被观察到的失败文件路径与激活证据。这保证了审计结论不是主观“看起来更好了”而是每一条都落在可验证的 delta 上。范围与测试完整性Scope and test integrity提交范围34e34b4..657a2ce精确包含 21 个预期的 roadmap/account/rail/design/test 文件生产变更严格限定在计划中的工作区页面、账户组件、rail/shell 组件、纯分类器pure classifier、locale 字典与工作区样式。两个新增测试文件tests/provider-workspace-auth.test.ts、tests/provider-workspace-rail.test.ts均为纯增量。全量比对确认没有任何断言删除、skip、todo、超时膨胀timeout inflation、测试夹具弱化或无关测试改动。用户本地无关的脏工作树dirty tree以及已删除的tests/codex-multi-state.test.ts未混入任何一个 goal commit。这避免了“顺手提交无关改动”这一集成审计最常见的污染源。这一节传递的审计纪律是先证明“改了什么、没改什么”再进入功能正确性判断。对于多提交、多阶段合并的工作单元测试文件是否被偷偷放宽往往比功能本身更早暴露质量问题。安全与状态所有权审计1. 规范的 Codex 所有权门控“Canonical Codex ownership is gated byisAccountProvider自定义 forward provider 不会继承账户池。”这条规则直接落于 gui/src/provider-workspace/auth.ts 的providerAuthSurface分类器export function providerAuthSurface(item: WorkspaceItem): ProviderAuthSurface { if (isAccountProvider(item.name, item)) return codex-accounts; const mode (item.authMode ?? ).toLowerCase(); if (mode forward || mode local || isLocalProvider(item)) return null; if (mode oauth) return oauth-accounts; ... return api-keys; }源码注释明确写道“a custom forward proxy must never inherit the global Codex account pool merely because it also uses forward authentication”——即即使某个供应商同时使用 forward 认证只要它不符合规范 OpenAI forward provider 的判定就绝不会显示 Codex 账户池。这是审计结论第 1 条的源码级依据。2. 可见标签的隐私边界审计确认可见的 generic/Codex 标签一律使用脱敏邮箱或本地化序号localized ordinal任何 token 或不透明账户 id 都不会出现在行、标题、aria label、确认框或 toast 中。实现支撑同样在auth.ts的oauthAccountDisplayLabelgui/src/provider-workspace/auth.ts优先取alias其次取email两者皆无时才回退到基于账户位置的本地化序号pws.accountOrdinal绝不回退到不透明 id。在 UI 层ProviderAuthPanel.tsx 的账户行副标题只显示account.email与displayAccountId(account.id)来自../../lib/privacy的掩码展示并在移除按钮的 aria-label 与 title 中拼接脱敏标签而非原始 id。3. 读取的代际绑定generation-bound通用generic列表读取按 provider 分代generation合并提交子集刷新不会抹掉其他 provider 的账户数据Codex 读取在整个列表 active 响应之间分代绑定被取代的迟到响应会被丢弃。这是典型的“stale response ordering”威胁对策审计要求绝不把失败的 JSON 当作空的成功账户集并对 generic 账户读取采用 per-provider request generation refs functional map merge细节见 010_account_switcher.md 的 exact diff plan。4. 非 2xx 变更保持旧状态审计确认非 2xx 的变更操作PUT/DELETE会保留之前的选择并宣布失败在线 QA 切换完成后恢复捕获的原始账户且恢复过程中不打印任何 id。对应 Codex 账户池的 active PUT 语义为检查非 2xx、失败时保持旧 active、成功时消费返回的 active id 再执行权威刷新同时防止 interval 刷新覆盖更新的切换。5. 残余问题一通用重复切换竞态Residual: generic duplicate blocking currently checks React state only. Two clicks in one render turn can both observenull.即重复切换的拦截仅依赖 React 状态同一个渲染周期内的两次点击都可能读到null而双双放行。审计要求修复fold为同步 ref 守卫——在 React 状态更新之前先用同步 ref 占位。最终的 B 修复收据证实“Generic account switching uses a synchronous target ref before React state, preventing two same-render clicks.”6. 残余问题二PUT 成功但权威 GET 失败时的虚假成功Residual: a successful generic PUT followed by a failed authoritative GET still emits a success toast while the old row remains selected.审计要求让fetchAccountSets返回成功与否并把加载失败暴露给用户而不是宣布“刷新成功”。最终修复为“Account refresh returns success; a failed post-PUT GET shows the load error rather than a contradictory success toast.”UX 与无障碍审计1. 原生按钮与状态语义通用 OAuth 行是原生button见 ProviderAuthPanel.tsxpwi-auth-row-main按钮带aria-current、禁用 reauth/pending 变更、loading/error/empty/many 状态均有文本语义与rolestatus/rolealert。2. 详情页 Tab 与 Rail 的键盘模型详情页 Tab 具有关联的id/panelaria-controls、aria-labelledby与 roving Arrow/Home/End 焦点。实现见 ProviderDetails.tsx 的onTabKeyDownArrowRight/ArrowLeft 循环移动Home/End 跳到首尾并同步switchTab与焦点落点Tab 列表渲染带roletab、tabIndex{tab candidate.id ? 0 : -1}roving tabindex。Rail 选项自己拥有焦点不存在重复的 listbox Tab 停止点。最终修复进一步收紧为只有一个tabIndex0的 roving 入口取最后聚焦/选中/首个可见行其余选项为-1Arrow/Home/End 更新焦点所有者——这正是独立终审第 4 条发现的落地形态。3. Rail 行的三层语义Rail 行暴露“图标 / 两行文案 / 尾部操作”层级见 ProviderRail.tsx 的RailRow主行显示名 仅必要的 Free/Local 例外徽章次行模型数量 仅在显示名冲突需要消歧时的配置 id尾部默认星标 状态点。审计确认无可见的 Ready 文本片段、保留原始img供应商色彩providerIconSrc直通img不做 workspace 色调蒙版替换见ProviderIcon的三态绘制逻辑、状态由容器派生且随响应式变化。Chevron 在持久桌面分栏导航下已移除。4. 残余问题三Codex 池卡片无键盘切换Residual: Codex pool cards are pointer-clickabledivelements with no keyboard switch control.修复要求移除整卡点击的可点击性改为为每个非当前、可用的 main/pool 账户提供显式原生Set as Next Session按钮嵌套的 ticket/remove 按钮保持独立语义remove 标签包含脱敏邮箱。最终 OpenAI Accounts 截图证实三个非当前可用账户各有显式按钮、卡片容器不可点击、remove 控件独立且标签脱敏。5. 全局减动效prefers-reduced-motion: reduce下所有过渡与 spinner 动画全局禁用——这是既有的全局能力审计确认为通过无需修复。路由审计哈希同步与子路由覆盖这是该次审计中唯一被浏览器真实复现的集成缺陷readPageFromHashacceptsproviders/workspace, but the page-sync effect compares the full hash to#providersand overwrites the suffix. The live browser reproduced this on every reload. The P amendments first-segment comparison is required and must still normalize invalid/empty/different-page hashes.源码证据在 gui/src/app-routing.ts 的readPageFromHash与 gui/src/app-routing.ts、gui/src/app-routing.ts 的哈希同步逻辑解析函数正确地接受providers/workspace这样的子视图后缀但页面同步 effect 却拿完整哈希与#providers比较导致加载/刷新#providers/workspace立即变成#providers直接破坏工作区深链与刷新连续性。修复修正案在 030 阶段提出并落地见 030_integration_qa.md 的“Evidence-backed repair amendment”将gui/src/App.tsx纳入集成范围仅针对哈希同步 effect比较当前哈希的首段与page段已匹配时保留合法后缀同时仍归一化空/非法/不同页面的哈希在tests/provider-workspace-rail.test.ts增加窄域源码契约 浏览器证明直接导航/刷新保留#providers/workspace。最终运行时验证C final verification给出精确结果直接#providers/workspace与 reload 均保留 workspace#providers/typo归一化为#providers。注意独立终审对这一点还做了修正升级仅白名单精确的providers/workspace子路由而不是“仅首段保留”——因为首段保留规则会错误地保留providers/typo这类非法后缀。独立终审GO-WITH-FIXES 与四条新发现独立终审由全新模型族的 Terra-high 评审执行逐文件审阅了每一个被修改的实现文件与两份测试后返回GO-WITH-FIXES确认了规范门控canonical gating正确无新增 raw-id/token 暴露面原始 SVG 路径保留账户/Codex 读取代际守卫有效Tab/Rail 键盘结构成立。同时新增四条可触达reachable发现全部纳入最终修复B精确子路由白名单而非仅首段保留已并入路由修复诚实的多账户登出刷新/失败处理——generic logout 必须检查response.ok成功时刷新 promoted 账户集 OAuth/config/quota失败时保持状态不变而非无条件显示已登出可见的 generic/Codex DELETE 失败处理——删除必须检查响应状态失败时显示本地化失败反馈且不刷新、不改变可见状态Rail 单一 roving Tab 入口——所有原生 option 按钮不能全部tabIndex0改为一个焦点所有者最后聚焦/选中/首个可见行Arrow/Home/End 移动焦点。评审报告声明不存在未审的实现文件且独立排除了无关脏树。A 阶段判定八项残余修复与最终结论A 判定汇总了审计中发现的八项可触达集成残余全部收拢进一个窄域最终修复#残余项修复要点1哈希子路由被同步 effect 覆盖精确providers/workspace白名单 首段比较保留后缀仍归一化非法哈希2通用重复切换竞态同渲染轮两次点击都读到 null同步 ref 守卫先于 React 状态3PUT 成功但权威 GET 失败仍发成功 toastfetchAccountSets返回成功状态暴露加载失败4Codex 池卡片无可键盘切换显式原生Set as Next Session按钮移除整卡点击5登出刷新不诚实generic logout 检查response.ok成功才刷新失败保持状态6DELETE 失败静默generic/Codex 删除检查状态码并显示本地化失败反馈7Rail 每项都可 Tab单一 roving Tab 入口 Arrow/Home/End 焦点模型8配套恢复/焦点语义恢复原始 live 账户、焦点模型与无障碍语义一并收口最终结论强调无需任何 server、凭据、配额策略、删除策略或 provider 资产变更——修复完全落在前端集成层。最终判定与质量证据链VERDICT: GO-WITH-FIXES (blockers0 after folded repair)该判定建立在 030 阶段的完整验证序列之上详见 030_integration_qa.md 的 C final verification receipt聚焦集成套件8 文件133 pass / 0 fail / 462 assertions全工作树测试套件、根bun run typecheck、GUI production build 全部 PASS仅保留构建前已存在的 chunk-size 警告聚焦改动文件 ESLint0 errors / 0 warningsGUI 全量 lint 仅剩基线ProviderOverview.tsx:152 react-hooks/set-state-in-effect一条修复前已存在、不在本切片privacy scan /git diff --check通过浏览器运行时默认 1600 CSS px 视口下 document1600 1600、workspace1296 1296、仅一个 rail option 带tabIndex0、零 console 错误/警告德/中桌面冒烟均保持clientWidth scrollWidthQA 后恢复 System/English。值得一提的是终审的诚实性纪律Terra-high 评审复审计时在四次有界等待30s/30s/30s/20s后未产出结果而被退役主验证用源码契约、聚焦/全量套件与 live 浏览器证明逐项关闭未把原评审的 GO-WITH-FIXES 误报为 PASS——这本身就是独立评审不可靠时的兜底范例。可复用的审计方法论要点先验范围再验功能核对提交清单与测试增量无删除断言、无 skip、无超时膨胀、无夹具弱化杜绝无关脏树混入隐私边界是硬指标可见表面行/标题/aria/confirm/toast零 token、零不透明 id掩码邮箱或本地化序号回退状态所有权以失败语义为准非 2xx 保持旧选择、迟到响应按代际丢弃、失败 JSON 绝不当作空成功集、重复提交用同步 ref 而非仅 React 状态拦截键盘模型要一以贯之roving tabindex 单入口、Arrow/Home/End 焦点移动、aria-current/aria-selected与可见文本一致路由哈希要区分“解析”与“同步”解析可接受子后缀但同步 effect 必须按首段比较并白名单精确合法子路由否则深链刷新即失效终审发现必须逐条 folding评审的每条 finding 都回落到一个具名、可复现、有源码契约与浏览器证据的修复而不是笼统的“已改进”。至此opencodex 的 Providers 工作区成功把“多账户选择”提升为一等公民工作区 Tab把 Provider Rail 重构为紧凑、语义化、零碰撞的导航面并通过这轮集成审计与修复闭环确立了“账户切换必须失败安全、可见表面必须凭据干净、键盘与路由必须语义一致”这一整套可长期复用的前端工程质量基线。赞分享【免费下载链接】opencodexUniversal provider proxy for OpenAI Codex Claude Code — use any LLM (Claude, Gemini, Grok, DeepSeek, Ollama…) with Codex CLI, App, SDK, and Claude Code项目地址https://gitcode.com/gh_mirrors/ope/opencodex点击查看免费下载相关推荐OpenCodex 工作区账户与 Provider 侧栏改造的 A-gate 审计从独立探索到 GO-WITH-FIXES 的阻断项治理OpenCodex 工作区账户与 Provider 侧栏改造的 A gate 审计从独立探索到 GO WITH FIXES 的阻断项治理 导读 本文梳理 OpOpenCodex Providers 工作区账户与导航基线审计——从契约证据到多账户激活场景的全链路梳理OpenCodex Providers 工作区账户与导航基线审计——从契约证据到多账户激活场景的全链路梳理 导读 本文以 OpenCodex 仓库中 devlopencodex 审计驱动的 CLI 账户管理开发从注册表分类缺陷到可复现的 A-gate 审计闭环opencodex 审计驱动的 CLI 账户管理开发从注册表分类缺陷到可复现的 A gate 审计闭环 导读 本文剖析 opencodex 项目中 Issue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考