Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions doc/GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -492,19 +492,19 @@ candidate ──人工晋升──▶ active ──▶ locked 回滚 = gi

## 6. Steps

38 个 step 在 `engine/steps/` 就地 `@step` 自注册(`rebase_native.py` / `issue.py` /
45 个 step 在 `engine/steps/` 就地 `@step` 自注册(`rebase_v3.py` / `issue.py` /
`pr/publish.py` 里有几个用 `register_step` 直接注册)。每个 step 声明两个属性:

- **kind**——`deterministic`(17)· `agent`(8)· `script`(7)· `validation`(3)·
`report`(3)。`kind == "agent"` 是有语义的:它意味着这个 step 走统一的
- **kind**——`deterministic`(25)· `agent`(8)· `script`(8)· `validation`(2)·
`report`(2)。`kind == "agent"` 是有语义的:它意味着这个 step 走统一的
`run_agent_step` 运行时治理(dispatch context、证据围栏、scope、结构化输出契约、
完整 trace),由一个参数化测试钉死。
- **risk**——`read` · `knowledge` · `write_workspace` · `push` · `report`。

失败是**值不是异常**:`StepResult.failure` 是六种 `FailureKind` 之一,
BLOCKED / ESCALATE / FORBIDDEN 会通知并停机,只有 RETRYABLE 会有界重试。

### 6.1 deterministic(17)— 不花模型调用
### 6.1 deterministic(25)— 不花模型调用

| step | risk | 做什么 |
|---|---|---|
Expand All @@ -522,9 +522,17 @@ BLOCKED / ESCALATE / FORBIDDEN 会通知并停机,只有 RETRYABLE 会有界
| `profile.ingest_docs` | knowledge | 摄入 AGENTS.md/CLAUDE.md 式人工指令(文档冗余行丢弃) |
| `profile.detect_drift` | read | Stage 4 漂移报告——刷新材料,绝不自动修 |
| `profile.decay_stale` | knowledge | Stage 4 休眠衰减:未确认的 fact 转 stale(排除但**不删**) |
| `rebase.prelude` | read | 父运行时设置 + wave 列表 |
| `rebase.phase2_prepare` | read | 预检 curator + phase-2 进度初始化 |
| `rebase.phase2_finalize` | read | 两个 wave 完成后推进父标记 |
| `workspace.guard_clean_rebase` | write_workspace | rebase 专用脏树守卫(adapter 策略委托) |
| `rebase.v3_prelude` | read | 模式解析写回、substate/锁/终局 finalizer、知识开账 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Attribute mode write-back to the CLI gate

Describe this step as validating the resolved mode and publishing its flags rather than resolving and writing it back. _v3_prelude only reads params.rebase_mode and returns BLOCKED when it is absent or unknown; rebase_engine.modes is invoked by the CLI before the playbook to perform authoritative resolution and write-back, so the current row assigns a safety-critical responsibility to the wrong component.

Useful? React with 👍 / 👎.

| `rebase.v3_guard` | write_workspace | 幂等重取 checkout flock + 注入 rebase 守卫策略 |
| `rebase.v3_scan` | read | 动态测试清单(CI YAML + 活测试树 + diff 分类) |
| `rebase.v3_wheel` | write_workspace | 选 upstream commit → 装进声明 venv → 最后 pin |
| `rebase.v3_assign` | read | commit→模块归类 + path-sync 后按 wave 分派 |
| `rebase.v3_wave_gate` | read | wave-1 失败裁决 wave-2 / 按配置升级 |
| `rebase.v3_push_gate` | read | 推送闸:结构性 vs 断言失败的确定性分类 |
| `rebase.v3_knowledge_prep` | knowledge | 知识层解析 + schema v2 保障(声明未展开 ⇒ BLOCKED) |
| `rebase.v3_phase5_report` | read | phase-5 汇总进 substate |
| `rebase.v3_finalize` | read | 终局裁决:substate 有失败 ⇒ BLOCKED needs-human |

### 6.2 agent(8)— 走统一运行时治理

Expand All @@ -539,30 +547,29 @@ BLOCKED / ESCALATE / FORBIDDEN 会通知并停机,只有 RETRYABLE 会有界
| `agent.profile_consolidate` | knowledge | Stage 4:**唯一**允许 rewrite/merge 的层,强制稳定性门禁 |
| `profile.judge` | read | Stage 4 只读审计 → JUDGE_REPORT.md,findings 只呈现不自动应用 |

### 6.3 script(7)— 委托或对外写
### 6.3 script(8)— 委托或对外写

| step | risk | 做什么 |
|---|---|---|
| `ci.push` | **push** | 受门禁的 push(PushPolicy ∧ 保护分支双闸,默认 dry-run) |
| `pr.post_review` | **push** | 单条 GitHub review + inline threads(显式 post 标志 + `ALLOW_POST`) |
| `issue.post_answer` | **push** | 发布 issue 回复(同样双闸) |
| `rebase.phase4` | **push** | 父 Phase 4(push + Buildkite CI),走 copilot 的 push guard |
| `rebase.run_external` | write_workspace | 委托给已有 5 阶段编排器(locked 流水线) |
| `rebase.phase1` | write_workspace | 父 Phase 1(init) |
| `rebase.module_rebase` | write_workspace | 单模块 rebase,委托父仓库自己的 `node_rebase_module` |
| `rebase.v3_ci` | **push** | phase-4 push + CI 轮次(WAL、双闸、op-id 台账) |
| `rebase.v3_module_rebase` | write_workspace | 单模块 rebase 单元(foreach;同 checkout 串行) |
| `rebase.v3_test_loop` | write_workspace | phase-3 本地测试环(逐测试恢复、baseline 分流) |
| `rebase.v3_precommit` | write_workspace | precommit 轮(passed/failed/failed_preexisting) |
| `rebase.v3_curate` | knowledge | 运行时知识策展 + watchdog 收割(只写 runtime 侧) |

> 全库只有这 4 个 `risk == "push"` 的 step,全部经 `push.py::guard_push`。

### 6.4 validation(3)与 report(3
### 6.4 validation(2)与 report(2

| step | kind | risk | 做什么 |
|---|---|---|---|
| `review.patch_gate` | validation | read | 条件式 patch review,push 前 fail-closed |
| `agent.verify_module` | validation | read | 逐模块 rebase 损伤检查——纯 LLM 建议,**不是**受治理 agent step |
| `rebase.phase3` | validation | write_workspace | 父 Phase 3(本地流水线测试 + SDK debug 循环) |
| `report.final_summary` | report | report | 写 `RUN_REPORT.md` + `DIAGNOSTICS.md` |
| `rebase.phase5` | report | report | 父 Phase 5 最终摘要 + 运行后 curator |
| `rebase.compare_with_locked` | report | report | `COMPARISON.md`:原生 run vs locked 基线(晋升证据) |
| `rebase.v3_compare` | report | read | 与基线对比裁决(劣于 baseline ⇒ BLOCKED) |

---

Expand Down
12 changes: 5 additions & 7 deletions doc/architecture/CODE_TOUR.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,11 @@ re-export,公开导入面不变)。
待裁决 skill candidate 队列)与 `DIAGNOSTICS.md`(逐 step 诊断,评审曾被三重
渲染并混入 blockers/confidence 噪声,现隔离)。

