From a6e51afb29ae24376ac1942629b4e690490eb9ef Mon Sep 17 00:00:00 2001 From: tzhouam Date: Fri, 18 Sep 2026 22:48:46 +0800 Subject: [PATCH 1/2] rebase: give module agents the curated knowledge base The rebase module agents could reach past failures (search_debug_memory) and learned skills (search_skills), but not the human-written knowledge pages -- component maps, model notes, CI and git lore. So an agent rediscovered by shell what a page already stated. Evidence from the v0.30.0 campaign: of 526 tool calls, 169 were run_shell and 26 grep, against 2 doc_search and 0 doc_read. doc_search was already reachable on the harness path via the MCP tool bridge, so the gap was instruction, not capability -- neither module prompt template mentioned the knowledge base at all, while DEBUG_MEMORY tokens actively push agents toward search_debug_memory (17 calls) and search_skills (10). This wires it on both backends: - doc_search/doc_read added to the adapter tool schemas, APPENDED after the parent dispatcher's 20 so that order stays an intact prefix. - RebaseBackends gains the two handlers, fail-closed by default like the rest, implemented in _build_backends over the same KnowledgeDocs view the review flows use (repo-scoped through the adapter manifest's knowledge.repo_subdir). - The instruction rides the builder-supplied ADAPTIVE_GUIDANCE slot rather than a template edit, so the shipped templates stay byte-identical to the parent's copies (test_templates_are_parent_verbatim still passes). Guidance tells agents to search the knowledge base before shell exploration, to cite the page path when it informed a decision, and that where a page and the code disagree the CODE is authoritative for a rebase. Goldens: module_prompt_*.txt and request_shape_turn1.json are deliberately regenerated -- the render and the tool surface both change by design. The prompt goldens no longer record the PARENT builder's output, and the test docstring now says so instead of claiming a parity it no longer has. The parent agent had no knowledge-base access, so this divergence is the point. Verified: full suite green; doc_search returns real pages for the vllm-omni slice (components/scheduler/architecture.md, models/qwen-omni/_index.md); a rendered module prompt carries the guidance with no unsubstituted tokens. Co-Authored-By: Claude Opus 5 (1M context) --- adapters/vllm_omni/rebase/tool_schemas.json | 60 +++++++++++++++---- .../engine/steps/rebase_v3.py | 42 +++++++++++++ .../rebase_engine/prompt_builder.py | 26 +++++++- .../rebase_engine/rebase_tools.py | 4 ++ test/goldens/module_prompt_model_config.txt | 9 ++- test/goldens/module_prompt_worker_runner.txt | 9 ++- test/goldens/request_shape_turn1.json | 42 ++++++++++++- test/test_adapter_knowledge.py | 15 ++++- test/test_engine_core.py | 4 ++ 9 files changed, 194 insertions(+), 17 deletions(-) diff --git a/adapters/vllm_omni/rebase/tool_schemas.json b/adapters/vllm_omni/rebase/tool_schemas.json index a8d70919..0bd6e104 100644 --- a/adapters/vllm_omni/rebase/tool_schemas.json +++ b/adapters/vllm_omni/rebase/tool_schemas.json @@ -168,7 +168,7 @@ }, { "name": "git_show_test_baseline", - "description": "Show the origin/main version of a test file. Use this FIRST when a test fails — compare origin/main's test with omni's test before changing any product code.", + "description": "Show the origin/main version of a test file. Use this FIRST when a test fails \u2014 compare origin/main's test with omni's test before changing any product code.", "input_schema": { "type": "object", "properties": { @@ -184,7 +184,7 @@ }, { "name": "reproduce", - "description": "Hermetically reproduce a failing test on a CLEAN GPU. This is the ONLY sanctioned way to run a GPU test — it kills leaked stage/API processes, clears dead device locks, asserts free VRAM, and runs with CUDA_LAUNCH_BLOCKING=1 so a device-side assert points at the true kernel. Prefer this over raw run_shell pytest, which corrupts shared GPU state and produces phantom failures. Returns a structured outcome including whether the failure looks environmental (env_dirty) vs a real code bug.", + "description": "Hermetically reproduce a failing test on a CLEAN GPU. This is the ONLY sanctioned way to run a GPU test \u2014 it kills leaked stage/API processes, clears dead device locks, asserts free VRAM, and runs with CUDA_LAUNCH_BLOCKING=1 so a device-side assert points at the true kernel. Prefer this over raw run_shell pytest, which corrupts shared GPU state and produces phantom failures. Returns a structured outcome including whether the failure looks environmental (env_dirty) vs a real code bug.", "input_schema": { "type": "object", "properties": { @@ -309,7 +309,7 @@ }, { "name": "request_plan_review", - "description": "Submit your plan for L4 review BEFORE making any code edits. You MUST call this after writing plan JSON + MD files and before editing any code. Pass the exact paths you just wrote to — the reviewer only reads those files, so there is no ambiguity. The L4 reviewer is a fresh, independent session — it has no access to your conversation history. It will critique your plan and return a verdict (lgtm/revise/block). The review is advisory — you retain final authority but MUST write a decision file per critique before editing code.", + "description": "Submit your plan for L4 review BEFORE making any code edits. You MUST call this after writing plan JSON + MD files and before editing any code. Pass the exact paths you just wrote to \u2014 the reviewer only reads those files, so there is no ambiguity. The L4 reviewer is a fresh, independent session \u2014 it has no access to your conversation history. It will critique your plan and return a verdict (lgtm/revise/block). The review is advisory \u2014 you retain final authority but MUST write a decision file per critique before editing code.", "input_schema": { "type": "object", "properties": { @@ -346,7 +346,7 @@ }, { "name": "search_debug_memory", - "description": "Search past debug memory for similar failures and their proven fixes. Use this FIRST when you encounter an error — someone may have already fixed it in a previous run. Returns matching entries with symptom, root cause, and the exact fix applied.", + "description": "Search past debug memory for similar failures and their proven fixes. Use this FIRST when you encounter an error \u2014 someone may have already fixed it in a previous run. Returns matching entries with symptom, root cause, and the exact fix applied.", "input_schema": { "type": "object", "properties": { @@ -386,15 +386,15 @@ }, "symptom": { "type": "string", - "description": "What went wrong — error message, traceback summary" + "description": "What went wrong \u2014 error message, traceback summary" }, "root_cause": { "type": "string", - "description": "Why it went wrong — upstream change, missing API, etc." + "description": "Why it went wrong \u2014 upstream change, missing API, etc." }, "fix": { "type": "string", - "description": "How you fixed it — what code was changed and why" + "description": "How you fixed it \u2014 what code was changed and why" }, "tags": { "type": "string", @@ -406,7 +406,7 @@ }, "watch_outs": { "type": "string", - "description": "Things to watch for — similar issues in other places" + "description": "Things to watch for \u2014 similar issues in other places" } }, "required": [ @@ -419,7 +419,7 @@ }, { "name": "skill_manage", - "description": "Create or update a reusable SKILL — a distilled runbook for a recurring rebase/debug pattern. Use this AFTER you confirm a fix that is likely to recur (e.g. an upstream API drift you had to port). Skills are injected into future runs' prompts for the matching module. Prefer editing an existing skill (action=update) over creating near-duplicates.", + "description": "Create or update a reusable SKILL \u2014 a distilled runbook for a recurring rebase/debug pattern. Use this AFTER you confirm a fix that is likely to recur (e.g. an upstream API drift you had to port). Skills are injected into future runs' prompts for the matching module. Prefer editing an existing skill (action=update) over creating near-duplicates.", "input_schema": { "type": "object", "properties": { @@ -441,7 +441,7 @@ }, "trigger": { "type": "string", - "description": "When this skill applies — the symptom/condition to match." + "description": "When this skill applies \u2014 the symptom/condition to match." }, "modules": { "type": "string", @@ -487,5 +487,45 @@ }, "required": [] } + }, + { + "name": "doc_search", + "description": "Search the repo's CURATED KNOWLEDGE BASE \u2014 human-written pages on components, models, CI, git workflow and debugging lore. Use this BEFORE exploring with shell: a page often states the design intent or the owning component outright, which grep cannot tell you. Complements search_debug_memory (past failures and their fixes) \u2014 this is documented design, not incident history. Returns matching pages with paths to open via doc_read.", + "input_schema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Free text: component, model, symbol, subsystem or concept." + }, + "limit": { + "type": "integer", + "description": "Max matches (default 20, max 40)." + } + }, + "required": [ + "query" + ] + } + }, + { + "name": "doc_read", + "description": "Read one knowledge page returned by doc_search. Pass the path exactly as doc_search reported it. Use offset to page through a long document.", + "input_schema": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Document path from a doc_search match." + }, + "offset": { + "type": "integer", + "description": "Character offset for long pages." + } + }, + "required": [ + "path" + ] + } } ] diff --git a/src/infermatrix_copilot/engine/steps/rebase_v3.py b/src/infermatrix_copilot/engine/steps/rebase_v3.py index 9a486769..cb0396b1 100644 --- a/src/infermatrix_copilot/engine/steps/rebase_v3.py +++ b/src/infermatrix_copilot/engine/steps/rebase_v3.py @@ -457,7 +457,49 @@ def skill_manage(**kw) -> dict: except Exception as exc: # noqa: BLE001 return {"error": f"skill proposal failed: {exc}"} + def doc_search(**kw) -> dict: + """Curated knowledge base, repo-scoped like the review flows. + + The rebase agents previously saw only debug_memory (past FIXES) and + skills; the human-written pages under the adapter's knowledge slice + — component maps, model notes, CI and git lore — were unreachable, + so a module agent rediscovered by shell what a page already stated. + """ + try: + from ...knowledge_docs import KnowledgeDocs + kn = manifest.get("knowledge") or {} + docs = KnowledgeDocs(ctx.settings.knowledge_dir, + kn.get("repo_subdir")) + query = str(kw.get("query") or kw.get("keyword") or "").strip() + if not query: + return {"error": "doc_search requires a non-empty query"} + limit = max(1, min(int(kw.get("limit") or 20), 40)) + hits = docs.search(query, limit=limit) + return {"query": query, "repo": repo, "matches": hits, + "truncated": len(hits) >= limit} + except Exception as exc: # noqa: BLE001 + return {"error": f"doc_search failed: {exc}"} + + def doc_read(**kw) -> dict: + """Read one knowledge page by the path doc_search returned.""" + try: + from ...knowledge_docs import KnowledgeDocs + kn = manifest.get("knowledge") or {} + docs = KnowledgeDocs(ctx.settings.knowledge_dir, + kn.get("repo_subdir")) + path = str(kw.get("path") or "").strip() + if not path: + return {"error": "doc_read requires a path from doc_search"} + page = docs.read(path, offset=int(kw.get("offset") or 0)) + return {"repo": repo, **page} + except FileNotFoundError: + return {"error": f"no such document: {kw.get('path')!r} " + "(use a path returned by doc_search)"} + except Exception as exc: # noqa: BLE001 + return {"error": f"doc_read failed: {exc}"} + return RebaseBackends( + doc_search=doc_search, doc_read=doc_read, search_debug_memory=search_debug_memory, record_debug_memory=record_debug_memory, skill_manage=skill_manage, search_skills=search_skills, diff --git a/src/infermatrix_copilot/rebase_engine/prompt_builder.py b/src/infermatrix_copilot/rebase_engine/prompt_builder.py index 150ad2f0..ba49a104 100644 --- a/src/infermatrix_copilot/rebase_engine/prompt_builder.py +++ b/src/infermatrix_copilot/rebase_engine/prompt_builder.py @@ -166,6 +166,30 @@ def _format_module_test_plan(plan: dict, return "\n".join(lines) + "\n" +_KNOWLEDGE_GUIDANCE = ( + "**Knowledge base.** Before exploring an unfamiliar component, model or CI\n" + "behaviour with shell, run `doc_search` with the component/model/symbol name\n" + "and `doc_read` the best match by its reported path. A curated page often\n" + "states design intent or the owning component outright, which grep cannot\n" + "tell you. This is documented design; `search_debug_memory` is incident\n" + "history — consult both. Cite the page path in your plan when it informed a\n" + "decision. If a page and the code disagree, the CODE is authoritative for\n" + "this rebase: say so in your decision file rather than editing to match." +) + + +def _with_knowledge_guidance(adaptive_guidance: str) -> str: + """Render the ADAPTIVE_GUIDANCE slot with the knowledge-base instruction. + + Carried here rather than in the templates on purpose: the shipped templates + are DATA held byte-identical to the parent agent's copies (enforced by + test_adapter_knowledge.test_templates_are_parent_verbatim), so behaviour + changes belong in builder-supplied tokens. + """ + rest = (adaptive_guidance or "").strip() + return f"{_KNOWLEDGE_GUIDANCE}\n\n{rest}" if rest else _KNOWLEDGE_GUIDANCE + + def build_module_prompt( module: str, data: ModulePromptData, @@ -249,7 +273,7 @@ def build_module_prompt( "SIGNAL_DIR": signal_dir, "MAX_DEBUG_RETRIES": str(max_debug_retries), "PROMPT_SOURCE": "", - "ADAPTIVE_GUIDANCE": adaptive_guidance.strip() or "(No adaptive rules yet.)", + "ADAPTIVE_GUIDANCE": _with_knowledge_guidance(adaptive_guidance), "KILL_TEST_SCRIPT": f"{script_dir}/lib/kill_test_tree.sh", "REMOTE_CONTEXT": "### Execution mode: LOCAL", "DEBUG_MEMORY": "Use the `search_debug_memory` tool to query past fixes. Do NOT read the debug_memory.md file directly.", diff --git a/src/infermatrix_copilot/rebase_engine/rebase_tools.py b/src/infermatrix_copilot/rebase_engine/rebase_tools.py index 0ea706ec..04a85cbd 100644 --- a/src/infermatrix_copilot/rebase_engine/rebase_tools.py +++ b/src/infermatrix_copilot/rebase_engine/rebase_tools.py @@ -61,6 +61,8 @@ class RebaseBackends: """Injected implementations for the knowledge-plane + plan-review tools. Each takes the tool's kwargs and returns the parent-shaped dict.""" + doc_search: Handler = field(default_factory=lambda: _unwired("doc_search")) + doc_read: Handler = field(default_factory=lambda: _unwired("doc_read")) search_debug_memory: Handler = field( default_factory=lambda: _unwired("search_debug_memory")) record_debug_memory: Handler = field( @@ -293,6 +295,8 @@ def _audit_ok(result: str) -> bool: "git_diff": (handle_git_diff, None), "git_diff_tests_upstream": (handle_git_diff_tests_upstream, None), "request_plan_review": (backends.request_plan_review, None), + "doc_search": (backends.doc_search, None), + "doc_read": (backends.doc_read, None), "search_debug_memory": (backends.search_debug_memory, None), "record_debug_memory": (backends.record_debug_memory, None), "skill_manage": (backends.skill_manage, None), diff --git a/test/goldens/module_prompt_model_config.txt b/test/goldens/module_prompt_model_config.txt index 24031dba..578b1161 100644 --- a/test/goldens/module_prompt_model_config.txt +++ b/test/goldens/module_prompt_model_config.txt @@ -146,7 +146,14 @@ Typical fixes vs `/nonexistent/vllm-checkout`: `StageEngineCoreClient.shutdown` ### Adaptive runbook -(No adaptive rules yet.) +**Knowledge base.** Before exploring an unfamiliar component, model or CI +behaviour with shell, run `doc_search` with the component/model/symbol name +and `doc_read` the best match by its reported path. A curated page often +states design intent or the owning component outright, which grep cannot +tell you. This is documented design; `search_debug_memory` is incident +history — consult both. Cite the page path in your plan when it informed a +decision. If a page and the code disagree, the CODE is authoritative for +this rebase: say so in your decision file rather than editing to match. Use the `search_debug_memory` tool to query past fixes. Do NOT read the debug_memory.md file directly. diff --git a/test/goldens/module_prompt_worker_runner.txt b/test/goldens/module_prompt_worker_runner.txt index 26fee748..9b61cba0 100644 --- a/test/goldens/module_prompt_worker_runner.txt +++ b/test/goldens/module_prompt_worker_runner.txt @@ -146,7 +146,14 @@ Typical fixes vs `/nonexistent/vllm-checkout`: `StageEngineCoreClient.shutdown` ### Adaptive runbook -(No adaptive rules yet.) +**Knowledge base.** Before exploring an unfamiliar component, model or CI +behaviour with shell, run `doc_search` with the component/model/symbol name +and `doc_read` the best match by its reported path. A curated page often +states design intent or the owning component outright, which grep cannot +tell you. This is documented design; `search_debug_memory` is incident +history — consult both. Cite the page path in your plan when it informed a +decision. If a page and the code disagree, the CODE is authoritative for +this rebase: say so in your decision file rather than editing to match. Use the `search_debug_memory` tool to query past fixes. Do NOT read the debug_memory.md file directly. diff --git a/test/goldens/request_shape_turn1.json b/test/goldens/request_shape_turn1.json index 87295d8f..4b442e11 100644 --- a/test/goldens/request_shape_turn1.json +++ b/test/goldens/request_shape_turn1.json @@ -418,12 +418,52 @@ }, "required": [] } + }, + { + "name": "doc_search", + "description": "Search the repo's CURATED KNOWLEDGE BASE — human-written pages on components, models, CI, git workflow and debugging lore. Use this BEFORE exploring with shell: a page often states the design intent or the owning component outright, which grep cannot tell you. Complements search_debug_memory (past failures and their fixes) — this is documented design, not incident history. Returns matching pages with paths to open via doc_read.", + "input_schema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Free text: component, model, symbol, subsystem or concept." + }, + "limit": { + "type": "integer", + "description": "Max matches (default 20, max 40)." + } + }, + "required": [ + "query" + ] + } + }, + { + "name": "doc_read", + "description": "Read one knowledge page returned by doc_search. Pass the path exactly as doc_search reported it. Use offset to page through a long document.", + "input_schema": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "Document path from a doc_search match." + }, + "offset": { + "type": "integer", + "description": "Character offset for long pages." + } + }, + "required": [ + "path" + ] + } } ], "messages": [ { "role": "user", - "content": "You are rebasing vllm-omni module `model_config`.\n\nGoal: make `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` compatible with upstream while preserving vllm-omni intent from `origin/main`.\n\n## CRITICAL: Plan-Review-Decision Gate (MANDATORY)\n\nThe `edit_file`, `run_pytest`, and `run_precommit` tools are LOCKED until you\ncomplete the plan-review-decision pipeline. You CANNOT edit code or run tests\nuntil you write a .decision.md file. Use `read_file`, `grep`, `run_shell`,\n`git_show_upstream`, `git_show_omni_main` for exploration.\n\n### YOUR FIRST TASK: Write plan files, then call `request_plan_review`\n\nStep 1 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\n (JSON: {\"version\":3,\"plan_id\":\"v0-XXXX\",\"intent\":\"...\",\"changes\":[...],\"verify\":[...],\"risks\":[...]})\n\nStep 1b — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md (full narrative)\n\nStep 2 — request_plan_review tool:\n plan_json_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\"\n plan_md_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md\"\n kind: \"rebase\"\n\nStep 3 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.decision.md (accept|partial|reject per critique)\n\nStep 4 — NOW edit_file, run_pytest, run_precommit are unlocked. Edit code.\n\nMax 2 revision rounds. If review fails, proceed anyway.\n\n## Environment\n- vLLM repo (read-only): /nonexistent/vllm-checkout (commit: )\n- vllm-omni repo (edit here only): /nonexistent/omni-checkout (commit: )\n- CUDA_VISIBLE_DEVICES=0,1\n- HF_HOME=/model\n\n### Execution mode: LOCAL\n\n## Execution flow\n1. **Plan first** (per contract above), then begin on `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.\n2. Run **41** (check API drift) + **42** (check upstream imports) before deep pytest. If 42 first shows broken imports, **fix then full 42 re-run** before long pytest.\n3. Triage the **first real** failure: traceback, `FAILED`, `MISMATCH`, `BROKEN`—not watchdog-only chatter.\n4. **Minimal patch** in `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` (+ omni tests/fixtures needed).\n5. Re-run **that** check first; prefer **targeted** pytest when the runbook allows.\n6. Full required verification.\n7. **No-op fail-fast:** if output unchanged across **two** consecutive repair attempts, stop.\n8. Repeated identical `TypeError` / ctor args on one stack → **one** kwargs/wiring fix, then re-verify.\n\n**Engine / unpack:** Fix return-shape, kwargs, ordering at the real omni engine boundary; keep `shutdown` kwargs in sync with upstream.\n\n**Diffusion / subprocess:** `StageDiffusionProc died during handshake` → full worker traceback; handshake/init vs OOM; one controlled retry if GPU contention is plausible.\n\n**CUDA OOM with foreign PIDs:** resource contention—document; do not spend all `3` on identical code tweaks if GPU picture unchanged.\n\n**Attempt history:** attempt 0 noisy, attempt 1 **PASSED** → do not over-fit attempt 0.\n\n**Two pytest lines in one step:** map `FAILED` to the command whose stderr failed.\n\n**Registry / dynamic imports:** align every runtime entry (e.g. `registry.py`) with `/nonexistent/vllm-checkout`.\n\n**Phase 3 debug:** reply with traceback + `MODULE=model_config` + owning area.\n\n**CPU/merge pipeline:** optional-dep `ModuleNotFoundError`, bad LoRA `HTTPException`/400—fix deps/fixtures in `/nonexistent/omni-checkout`.\n\n## Parallel execution (Phase 2)\nOther module agents edit `/nonexistent/omni-checkout` concurrently.\n\n1. Dirty `git status` outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` is **expected**—ignore it.\n2. Never `git stash`, `git checkout`, or `git clean` paths outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` (you would destroy other agents' work).\n3. Do not ask the user to clean the workspace or wait for other modules.\n4. `tasks/01_guard_branch_clean.sh` already ran in Phase 1; do not re-verify globally.\n\n**Primary scope = `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.** Repeated `Module progress: (k done, f failed, s skipped) (k/M)` with the **same tuple** = **plateau** (heartbeat), not new failures. A tuple change then `ERROR: Module rebase failed` **without** `Timeout waiting for modules` = aggregate wave outcome—check signals.\n\n**All-fail-in-one-poll:** `(0,0,0)` → `(0,N,0)` with all modules failing in the same tick is likely **systemic** (shared config, common import, env var, tmux failure). Check shared infrastructure first. **Single-module waves:** same systemic check before blaming your code.\n\n**Straggler avoidance:** Finish checks and write the completion contract promptly. In **single-module waves** (no parallel modules), the orchestrator waits only for you—write your verdict as soon as final.\n\n**Orchestrator restart/resume:** `Skipping (already done)` = incremental relaunch. Do not assume all agents restart together.\n\n### Shared log hygiene\nAnchor on the **current run**—match `Resuming run: rebase-* (phase: …)` for **this** session. `[claude_auth]` / `API key probe OK` is CLI init—**not** a module failure. Repeated `Using level-1 agent model:` banners are **noise**—diagnose from `ERROR:` / phase banners / task names. Git boilerplate (`detached HEAD`, `git switch -c`) is scaffold—not merge outcome unless paired with conflict/error lines. `SSH fetch failed; retrying via HTTPS token auth` followed by HTTPS success is normal infrastructure fallback—**not** a module failure.\n\n### Autonomous scope extension\nFully unattended—**never** ask for guidance, confirmation, permission, or numbered options. Decide and act.\n\n**Plan review timeout:** If `## CRITICAL: Plan-Review-Decision Gate (MANDATORY)\n\nThe `edit_file`, `run_pytest`, and `run_precommit` tools are LOCKED until you\ncomplete the plan-review-decision pipeline. You CANNOT edit code or run tests\nuntil you write a .decision.md file. Use `read_file`, `grep`, `run_shell`,\n`git_show_upstream`, `git_show_omni_main` for exploration.\n\n### YOUR FIRST TASK: Write plan files, then call `request_plan_review`\n\nStep 1 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\n (JSON: {\"version\":3,\"plan_id\":\"v0-XXXX\",\"intent\":\"...\",\"changes\":[...],\"verify\":[...],\"risks\":[...]})\n\nStep 1b — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md (full narrative)\n\nStep 2 — request_plan_review tool:\n plan_json_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\"\n plan_md_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md\"\n kind: \"rebase\"\n\nStep 3 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.decision.md (accept|partial|reject per critique)\n\nStep 4 — NOW edit_file, run_pytest, run_precommit are unlocked. Edit code.\n\nMax 2 revision rounds. If review fails, proceed anyway.` triggers a plan-and-review protocol that times out (no `.review_done` within the allotted wait), proceed with your plan. Do not treat review timeout as a module failure.\n\nIf a **required verification** fails and root cause is under `/nonexistent/omni-checkout` but outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`:\n1. **Follow the root cause**—minimal targeted fixes anywhere under `/nonexistent/omni-checkout`.\n2. Keep fixes **small**—align with `/nonexistent/vllm-checkout`; no unrelated refactors.\n3. **Document** every out-of-scope edit in the completion contract.\n4. Prefer **additive** changes if another agent may touch the same file.\n5. After **two** failed attempts on that out-of-scope fix, **stop** and write `.fail` with traceback.\n\n## Evaluation gates\n**Truth = the latest checker output: exit code, final banner, every `MISMATCH`/`BROKEN`.** Ignore fix-agent tmux chatter and lines like `Import fix agent reported success` until a **full** `41`/`42` run after that path confirms (exit 0, zero `MISMATCH`/`BROKEN`).\n\n- **Chronology:** Anchor on the **latest** full run. Old failures are void after a later run exits 0 with no `MISMATCH`/`BROKEN`.\n- **Success-before-failure:** Earlier green `41`/`42`/install lines before a later `ERROR:` still stand—do not blame install/Dockerfile unless that step also shows failure in the **same** segment.\n- **42 after fix:** After `ERROR: N broken upstream import(s)`, **re-run** `tasks/42_check_upstream_imports.sh` before treating imports as green.\n- **SKIP on green 41:** `SKIP` + exit **0** + `API drift check passed.` + no `MISMATCH` = pass. `SKIP` + non-zero exit or any `MISMATCH` = not green.\n- **42 noise:** `All upstream imports resolve correctly.` may be followed by `Broken imports detected.`—anchor on the **last full `42` block**: exit 0 + no `BROKEN` = pass. If ambiguous, re-run 42.\n- **SKIP when symbol absent:** Fix real imports/call sites per `/nonexistent/vllm-checkout`—no fake shims for drift only.\n- **First pass alignment:** Match `/nonexistent/vllm-checkout` early. If `41` prints `FORBIDDEN` imports, fix in the same drift pass.\n\nAfter edits, re-run **41** (zero `MISMATCH`) and **42** (zero `BROKEN`). ROCm/tokenizer/`TRANSFORMERS_CACHE` warnings are **noise** when checkers exit 0 green.\n\n**Phase 1 ops (not your concern unless blocked):** Wheel/install halts—read `vllm_install.log` end-to-end. **`Failed modules: none`** + wheel failure ⇒ no module wave. **Phase 1 merge:** `CONFLICT`, `Automatic merge failed` → orchestrator halted **before** Phase 2—not your failure. **Path sync:** `tasks/35_sync_module_paths.sh failed`, missing `path_sync_final_*.json` → mapping drift, not pytest failure.\n\n**Phase 1 complete ≠ Phase 2 done:** You must still finish verification and the completion contract.\n\n**Merge (your edits):** Resolve conflict markers **only** inside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`. No `git merge`/`git stash` for the rest of the tree.\n\n## API drift (blocking before broad pytest)\n`tasks/41_check_api_drift.sh` is **hard.** Any `MISMATCH` or non-zero exit → not green. Read output end-to-end; confirm on the **latest** full run after each fix. Open `api_drift_check.md` (or logged report) and fix **every** listed mismatch.\n\nTypical fixes vs `/nonexistent/vllm-checkout`: `StageEngineCoreClient.shutdown` kwargs; `launch_core_engines` unpack/return-shape at the real omni↔upstream boundary. **`SKIP launch_core_engines unpack-check`** when the file does not inline `launch_core_engines` is fine on exit 0—no fake unpack.\n\n**Infra:** `BROKEN`/`MISMATCH` followed by `tmux: command not found`—fix cited code first; `tmux` missing is environment. **`ImportError` from `/nonexistent/vllm-checkout/vllm/_C.abi3.so` with `undefined symbol`** → stale/incompatible binary—reinstall from `/nonexistent/vllm-checkout` (e.g. `VLLM_USE_PRECOMPILED=1 uv pip install -e .`). Never edit upstream source. Bad wheel index: same triage via `vllm_install.log` + `platform_tag`.\n\n## Inputs\n### Module prompt source\n\n\n### Adaptive runbook\n(No adaptive rules yet.)\n\nUse the `search_debug_memory` tool to query past fixes. Do NOT read the debug_memory.md file directly.\n\n### Debug-memory workflow (mandatory)\nCross-run lessons at `/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/memory/debug_memory.md` (pre-filtered for module=`model_config`). When a verification step fails or a non-trivial decision is made:\n\n1. **Read** the block above first; apply any matching past fix. Extend search:\n python3 'Use `search_debug_memory` tool instead of CLI.' search --module=model_config --limit=5 \"\"\n2. **Record** BEFORE writing `/fixed/signals/module.model_config.done` or `.fail`:\n python3 'Use `search_debug_memory` tool instead of CLI.' record \\\n --module=model_config \\\n --key=\"\" \\\n --tags= --files= --run=run-golden \\\n --body-file=/tmp/debug_memory_entry.md\n Body: `### Symptom` / `### Root cause` / `### Fix` / `### Watch-outs`.\n For `.fail`, add `tags: dead-end` with what you tried and why.\n\n## Pre-diagnosed: Upstream architectural changes (Phase 1 detected)\n\nThese imports/functions were CHANGED or REMOVED by upstream vLLM commits.\nThe diff excerpts show what changed — do a proper port matching the new API.\nDo NOT create no-op stubs or compat shims.\n\n### x.py: `gone`\n**Removed/moved from**: `vllm.old.mod`\n**Commit**: `deadbee` moved it\n**Diff excerpt**:\n```diff\n-old\n+new\n```\n**All affected call sites** (must be updated):\n - `x.py:10`\n\n\n## Tests you must pass\n\n### From Buildkite CI (must pass)\n- `slug_a`\n\n### Upstream test changes (compare with origin/main)\n- **RENAMED**: `tests/a.py` → `tests/b.py`\n\n\n### Relevant upstream commits\n(no relevant commits)\n\nIf `(no relevant commits)` is empty while notes imply commits: do not invent churn—flag misalignment. Preserve **cross-path** wiring when commits span executor, reasoning, tool parsers, `transformers_utils`, etc.\n\n### vllm-omni files to update\nvllm_omni/config/model.py vllm_omni/engine/arg_utils.py\n\n### Reference sources\n- Upstream vLLM target branch: /nonexistent/vllm-checkout\n Key paths: vllm/config/ vllm/engine/arg_utils.py\n- vllm-omni baseline intent:\n `git show origin/main:` in /nonexistent/omni-checkout\n\n## Hard rules\n1. Edit only under /nonexistent/omni-checkout. Never modify /nonexistent/vllm-checkout.\n2. **Temporary files**: Create all helper scripts and scratch artifacts under `\\${AGENT_TMP}` (outside the repos). Never create temp files in `/nonexistent/omni-checkout` or `/nonexistent/vllm-checkout`.\n3. Use only env from this prompt: `CUDA_VISIBLE_DEVICES=0,1`, `HF_HOME=/model`. Ignore stale values in module prompt source.\n4. Preserve omni-specific behavior from `origin/main` while adapting to upstream APIs.\n5. Do not change copyright/license headers or license files.\n6. Execute only valid shell commands. Never run bare narrative tokens (example: `Resume`).\n7. **Never ask the user a question or wait for human input.**\n\n## Orchestrator / CI signals\nOn its own line (parser-friendly):\n`MODULE=model_config`\n\n**CI → module:** `Cannot map CI test`, unmapped jobs, `Pipeline tests could not be fully resolved` → routing/remote pipeline resolution—report exact job string + last error line + `MODULE=model_config`; do not burn `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` if no `FAILED`/`MISMATCH`/`BROKEN` tied to your edits.\n\n**Unmapped debug dispatch:** `No CI→module mapping`, `DEBUG DISPATCHED` → use downloaded job logs under the run's `buildkite/`; triage from that artifact.\n\n**CI debug commit chain:** `ERROR: 0 CI failure(s) remain unresolved.` + fixes exist ≠ git commit succeeded. `Failed to commit CI debug fixes` or `No fixes to push` = pre-commit/lint blocker—fix Ruff/format on touched files.\n\n**Phase 3 \"could not be fully resolved\":** Two subtypes:\n- **Stall (no pytest body):** `ERROR:` immediate after `Running [k/N]:` without captured `FAILED`/`ERROR: FAILED: …` → pipeline/remote resolution stall. Reply + `MODULE=model_config`; do **not** mass-rewrite omni.\n- **Unresolved failures:** Jobs completed but slug list shows unresolved failures. The slug enumeration after `ERROR: CI pipeline finished with N hard failure(s):` is authoritative. Find failure traceback in `tests/_.log`.\n- **With debug wait:** `Sent message to agent session` + `Waiting for module agent` → debug-response stall.\n- **Resume/restart gaps:** `RESUME-SKIP [k/N]: ` = already passed. Anchor on latest Phase 3 block.\n- **Broken jobs (`state=broken`):** Cannot be retried. Escalate directly to debug.\n\n`CI_TESTS_KEEP_GOING_ON_FAIL=1`: Later passing run for the same test does **not** erase the earlier failure. The terminal slug enumeration after `ERROR: CI pipeline finished with N hard failure(s):` is the authoritative failure set. `Sending failure notification` / `Failure notification email sent.` / `Running post-run self-refinement` are cleanup steps, not failure arcs.\n\n**Wave / aggregate failure:** `ERROR: Module rebase failed. Check signals for details.`—list `/fixed/signals/module.*.done` and `module.*.fail` to identify failing modules. When `failed >= 1`, cat each `.fail` file and report which modules failed and why.\n\n**Default ownership:** `tests/entrypoints/test_omni_entrypoints.py`, async entrypoints, online-serving → online_serving. GPU/diffusion/orchestrator tracebacks → model_executor or module in trace.\n\n**Pytest truth:** `ERROR: FAILED: (rc=…)`/`FAILED`/`ERROR` **override** `[watchdog] … CONTINUE` when `rc≠0`. `rc=143` SIGTERM; `rc=124` timeout; `rc=2` collection error.\n\n**Global timeout / stall:** `Build timed out` + frozen `Module progress` → parallel wave issue, not your `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`. Confirm your module wrote the completion marker.\n\n**Other signals to filter:**\n- `[MODEL DOWNLOAD]`, `IGNORE (gated model access / HF 401)`, remote container deps (`installing vllm-omni[dev]`) → infra noise unless pytest after recovery fails on your files.\n- `Debug SUPERVISOR: timeout waiting for repair agent` → repair agent timed out, not your module. Triage from test log.\n- Coverage retry (`Coverage plugin missing … retrying without --cov`) → authoritative outcome is the run **after** that retry.\n- `Timeout waiting for debug response from ` → last log lines + `MODULE=model_config`; hand off.\n- `plan-daemon` sed failure → non-critical housekeeping.\n- `Session ... no longer exists on disk; follow-up will start a fresh session` → Phase 2 sessions cleaned up before Phase 3; expected lifecycle. **Fresh session → re-read context** from test log—do not carry over prior session state.\n- Install (`Failed to uninstall … RECORD file` when completions pass) → ignore unless imports break.\n- uv cache lock → concurrency, not wheel issues.\n- Wheel URL mismatch in `Dockerfile.ci` → ops/config, report.\n- Post-green CI (`ECONNRESET`, push auth) → report exact line. Pre-commit: fix real Ruff/format in `/nonexistent/omni-checkout`.\n\n## Verification (must all pass)\n**Module pytest wrapper:** Every verification line uses `bash '…/run_module_pytest.sh' …`. **Do not replace with bare `pytest`.** It applies `test_watchdog.sh`, `TEST_TIMEOUT_SEC`, logs under `\\${LOG_DIR}/tests/module_*.log`, and shared GPU lock for **every** pytest line from Phase-2 sessions.\n\n**Long-running shell waits — avoid CLI auth-token expiry:** A single `shellToolCall` blocking idle for >~120 seconds crashes mid-run with `Invalid API key — Please run /login`. The wrapper retries but each retry restarts your session.\n- **Do not** issue `sleep 480 && tail …` to wait for long tests. Use `bash '…/run_module_pytest.sh' …` (has its own watchdog + log streaming).\n- For background tasks, prefer **short polled checks** (`for i in 1 2 3 …; do sleep 30; ; done`).\n- Cap per-call sleep at 60 s when waiting on a known-running pid; loop with status checks.\n- **Thinking stalls are equally dangerous.** Produce incremental output (file writes, short commands, debug memory entries) to maintain heartbeat visibility. Silent agents are timed out after 7200s with `No code changes from debug agents.`\n\nRun:\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' python -c 'from vllm_omni.config.model import OmniModelConfig; from vllm_omni.engine.arg_utils import OmniEngineArgs; print('OK')'\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' -vv -s tests/entrypoints/test_stage_utils.py\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' -vv -s tests/metrics/test_stats.py\n\nIf pytest fails `unrecognized arguments` on `--cov*` only, rerun **once** without `--cov*`; that result is authoritative.\n\nLint (omni): `ruff check` (and `ruff format` if used) on changed files; **E402** (imports not at top) blocks pre-commit—fix structure, not just silence.\n\n## Upstream import validation\nAfter edits, validate all `from vllm.*` imports in changed files **and** modules pytest/registry loads indirectly:\npython3 -c \"import ast, importlib, sys\nfor fpath in sys.argv[1:]:\n with open(fpath) as f: tree = ast.parse(f.read())\n for node in ast.walk(tree):\n if isinstance(node, ast.ImportFrom) and node.module and node.module.startswith('vllm.'):\n mod = importlib.import_module(node.module)\n for alias in node.names:\n assert hasattr(mod, alias.name), f'BROKEN: {fpath}:{node.lineno} from {node.module} import {alias.name}'\n print(f' OK {fpath}')\n\" \n\nIf broken, find the new symbol in /nonexistent/vllm-checkout and update omni. Same semantics as `tasks/42_check_upstream_imports.sh`.\n\n## Failure handling (up to 3 attempts)\n\n### MANDATORY: When a test fails, FIRST check origin/main baseline\n1. Call `git_show_test_baseline \"\"` — this shows how origin/main updated this test\n2. If origin/main CHANGED the test (new params, imports, assertions) → apply the SAME changes to omni\n3. If origin/main DELETED the test → check if omni still needs it\n4. If origin/main RENAMED/SPLIT the test → find the new file and port omni modifications there\n5. Only after aligning the test with origin/main, fix product code\n6. Do NOT change product code to make a stale test pass\n7. NEVER re-create or restore a test file that origin/main deleted or renamed\n just because the rebase harness (config.sh / a CI test command) still\n references the old path. Harness config is NOT ground truth: if a referenced\n test path no longer exists (pytest rc=4, \"file or directory not found\"), use\n the renamed `*_expansion.py`-style file and report the harness drift in your\n module summary — resurrecting deleted tests reintroduces retired code paths.\n\n### General debugging\n1. Read **full** traceback / `MISMATCH` / `BROKEN` (not watchdog-only).\n2. Classify: `unrecognized arguments` → setup. Ruff after green pytest → still blocking. Unmapped CI → mapping. **`41`/`MISMATCH`** → signature/unpack. **`42`/`BROKEN`** → import path/symbol vs `/nonexistent/vllm-checkout`.\n3. **Time check:** If > 5 minutes of wall-clock work (not test wait) on the same failure without progress, write a `.fail` with what you tried and stop. Do not repeat the same fix pattern.\n - **\"No code changes\" trap:** If root cause is infra/config/environment, not omni code, you must still produce output. Document what you checked and why no fix is possible. Silence wastes the debug round.\n4. Map failing omni call site ↔ upstream in `/nonexistent/vllm-checkout`; `git show origin/main` for intent.\n5. Minimal compatible fix in `/nonexistent/omni-checkout`.\n6. Re-run failing check, then full verification.\n7. Report: changed files, summary, latest results, `MODULE=model_config`.\n\nInfra (`rc=124`, GPU lock, OOM kill storms): one controlled retry with snapshot; then stop with traceback.\n\n**Dirty files from other modules:** ignore; never stash/revert/commit outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.\n\nMerge conflicts in your files: report paths, markers cleared, strategy—do not blame pytest until verification fails.\n\n## Killing hung tests\nNever `pgrep -f | kill` alone (broad pattern). Use:\n bash /data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/kill_test_tree.sh \"pytest.*\"\nor:\n bash /data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/kill_test_tree.sh --pid \n\n## Completion contract\nOn success, write exactly:\n`MODULE_DONE model_config`\nto:\n`/fixed/signals/module.model_config.done`\n\nIf you made **out-of-scope edits** (files outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` but inside `/nonexistent/omni-checkout`), append to the signal file these lines verbatim:\n\nOUT_OF_SCOPE_EDITS:\n- : \n\nIf tests still fail after 3, write a **detailed, self-contained** failure summary to:\n`/fixed/signals/module.model_config.fail`\nand stop. The orchestrator reads this file to diagnose failures, so include: (a) the failing command and exit code, (b) last 20 lines of traceback/error output, (c) out-of-scope edits attempted (if any), and (d) remaining root cause." + "content": "You are rebasing vllm-omni module `model_config`.\n\nGoal: make `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` compatible with upstream while preserving vllm-omni intent from `origin/main`.\n\n## CRITICAL: Plan-Review-Decision Gate (MANDATORY)\n\nThe `edit_file`, `run_pytest`, and `run_precommit` tools are LOCKED until you\ncomplete the plan-review-decision pipeline. You CANNOT edit code or run tests\nuntil you write a .decision.md file. Use `read_file`, `grep`, `run_shell`,\n`git_show_upstream`, `git_show_omni_main` for exploration.\n\n### YOUR FIRST TASK: Write plan files, then call `request_plan_review`\n\nStep 1 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\n (JSON: {\"version\":3,\"plan_id\":\"v0-XXXX\",\"intent\":\"...\",\"changes\":[...],\"verify\":[...],\"risks\":[...]})\n\nStep 1b — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md (full narrative)\n\nStep 2 — request_plan_review tool:\n plan_json_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\"\n plan_md_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md\"\n kind: \"rebase\"\n\nStep 3 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.decision.md (accept|partial|reject per critique)\n\nStep 4 — NOW edit_file, run_pytest, run_precommit are unlocked. Edit code.\n\nMax 2 revision rounds. If review fails, proceed anyway.\n\n## Environment\n- vLLM repo (read-only): /nonexistent/vllm-checkout (commit: )\n- vllm-omni repo (edit here only): /nonexistent/omni-checkout (commit: )\n- CUDA_VISIBLE_DEVICES=0,1\n- HF_HOME=/model\n\n### Execution mode: LOCAL\n\n## Execution flow\n1. **Plan first** (per contract above), then begin on `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.\n2. Run **41** (check API drift) + **42** (check upstream imports) before deep pytest. If 42 first shows broken imports, **fix then full 42 re-run** before long pytest.\n3. Triage the **first real** failure: traceback, `FAILED`, `MISMATCH`, `BROKEN`—not watchdog-only chatter.\n4. **Minimal patch** in `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` (+ omni tests/fixtures needed).\n5. Re-run **that** check first; prefer **targeted** pytest when the runbook allows.\n6. Full required verification.\n7. **No-op fail-fast:** if output unchanged across **two** consecutive repair attempts, stop.\n8. Repeated identical `TypeError` / ctor args on one stack → **one** kwargs/wiring fix, then re-verify.\n\n**Engine / unpack:** Fix return-shape, kwargs, ordering at the real omni engine boundary; keep `shutdown` kwargs in sync with upstream.\n\n**Diffusion / subprocess:** `StageDiffusionProc died during handshake` → full worker traceback; handshake/init vs OOM; one controlled retry if GPU contention is plausible.\n\n**CUDA OOM with foreign PIDs:** resource contention—document; do not spend all `3` on identical code tweaks if GPU picture unchanged.\n\n**Attempt history:** attempt 0 noisy, attempt 1 **PASSED** → do not over-fit attempt 0.\n\n**Two pytest lines in one step:** map `FAILED` to the command whose stderr failed.\n\n**Registry / dynamic imports:** align every runtime entry (e.g. `registry.py`) with `/nonexistent/vllm-checkout`.\n\n**Phase 3 debug:** reply with traceback + `MODULE=model_config` + owning area.\n\n**CPU/merge pipeline:** optional-dep `ModuleNotFoundError`, bad LoRA `HTTPException`/400—fix deps/fixtures in `/nonexistent/omni-checkout`.\n\n## Parallel execution (Phase 2)\nOther module agents edit `/nonexistent/omni-checkout` concurrently.\n\n1. Dirty `git status` outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` is **expected**—ignore it.\n2. Never `git stash`, `git checkout`, or `git clean` paths outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` (you would destroy other agents' work).\n3. Do not ask the user to clean the workspace or wait for other modules.\n4. `tasks/01_guard_branch_clean.sh` already ran in Phase 1; do not re-verify globally.\n\n**Primary scope = `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.** Repeated `Module progress: (k done, f failed, s skipped) (k/M)` with the **same tuple** = **plateau** (heartbeat), not new failures. A tuple change then `ERROR: Module rebase failed` **without** `Timeout waiting for modules` = aggregate wave outcome—check signals.\n\n**All-fail-in-one-poll:** `(0,0,0)` → `(0,N,0)` with all modules failing in the same tick is likely **systemic** (shared config, common import, env var, tmux failure). Check shared infrastructure first. **Single-module waves:** same systemic check before blaming your code.\n\n**Straggler avoidance:** Finish checks and write the completion contract promptly. In **single-module waves** (no parallel modules), the orchestrator waits only for you—write your verdict as soon as final.\n\n**Orchestrator restart/resume:** `Skipping (already done)` = incremental relaunch. Do not assume all agents restart together.\n\n### Shared log hygiene\nAnchor on the **current run**—match `Resuming run: rebase-* (phase: …)` for **this** session. `[claude_auth]` / `API key probe OK` is CLI init—**not** a module failure. Repeated `Using level-1 agent model:` banners are **noise**—diagnose from `ERROR:` / phase banners / task names. Git boilerplate (`detached HEAD`, `git switch -c`) is scaffold—not merge outcome unless paired with conflict/error lines. `SSH fetch failed; retrying via HTTPS token auth` followed by HTTPS success is normal infrastructure fallback—**not** a module failure.\n\n### Autonomous scope extension\nFully unattended—**never** ask for guidance, confirmation, permission, or numbered options. Decide and act.\n\n**Plan review timeout:** If `## CRITICAL: Plan-Review-Decision Gate (MANDATORY)\n\nThe `edit_file`, `run_pytest`, and `run_precommit` tools are LOCKED until you\ncomplete the plan-review-decision pipeline. You CANNOT edit code or run tests\nuntil you write a .decision.md file. Use `read_file`, `grep`, `run_shell`,\n`git_show_upstream`, `git_show_omni_main` for exploration.\n\n### YOUR FIRST TASK: Write plan files, then call `request_plan_review`\n\nStep 1 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\n (JSON: {\"version\":3,\"plan_id\":\"v0-XXXX\",\"intent\":\"...\",\"changes\":[...],\"verify\":[...],\"risks\":[...]})\n\nStep 1b — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md (full narrative)\n\nStep 2 — request_plan_review tool:\n plan_json_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.json\"\n plan_md_path: \"/fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.md\"\n kind: \"rebase\"\n\nStep 3 — write_file → /fixed/logdir/plans/module-model_config/dispatch_initial/plan-v0-XXXX.decision.md (accept|partial|reject per critique)\n\nStep 4 — NOW edit_file, run_pytest, run_precommit are unlocked. Edit code.\n\nMax 2 revision rounds. If review fails, proceed anyway.` triggers a plan-and-review protocol that times out (no `.review_done` within the allotted wait), proceed with your plan. Do not treat review timeout as a module failure.\n\nIf a **required verification** fails and root cause is under `/nonexistent/omni-checkout` but outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`:\n1. **Follow the root cause**—minimal targeted fixes anywhere under `/nonexistent/omni-checkout`.\n2. Keep fixes **small**—align with `/nonexistent/vllm-checkout`; no unrelated refactors.\n3. **Document** every out-of-scope edit in the completion contract.\n4. Prefer **additive** changes if another agent may touch the same file.\n5. After **two** failed attempts on that out-of-scope fix, **stop** and write `.fail` with traceback.\n\n## Evaluation gates\n**Truth = the latest checker output: exit code, final banner, every `MISMATCH`/`BROKEN`.** Ignore fix-agent tmux chatter and lines like `Import fix agent reported success` until a **full** `41`/`42` run after that path confirms (exit 0, zero `MISMATCH`/`BROKEN`).\n\n- **Chronology:** Anchor on the **latest** full run. Old failures are void after a later run exits 0 with no `MISMATCH`/`BROKEN`.\n- **Success-before-failure:** Earlier green `41`/`42`/install lines before a later `ERROR:` still stand—do not blame install/Dockerfile unless that step also shows failure in the **same** segment.\n- **42 after fix:** After `ERROR: N broken upstream import(s)`, **re-run** `tasks/42_check_upstream_imports.sh` before treating imports as green.\n- **SKIP on green 41:** `SKIP` + exit **0** + `API drift check passed.` + no `MISMATCH` = pass. `SKIP` + non-zero exit or any `MISMATCH` = not green.\n- **42 noise:** `All upstream imports resolve correctly.` may be followed by `Broken imports detected.`—anchor on the **last full `42` block**: exit 0 + no `BROKEN` = pass. If ambiguous, re-run 42.\n- **SKIP when symbol absent:** Fix real imports/call sites per `/nonexistent/vllm-checkout`—no fake shims for drift only.\n- **First pass alignment:** Match `/nonexistent/vllm-checkout` early. If `41` prints `FORBIDDEN` imports, fix in the same drift pass.\n\nAfter edits, re-run **41** (zero `MISMATCH`) and **42** (zero `BROKEN`). ROCm/tokenizer/`TRANSFORMERS_CACHE` warnings are **noise** when checkers exit 0 green.\n\n**Phase 1 ops (not your concern unless blocked):** Wheel/install halts—read `vllm_install.log` end-to-end. **`Failed modules: none`** + wheel failure ⇒ no module wave. **Phase 1 merge:** `CONFLICT`, `Automatic merge failed` → orchestrator halted **before** Phase 2—not your failure. **Path sync:** `tasks/35_sync_module_paths.sh failed`, missing `path_sync_final_*.json` → mapping drift, not pytest failure.\n\n**Phase 1 complete ≠ Phase 2 done:** You must still finish verification and the completion contract.\n\n**Merge (your edits):** Resolve conflict markers **only** inside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`. No `git merge`/`git stash` for the rest of the tree.\n\n## API drift (blocking before broad pytest)\n`tasks/41_check_api_drift.sh` is **hard.** Any `MISMATCH` or non-zero exit → not green. Read output end-to-end; confirm on the **latest** full run after each fix. Open `api_drift_check.md` (or logged report) and fix **every** listed mismatch.\n\nTypical fixes vs `/nonexistent/vllm-checkout`: `StageEngineCoreClient.shutdown` kwargs; `launch_core_engines` unpack/return-shape at the real omni↔upstream boundary. **`SKIP launch_core_engines unpack-check`** when the file does not inline `launch_core_engines` is fine on exit 0—no fake unpack.\n\n**Infra:** `BROKEN`/`MISMATCH` followed by `tmux: command not found`—fix cited code first; `tmux` missing is environment. **`ImportError` from `/nonexistent/vllm-checkout/vllm/_C.abi3.so` with `undefined symbol`** → stale/incompatible binary—reinstall from `/nonexistent/vllm-checkout` (e.g. `VLLM_USE_PRECOMPILED=1 uv pip install -e .`). Never edit upstream source. Bad wheel index: same triage via `vllm_install.log` + `platform_tag`.\n\n## Inputs\n### Module prompt source\n\n\n### Adaptive runbook\n**Knowledge base.** Before exploring an unfamiliar component, model or CI\nbehaviour with shell, run `doc_search` with the component/model/symbol name\nand `doc_read` the best match by its reported path. A curated page often\nstates design intent or the owning component outright, which grep cannot\ntell you. This is documented design; `search_debug_memory` is incident\nhistory — consult both. Cite the page path in your plan when it informed a\ndecision. If a page and the code disagree, the CODE is authoritative for\nthis rebase: say so in your decision file rather than editing to match.\n\nUse the `search_debug_memory` tool to query past fixes. Do NOT read the debug_memory.md file directly.\n\n### Debug-memory workflow (mandatory)\nCross-run lessons at `/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/memory/debug_memory.md` (pre-filtered for module=`model_config`). When a verification step fails or a non-trivial decision is made:\n\n1. **Read** the block above first; apply any matching past fix. Extend search:\n python3 'Use `search_debug_memory` tool instead of CLI.' search --module=model_config --limit=5 \"\"\n2. **Record** BEFORE writing `/fixed/signals/module.model_config.done` or `.fail`:\n python3 'Use `search_debug_memory` tool instead of CLI.' record \\\n --module=model_config \\\n --key=\"\" \\\n --tags= --files= --run=run-golden \\\n --body-file=/tmp/debug_memory_entry.md\n Body: `### Symptom` / `### Root cause` / `### Fix` / `### Watch-outs`.\n For `.fail`, add `tags: dead-end` with what you tried and why.\n\n## Pre-diagnosed: Upstream architectural changes (Phase 1 detected)\n\nThese imports/functions were CHANGED or REMOVED by upstream vLLM commits.\nThe diff excerpts show what changed — do a proper port matching the new API.\nDo NOT create no-op stubs or compat shims.\n\n### x.py: `gone`\n**Removed/moved from**: `vllm.old.mod`\n**Commit**: `deadbee` moved it\n**Diff excerpt**:\n```diff\n-old\n+new\n```\n**All affected call sites** (must be updated):\n - `x.py:10`\n\n\n## Tests you must pass\n\n### From Buildkite CI (must pass)\n- `slug_a`\n\n### Upstream test changes (compare with origin/main)\n- **RENAMED**: `tests/a.py` → `tests/b.py`\n\n\n### Relevant upstream commits\n(no relevant commits)\n\nIf `(no relevant commits)` is empty while notes imply commits: do not invent churn—flag misalignment. Preserve **cross-path** wiring when commits span executor, reasoning, tool parsers, `transformers_utils`, etc.\n\n### vllm-omni files to update\nvllm_omni/config/model.py vllm_omni/engine/arg_utils.py\n\n### Reference sources\n- Upstream vLLM target branch: /nonexistent/vllm-checkout\n Key paths: vllm/config/ vllm/engine/arg_utils.py\n- vllm-omni baseline intent:\n `git show origin/main:` in /nonexistent/omni-checkout\n\n## Hard rules\n1. Edit only under /nonexistent/omni-checkout. Never modify /nonexistent/vllm-checkout.\n2. **Temporary files**: Create all helper scripts and scratch artifacts under `\\${AGENT_TMP}` (outside the repos). Never create temp files in `/nonexistent/omni-checkout` or `/nonexistent/vllm-checkout`.\n3. Use only env from this prompt: `CUDA_VISIBLE_DEVICES=0,1`, `HF_HOME=/model`. Ignore stale values in module prompt source.\n4. Preserve omni-specific behavior from `origin/main` while adapting to upstream APIs.\n5. Do not change copyright/license headers or license files.\n6. Execute only valid shell commands. Never run bare narrative tokens (example: `Resume`).\n7. **Never ask the user a question or wait for human input.**\n\n## Orchestrator / CI signals\nOn its own line (parser-friendly):\n`MODULE=model_config`\n\n**CI → module:** `Cannot map CI test`, unmapped jobs, `Pipeline tests could not be fully resolved` → routing/remote pipeline resolution—report exact job string + last error line + `MODULE=model_config`; do not burn `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` if no `FAILED`/`MISMATCH`/`BROKEN` tied to your edits.\n\n**Unmapped debug dispatch:** `No CI→module mapping`, `DEBUG DISPATCHED` → use downloaded job logs under the run's `buildkite/`; triage from that artifact.\n\n**CI debug commit chain:** `ERROR: 0 CI failure(s) remain unresolved.` + fixes exist ≠ git commit succeeded. `Failed to commit CI debug fixes` or `No fixes to push` = pre-commit/lint blocker—fix Ruff/format on touched files.\n\n**Phase 3 \"could not be fully resolved\":** Two subtypes:\n- **Stall (no pytest body):** `ERROR:` immediate after `Running [k/N]:` without captured `FAILED`/`ERROR: FAILED: …` → pipeline/remote resolution stall. Reply + `MODULE=model_config`; do **not** mass-rewrite omni.\n- **Unresolved failures:** Jobs completed but slug list shows unresolved failures. The slug enumeration after `ERROR: CI pipeline finished with N hard failure(s):` is authoritative. Find failure traceback in `tests/_.log`.\n- **With debug wait:** `Sent message to agent session` + `Waiting for module agent` → debug-response stall.\n- **Resume/restart gaps:** `RESUME-SKIP [k/N]: ` = already passed. Anchor on latest Phase 3 block.\n- **Broken jobs (`state=broken`):** Cannot be retried. Escalate directly to debug.\n\n`CI_TESTS_KEEP_GOING_ON_FAIL=1`: Later passing run for the same test does **not** erase the earlier failure. The terminal slug enumeration after `ERROR: CI pipeline finished with N hard failure(s):` is the authoritative failure set. `Sending failure notification` / `Failure notification email sent.` / `Running post-run self-refinement` are cleanup steps, not failure arcs.\n\n**Wave / aggregate failure:** `ERROR: Module rebase failed. Check signals for details.`—list `/fixed/signals/module.*.done` and `module.*.fail` to identify failing modules. When `failed >= 1`, cat each `.fail` file and report which modules failed and why.\n\n**Default ownership:** `tests/entrypoints/test_omni_entrypoints.py`, async entrypoints, online-serving → online_serving. GPU/diffusion/orchestrator tracebacks → model_executor or module in trace.\n\n**Pytest truth:** `ERROR: FAILED: (rc=…)`/`FAILED`/`ERROR` **override** `[watchdog] … CONTINUE` when `rc≠0`. `rc=143` SIGTERM; `rc=124` timeout; `rc=2` collection error.\n\n**Global timeout / stall:** `Build timed out` + frozen `Module progress` → parallel wave issue, not your `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`. Confirm your module wrote the completion marker.\n\n**Other signals to filter:**\n- `[MODEL DOWNLOAD]`, `IGNORE (gated model access / HF 401)`, remote container deps (`installing vllm-omni[dev]`) → infra noise unless pytest after recovery fails on your files.\n- `Debug SUPERVISOR: timeout waiting for repair agent` → repair agent timed out, not your module. Triage from test log.\n- Coverage retry (`Coverage plugin missing … retrying without --cov`) → authoritative outcome is the run **after** that retry.\n- `Timeout waiting for debug response from ` → last log lines + `MODULE=model_config`; hand off.\n- `plan-daemon` sed failure → non-critical housekeeping.\n- `Session ... no longer exists on disk; follow-up will start a fresh session` → Phase 2 sessions cleaned up before Phase 3; expected lifecycle. **Fresh session → re-read context** from test log—do not carry over prior session state.\n- Install (`Failed to uninstall … RECORD file` when completions pass) → ignore unless imports break.\n- uv cache lock → concurrency, not wheel issues.\n- Wheel URL mismatch in `Dockerfile.ci` → ops/config, report.\n- Post-green CI (`ECONNRESET`, push auth) → report exact line. Pre-commit: fix real Ruff/format in `/nonexistent/omni-checkout`.\n\n## Verification (must all pass)\n**Module pytest wrapper:** Every verification line uses `bash '…/run_module_pytest.sh' …`. **Do not replace with bare `pytest`.** It applies `test_watchdog.sh`, `TEST_TIMEOUT_SEC`, logs under `\\${LOG_DIR}/tests/module_*.log`, and shared GPU lock for **every** pytest line from Phase-2 sessions.\n\n**Long-running shell waits — avoid CLI auth-token expiry:** A single `shellToolCall` blocking idle for >~120 seconds crashes mid-run with `Invalid API key — Please run /login`. The wrapper retries but each retry restarts your session.\n- **Do not** issue `sleep 480 && tail …` to wait for long tests. Use `bash '…/run_module_pytest.sh' …` (has its own watchdog + log streaming).\n- For background tasks, prefer **short polled checks** (`for i in 1 2 3 …; do sleep 30; ; done`).\n- Cap per-call sleep at 60 s when waiting on a known-running pid; loop with status checks.\n- **Thinking stalls are equally dangerous.** Produce incremental output (file writes, short commands, debug memory entries) to maintain heartbeat visibility. Silent agents are timed out after 7200s with `No code changes from debug agents.`\n\nRun:\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' python -c 'from vllm_omni.config.model import OmniModelConfig; from vllm_omni.engine.arg_utils import OmniEngineArgs; print('OK')'\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' -vv -s tests/entrypoints/test_stage_utils.py\nbash '/data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/run_module_pytest.sh' -vv -s tests/metrics/test_stats.py\n\nIf pytest fails `unrecognized arguments` on `--cov*` only, rerun **once** without `--cov*`; that result is authoritative.\n\nLint (omni): `ruff check` (and `ruff format` if used) on changed files; **E402** (imports not at top) blocks pre-commit—fix structure, not just silence.\n\n## Upstream import validation\nAfter edits, validate all `from vllm.*` imports in changed files **and** modules pytest/registry loads indirectly:\npython3 -c \"import ast, importlib, sys\nfor fpath in sys.argv[1:]:\n with open(fpath) as f: tree = ast.parse(f.read())\n for node in ast.walk(tree):\n if isinstance(node, ast.ImportFrom) and node.module and node.module.startswith('vllm.'):\n mod = importlib.import_module(node.module)\n for alias in node.names:\n assert hasattr(mod, alias.name), f'BROKEN: {fpath}:{node.lineno} from {node.module} import {alias.name}'\n print(f' OK {fpath}')\n\" \n\nIf broken, find the new symbol in /nonexistent/vllm-checkout and update omni. Same semantics as `tasks/42_check_upstream_imports.sh`.\n\n## Failure handling (up to 3 attempts)\n\n### MANDATORY: When a test fails, FIRST check origin/main baseline\n1. Call `git_show_test_baseline \"\"` — this shows how origin/main updated this test\n2. If origin/main CHANGED the test (new params, imports, assertions) → apply the SAME changes to omni\n3. If origin/main DELETED the test → check if omni still needs it\n4. If origin/main RENAMED/SPLIT the test → find the new file and port omni modifications there\n5. Only after aligning the test with origin/main, fix product code\n6. Do NOT change product code to make a stale test pass\n7. NEVER re-create or restore a test file that origin/main deleted or renamed\n just because the rebase harness (config.sh / a CI test command) still\n references the old path. Harness config is NOT ground truth: if a referenced\n test path no longer exists (pytest rc=4, \"file or directory not found\"), use\n the renamed `*_expansion.py`-style file and report the harness drift in your\n module summary — resurrecting deleted tests reintroduces retired code paths.\n\n### General debugging\n1. Read **full** traceback / `MISMATCH` / `BROKEN` (not watchdog-only).\n2. Classify: `unrecognized arguments` → setup. Ruff after green pytest → still blocking. Unmapped CI → mapping. **`41`/`MISMATCH`** → signature/unpack. **`42`/`BROKEN`** → import path/symbol vs `/nonexistent/vllm-checkout`.\n3. **Time check:** If > 5 minutes of wall-clock work (not test wait) on the same failure without progress, write a `.fail` with what you tried and stop. Do not repeat the same fix pattern.\n - **\"No code changes\" trap:** If root cause is infra/config/environment, not omni code, you must still produce output. Document what you checked and why no fix is possible. Silence wastes the debug round.\n4. Map failing omni call site ↔ upstream in `/nonexistent/vllm-checkout`; `git show origin/main` for intent.\n5. Minimal compatible fix in `/nonexistent/omni-checkout`.\n6. Re-run failing check, then full verification.\n7. Report: changed files, summary, latest results, `MODULE=model_config`.\n\nInfra (`rc=124`, GPU lock, OOM kill storms): one controlled retry with snapshot; then stop with traceback.\n\n**Dirty files from other modules:** ignore; never stash/revert/commit outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py`.\n\nMerge conflicts in your files: report paths, markers cleared, strategy—do not blame pytest until verification fails.\n\n## Killing hung tests\nNever `pgrep -f | kill` alone (broad pattern). Use:\n bash /data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/kill_test_tree.sh \"pytest.*\"\nor:\n bash /data/zhoutaichang/copilot/vllm-omni-rebase-agent/agent/lib/kill_test_tree.sh --pid \n\n## Completion contract\nOn success, write exactly:\n`MODULE_DONE model_config`\nto:\n`/fixed/signals/module.model_config.done`\n\nIf you made **out-of-scope edits** (files outside `vllm_omni/config/model.py vllm_omni/engine/arg_utils.py` but inside `/nonexistent/omni-checkout`), append to the signal file these lines verbatim:\n\nOUT_OF_SCOPE_EDITS:\n- : \n\nIf tests still fail after 3, write a **detailed, self-contained** failure summary to:\n`/fixed/signals/module.model_config.fail`\nand stop. The orchestrator reads this file to diagnose failures, so include: (a) the failing command and exit code, (b) last 20 lines of traceback/error output, (c) out-of-scope edits attempted (if any), and (d) remaining root cause." } ] } \ No newline at end of file diff --git a/test/test_adapter_knowledge.py b/test/test_adapter_knowledge.py index d8eb989b..5aaf9225 100644 --- a/test/test_adapter_knowledge.py +++ b/test/test_adapter_knowledge.py @@ -58,9 +58,18 @@ def prompt_data() -> ModulePromptData: @pytest.mark.parametrize("module", ["model_config", "worker_runner"]) def test_module_prompt_matches_parent_golden(prompt_data, module): - """Byte-identical render vs the PARENT builder's captured output (the - golden was generated by running agent/prompts/builder.py itself with the - same fixed inputs). Prompt bytes are prompt-cache load-bearing.""" + """Byte-identical render vs the stored golden. Prompt bytes are + prompt-cache load-bearing. + + NOTE (2026-09-18): these goldens no longer record the PARENT builder's + output. The parent agent had no access to the curated knowledge base, and + the owner asked for the rebase pipeline to consult it, so the render now + carries knowledge-base guidance in the ADAPTIVE_GUIDANCE slot and the tool + surface gained doc_search/doc_read. The goldens were deliberately + regenerated from THIS builder at that change. The shipped templates remain + byte-identical to the parent's — see test_templates_are_parent_verbatim, + which is why the guidance rides a builder-supplied token, not a template + edit.""" ours = build_module_prompt(module, prompt_data, **GOLDEN_KWARGS) golden = (GOLDENS / f"module_prompt_{module}.txt").read_text() assert ours == golden diff --git a/test/test_engine_core.py b/test/test_engine_core.py index d80f9d03..0e5879f6 100644 --- a/test/test_engine_core.py +++ b/test/test_engine_core.py @@ -189,6 +189,10 @@ def test_tool_schemas_load_in_parent_dispatcher_order(): "git_diff", "git_diff_tests_upstream", "request_plan_review", "search_debug_memory", "record_debug_memory", "skill_manage", "search_skills", + # appended AFTER the parent's 20 (2026-09-18): the knowledge-base + # tools the parent dispatcher never had. Parent order above is the + # intact prefix, so this still pins it. + "doc_search", "doc_read", ] with pytest.raises(ValueError, match="has no handler"): build_rebase_tools([{"name": "mystery", "description": "?", From 611f3139dff269544bd7fc02e7fa0dd1148d3d39 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Sat, 19 Sep 2026 00:30:18 +0800 Subject: [PATCH 2/2] doc(spec): re-verify rebase specs for the knowledge-base tools check_spec_freshness --strict flagged engine/steps/rebase_v3 and rebase_engine as STALE: their source changed after the specs were last verified (2026-09-06). Records what actually changed rather than only bumping the date: - rebase_engine: rebase_tools now carries the parent's 20 tools PLUS doc_search/doc_read, appended after the parent order. - rebase_v3: _build_backends wires those two over the same KnowledgeDocs view the review flows use, repo-scoped by the manifest's knowledge.repo_subdir. Co-Authored-By: Claude Opus 5 (1M context) --- doc/architecture/SPEC/engine/steps/rebase_v3.md | 4 ++-- doc/architecture/SPEC/rebase_engine.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/architecture/SPEC/engine/steps/rebase_v3.md b/doc/architecture/SPEC/engine/steps/rebase_v3.md index b1164da0..a5f66745 100644 --- a/doc/architecture/SPEC/engine/steps/rebase_v3.md +++ b/doc/architecture/SPEC/engine/steps/rebase_v3.md @@ -1,6 +1,6 @@ # engine/steps/rebase_v3.py —— 规范 - + `LOC ~2204 · step 库(v3 rebase 装配层) · refactor-status: oversized` @@ -26,7 +26,7 @@ step —— 薄的受治理 wrapper,substate-first、类型化失败、发布 ## 公开契约(注册的 step 之外) `_adapter_manifest/_substate/_task_params`(被 `rebase_knowledge` import)、 -`manifest_job_to_test_job`(golden 测试)、`_build_backends`(read-compat +`manifest_job_to_test_job`(golden 测试)、`_build_backends`(含 `doc_search`/`doc_read`:复用 review 流程同一套 `KnowledgeDocs` 视图,按 adapter manifest 的 `knowledge.repo_subdir` 限定仓库)(read-compat 测试)、`_make_ci_client`(模块级工厂,测试注入 fake 客户端)。 ## 不变量 diff --git a/doc/architecture/SPEC/rebase_engine.md b/doc/architecture/SPEC/rebase_engine.md index c59965e4..a16b4027 100644 --- a/doc/architecture/SPEC/rebase_engine.md +++ b/doc/architecture/SPEC/rebase_engine.md @@ -1,6 +1,6 @@ # rebase_engine/ —— 规范 - + `LOC ~7500(26 个模块) · repo-rebase-v3 的原生 rebase 引擎 · refactor-status: ok` @@ -35,7 +35,7 @@ | `push_gate.py` | 推送闸裁决:结构性 vs 断言失败的确定性分类(Rev 8 §2.3) | | `push_to_ci.py` | commit+push-to-CI 编排:preflight、WAL 卫生、C4 双闸、单一传输 | | `push_wal.py` | 推送 WAL:先落盘的 intent、精确 OID 三分对账、回滚数据 | -| `rebase_tools.py` | 父级 20 工具作为 `ToolDef`;未接线后端**可见地**失败 | +| `rebase_tools.py` | 父级 20 工具 + `doc_search`/`doc_read`(追加在父级顺序之后)作为 `ToolDef`;未接线后端**可见地**失败 | | `runctx.py` | `RebaseRuntime` + `CheckoutLock`(flock+卫生盾)+ 按事件循环的注册表 | | `substate.py` | 可持久、单写者、merge-not-overwrite 的 `state.json`(run_id 戳) | | `test_loop.py` | 本地测试环:逐测试恢复、baseline 复跑分流回归、类型化 skip |