Skip to content
12 changes: 11 additions & 1 deletion doc/architecture/SPEC/config.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# config.py —— 规范

<!-- verified-against: 2026-09-08 -->
<!-- verified-against: 2026-09-19 -->

`LOC ~658 · 配置 · refactor-status: oversized`

Expand Down Expand Up @@ -79,3 +79,13 @@ provider 的缺省模型必须在**这一处**解析,否则 `ResolvedTarget.mo
如果再增长,请分组成嵌套 settings 模型(`LLMSettings` / `PushSettings` /
`ReviewSettings` / `BackendSettings`),**而不是拆文件** —— 调用点依赖"一个 `Settings`
对象到达每个 `StepContext`"。

## rebase 后端抽象(2026-09-19)

`rebase_backend`(默认 `api`)选择跑 rebase **module agent** 的 provider:
`api` 为进程内 Anthropic tool-use 循环,其余为 harness provider id
(`cursor` / `claude-code` / `codex`)。`rebase_backend_model` 是 harness
**内部**的模型 id(如 `cursor-grok-4.6-high-fast`)。

注意:tier 模型名指向 RAW-API 模型,对 harness CLI 无意义,**绝不**转发过去;
为空时回落到 `strict_backend_model`,再回落到 harness 自身默认值。
10 changes: 9 additions & 1 deletion doc/architecture/SPEC/engine/steps/rebase_v3.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# engine/steps/rebase_v3.py —— 规范

<!-- verified-against: 2026-09-06 -->
<!-- verified-against: 2026-09-19 -->

`LOC ~2204 · step 库(v3 rebase 装配层) · refactor-status: oversized`

Expand Down Expand Up @@ -90,3 +90,11 @@ import(见重构备注)。
违例;对 `.workspace._guard_clean_rebase` 的直接 import 是另一条。拆分时
substate + `state_updates` 双写、模块短路/串行锁的 crash-window 契约**必须**
原样保留(resume 完整性测试护住)。

## harness 后端派发(2026-09-19)

module agent 可派发到 harness provider(`settings.rebase_backend`)。
harness 会话通过 MCP tool bridge 拿到同一套工具面,plan gate 在派发处强制。
`build_backends(repo=)` 收的是仓库 **ROOT 路径**(→ `TestRunner(repo_root=)`),
不是仓库名:传名字会让 run_pytest/run_precommit/reproduce 以
`FileNotFoundError` 静默失效,module 却报告完成。
9 changes: 8 additions & 1 deletion doc/architecture/SPEC/providers/cursor.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# providers/cursor.py —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-09-19 -->

`LOC ~207 · harness transport(Cursor 订阅) · refactor-status: ok`

Expand Down Expand Up @@ -38,3 +38,10 @@ stdlib + `.base` + `.registry` + `..agent_loop.AgentOutcome` + `..llm` 的类型
## 重构备注
这套调用形状是由 Composer 评测臂(`eval/dataset/run_cursor_arm.py`)验证出来的;
**如果那个脚本和这个 transport 发生漂移,评测臂就不再是在测量产品了。**

## 作为 rebase module-agent 后端(2026-09-19)

`REBASE_BACKEND=cursor` 时,cursor-agent 承担 rebase module agent。
registry 给 cursor 的能力是 `{mcp_tools, usage_reporting}`——**没有**
`builtin_tools_off`,所以 cursor 自带工具会绕过 bridge:bridged 调用受
scope 约束,native 调用只被**记录**。
7 changes: 6 additions & 1 deletion doc/architecture/SPEC/rebase_engine.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# rebase_engine/ —— 规范

<!-- verified-against: 2026-09-06 -->
<!-- verified-against: 2026-09-19 -->

`LOC ~7500(26 个模块) · repo-rebase-v3 的原生 rebase 引擎 · refactor-status: ok`

Expand Down Expand Up @@ -132,3 +132,8 @@ worktree)、`test_assembly.py`(tools/loop/module/prompt/wheel)、
是 PR4d 执行后的退役候补("无永久双 store 世界")。docstring 里的
choke-point 编号(agent_loop/rebase_tools 写"C5")落后于 `_CONSTRAINTS.md`
目录(工具 choke point = C3)—— 值得统一,改注释不改行为。

## module_rebase 的 harness 路径(2026-09-19)

`module_rebase` 既可跑进程内 agent 循环,也可把一个 module 交给 harness
provider;两条路径共用同一 prompt、同一工具面与同一 plan gate。
9 changes: 8 additions & 1 deletion doc/architecture/SPEC/tool_bridge.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# tool_bridge.py —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-09-19 -->

`LOC ~308 · 面向 harness 会话的 scoped 工具 MCP server · refactor-status: ok`

Expand Down Expand Up @@ -48,3 +48,10 @@ knowledge/repo-map 工厂。
因为它捆绑的运行时不带 MCP client,拿到无法履约的 spec 时会记一条 `capability_gap`。
任何"这次 run 走了工具桥"的说法,都必须**对照那个标志核实**,
而不是从"后端是 harness"推定。

## 向 harness 会话提供 rebase 工具面(2026-09-19)

bridge 把 run 的 20 工具面 + `doc_search`/`doc_read` 暴露给 harness 会话。
生成的 MCP 工具函数必须是 **keyword-only**(schema 会交错 required/optional),
零属性工具不能带裸 `*`,且必须**丢掉**未设置的 optional——传 None 会打断
每一次 `read_file`。失败的 bridged 调用记录失败**原因**。
32 changes: 32 additions & 0 deletions doc/features/provider-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,38 @@ STRICT_BACKEND_TIMEOUT_S=1800 # 单会话墙钟上限
**M2 —— claude-code** · **M3 —— codex**:同样的验收形状(离线假 CLI 测试 + 各一次实网
冒烟);M2 另外要证明在净化环境下**嵌套 CC**(Strict 宿主 = Claude Code)能工作。

**M4 —— rebase 模块 agent 走 harness(2026-09-18)**

rebase 模块 agent 此前**硬接**在 API transport 上(`rebase_v3._tier_client` →
`Anthropic`),provider 注册表只服务 `STRICT_BACKEND`/评审侧。M4 把它接到同一套
抽象上:`ModuleRunConfig.backend`(默认 `api`,保持进程内循环逐字节不变)非 `api`
时,整个模块步骤交给该 harness 的 `run_session`。

两件进程内循环独有的东西必须跟着搬进桥里,否则 harness 后端等于没有它们:

1. **20 个 adapter 工具**(不是共享注册表里的 6 个)。桥收到带 `rebase` 段的 spec 时,
在**自己的进程内**用同一个 `build_rebase_tools` 重建工具包,经 `dispatch(..., extra=)`
下发——scope 守卫、越界记录、结果上限与进程内一致。`build_backends`(原
`_build_backends`)改为吃显式可序列化入参,正是为了能在桥进程里重建同一套生产 backends。
2. **计划闸门**。`PlanGate` 在 **dispatch 处**拒绝 `edit_file`/`run_pytest`/
`run_precommit`,并在闸门关闭时把 `write_file` 限制在计划目录内;开闸条件与
`agent_loop` 完全一致:**成功**写出 `.decision.md`。这比"只是不广告工具"更强——
harness 即使自己发出调用也会被拒。闸门开启会记 `plan_gate_opened`,父进程据此回读
`plan_done`。

spec 只携带路径与模型标识:**不含 api_key,不含子进程 env**,凭证与 env 由桥进程自己的
环境提供,`run_dir/bridge/` 下不落任何机密。

已知缺口(明示):`_PATH_ARGS` 只认识共享工具,因此对带路径参数的 adapter 工具,
读包含性预检是 no-op(写仍由 `ToolScope` 在 dispatch 内守住)。另外 cursor/codex
**没有原生轮次上限**,`max_iters` 只在 claude-code(`--max-turns`)上生效,其余靠
`harness_timeout_s` 与提示词里的预算纪律兜底。

**策略变更,需记录**:本仓库原先明确规定知识/记忆检索**不过桥**("harness 会话可以读
本仓库的知识,但永远不能写入")。owner 于 2026-09-18 决定 rebase 走 harness 时要求
**全量平价**,因此 `search_debug_memory`/`record_debug_memory`/`skill_manage`/
`search_skills` 一并经桥重建——这是对既有决策的**反转**,不是顺带实现。

## 测试计划(离线优先,本仓库纪律)

- `test_providers.py` —— 注册表解析;Strict 与 CLI 在空选择下的行为差异;
Expand Down
11 changes: 11 additions & 0 deletions src/infermatrix_copilot/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,17 @@ class Settings(BaseSettings):
# v3 module-agent plan reviewer (rebase_engine/plan_review.py): empty =
# review on the run's own tier model — never silently skipped
rebase_reviewer_model: str = ""
# Which provider runs the rebase MODULE agents: "api" (default, the
# in-process Anthropic tool-use loop) or a harness provider id
# ("cursor", "claude-code", "codex"). Harness runs serve the same
# 20-tool surface through the MCP tool bridge; see
# doc/features/provider-registry.md.
rebase_backend: str = "api"
# Model id INSIDE the harness for rebase module agents (e.g.
# "cursor-grok-4.6-high-fast"). The tier model names a RAW-API model and
# is meaningless to a harness CLI, so it is never forwarded there; empty
# falls back to `strict_backend_model`, then the harness's own default.
rebase_backend_model: str = ""
# v3 remote CI (rebase_engine/ci_loop.run_ci_rounds) — neutral knobs;
# pipeline identities live in the adapter. Defaults are the parent's.
rebase_ci_retries: int = 2 # push/rebuild rounds after the first
Expand Down
Loading
Loading