wip: checkpoint 2026-03-29 runtime work
This commit is contained in:
482
docs/plans/2026-03-29-sgclaw-superrpa-decoupled-runtime-plan.md
Normal file
482
docs/plans/2026-03-29-sgclaw-superrpa-decoupled-runtime-plan.md
Normal file
@@ -0,0 +1,482 @@
|
||||
# sgClaw SuperRPA Decoupled Runtime Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Keep the SuperRPA parent-child security model, while moving high-frequency sgClaw startup, model, skill, and frontend presentation changes out of SuperRPA compile-time code and into runtime-managed configuration.
|
||||
|
||||
**Architecture:** SuperRPA remains the trusted host that owns process spawning, pipe security, browser/office capability gates, and frontend host contracts. sgClaw becomes the runtime-configured execution engine that reads launch/runtime policy from files, with SuperRPA preferring external launch descriptors and external frontend bundles before falling back to bundled defaults. This preserves the security boundary while removing the need to rebuild the browser for routine sgClaw iteration.
|
||||
|
||||
**Tech Stack:** Chromium C++ WebUI, TypeScript/Lit frontend, Rust sgClaw runtime, JSON config files, local filesystem-based runtime assets, existing pipe protocol and Zeroclaw planner-first execution path.
|
||||
|
||||
### Task 1: Freeze the design in docs before further code changes
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/L1-系统架构与安全模型层.md`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/L2-核心模块与接口契约层.md`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/L4-工程实现与部署拓扑层.md`
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/docs/plans/2026-03-29-sgclaw-superrpa-runtime-config-design.md`
|
||||
|
||||
**Step 1: Write the design delta doc**
|
||||
|
||||
Document these decisions explicitly:
|
||||
- SuperRPA owns host security and capability exposure only.
|
||||
- sgClaw owns planner, model routing, skill orchestration, and business behavior.
|
||||
- Launch behavior is described by runtime files, not hardcoded browser-side constants.
|
||||
- Frontend only has display rights; planner/executor decisions stay in sgClaw/Zeroclaw.
|
||||
|
||||
**Step 2: Add the failing doc checklist**
|
||||
|
||||
Create a checklist inside the design doc with these questions and mark them initially unresolved:
|
||||
- Can browser startup switch sgClaw binary without rebuilding Chromium?
|
||||
- Can model/provider selection change without rebuilding Chromium?
|
||||
- Can floating UI be replaced without rebuilding Chromium?
|
||||
- Can acceptance flows prove planner-first behavior visually and functionally?
|
||||
|
||||
**Step 3: Update the core architecture docs**
|
||||
|
||||
Add short sections showing:
|
||||
- Launch config file path and fallback rules.
|
||||
- Runtime config ownership split between SuperRPA and sgClaw.
|
||||
- External frontend bundle loading path and fallback to bundled assets.
|
||||
|
||||
**Step 4: Review docs for consistency**
|
||||
|
||||
Check that `L1`, `L2`, `L4`, and the new design doc all use the same terms:
|
||||
- `host`
|
||||
- `launch config`
|
||||
- `runtime config`
|
||||
- `frontend bundle`
|
||||
- `planner-first`
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/sgClaw/claw add \
|
||||
docs/L1-系统架构与安全模型层.md \
|
||||
docs/L2-核心模块与接口契约层.md \
|
||||
docs/L4-工程实现与部署拓扑层.md \
|
||||
docs/plans/2026-03-29-sgclaw-superrpa-runtime-config-design.md
|
||||
git -C /home/zyl/projects/sgClaw/claw commit -m "docs: define superrpa sgclaw runtime boundary"
|
||||
```
|
||||
|
||||
### Task 2: Finish and lock down the current stale-backend fix
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.h`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc`
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/tools/browser_runtime/sgclaw_browser_entry.sh`
|
||||
|
||||
**Step 1: Write the failing regression test**
|
||||
|
||||
Add internal tests for binary resolution priority:
|
||||
1. `SUPERRPA_SGCLAW_BINARY` override wins.
|
||||
2. `skillsDir`-inferred source checkout wrapper wins over bundled binary.
|
||||
3. Bundled `out/.../sgclaw` is only a fallback.
|
||||
|
||||
**Step 2: Run the failing test**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease functions_ui_mainline_unittests
|
||||
/home/zyl/projects/superRpa/src/out/KylinRelease/functions_ui_mainline_unittests --gtest_filter="SgClawSessionServiceInternalTest.*"
|
||||
```
|
||||
|
||||
Expected: the new test target fails before the final test helper wiring is complete.
|
||||
|
||||
**Step 3: Write the minimal implementation**
|
||||
|
||||
Expose a testable internal resolver function that accepts:
|
||||
- config path
|
||||
- bundled binary path
|
||||
- optional env override string
|
||||
- output detail string
|
||||
|
||||
Keep production `Start()` calling the same shared resolver to avoid divergence.
|
||||
|
||||
**Step 4: Run tests to verify they pass**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease functions_ui_mainline_unittests
|
||||
/home/zyl/projects/superRpa/src/out/KylinRelease/functions_ui_mainline_unittests --gtest_filter="SgClawSessionServiceInternalTest.*:FunctionsUiMainlineTest.StartPublishesDetailedRulesDiagnosticsToUiLogs"
|
||||
```
|
||||
|
||||
Expected: all targeted tests pass.
|
||||
|
||||
**Step 5: Run browser compile verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease chrome
|
||||
```
|
||||
|
||||
Expected: `LINK ./chrome` with exit code `0`.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/superRpa/src add \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_session_service.h \
|
||||
chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc
|
||||
git -C /home/zyl/projects/sgClaw/claw add \
|
||||
tools/browser_runtime/sgclaw_browser_entry.sh
|
||||
git -C /home/zyl/projects/superRpa/src commit -m "superrpa: resolve sgclaw binary from runtime config"
|
||||
```
|
||||
|
||||
### Task 3: Add a real launch descriptor so SuperRPA no longer hardcodes sgClaw startup policy
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_webui_config.h`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_webui_config.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config_state.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config_mainline_unittest.ts`
|
||||
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_launch_config.h`
|
||||
- Create: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_launch_config.cc`
|
||||
- Test: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc`
|
||||
|
||||
**Step 1: Write the failing config tests**
|
||||
|
||||
Cover:
|
||||
- missing launch config falls back safely
|
||||
- explicit `binary`, `args`, `env`, `working_dir`, `runtime_config_path` parse correctly
|
||||
- unsafe or nonexistent paths are rejected with clear UI-visible errors
|
||||
|
||||
**Step 2: Run the failing tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease functions_ui_mainline_unittests
|
||||
/home/zyl/projects/superRpa/src/out/KylinRelease/functions_ui_mainline_unittests --gtest_filter="*SgClaw*Config*"
|
||||
```
|
||||
|
||||
Expected: launch-config cases fail before parser/consumer code is added.
|
||||
|
||||
**Step 3: Implement minimal launch config support**
|
||||
|
||||
Define a host-side launch descriptor with fields:
|
||||
- `binary`
|
||||
- `args`
|
||||
- `env`
|
||||
- `working_dir`
|
||||
- `runtime_config_path`
|
||||
- `frontend_bundle_dir`
|
||||
|
||||
Load it from a predictable profile-local path, with safe defaults and fallback to existing behavior.
|
||||
|
||||
**Step 4: Wire startup to the descriptor**
|
||||
|
||||
Have `SgClawSessionService::Start()` resolve:
|
||||
- executable path
|
||||
- process args
|
||||
- working dir
|
||||
- env
|
||||
- runtime config path
|
||||
|
||||
without requiring browser recompilation for routine changes.
|
||||
|
||||
**Step 5: Wire config UI to persist supported fields**
|
||||
|
||||
Make `sgclaw-config` save and load the new fields so local users can adjust launch behavior from the UI or by editing the JSON file directly.
|
||||
|
||||
**Step 6: Run tests and browser compile**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease functions_ui_mainline_unittests chrome
|
||||
```
|
||||
|
||||
Expected: config tests pass and browser still links.
|
||||
|
||||
**Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/superRpa/src add \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_launch_config.h \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_launch_config.cc \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_webui_config.h \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_webui_config.cc \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc \
|
||||
chrome/browser/ui/webui/superrpa/functions_ui.cc \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config.ts \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config_state.ts \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-config/sgclaw-config_mainline_unittest.ts
|
||||
git -C /home/zyl/projects/superRpa/src commit -m "superrpa: add runtime launch config for sgclaw"
|
||||
```
|
||||
|
||||
### Task 4: Expand sgClaw runtime config so model/provider/skill policy live in sgClaw, not SuperRPA
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/config/settings.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/config/mod.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/config_adapter.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/agent/runtime.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/agent/planner.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_config_test.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/runtime_profile_test.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/planner_test.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/L3-数据流与Skill体系层.md`
|
||||
|
||||
**Step 1: Write failing Rust tests**
|
||||
|
||||
Cover config-driven behavior for:
|
||||
- planner-first mode
|
||||
- provider list / active provider
|
||||
- browser backend selection
|
||||
- office backend selection
|
||||
- skills prompt mode
|
||||
- runtime profile
|
||||
|
||||
**Step 2: Run the failing tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cargo test compat_config_test runtime_profile_test planner_test --manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml
|
||||
```
|
||||
|
||||
Expected: new config fields are missing or ignored.
|
||||
|
||||
**Step 3: Implement minimal config schema changes**
|
||||
|
||||
Add fields that let sgClaw choose behavior without host rebuild:
|
||||
- `planner_mode`
|
||||
- `providers`
|
||||
- `active_provider`
|
||||
- `browser_backend`
|
||||
- `office_backend`
|
||||
- `skills_prompt_mode`
|
||||
- `runtime_profile`
|
||||
|
||||
**Step 4: Keep Zeroclaw-first execution**
|
||||
|
||||
Ensure the planner reads config before execution and produces a visible plan event for the frontend, but the frontend still only renders what sgClaw emits.
|
||||
|
||||
**Step 5: Re-run Rust tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cargo test --manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml compat_config_test runtime_profile_test planner_test runtime_task_flow_test
|
||||
```
|
||||
|
||||
Expected: planner/config tests pass.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/sgClaw/claw add \
|
||||
src/config/settings.rs \
|
||||
src/config/mod.rs \
|
||||
src/compat/config_adapter.rs \
|
||||
src/agent/runtime.rs \
|
||||
src/agent/planner.rs \
|
||||
tests/compat_config_test.rs \
|
||||
tests/runtime_profile_test.rs \
|
||||
tests/planner_test.rs \
|
||||
docs/L3-数据流与Skill体系层.md
|
||||
git -C /home/zyl/projects/sgClaw/claw commit -m "sgclaw: move runtime policy into config"
|
||||
```
|
||||
|
||||
### Task 5: Decouple the floating UI so visual iteration stops depending on Chromium rebuilds
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_state.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_mainline_unittest.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/frontend/runtime-host/README.md`
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/frontend/runtime-host/manifest.example.json`
|
||||
|
||||
**Step 1: Write failing UI host tests**
|
||||
|
||||
Cover:
|
||||
- external frontend bundle dir is preferred when declared in launch config
|
||||
- bundled frontend assets still load when external assets are absent
|
||||
- planner events are rendered as plan cards/log lines before execution
|
||||
|
||||
**Step 2: Run the failing frontend/browser tests**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease chrome/test/data/webui_test_resources
|
||||
```
|
||||
|
||||
Then run the relevant TypeScript tests already wired for the sgClaw chat surface.
|
||||
|
||||
**Step 3: Implement the minimal external bundle loader**
|
||||
|
||||
SuperRPA should:
|
||||
- keep the host shell and JS bridge fixed
|
||||
- optionally load external `sgclaw-chat` assets from runtime-configured directory
|
||||
- fall back to bundled assets when missing
|
||||
|
||||
**Step 4: Surface planner output early**
|
||||
|
||||
Use existing runtime event flow so the frontend shows:
|
||||
- plan summary
|
||||
- current step
|
||||
- execution logs
|
||||
|
||||
without moving control logic into the frontend.
|
||||
|
||||
**Step 5: Re-run tests**
|
||||
|
||||
Run the existing sgClaw chat WebUI tests and a browser smoke.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/superRpa/src add \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_state.ts \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_mainline_unittest.ts \
|
||||
chrome/browser/ui/webui/superrpa/functions_ui.cc \
|
||||
chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc
|
||||
git -C /home/zyl/projects/sgClaw/claw add \
|
||||
frontend/runtime-host/README.md \
|
||||
frontend/runtime-host/manifest.example.json
|
||||
git -C /home/zyl/projects/superRpa/src commit -m "superrpa: support external sgclaw frontend bundle"
|
||||
```
|
||||
|
||||
### Task 6: Close the current remaining behavioral gaps before new feature work
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/live_acceptance_score_test.py`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_messages.ts`
|
||||
|
||||
**Step 1: Write failing acceptance assertions**
|
||||
|
||||
Add explicit checks for:
|
||||
- no repeated assistant paragraphs
|
||||
- no fake fallback data when browser path exists
|
||||
- planner-first output appears before tool execution
|
||||
- Zhihu hotlist extraction returns structured rows
|
||||
- office export returns a real output path
|
||||
|
||||
**Step 2: Run the failing acceptance flow**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 /home/zyl/projects/sgClaw/claw/tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py
|
||||
```
|
||||
|
||||
Expected: current score exposes the remaining regressions if they still exist.
|
||||
|
||||
**Step 3: Fix the smallest issue set first**
|
||||
|
||||
Order:
|
||||
1. repeated message rendering / repeated summary emission
|
||||
2. planner event visibility
|
||||
3. structured hotlist extraction handoff
|
||||
4. office export path propagation
|
||||
|
||||
**Step 4: Re-run acceptance**
|
||||
|
||||
Run the same command until:
|
||||
- `hotlist_data_correctness > 0`
|
||||
- `xlsx_export_success > 0`
|
||||
- repeated text is absent
|
||||
|
||||
**Step 5: Record fresh evidence**
|
||||
|
||||
Update the acceptance markdown with:
|
||||
- timestamp
|
||||
- score
|
||||
- exact exported path
|
||||
- screenshot/log snippets
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/sgClaw/claw add \
|
||||
tests/live_acceptance_score_test.py \
|
||||
tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py \
|
||||
docs/acceptance/2026-03-29-zhihu-hotlist-excel.md
|
||||
git -C /home/zyl/projects/superRpa/src add \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat.ts \
|
||||
chrome/browser/resources/superrpa/devtools/functions/sgclaw-chat/sgclaw-chat_messages.ts
|
||||
git -C /home/zyl/projects/sgClaw/claw commit -m "acceptance: stabilize zhihu hotlist excel flow"
|
||||
```
|
||||
|
||||
### Task 7: Final integrated verification
|
||||
|
||||
**Files:**
|
||||
- Verify only: `/home/zyl/projects/sgClaw/claw/docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
- Verify only: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
||||
- Verify only: `/home/zyl/projects/sgClaw/claw/tools/browser_runtime/sgclaw_browser_entry.sh`
|
||||
|
||||
**Step 1: Build all affected binaries**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
autoninja -C /home/zyl/projects/superRpa/src/out/KylinRelease chrome functions_ui_mainline_unittests
|
||||
cargo test --manifest-path /home/zyl/projects/sgClaw/claw/Cargo.toml
|
||||
```
|
||||
|
||||
Expected: both complete successfully.
|
||||
|
||||
**Step 2: Do the live browser smoke**
|
||||
|
||||
Run browser with the local profile and verify the logs include one of:
|
||||
- `using SUPERRPA_SGCLAW_BINARY override: ...`
|
||||
- `using source checkout sgclaw inferred from skillsDir: ...`
|
||||
- `using bundled sgclaw from browser output dir: ...`
|
||||
|
||||
The expected dev mode result is the source checkout path, not the stale bundled fallback.
|
||||
|
||||
**Step 3: Run the final business acceptance**
|
||||
|
||||
Ask sgClaw to:
|
||||
1. read Zhihu hotlist
|
||||
2. export Excel
|
||||
3. open the screen presentation in a new tab
|
||||
|
||||
Verify:
|
||||
- planner appears first
|
||||
- skills are actually used
|
||||
- exported file path is returned
|
||||
- new-tab presentation opens
|
||||
|
||||
**Step 4: Record the result**
|
||||
|
||||
Append the final evidence to:
|
||||
- `/home/zyl/projects/sgClaw/claw/docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git -C /home/zyl/projects/sgClaw/claw commit -m "chore: record final sgclaw superrpa runtime verification"
|
||||
```
|
||||
|
||||
## Remaining Items Explicitly Carried Into This Plan
|
||||
|
||||
- The current stale-backend risk is not considered closed until the resolver has automated regression coverage.
|
||||
- The current local edit in `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/functions_ui_mainline_unittest.cc` must be either completed under Task 2 or replaced with the final tested version.
|
||||
- The current wrapper script `/home/zyl/projects/sgClaw/claw/tools/browser_runtime/sgclaw_browser_entry.sh` is still untracked and must be committed as part of Task 2.
|
||||
- The Zhihu hotlist to Excel acceptance still has unresolved correctness and export-path gaps and remains part of the critical path.
|
||||
- The repeated assistant text regression remains part of the critical path because it corrupts operator trust during demos.
|
||||
|
||||
Plan complete and saved to `docs/plans/2026-03-29-sgclaw-superrpa-decoupled-runtime-plan.md`. Two execution options:
|
||||
|
||||
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
|
||||
|
||||
**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
|
||||
|
||||
**Which approach?**
|
||||
@@ -0,0 +1,451 @@
|
||||
# SGClaw ZeroClaw Planner-First Realignment Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Realign the browser submit path so `sgclaw` uses `zeroclaw` as the primary planner/executor, with `sgclaw` acting only as the secure SuperRPA host plus custom tool bridge.
|
||||
|
||||
**Architecture:** Stop treating `zeroclaw` as a thin LLM wrapper. The browser message path should enter a `zeroclaw`-native orchestration entry point first, let `zeroclaw` perform planning/tool-loop control, and expose SuperRPA-specific browser/office/screen capabilities as regular tools inside that runtime. Any deterministic fast paths for Zhihu/Office must be implemented as `zeroclaw`-aligned execution components, not as frontend-owned control flow. The frontend may display the generated plan and current stage for UX, but it must not own planning or execution decisions.
|
||||
|
||||
**Tech Stack:** Rust, `sgclaw` compat bridge, `third_party/zeroclaw` agent loop, SuperRPA browser pipe, local skill library, OpenXML office export, HTML screen export, cargo tests, Python live acceptance.
|
||||
|
||||
### Task 1: Freeze The Current Architecture Gap With Characterization Tests
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/claw/src/agent/mod.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/claw/third_party/zeroclaw/src/agent/loop_.rs`
|
||||
|
||||
**Step 1: Write the failing test**
|
||||
|
||||
Add a test that submits `读取知乎热榜前10,并导出 excel 文件` through `handle_browser_message_with_context(...)` and asserts the browser submit path does **not** terminate inside the current thin `Agent::turn_streamed(...)` compat bridge.
|
||||
|
||||
The test should check for one of these observable signals:
|
||||
- a new orchestration mode log such as `zeroclaw_process_message_primary`
|
||||
- absence of the old `compat_llm_primary` mode log
|
||||
- absence of selector-thrashing logs like repeated `getText .HotList-item`, `[data-hot-item]`, `ol li`
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_submit_path_prefers_zeroclaw_process_message_orchestrator -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL because the current implementation still enters `src/compat/runtime.rs` and drives `agent.turn_streamed(...)` directly.
|
||||
|
||||
**Step 3: Write the smallest additional characterization test**
|
||||
|
||||
Add a second failing test that proves SuperRPA-specific tools remain available after the orchestration switch:
|
||||
- browser host tool
|
||||
- `openxml_office`
|
||||
- `screen_html_export`
|
||||
|
||||
This test should not require real network calls.
|
||||
|
||||
**Step 4: Run both failing tests**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: at least the new characterization tests fail for the expected reason.
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/compat_runtime_test.rs
|
||||
git commit -m "test: characterize browser path bypass of zeroclaw orchestrator"
|
||||
```
|
||||
|
||||
### Task 2: Introduce A ZeroClaw-Native Browser Orchestration Entry Point
|
||||
|
||||
**Files:**
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/src/compat/orchestration.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/mod.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/agent/mod.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/claw/third_party/zeroclaw/src/agent/loop_.rs:4752`
|
||||
|
||||
**Step 1: Write the failing unit test for the new entry point**
|
||||
|
||||
Add a test for a new helper in `src/compat/orchestration.rs` that:
|
||||
- receives browser task context
|
||||
- builds a `zeroclaw` config
|
||||
- returns a browser-safe orchestration handle or result
|
||||
|
||||
The test should prove the new helper is chosen by `handle_browser_message_with_context(...)`.
|
||||
|
||||
**Step 2: Run the new test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_submit_path_prefers_zeroclaw_process_message_orchestrator -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL because the helper does not exist yet.
|
||||
|
||||
**Step 3: Implement the minimal entry point**
|
||||
|
||||
Create `src/compat/orchestration.rs` with one responsibility:
|
||||
- bridge browser submit tasks into a `zeroclaw`-native orchestration path
|
||||
|
||||
Do not implement Zhihu-specific logic here. This layer must only:
|
||||
- map config
|
||||
- map task context/history
|
||||
- inject SuperRPA tools
|
||||
- call the chosen `zeroclaw` orchestration function
|
||||
|
||||
**Step 4: Switch `handle_browser_message_with_context(...)` to the new entry point**
|
||||
|
||||
Modify:
|
||||
- `/home/zyl/projects/sgClaw/claw/src/agent/mod.rs`
|
||||
|
||||
Replace the direct `compat::runtime::execute_task_with_sgclaw_settings(...)` primary path with the new orchestration bridge.
|
||||
|
||||
**Step 5: Run the test to verify it passes**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_submit_path_prefers_zeroclaw_process_message_orchestrator -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/compat/orchestration.rs src/compat/mod.rs src/agent/mod.rs src/compat/runtime.rs tests/compat_runtime_test.rs
|
||||
git commit -m "refactor: route browser submit flow through zeroclaw orchestration bridge"
|
||||
```
|
||||
|
||||
### Task 3: Register SuperRPA Browser/Office/Screen Capabilities As Native ZeroClaw Tools
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/browser_tool_adapter.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/openxml_office_tool.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/screen_html_export_tool.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/engine.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/orchestration.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_openxml_office_tool_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_screen_html_export_tool_test.rs`
|
||||
|
||||
**Step 1: Write the failing tool-registration test**
|
||||
|
||||
Add a test that asserts the `zeroclaw` orchestration path exposes:
|
||||
- the preferred SuperRPA browser tool
|
||||
- `openxml_office` when Excel export is requested
|
||||
- `screen_html_export` when screen export is requested
|
||||
|
||||
The test must verify this through the new orchestration path, not the old compat path.
|
||||
|
||||
**Step 2: Run the test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_orchestration_registers_superrpa_tools_natively -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL until tool wiring is complete.
|
||||
|
||||
**Step 3: Implement minimal native tool registration**
|
||||
|
||||
Ensure the new orchestration bridge injects `sgclaw` tools into the `zeroclaw` runtime without changing frontend code. Keep tool naming stable:
|
||||
- `superrpa_browser`
|
||||
- `openxml_office`
|
||||
- `screen_html_export`
|
||||
|
||||
**Step 4: Verify tool-level tests still pass**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_openxml_office_tool_test -- --nocapture
|
||||
cargo test --test compat_screen_html_export_tool_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 5: Run the new orchestration registration test**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_orchestration_registers_superrpa_tools_natively -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/compat/browser_tool_adapter.rs src/compat/openxml_office_tool.rs src/compat/screen_html_export_tool.rs src/runtime/engine.rs src/compat/orchestration.rs tests/compat_runtime_test.rs tests/compat_openxml_office_tool_test.rs tests/compat_screen_html_export_tool_test.rs
|
||||
git commit -m "feat: expose superrpa browser and export tools through zeroclaw orchestration"
|
||||
```
|
||||
|
||||
### Task 4: Remove Frontend-Owned Or Custom Compat Mainline Control Flow
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/agent/mod.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/skill_runner.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/claw/docs/plans/2026-03-29-sgclaw-zeroclaw-planner-first-execution-plan.md`
|
||||
|
||||
**Step 1: Write the failing regression test**
|
||||
|
||||
Add a test that proves Zhihu hotlist export no longer depends on a frontend-owned mainline such as:
|
||||
- `compat_skill_runner_primary`
|
||||
- direct `sgclaw`-local branching before `zeroclaw`
|
||||
|
||||
The expected primary mode should be a `zeroclaw`-owned orchestration mode.
|
||||
|
||||
**Step 2: Run the regression test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test zhihu_export_does_not_use_frontend_owned_mainline -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL while `src/compat/skill_runner.rs` still owns primary control flow.
|
||||
|
||||
**Step 3: Remove or demote the custom mainline**
|
||||
|
||||
Change the code so:
|
||||
- `src/compat/skill_runner.rs` becomes either a helper invoked inside the `zeroclaw` tool/runtime ecosystem, or is removed if redundant
|
||||
- `src/agent/mod.rs` no longer branches to a custom primary executor before `zeroclaw`
|
||||
|
||||
Do not leave two competing primary modes.
|
||||
|
||||
**Step 4: Run the regression test**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test zhihu_export_does_not_use_frontend_owned_mainline -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 5: Run the broader compat suite**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/compat/runtime.rs src/agent/mod.rs src/compat/skill_runner.rs tests/compat_runtime_test.rs
|
||||
git commit -m "refactor: remove frontend-owned primary control flow from browser submit path"
|
||||
```
|
||||
|
||||
### Task 5: Align Skills With ZeroClaw Execution Semantics Instead Of Prompt-Only Semantics
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/engine.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/third_party/zeroclaw/src/tools/read_skill.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/read_skill_tool_test.rs`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/skill_lib/skills/zhihu-hotlist/SKILL.md`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/skill_lib/skills/office-export-xlsx/SKILL.md`
|
||||
- Reference only: `/home/zyl/projects/sgClaw/skill_lib/skills/zhihu-hotlist-screen/SKILL.md`
|
||||
|
||||
**Step 1: Write the failing skill-execution regression test**
|
||||
|
||||
Add a test that proves skill usage in the browser submit path is not just:
|
||||
- prompt injection
|
||||
- `read_skill` text stuffing
|
||||
- model-led selector wandering
|
||||
|
||||
Instead, the test should verify the task produces:
|
||||
- a plan-driven collection/execution flow
|
||||
- a real `.xlsx` or `.html` artifact path
|
||||
- no selector-thrashing loop
|
||||
|
||||
**Step 2: Run the test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_skill_usage_is_execution_not_prompt_only -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL until skill semantics are aligned with execution.
|
||||
|
||||
**Step 3: Implement the minimal alignment**
|
||||
|
||||
Change the orchestration so `read_skill` is a fallback for missing context, not the primary means of making high-frequency browser workflows executable.
|
||||
|
||||
Keep:
|
||||
- skill discovery
|
||||
- skill references
|
||||
- artifact contract wording
|
||||
|
||||
Reduce:
|
||||
- over-reliance on prompt stuffing
|
||||
- over-reliance on model-led selector discovery for known workflows
|
||||
|
||||
**Step 4: Re-run the skill regression tests**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test compat_runtime_test browser_skill_usage_is_execution_not_prompt_only -- --nocapture
|
||||
cargo test --test read_skill_tool_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add src/runtime/engine.rs src/compat/runtime.rs third_party/zeroclaw/src/tools/read_skill.rs tests/compat_runtime_test.rs tests/read_skill_tool_test.rs
|
||||
git commit -m "refactor: align browser skill execution with zeroclaw-native workflow semantics"
|
||||
```
|
||||
|
||||
### Task 6: Verify The Planner-First Path End-To-End
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/runtime_profile_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_config_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/live_acceptance_score_test.py`
|
||||
- Reference only: `/home/zyl/projects/superRpa/src/out/KylinRelease/sgclaw`
|
||||
|
||||
**Step 1: Run the Rust regression suites**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test runtime_profile_test -- --nocapture
|
||||
cargo test --test compat_config_test -- --nocapture
|
||||
cargo test --test compat_runtime_test -- --nocapture
|
||||
cargo test --test read_skill_tool_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 2: Run the Python scoring test**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
python3 -m unittest tests/live_acceptance_score_test.py
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 3: Run the live Zhihu hotlist Excel acceptance**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
python3 tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py
|
||||
```
|
||||
|
||||
Expected:
|
||||
- total score returns to `100`
|
||||
- logs show planner-first `zeroclaw` orchestration instead of selector-thrashing
|
||||
- no `shell`, `web_fetch`, `web_search_tool`
|
||||
- final summary includes a real `.xlsx` path
|
||||
|
||||
**Step 4: Update the acceptance note**
|
||||
|
||||
Record:
|
||||
- new orchestration mode
|
||||
- tool sequence
|
||||
- timing notes
|
||||
- any remaining selector or latency risk
|
||||
|
||||
**Step 5: Rebuild and sync the runtime binary used by SuperRPA**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo build
|
||||
cp /home/zyl/projects/sgClaw/claw/target/debug/sgclaw /home/zyl/projects/superRpa/src/out/KylinRelease/sgclaw
|
||||
sha256sum /home/zyl/projects/sgClaw/claw/target/debug/sgclaw /home/zyl/projects/superRpa/src/out/KylinRelease/sgclaw
|
||||
```
|
||||
|
||||
Expected: the two hashes match exactly.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/acceptance/2026-03-29-zhihu-hotlist-excel.md tests/runtime_profile_test.rs tests/compat_config_test.rs tests/compat_runtime_test.rs tests/live_acceptance_score_test.py
|
||||
git commit -m "test: verify planner-first zeroclaw browser orchestration end to end"
|
||||
```
|
||||
|
||||
### Task 7: Surface The Generated Plan In The Chat UI Without Giving Frontend Control
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/event_bridge.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/pipe/protocol.rs`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/ui/webui/superrpa/sgclaw_session_service.cc`
|
||||
- Modify: `/home/zyl/projects/superRpa/src/chrome/browser/resources/superrpa/` (the active sgClaw chat UI files that render task progress)
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/pipe_protocol_test.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
|
||||
**Step 1: Write the failing protocol/UI test**
|
||||
|
||||
Add a test that proves the backend can emit a structured planning event before tool execution starts. The event must carry:
|
||||
- a short plan title
|
||||
- a flat ordered step list
|
||||
- current phase such as `planning`, `executing`, `completed`
|
||||
|
||||
The frontend test or fixture should verify the chat can render the plan summary without waiting for final completion.
|
||||
|
||||
**Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test pipe_protocol_test -- --nocapture
|
||||
cargo test --test compat_runtime_test plan_events_are_emitted_before_browser_execution -- --nocapture
|
||||
```
|
||||
|
||||
Expected: FAIL because the protocol does not yet expose a dedicated plan-progress event.
|
||||
|
||||
**Step 3: Add the minimal backend event shape**
|
||||
|
||||
Extend the `sgclaw` pipe/event bridge so the orchestration layer can emit:
|
||||
- planner summary
|
||||
- execution stage transitions
|
||||
|
||||
Keep the event read-only from the frontend’s perspective. The UI may display it, but cannot edit or branch execution.
|
||||
|
||||
**Step 4: Render the plan in the active chat UI**
|
||||
|
||||
Update the SuperRPA sgClaw chat UI so it:
|
||||
- prints the generated plan immediately after planning completes
|
||||
- keeps the plan compact and collapsible
|
||||
- highlights the current phase while waiting
|
||||
|
||||
Do not add frontend-owned retry logic, decision logic, or browser action generation.
|
||||
|
||||
**Step 5: Run verification**
|
||||
|
||||
Run:
|
||||
```bash
|
||||
cargo test --test pipe_protocol_test -- --nocapture
|
||||
cargo test --test compat_runtime_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected: PASS.
|
||||
|
||||
**Step 6: Manual browser validation**
|
||||
|
||||
Submit:
|
||||
```text
|
||||
读取知乎热榜前10,并导出 excel 文件
|
||||
```
|
||||
|
||||
Expected:
|
||||
- the chat first shows a short generated plan
|
||||
- the user sees stage transitions instead of a blank wait
|
||||
- execution still follows the backend-owned `zeroclaw` path
|
||||
|
||||
**Step 7: Commit**
|
||||
|
||||
```bash
|
||||
git add src/compat/event_bridge.rs src/pipe/protocol.rs tests/pipe_protocol_test.rs tests/compat_runtime_test.rs
|
||||
git commit -m "feat: surface backend-generated execution plans in sgclaw chat ui"
|
||||
```
|
||||
444
docs/plans/2026-03-29-zhihu-hotlist-office-export-plan.md
Normal file
444
docs/plans/2026-03-29-zhihu-hotlist-office-export-plan.md
Normal file
@@ -0,0 +1,444 @@
|
||||
# Zhihu Hotlist To Excel Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Make sgClaw reliably read Zhihu hotlist data through a Zhihu browser skill and export the collected structured result into a local `.xlsx` file through an independent Office skill.
|
||||
|
||||
**Architecture:** Keep zeroclaw as the core planner, but stop it from wandering across unrelated tools once a browser-attached skill is selected. The hotlist skill must produce a strict structured artifact, and the Office skill must consume that artifact through a dedicated `openxml_office` tool that wraps the sibling `openxml_cli` project. For the first delivery, reuse `openxml_cli template render` with a bundled `.xlsx` template instead of inventing a new workbook-construction API.
|
||||
|
||||
**Tech Stack:** Rust, vendored zeroclaw, sgClaw browser pipe, skill packages under `/home/zyl/projects/sgClaw/skill_lib`, sibling `openxml_cli`, JSON payload handoff, `.xlsx` template render, Python/Rust regression tests, real-provider smoke verification.
|
||||
|
||||
## Scope Guard
|
||||
|
||||
- In scope:
|
||||
- browser-attached skill execution discipline
|
||||
- `zhihu-hotlist` structured export artifact
|
||||
- new `office-export-xlsx` skill
|
||||
- new `openxml_office` runtime tool
|
||||
- end-to-end acceptance for "读取知乎热榜数据,并导出 excel 文件"
|
||||
- Out of scope:
|
||||
- generic Office authoring platform
|
||||
- arbitrary shell-based export flows
|
||||
- browser-side file generation as the main export path
|
||||
- broad multi-site data export before Zhihu hotlist is stable
|
||||
|
||||
## Current Findings To Preserve
|
||||
|
||||
- Real-provider validation already proved that `zhihu-hotlist`, `zhihu-navigate`, and `zhihu-write` can be selected through `read_skill`.
|
||||
- The current failure mode is not "skill missing" but "tool discipline collapse":
|
||||
- `file_read`, `glob_search`, and `shell` are attempted after `read_skill`
|
||||
- `zhihu-write` can fill title/body but still exceeds max tool iterations
|
||||
- `zhihu-navigate` succeeds for some intents but still detours through non-browser tools
|
||||
- The sibling Office project already exists at `/home/zyl/projects/sgClaw/openxml_cli`.
|
||||
- `openxml_cli` currently exposes `capabilities`, `template inspect`, `template validate`, and `template render`; it does not yet expose a direct "create workbook from scratch" command.
|
||||
|
||||
## Final Acceptance Contract
|
||||
|
||||
Input:
|
||||
|
||||
```text
|
||||
读取知乎热榜数据,并导出 excel 文件
|
||||
```
|
||||
|
||||
Required behavior:
|
||||
|
||||
1. sgClaw selects `zhihu-hotlist`.
|
||||
2. sgClaw gathers hotlist rows through the SuperRPA browser interface only.
|
||||
3. sgClaw converts the result into a structured JSON export payload.
|
||||
4. sgClaw selects `office-export-xlsx`.
|
||||
5. sgClaw calls `openxml_office`.
|
||||
6. A local `.xlsx` file is produced and its path is returned.
|
||||
|
||||
Required logs:
|
||||
|
||||
- `read_skill zhihu-hotlist`
|
||||
- browser actions only: `navigate`, `getText`, optionally `click`
|
||||
- `read_skill office-export-xlsx`
|
||||
- `call openxml_office`
|
||||
|
||||
Forbidden logs during the mainline path:
|
||||
|
||||
- `call shell`
|
||||
- `call glob_search`
|
||||
- `call file_read` on skill references or skill roots
|
||||
- `docker run`
|
||||
|
||||
Required Excel content:
|
||||
|
||||
- one sheet named `知乎热榜`
|
||||
- columns: `rank`, `title`, `heat`
|
||||
- at least 10 hotlist rows
|
||||
- exported values match the collected rows
|
||||
|
||||
## Task 1: Lock Browser-Attached Skill Runs To The Right Tools
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/engine.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/tool_policy.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
|
||||
**Intent:**
|
||||
- Once the task is clearly in a browser-attached Zhihu skill flow, the runtime must stop offering unrelated tools such as `shell`, `glob_search`, and arbitrary `file_read`.
|
||||
|
||||
**Step 1: Write the failing regression tests**
|
||||
|
||||
Add focused tests in `tests/compat_runtime_test.rs` for:
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn zhihu_hotlist_skill_flow_does_not_expose_shell_or_glob_tools() {}
|
||||
|
||||
#[test]
|
||||
fn browser_attached_export_flow_exposes_browser_and_office_tools_only() {}
|
||||
```
|
||||
|
||||
Assertions to include:
|
||||
|
||||
- request tool list contains `superrpa_browser`
|
||||
- request tool list contains `read_skill`
|
||||
- request tool list does not contain `shell`
|
||||
- request tool list does not contain `glob_search`
|
||||
- request tool list does not contain generic `file_read` during the constrained browser skill phase
|
||||
|
||||
**Step 2: Run the focused tests to verify failure**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cargo test --test compat_runtime_test zhihu_hotlist_skill_flow_does_not_expose_shell_or_glob_tools -- --nocapture
|
||||
cargo test --test compat_runtime_test browser_attached_export_flow_exposes_browser_and_office_tools_only -- --nocapture
|
||||
```
|
||||
|
||||
Expected:
|
||||
- fail because current runtime still exposes too many tools in browser-attached mode
|
||||
|
||||
**Step 3: Implement minimal constrained-tool policy**
|
||||
|
||||
Implement a browser-skill execution mode that:
|
||||
|
||||
- keeps `superrpa_browser`
|
||||
- keeps compatibility alias `browser_action`
|
||||
- keeps `read_skill`
|
||||
- optionally keeps the new `openxml_office` tool only for export tasks
|
||||
- removes `shell`, `glob_search`, and free-form `file_read` from the allowed tool list for these phases
|
||||
|
||||
Do this in `src/runtime/engine.rs` by deriving a narrower `allowed_tools` set from:
|
||||
|
||||
- runtime profile
|
||||
- browser surface present flag
|
||||
- instruction intent
|
||||
- whether export mode is active
|
||||
|
||||
**Step 4: Re-run the focused tests**
|
||||
|
||||
Run the same commands.
|
||||
|
||||
Expected:
|
||||
- both pass
|
||||
|
||||
## Task 2: Convert Zhihu Hotlist Skill To Structured Output First
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/skill_lib/skills/zhihu-hotlist/SKILL.md`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/skill_lib_validation_test.py`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
|
||||
**Intent:**
|
||||
- The hotlist skill should stop ending with prose-only summaries. Its primary output must be a stable export artifact the Office skill can consume.
|
||||
|
||||
**Step 1: Write the failing tests**
|
||||
|
||||
Add tests that enforce:
|
||||
|
||||
- `zhihu-hotlist` prompt body contains an explicit `Export Artifact` section
|
||||
- the artifact schema includes `sheet_name`, `columns`, and `rows`
|
||||
- runtime regression checks can find those fields in the skill content when `read_skill` is used
|
||||
|
||||
**Step 2: Run tests to verify failure**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 -m unittest tests.skill_lib_validation_test
|
||||
cargo test --test compat_runtime_test handle_browser_message_executes_real_zhihu_hotlist_skill_flow -- --nocapture
|
||||
```
|
||||
|
||||
Expected:
|
||||
- validation fails because the artifact contract is not yet required
|
||||
|
||||
**Step 3: Update `zhihu-hotlist`**
|
||||
|
||||
Add an `Export Artifact` section that requires this shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"source": "https://www.zhihu.com/hot",
|
||||
"sheet_name": "知乎热榜",
|
||||
"columns": ["rank", "title", "heat"],
|
||||
"rows": [[1, "标题", "344万"]]
|
||||
}
|
||||
```
|
||||
|
||||
Also add hard rules:
|
||||
|
||||
- no extra exploratory tools after the browser data is collected
|
||||
- prose summary is secondary, structured artifact is primary
|
||||
|
||||
**Step 4: Re-run tests**
|
||||
|
||||
Expected:
|
||||
- validation passes
|
||||
|
||||
## Task 3: Create The Office Export Skill Package
|
||||
|
||||
**Files:**
|
||||
- Create: `/home/zyl/projects/sgClaw/skill_lib/skills/office-export-xlsx/SKILL.md`
|
||||
- Create: `/home/zyl/projects/sgClaw/skill_lib/skills/office-export-xlsx/references/export-flow.md`
|
||||
- Create: `/home/zyl/projects/sgClaw/skill_lib/skills/office-export-xlsx/assets/zhihu_hotlist_template.xlsx`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/skill_lib_validation_test.py`
|
||||
|
||||
**Intent:**
|
||||
- Add a fully separate Office skill that knows nothing about browser scraping and only turns structured table data into a local Excel file.
|
||||
|
||||
**Step 1: Write the failing validation test**
|
||||
|
||||
Extend `tests/skill_lib_validation_test.py` so discovery expects:
|
||||
|
||||
```python
|
||||
EXPECTED_SKILL_NAMES = [
|
||||
"office-export-xlsx",
|
||||
"zhihu-hotlist",
|
||||
"zhihu-navigate",
|
||||
"zhihu-write",
|
||||
]
|
||||
```
|
||||
|
||||
Also require the new skill to mention:
|
||||
|
||||
- `openxml_office`
|
||||
- `.xlsx`
|
||||
- `sheet_name`
|
||||
- `columns`
|
||||
- `rows`
|
||||
|
||||
**Step 2: Run the validation test to verify failure**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 -m unittest tests.skill_lib_validation_test
|
||||
```
|
||||
|
||||
Expected:
|
||||
- fail because the new skill package does not exist yet
|
||||
|
||||
**Step 3: Create the skill package**
|
||||
|
||||
`SKILL.md` must define:
|
||||
|
||||
- when to use: local Office export from structured rows
|
||||
- required input schema
|
||||
- output: exported file path
|
||||
- tool rule: only call `openxml_office`, do not use browser tools
|
||||
|
||||
`export-flow.md` must define:
|
||||
|
||||
- validate payload shape
|
||||
- choose output path
|
||||
- invoke `openxml_office`
|
||||
- return file path and row count
|
||||
|
||||
The first workbook template should be a fixed `zhihu_hotlist_template.xlsx` with:
|
||||
|
||||
- sheet `知乎热榜`
|
||||
- row 1 headers already present
|
||||
- table fill anchored to a stable name or placeholder expected by `openxml_cli`
|
||||
|
||||
**Step 4: Re-run validation**
|
||||
|
||||
Expected:
|
||||
- new skill passes audit
|
||||
|
||||
## Task 4: Add The `openxml_office` Runtime Tool
|
||||
|
||||
**Files:**
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/src/compat/openxml_office_tool.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/mod.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/compat/runtime.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/tool_policy.rs`
|
||||
- Test: `/home/zyl/projects/sgClaw/claw/tests/compat_openxml_office_tool_test.rs`
|
||||
|
||||
**Intent:**
|
||||
- Wrap sibling `openxml_cli` as a first-class local tool instead of leaking Office export through shell prompting.
|
||||
|
||||
**Step 1: Write the failing tool test**
|
||||
|
||||
Create `tests/compat_openxml_office_tool_test.rs` with cases for:
|
||||
|
||||
- capability probe
|
||||
- render request assembly for xlsx export
|
||||
- rejection when rows/columns are missing
|
||||
- stable JSON output containing `output_path`
|
||||
|
||||
**Step 2: Run the test to verify failure**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cargo test --test compat_openxml_office_tool_test -- --nocapture
|
||||
```
|
||||
|
||||
Expected:
|
||||
- fail because the tool does not exist
|
||||
|
||||
**Step 3: Implement minimal tool**
|
||||
|
||||
Tool contract:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "export_hotlist_xlsx",
|
||||
"template_path": ".../zhihu_hotlist_template.xlsx",
|
||||
"output_path": "/tmp/zhihu_hotlist.xlsx",
|
||||
"sheet_name": "知乎热榜",
|
||||
"columns": ["rank", "title", "heat"],
|
||||
"rows": [[1, "标题", "344万"]]
|
||||
}
|
||||
```
|
||||
|
||||
Implementation rules:
|
||||
|
||||
- write the payload JSON to a temp file
|
||||
- invoke sibling `openxml_cli template render --request <file> --json`
|
||||
- return parsed JSON result and normalized `output_path`
|
||||
- no free-form shell composition from model text
|
||||
|
||||
**Step 4: Re-run the focused tests**
|
||||
|
||||
Expected:
|
||||
- pass
|
||||
|
||||
## Task 5: Wire Export Tasks To Use Two Skills In Sequence
|
||||
|
||||
**Files:**
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/src/runtime/engine.rs`
|
||||
- Modify: `/home/zyl/projects/sgClaw/claw/tests/compat_runtime_test.rs`
|
||||
|
||||
**Intent:**
|
||||
- The single user instruction must naturally flow from hotlist capture into Office export, not end after the first skill.
|
||||
|
||||
**Step 1: Write the failing runtime test**
|
||||
|
||||
Add a focused regression test for:
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn zhihu_hotlist_export_task_reads_hotlist_skill_then_office_skill() {}
|
||||
```
|
||||
|
||||
Assertions:
|
||||
|
||||
- request stream includes `read_skill zhihu-hotlist`
|
||||
- later includes `read_skill office-export-xlsx`
|
||||
- office phase exposes `openxml_office`
|
||||
- no `shell` is exposed in the constrained task path
|
||||
|
||||
**Step 2: Run the test to verify failure**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cargo test --test compat_runtime_test zhihu_hotlist_export_task_reads_hotlist_skill_then_office_skill -- --nocapture
|
||||
```
|
||||
|
||||
Expected:
|
||||
- fail because the task currently has no structured handoff to Office export
|
||||
|
||||
**Step 3: Implement minimal chaining support**
|
||||
|
||||
Do not add a hard-coded workflow engine.
|
||||
|
||||
Minimal implementation:
|
||||
|
||||
- strengthen prompt contract so export tasks require structured hotlist artifact
|
||||
- include `openxml_office` in allowed tools for export intent
|
||||
- keep browser-only tools for the collection phase and Office-only tool for the export phase
|
||||
|
||||
**Step 4: Re-run the test**
|
||||
|
||||
Expected:
|
||||
- pass
|
||||
|
||||
## Task 6: Add Real Acceptance Harness And Scoring
|
||||
|
||||
**Files:**
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py`
|
||||
- Create: `/home/zyl/projects/sgClaw/claw/docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
|
||||
**Intent:**
|
||||
- Make the final acceptance repeatable with the real user config and a transparent score.
|
||||
|
||||
**Step 1: Write the script**
|
||||
|
||||
The script must:
|
||||
|
||||
- use `/home/zyl/.config/superrpa/Default/superrpa/sgclaw_config.json`
|
||||
- boot local `target/debug/sgclaw`
|
||||
- send one browser `submit_task`
|
||||
- respond to browser commands with controlled fixture responses
|
||||
- capture:
|
||||
- loaded skills
|
||||
- selected skills
|
||||
- forbidden tool calls
|
||||
- final summary
|
||||
- exported file path
|
||||
|
||||
**Step 2: Define score rubric**
|
||||
|
||||
Rubric:
|
||||
|
||||
- `skill selection`: 30
|
||||
- `tool discipline`: 25
|
||||
- `hotlist data correctness`: 20
|
||||
- `xlsx export success`: 20
|
||||
- `final response quality`: 5
|
||||
|
||||
Automatic deductions:
|
||||
|
||||
- `shell` called: `-15`
|
||||
- `glob_search` called: `-10`
|
||||
- `file_read` on skill references: `-10`
|
||||
- wrong skill selected first: `-15`
|
||||
- export missing output path: `-20`
|
||||
|
||||
**Step 3: Run acceptance**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
python3 tools/live_acceptance/run_zhihu_hotlist_excel_acceptance.py
|
||||
```
|
||||
|
||||
Expected:
|
||||
- prints total score and per-dimension breakdown
|
||||
- stores final evidence in `docs/acceptance/2026-03-29-zhihu-hotlist-excel.md`
|
||||
|
||||
## Delivery Sequence
|
||||
|
||||
Execute in this order:
|
||||
|
||||
1. Task 1: constrain tools
|
||||
2. Task 2: structure hotlist output
|
||||
3. Task 3: add office skill package
|
||||
4. Task 4: add `openxml_office`
|
||||
5. Task 5: chain the two skills
|
||||
6. Task 6: run acceptance and score
|
||||
|
||||
## Definition Of Done
|
||||
|
||||
- browser-attached hotlist tasks no longer wander into `shell`, `glob_search`, or ad-hoc `file_read`
|
||||
- `office-export-xlsx` exists as an independent skill
|
||||
- `openxml_office` exists as an explicit tool
|
||||
- a single user task can collect hotlist data and export `.xlsx`
|
||||
- acceptance score is at least `85/100`
|
||||
Reference in New Issue
Block a user