- **委托/夜跑支流**(数据流出到父流水线):
**`engine/steps/rebase_ext.py`**(115)——`rebase.run_external`:锁定夜跑的
受监控子进程委托。**`engine/steps/rebase_native.py`**(443)——原生分解候选
(wrap 父包函数、不重写;`repo-rebase-native` playbook,candidate)。
**`rebase/monitor.py`**(163)——只读消费父 orchestrator 的 `state.json`
(phase/module/test 进度)→ copilot 进度事件 + 失败分类 + 升级材料,绝不写
父文件;`rebase/__init__.py`(13)导出。
- **rebase 支流**(2026-08-25 cutover 后):委托版 `rebase_ext`、包装版
`rebase_native` 与父流水线监视器 `rebase/monitor.py` 已随 v1/v2 退役删除。
现行实现是 **`engine/steps/rebase_v3.py`** + **`engine/steps/rebase_knowledge.py`**
(step 装配)与 **`rebase_engine/`** 包(原语:worktree/推送 WAL/CI 轮次/
测试环境/知识迁移;见 `SPEC/rebase_engine.md`)。

- **profile 建立支流**(通向 §6):**`engine/steps/profile.py`**(441)——
`profile.fingerprint` → `structure_scan` → `ingest_docs` → `agent.profile_repo`
Expand Down
4 changes: 2 additions & 2 deletions doc/architecture/SPEC/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@
|---|---|
| 接口 / 任务 | `task_spec` `intent` `cli` `chat` `ui` `config` |
| 引擎底座 | `engine/step` `engine/registry` `engine/executor` `engine/planner` `engine/agent_runtime` `agent_loop` `tools` `scopes` `llm` |
| Step 库 | `engine/steps/__init__` `engine/steps/_common` `engine/steps/{workspace,rebase_ext,review,report,pr,issue,profile,rebase_native}` |
| Step 库 | `engine/steps/__init__` `engine/steps/_common` `engine/steps/{workspace,review,report,pr,issue,profile,rebase_v3,rebase_knowledge}` |
| 规划数据 | `playbooks/store` `playbooks/PLAYBOOKS`(yaml) |
| 边缘 —— 语言 | `profiles/languages`(按语言的规则,共享) |
| 边缘 | `adapters/base` `ci/normalize` `ci/providers` `rebase/monitor` |
| 边缘 | `adapters/base` `ci/normalize` `ci/providers` `ci/buildkite` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add every new specification to the file index

Keep this supposedly complete mirror index synchronized with the pages introduced by this commit. It still omits engine/lifecycle.md, rebase_engine.md, testing.md, memory/curator.md, and memory/paths.md, so contributors following the README before modifying those source modules cannot discover their new contracts from the declared index.

Useful? React with 👍 / 👎.

| 安全原语 | `scopes` `push` |
| Profile | `profiles/store` `profiles/establish` `profiles/repo_map` `profiles/consolidate` |
| 跨切 | `review/{diff_summary,triggers,reviewer}` `memory/{debug_memory,skills}` `run_trace` `notify` `metrics` |
Expand Down
12 changes: 9 additions & 3 deletions doc/architecture/SPEC/adapters/base.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# adapters/base.py —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-08-25 -->

`LOC ~368 · 边缘(仓库知识) · refactor-status: ok`
`LOC ~423 · 边缘(仓库知识) · refactor-status: ok`

## 职责
`RepoAdapter`(住在边缘的仓库知识)、adapter 注册表,以及确定性的 Phase-0 引导。
Expand All @@ -14,14 +14,20 @@
(见 DESIGN 的命名说明)。

## 公开契约
`expand_path(value, extra?)`、`AdapterError` 与其子类 `AdapterNotFound`;
`RepoAdapter`(属性 `status`、`repo_path`、`protected_branches`、`modules`、
`high_risk_modules`、`capabilities`、`skills_dir`、`debug_memory_db`、
`profile_dir`、`briefing()`;方法 `module_for_path`);`load_adapter`、
`update_manifest`、`AdapterRegistry(resolve/all)`;`fingerprint_repo`、
`draft_adapter`。

## 不变量
- **D2**:`update_manifest` **拒绝** agent 对 `push`/`repo`/`upstream` 的写入。
- **D2**:`update_manifest` **拒绝** agent 对 `push`/`repo`/`upstream`/`rebase` 的写入。
- `expand_path` 先展开进程 env,再用 `extra`(典型是 `Settings.expansion_env()`,
即 `.env` 里 pydantic 吃进 Settings 而未 export 的键)做**回退**;进程 env 永远
获胜且**绝不被修改**;仍未解析的变量 → 返回 ""(fail-closed,能力缺口路径)。
- **未知 adapter 名抛 `AdapterNotFound`**(子类);把"不存在"当兼容路径的调用方
只能捕获这个子类 —— 已知 adapter 的畸形 manifest 必须仍是硬失败。
- `capabilities` 由 manifest 推导(repo.path/language.*/ci.provider/upstream.*/
modules)+ 显式的 `capabilities:` —— 与 playbook 的 `requires:` 匹配。
- `high_risk_modules` = 标了 `risk: high` 的模块(喂给 patch-review,**A5**)。
Expand Down
4 changes: 2 additions & 2 deletions doc/architecture/SPEC/chat.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# chat.py —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-08-25 -->

`LOC ~440 · 接口(对话式 REPL) · refactor-status: split-candidate`
`LOC ~497 · 接口(对话式 REPL) · refactor-status: split-candidate`

## 职责
Claude-Code 风格的对话式 REPL(配置了 LLM 时的默认形态):一个持续的对话,
Expand Down
62 changes: 62 additions & 0 deletions doc/architecture/SPEC/ci/buildkite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ci/buildkite.py —— 规范

<!-- verified-against: 2026-08-25 -->

`LOC ~253 · 边缘(CI provider 客户端) · refactor-status: ok`

## 职责
rebase 引擎受守卫构建生命周期所注入的 `CIClient` —— 定界到单条 pipeline 的
Buildkite REST 客户端。

## 公开契约
`BuildkiteCI(token, org, pipeline, build_env?, request?, ignore_branch_filters=False)`;
协议方法 `create_build / get_build / find_builds_by_meta / cancel_build /
get_job_log / list_jobs / retry_job`;采纳/基线查询 `builds_for_commit`、
`latest_builds`;异常 `BuildkiteError`。`request`(`RequestFn`)可注入(测试
fake 绕开 urllib)。

## 不变量
- **A5**:org、pipeline、build env 全部来自 adapter(`ci.org` + `rebase.ci.*`)
—— 这里不点名任何仓库、pipeline 或队列。
- **归一化在这个边界发生**:build dict 的 `id` 是 build **number** 的字符串
(REST 按 number 寻址,UUID 不可路由),`web_url` 兜底拼出 —— `ci_loop`
的 op 台账因此存跨进程重启仍可解析的 id。
- **逐调用点的错误契约**:变更类调用与身份查询(create/cancel/
find_builds_by_meta/retry 非 400/builds_for_commit/latest_builds)在意外
响应上**抛** `BuildkiteError` —— op 标记 created 之前必须先看到失败,恢复/
采纳必须升级而不是猜(API 错误绝不当"无匹配");轮询读(`get_build`→`{}`、
`get_job_log`→`""`)**降级**不中止监控(**E2**;最终 reconciliation 裁决)。
- `create_build` 只把**一种**响应转成类型化拒绝:422 + "branches have been
disabled" → `BuildCreationRefused`(round loop 据此报 schedule-only 指引,
**B1** 路由的原料);其余 4xx 一律 `BuildkiteError` —— 那条指引在运维性
错误(401/403/404…)上会误导。
- adapter 显式 opt-in(`rebase.ci.ignore_branch_filters`)才在 create 上发送
`ignore_pipeline_branch_filters`(schedule-only pipeline 的官方补救;step
级 branch filter 依然生效);默认**绝不发送**。
- `list_jobs` 两路读取(/jobs 端点 → build 内嵌 jobs),两路都不可读时**抛**
—— 取数失败必须与"确实没有 job"可区分,否则 API 故障期间的 reconciliation
会静默通过。
- `retry_job` 的 400 = 该 job **类型**不可重试(`(None, False)`,归 ignorable);
其他失败一律抛 —— API 故障绝不被当成代码失败去派发变更 agent。

## 边界 —— 不属于这里
不含轮次/监控/失败分类(`rebase_engine/ci_loop`);不含推送
(`rebase_engine/push_to_ci`);同头 schedule 构建的**采纳决策**在
`ci_loop.run_ci_rounds` + `rebase.v3_ci`,这里只提供查询面。

## 依赖(允许)
stdlib 的 `json`/`urllib`;`BuildCreationRefused` 从 `rebase_engine.ci_loop`
惰性 import(类型化拒绝定义在消费方)。

## 扩展点
新的 provider 客户端 = 实现同一 `CIClient` 协议的**新文件**,不是这里的分支。

## 测试
`test_ci_wiring.py`(注入 RequestFn:归一化、逐调用点错误契约、branch-filter
opt-in 默认关、BuildCreationRefused 只认 422+disabled、list_jobs/retry_job)。

## 重构备注
干净。保持"变更抛 / 轮询降级"的逐调用点契约稳定 —— `create_build_guarded`
与最终 reconciliation 都押在它上面。对 `ci_loop.BuildCreationRefused` 的
惰性 import 是一条轻微的向内依赖(边缘 → rebase_engine);接入第二个
provider 时把这个异常类型上提到共享的 CI 契约模块。
12 changes: 10 additions & 2 deletions doc/architecture/SPEC/cli.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# cli/ —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-08-25 -->

`LOC ~1000(5 个文件) · 接口 + 编排门面 · refactor-status: ok`
`LOC ~1240(6 个文件) · 接口 + 编排门面 · refactor-status: ok`

## 职责
flag CLI 与 `Copilot` 门面:解析 → 过门 → 执行;并持有 run 目录、RunTrace、notifier
Expand All @@ -18,6 +18,8 @@ flag CLI 与 `Copilot` 门面:解析 → 过门 → 执行;并持有 run 目
的调用)。
- `utils.py` —— 纯格式化器:`parse_task_params`、`format_metrics_line`。
- `doctor.py` —— 预检诊断(2026-07 新增):逐项 ✓/✗,每个失败给出**唯一**确切的修复命令。
- 子命令:`doctor` 与 `migrate-knowledge`(PR4d 部署期知识迁移;**显式 owner
动作,零 LLM**,需 `--repo <name>`,支持 report-only;见 RUNBOOK)。

## 公开契约(可从 `infermatrix_copilot.cli` import)
`main(argv)`;`Copilot`(`resolve`、`run_task`、`run_playbook`、`run_queue`、
Expand All @@ -33,6 +35,12 @@ flag CLI 与 `Copilot` 门面:解析 → 过门 → 执行;并持有 run 目
- 仓库知识(保护分支、高风险模块)由 adapter 进入 run state(**A5**);
被阻塞 → 退出码 3(`BLOCKED_EXIT`)。
- `--playbook` 是运行 candidate 的**唯一**方式。
- **rebase_mode 是带权威写回的**:`params.rebase_mode` 在过门前经
`rebase_engine.modes` 解析并写回(`mode_state_flags` 决定 `when:` 门),
冲突抛 `ModeConflictError` —— review 上下文向 reviewer 说明该模式下
哪些 step 会跑。
- **每仓库知识锁(SHARED)持有整个 run 的生命周期**:run 之间不互斥,
只与 `migrate-knowledge` 的 EXCLUSIVE 锁互斥 —— 迁移绝不与活跃 run 并发。
- **`doctor` 只读,且永不打印密钥的值** —— 只打印它的名字。除非传 `--probe`,
否则它不做任何付费 LLM 调用;`--probe` 是唯一的付费检查(每个已配置档位一个 token)。
`--json` 供 CI 使用,而**在没有凭据时以非零码退出正是 CI 里的预期状态**。
Expand Down
26 changes: 18 additions & 8 deletions doc/architecture/SPEC/config.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
# config.py —— 规范

<!-- verified-against: 2026-08-18 -->
<!-- verified-against: 2026-08-25 -->

`LOC ~418 · 配置 · refactor-status: oversized`
`LOC ~630 · 配置 · refactor-status: oversized`

## 职责
从 env / `.env` 加载的 `Settings`(pydantic-settings),以及把本次 run 的档位与后端
选择变成具体目标的那些推导 helper。

## 功能
为 LLM 端点与逐档模型、仓库、引擎预算、推送安全、PR debug、外部 rebase、agent 运行时、
为 LLM 端点与逐档模型、仓库、引擎预算、推送安全、PR debug、v3 rebase
(reviewer 模型、远端 CI 轮次/预算、`github_token` 推送凭据)、agent 运行时、
ensemble、MoA、评审深度与按 pass 路由、Strict 后端选择、profile、patch 触发器、
metrics 与升级,提供带类型字段和安全默认值。
metrics 与升级,提供带类型字段和安全默认值;外加 PR4d 知识运行时 cutover
(`imx_knowledge_runtime`)与 manifest 展开回退(`expansion_env()`)。

## 公开契约
带全部可调项的 `Settings`;`reviewer` / `intent`(回退到 `agent_model`);
`repo_path(name)`;`model_for(mode)`;`tier_target(role)` → `ResolvedTarget`;
以及 `strict_backend` 校验器。
`expansion_env()`;`knowledge_runtime_repos`;以及 `strict_backend` 校验器。

## 不变量(**A5**、**C2**、**B1**)
- 密钥只经 env / `.env`(被 git 忽略,**绝不提交**)。
- 仓库专属默认值(`default_repo`、`rebase_agent_root`、`high_risk_modules`、
`cost_ref_*`)**只是兜底**;adapter/profile 会覆盖它们。它们是这里**唯一被允许**的
仓库字面量,泄漏上限为 3,并由 `test_v2_p0.py::test_repo_neutral_core` 钉住。
- 仓库专属默认值(`default_repo`、`rebase_agent_root`、`cost_ref_*`)**只是兜底**;
adapter/profile 会覆盖它们。它们是这里**唯一被允许**的仓库字面量,由
`test_v2_p0.py::test_repo_neutral_core` 钉住上限。`high_risk_modules` 的默认值
已**中立化为空**(风险声明是仓库知识,由 adapter 的 tier 声明获胜)。
- **`expansion_env()` 过滤密钥**:名字含 key/token/secret/password 的字段与 `.env`
键一律排除,dotenv 读取 `interpolate=False`——manifest 路径永远不能把凭据拉进
错误信息或日志;Settings 字段在重名时获胜(已体现进程 env 优先)。
- **`imx_knowledge_runtime` 按仓库 fail-closed**:列出的仓库在 resolve 时校验
`MIGRATION_COMPLETE.json`,缺标记即失败;未列出的仓库保持 legacy 路径逐字节不变。
- `github_token` 只服务 v3 远端 CI 推送的 **header 认证**(推送传输按设计禁用
credential helper,绝不落共享凭据存储)。
- **`STRICT_BACKEND` 在前面就被校验**,失败时列出合法集合。未知后端**绝不能**到达
`providers.resolve_provider` —— 两层,因为 `.env` 里的一个拼写错误不该启动一次注定
失败的 run。
Expand Down
Loading
Loading