Skip to content

feat(parity): Wave E — settings persistence, exit_plan_mode, --fork-session, fallback signature strip, hermetic tests (v1.30.0)#119

Merged
sweetcornna merged 1 commit into
mainfrom
feat/waveE-parity-batch
Jul 20, 2026
Merged

feat(parity): Wave E — settings persistence, exit_plan_mode, --fork-session, fallback signature strip, hermetic tests (v1.30.0)#119
sweetcornna merged 1 commit into
mainfrom
feat/waveE-parity-batch

Conversation

@sweetcornna

Copy link
Copy Markdown
Owner

Wave E — claude-code parity 小批量五连 (v1.30.0)

Gap ledger Wave E,五项独立小改动打包成一个 PR(每项都有自己的 TDD 红→绿轨迹)。

E1 — 分层权限设置持久化 + 控制台 persist 答案

问题:PermissionGate.from_layered_sources 零生产调用方——所有部署只从 env 建 gate,durable 规则只能写环境变量;控制台 "always" 授权随会话蒸发。

  • 新模块 corlinman_agent.permission_settings:build_permission_gate()<data_dir>/settings.json(用户层)→ <项目>/.corlinman/settings.local.json(项目层)→ CORLINMAN_AGENT_PERMISSIONS env(最终话语权)叠层;mode/strict 同 precedence;无设置文件时与旧 from_env() 字节等价(含 first-match-wins 默认)。坏文件/坏块跳过不崩溃。
  • ApprovalGate + servicer 默认 gate 构造切到新加载器。
  • 控制台审批新增第三答案 p/persist:等同 always 并经 persist_allow_rule 原子写入(tmp+rename、幂等)用户层 settings;persist 钩子失败降级为会话级授权而非拒绝a 保持会话级(Codex Console permission surface: /permissions, /plan, --permission-mode + interactive approval (v1.23.0) #104——授权不越上下文边界)。

E2 — exit_plan_mode 内置工具

plan mode 拒掉全部 mutating 工具,此前只能人肉 /permissions 放行。现在模型计划就绪自己调用:

  • plan → default 翻转 + 交互审批缓存重置(两个 resolver 来源——set_approval_resolverapp_state.approval_resolver——都重置);非 plan mode 干净 no-op;可选 plan 摘要回显。
  • 二阶边缘预堵(本 parity 程序的教训:权限面每修一处开一个二阶边缘):权限 mode 是 servicer 级全局的,plan 模式下 spawn 工具不属 mutating、子代理可被派生——child executor 现在与递归 spawn / 后台 shell 同款拒绝子代理调用 exit_plan_mode,只有顶层回合能结束 plan mode。
  • skill allowed-tools 控制工具直通名单加入本工具,防 skill 把模型困死在 plan mode。

E3 — --fork-session

  • AgentJournal.fork_session:仅复制 completed 回合、按时间序、消息/tool_calls 保真;in_progress(在别处直播)与 errored(T4.4 面包屑)不复制;单回合损坏 log+跳过;源会话全程只读。Postgres 后端 list_session_turns 为 stub → 干净降级 0-turn fork(docstring 注明,含 limit 截断语义)。
  • 控制台 --fork-session:恢复前铸新 console:<id> key 并 fork,原会话零污染;attach 模式回显不支持说明后继续不 fork。

E4 — fallback 跨模型 thinking 签名剥离

thinking 块签名按模型铸造;OpenAI 兼容入口带入的客户端历史在 model-not-found / 持续过载两条 fallback 分支切模型重放时会把可恢复错误变成硬 400。两条分支重放前剥 thinking/redacted_thinking 块与 signature 键(纯 thinking 内容折叠为 "")。

E5 — 测试封闭性

conftest.py autouse fixture 对非 live 测试清洗 ANTHROPIC_BASE_URL + 6 个代理变量——宿主泄漏的路由 env 曾把 respx-mock 的 provider 套件重路由到真网络造成假失败。live_llm/live_transport 不受影响;测试自身 monkeypatch.setenv 仍生效。

验证

  • ruff / mypy(595 files)/ lint-imports 全绿
  • pytest 非 live 全量:6708 passed, 4 skipped
  • ui typecheck + lint + build 全绿;gen-proto.sh diff-clean
  • 新增测试 30+:13(settings 分层/持久化)+ 8(console 审批含 persist 契约)+ 6(exit_plan_mode 含子代理拒绝、app_state resolver 重置)+ 10(journal fork + console fork)+ 3(签名剥离)+ 2(封闭性契约)

备注

@github-actions github-actions Bot added codex:needs-review A Codex review is needed for the current PR head. codex:review-requested A Codex review was requested or should be running automatically. status: 🔁 re-review loop A fresh Codex review was requested after the latest change or comment. labels Jul 8, 2026
…ession, fallback signature strip, hermetic tests (v1.30.0)

E1 Layered permission settings + console persist answer:
- corlinman_agent.permission_settings: build_permission_gate() stacks
  <data_dir>/settings.json (user) -> ./.corlinman/settings.local.json
  (project) -> CORLINMAN_AGENT_PERMISSIONS env (final word); mode/strict
  follow the same precedence; byte-identical to from_env() when no file
  contributes. persist_allow_rule() writes durable allow rules atomically
  (tmp+rename, idempotent). ApprovalGate + servicer default gates now use
  the loader.
- Console approval gains a third answer p/persist: allow + session cache
  + durable settings rule; a failing persist hook degrades to a session
  grant, never a deny. "a" stays session-scoped (Codex #104).

E2 exit_plan_mode builtin (claude-code parity):
- Model-callable plan->default flip with approval-cache reset across BOTH
  resolver sources (set_approval_resolver + app_state.approval_resolver);
  clean no-op outside plan mode; optional plan summary echo.
- Child tool executor refuses exit_plan_mode: permission mode is
  servicer-global, only the top-level turn may end plan mode.
- Skill allowed-tools control passthrough includes it so a skill can't
  strand the model in plan mode.

E3 --fork-session (claude-code parity):
- AgentJournal.fork_session copies only completed turns chronologically
  onto a fresh key (in_progress/errored skipped; per-turn best-effort;
  source read-only). Console flag mints a new console:<id> key and forks
  before resume; attach mode degrades with a note.

E4 Cross-model thinking-signature strip on fallback:
- Both reasoning-loop fallback branches (model-not-found, sustained
  overload) strip thinking/redacted_thinking blocks and signature keys
  from replayed history — per-model signatures otherwise turn a
  recoverable failover into a hard 400.

E5 Hermetic tests:
- Root conftest.py scrubs ANTHROPIC_BASE_URL + proxy env for non-live
  tests so host routing config can't reroute respx-mocked suites.

Gate: ruff + mypy (595 files) + lint-imports + pytest 6708 passed /
4 skipped + ui typecheck/lint/build + gen-proto diff-clean.
@sweetcornna
sweetcornna force-pushed the feat/waveE-parity-batch branch from b7cd720 to 880b1d5 Compare July 20, 2026 01:50
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions Bot added codex:needs-rerun A new push or stale result means @codex review should be requested again. codex:reviewed Codex posted a review result or thumbs-up after the latest request. status: 👀 ready for maintainer look No automation blocker is known; a maintainer should inspect the current result. and removed codex:review-requested A Codex review was requested or should be running automatically. codex:needs-review A Codex review is needed for the current PR head. codex:needs-rerun A new push or stale result means @codex review should be requested again. status: 🔁 re-review loop A fresh Codex review was requested after the latest change or comment. labels Jul 20, 2026
@sweetcornna
sweetcornna merged commit 8eafb7b into main Jul 20, 2026
10 checks passed
@github-actions github-actions Bot added the status: ✅ merge-ready Evidence and review are clear; normal merge gates may proceed. label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex:reviewed Codex posted a review result or thumbs-up after the latest request. status: ✅ merge-ready Evidence and review are clear; normal merge gates may proceed. status: 👀 ready for maintainer look No automation blocker is known; a maintainer should inspect the current result.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant