Files
claw/docs/superpowers/plans/2026-04-12-tq-lineloss-ws-dual-transport-plan.md
木炎 c60cd308ca feat: service console auto-connect, settings panel, and batch of enhancements
- Auto-connect WebSocket on page load in service console
- Settings modal for editing sgclaw_config.json (API key, base URL, model, skills dir, etc.)
- UpdateConfig/ConfigUpdated protocol messages for remote config save
- save_to_path() for SgClawSettings serialization
- ConfigUpdated handler in sg_claw_client binary
- Protocol serialization tests for new message types
- HTML test assertions for auto-connect and settings UI
- Additional pending changes: deterministic submit, org units, lineloss xlsx export, browser script tool, and docs

🤖 Generated with [Qoder][https://qoder.com]
2026-04-14 14:32:46 +08:00

18 KiB

TQ Lineloss WS Dual-Transport Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Add ws communication support for the existing tq-lineloss-report.collect_lineloss deterministic browser_script path on the feature/claw-ws branch while preserving the current pipe path and validated Zhihu ws behavior.

Architecture: Reuse the existing backend-neutral execution seam that already exists for deterministic submit and browser_script execution. Keep lineloss business parsing, canonical args, and artifact interpretation unchanged; only make the ws backend/protocol and submit-path verification complete enough for the same lineloss skill contract to run over both pipe and ws.

Tech Stack: Rust 2021, Cargo tests, existing BrowserBackend abstraction, WsBrowserBackend, ws_protocol, browser websocket contract in docs/_tmp_sgbrowser_ws_api_doc.txt, existing staged browser_script skill execution seam.


Execution Context

  • Follow @superpowers:test-driven-development for each behavior change.
  • Follow @superpowers:verification-before-completion before claiming each task is done.
  • Do not create a git worktree unless the user explicitly asks.
  • This plan is ws enablement only for the already-added lineloss deterministic skill path.
  • Do not redesign deterministic routing, org parsing, period parsing, staged skill packaging, or artifact contracts unless a failing ws-specific test proves a minimal compatibility fix is required.
  • Do not modify validated Zhihu hotlist/export business behavior; only add regression coverage around it.
  • Preserve the current pipe execution path as the control implementation.
  • Preserve the current BrowserBackend seam; do not introduce a second lineloss-specific ws execution path.

Scope Boundary

In scope

  • Make the existing lineloss deterministic browser_script skill path run through ws on this branch.
  • Keep the same canonical tool args and returned artifact interpretation for both pipe and ws.
  • Verify ws browser-script execution against the documented browser ws contract.
  • Add focused tests for ws lineloss execution and regressions for Zhihu ws + pipe lineloss.

Out of scope

  • Changing lineloss trigger semantics (。。。).
  • Changing org/unit normalization semantics or source dictionary shape.
  • Changing period normalization semantics.
  • Reworking staged skill docs or JS business collection logic beyond ws-compatibility necessities.
  • Any Zhihu feature work.
  • Any pipe-only cleanup/refactor.
  • Any general scene-registry redesign.

File Map

Expected code changes

  • Modify: src/pipe/protocol.rs:49-78,130-165,192-209
    • keep Action::Eval encoding aligned with the current transport contract and lineloss skill expectations
  • Modify: src/pipe/browser_tool.rs:62-125
    • ensure eval response correlation and payload handling remain sufficient for deterministic lineloss execution
  • Modify only if a focused test proves it is necessary: src/compat/browser_script_skill_tool.rs:135-255
    • preserve browser_script contract; only make minimal output-shape handling fixes if eval payloads differ from the pipe baseline in a way current code cannot consume
  • Modify only if a focused parity test proves it is necessary: src/compat/direct_skill_runtime.rs:50-129
    • preserve shared backend-neutral execution helper behavior; no business logic changes
  • Read and normally leave unchanged: src/compat/deterministic_submit.rs:96-157
    • this is the business contract baseline and should not be rewritten for transport parity work
  • Read and normally leave unchanged: src/agent/mod.rs:242-285
    • this contains the current deterministic dispatch split used by this branch

Expected test changes

  • Modify: tests/agent_runtime_test.rs
    • add/extend deterministic lineloss runtime coverage and parity assertions using the current runtime path
  • Modify: tests/compat_runtime_test.rs
    • add/extend focused pipe lineloss regression assertions so transport work cannot silently break pipe
  • Modify only if end-to-end submit coverage truly needs it: tests/runtime_task_flow_test.rs
    • verify broader submit-flow expectations remain intact

Reference-only files

  • Read only: docs/superpowers/plans/2026-04-11-tq-lineloss-deterministic-skill-plan.md
  • Read only: docs/superpowers/specs/2026-04-11-tq-lineloss-deterministic-skill-design.md
  • Read only: docs/_tmp_sgbrowser_ws_api_doc.txt

Locked contracts

Contract 1: Same lineloss deterministic business contract on both transports

The ws path must reuse the existing values produced by src/compat/deterministic_submit.rs:84-95 and src/compat/deterministic_submit.rs:135-166:

  • expected_domain
  • org_label
  • org_code
  • period_mode
  • period_mode_code
  • period_value
  • period_payload

No ws-specific lineloss args may be introduced in this slice.

Contract 2: Same browser_script execution seam on both transports

The ws path must continue to use execute_browser_script_skill_raw_output_with_browser_backend(...) from src/compat/direct_skill_runtime.rs:95-112, which in turn uses the same browser_script tool path as pipe. Do not add a second lineloss-only ws runner.

Contract 3: Same artifact interpretation on both transports

The ws path must produce output that remains consumable by summarize_lineloss_output(...) / summarize_lineloss_artifact(...) in src/compat/deterministic_submit.rs:168-257 without transport-specific branching.

Contract 4: Zhihu ws behavior must stay unchanged

The existing ws browser-script / export path already validated by tests/agent_runtime_test.rs and tests/compat_runtime_test.rs is a hard regression boundary. If a change breaks Zhihu tests, fix the ws seam instead of weakening Zhihu expectations.

Contract 5: Pipe remains the baseline

For identical lineloss deterministic inputs, the pipe path should continue to succeed without requiring ws configuration.


Task 1: Lock the ws contract with failing transport-level tests

Files:

  • Modify: tests/agent_runtime_test.rs

  • Modify: tests/compat_runtime_test.rs

  • Read: docs/_tmp_sgbrowser_ws_api_doc.txt

  • Step 1: Add a failing ws lineloss deterministic runtime test

Model it after the existing ws harness in tests/agent_runtime_test.rs:69-166, but target lineloss deterministic execution instead of Zhihu. The test should:

  • configure browserWsUrl
  • submit a deterministic lineloss instruction ending with 。。。
  • return a ws callback payload representing a lineloss report-artifact
  • assert success summary includes canonical org, period, status, and rows

Suggested skeleton:

#[test]
fn ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact() {
    // arrange ws config + ws server + lineloss artifact callback
    // act handle_browser_message_with_context(... SubmitTask ...)
    // assert TaskComplete success summary contains canonical org/period/rows
}
  • Step 2: Add a failing pipe regression test for the same lineloss contract

In tests/compat_runtime_test.rs, add a focused pipe-side assertion that the same deterministic lineloss instruction still succeeds through the current pipe seam and uses the same summary contract.

Suggested skeleton:

#[test]
fn pipe_deterministic_lineloss_submit_preserves_existing_summary_contract() {
    // arrange MockTransport responses for browser_script eval
    // act handle_browser_message_with_context(...)
    // assert success summary matches canonical contract
}
  • Step 3: Add a failing ws regression assertion for Zhihu

Add or tighten a Zhihu ws assertion proving ordinary Zhihu requests still use the existing ws path and do not get intercepted by lineloss deterministic logic.

  • Step 4: Run the three focused tests to confirm failure

Run:

cargo test ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact -- --exact
cargo test pipe_deterministic_lineloss_submit_preserves_existing_summary_contract -- --exact
cargo test ws_zhihu_submit_path_remains_unchanged_after_lineloss_transport_work -- --exact

Expected: at least the new ws lineloss test fails before the seam is completed.

  • Step 5: Commit
git add tests/agent_runtime_test.rs tests/compat_runtime_test.rs
git commit -m "test: lock ws and pipe lineloss transport contracts"

Task 2: Make the current eval transport contract explicitly satisfy browser-script requirements

Files:

  • Modify: src/pipe/protocol.rs:49-78,130-165,192-209

  • Modify: src/pipe/browser_tool.rs:62-124

  • Modify only if tests prove necessary: src/compat/browser_script_skill_tool.rs:99-180,214-255

  • Modify: tests/pipe_protocol_test.rs

  • Modify: tests/browser_tool_test.rs

  • Modify: tests/browser_script_skill_tool_test.rs

  • Step 1: Add failing protocol/result-contract tests first

Extend or add focused tests to lock the current branch's real transport contract:

  • Action::Eval remains supported by the line protocol and command encoding
  • eval request/response correlation remains stable via seq matching for lineloss-style target URLs
  • eval/browser_script result handling preserves the full JSON artifact string without truncation before deterministic lineloss summarization consumes it

Suggested skeletons:

#[test]
fn eval_action_remains_supported_in_protocol() {}

#[test]
fn browser_tool_matches_eval_response_by_seq_for_lineloss_flow() {}

#[test]
fn browser_script_tool_preserves_json_artifact_string_for_lineloss() {}
  • Step 2: Run the focused Task 2 tests to confirm failure

Run:

cargo test eval_action_remains_supported_in_protocol -- --exact
cargo test browser_tool_matches_eval_response_by_seq_for_lineloss_flow -- --exact
cargo test browser_script_tool_preserves_json_artifact_string_for_lineloss -- --exact

Expected: at least one test fails if the current protocol/correlation/result handling is still insufficient for the lineloss artifact path.

  • Step 3: Implement the minimal transport-contract fix

Allowed changes:

  • adjust only the Action::Eval protocol/encoding support in src/pipe/protocol.rs
  • adjust only request/response correlation in src/pipe/browser_tool.rs
  • if and only if tests still prove it necessary, make a tiny result-shape/stringification fix in src/compat/browser_script_skill_tool.rs
  • keep existing Zhihu-compatible behavior intact

Not allowed:

  • adding lineloss-only transport fields

  • adding a second lineloss-specific execution path

  • changing deterministic lineloss business parsing or summary rules

  • Step 4: Re-run the focused Task 2 tests

Run:

cargo test eval_action_remains_supported_in_protocol -- --exact
cargo test browser_tool_matches_eval_response_by_seq_for_lineloss_flow -- --exact
cargo test browser_script_tool_preserves_json_artifact_string_for_lineloss -- --exact

Expected: PASS.

  • Step 5: Re-run the focused ws lineloss runtime test from Task 1

Run:

cargo test ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact -- --exact

Expected: PASS.

  • Step 6: Commit
git add src/pipe/protocol.rs src/pipe/browser_tool.rs src/compat/browser_script_skill_tool.rs tests/pipe_protocol_test.rs tests/browser_tool_test.rs tests/browser_script_skill_tool_test.rs
git commit -m "fix: align eval transport contract with lineloss browser script flow"

Task 3: Make eval result-shape handling surface the lineloss artifact cleanly

Files:

  • Modify: src/pipe/browser_tool.rs:62-125

  • Modify only if tests prove necessary: src/compat/browser_script_skill_tool.rs:159-180,248-255

  • Modify: tests/browser_script_skill_tool_test.rs

  • Step 1: Add a failing result-shape test

Lock that an eval response carrying a JSON string report artifact is surfaced as the same browser_script tool output shape expected by execute_browser_script_tool(...).

Suggested skeleton:

#[test]
fn ws_backend_eval_returns_text_payload_consumable_by_browser_script_tool() {
    // arrange an eval response whose data.text is a JSON string artifact
    // assert execute_browser_script_tool(...) returns the full artifact text without truncation
}
  • Step 2: Run the result-shape test to confirm failure

Run:

cargo test ws_backend_eval_returns_text_payload_consumable_by_browser_script_tool -- --exact

Expected: FAIL only if current eval/result handling is not sufficient for full lineloss artifact output.

  • Step 3: Implement the minimal result-shape fix

Allowed fixes:

  • adjust BrowserPipeTool::invoke(...) only if response packaging itself is wrong
  • if and only if still required, make a tiny output-shape compatibility fix in src/compat/browser_script_skill_tool.rs so JSON string data.text payloads are preserved identically to the pipe baseline

Not allowed:

  • transport-specific lineloss parsing

  • changes to deterministic business logic

  • adding a second lineloss-specific execution path

  • Step 4: Re-run the result-shape test

Run:

cargo test ws_backend_eval_returns_text_payload_consumable_by_browser_script_tool -- --exact

Expected: PASS.

  • Step 5: Re-run the focused ws lineloss runtime test from Task 1

Run:

cargo test ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact -- --exact

Expected: PASS.

  • Step 6: Commit
git add src/pipe/browser_tool.rs src/compat/browser_script_skill_tool.rs tests/browser_script_skill_tool_test.rs
git commit -m "fix: make eval result shape match browser script contract"

Task 4: Verify the current backend-neutral deterministic execution path without changing business rules

Files:

  • Read baseline: src/agent/mod.rs:242-285

  • Read baseline: src/compat/deterministic_submit.rs:96-157

  • Modify only if a focused parity test proves it is necessary: src/compat/direct_skill_runtime.rs:50-129

  • Modify: tests/agent_runtime_test.rs

  • Modify: tests/compat_runtime_test.rs

  • Step 1: Add a failing integration test for backend-neutral parity

Add a test proving these two current-branch paths produce the same lineloss summary contract for equivalent artifact payloads:

  • pipe path via the existing deterministic submit flow in tests/compat_runtime_test.rs
  • runtime path via handle_browser_message_with_context(...) deterministic submit routing in tests/agent_runtime_test.rs

Suggested skeleton:

#[test]
fn deterministic_lineloss_pipe_and_ws_paths_share_summary_contract() {}
  • Step 2: Run the parity test to confirm failure or gap

Run:

cargo test deterministic_lineloss_pipe_and_ws_paths_share_summary_contract -- --exact

Expected: FAIL only if a remaining shared execution seam gap still exists.

  • Step 3: Apply the smallest shared execution fix if needed

Allowed changes:

  • tiny helper extraction or result handling in src/compat/direct_skill_runtime.rs

  • no new lineloss-specific branch

  • no change to deterministic lineloss business parsing or summary rules

  • no change to configured direct-submit behavior for non-lineloss skills

  • Step 4: Re-run the parity test

Run:

cargo test deterministic_lineloss_pipe_and_ws_paths_share_summary_contract -- --exact

Expected: PASS.

  • Step 5: Commit
git add src/compat/direct_skill_runtime.rs tests/agent_runtime_test.rs tests/compat_runtime_test.rs
git commit -m "fix: preserve shared deterministic execution across pipe and ws"

Task 5: Run the full focused verification set and stop if any Zhihu or pipe regression appears

Files:

  • Reuse: tests/agent_runtime_test.rs

  • Reuse: tests/compat_runtime_test.rs

  • Reuse: tests/runtime_task_flow_test.rs

  • Step 1: Run focused ws + lineloss + Zhihu regression tests

Run:

cargo test --test agent_runtime_test
cargo test --test compat_runtime_test
cargo test --test runtime_task_flow_test

Expected: PASS.

  • Step 2: Run targeted protocol/backend unit tests

Run:

cargo test eval_action_remains_supported_in_protocol -- --exact
cargo test browser_tool_matches_eval_response_by_seq_for_lineloss_flow -- --exact
cargo test browser_script_tool_preserves_json_artifact_string_for_lineloss -- --exact
cargo test ws_backend_eval_returns_text_payload_consumable_by_browser_script_tool -- --exact
cargo test deterministic_lineloss_pipe_and_ws_paths_share_summary_contract -- --exact

Expected: PASS.

  • Step 3: Run the full Rust suite

Run:

cargo test

Expected: PASS.

  • Step 4: Manual review of diff scope

Confirm the diff only touches:

  • current transport/result seam files (src/pipe/protocol.rs, src/pipe/browser_tool.rs)
  • narrow shared browser_script/result compatibility helpers if strictly necessary
  • tests

If diff includes Zhihu business logic, lineloss parsing rules, staged skill business JS, or unrelated cleanup, remove those changes before completion.

  • Step 5: Commit
git add src/pipe/protocol.rs src/pipe/browser_tool.rs src/compat/browser_script_skill_tool.rs src/compat/direct_skill_runtime.rs tests/pipe_protocol_test.rs tests/browser_tool_test.rs tests/browser_script_skill_tool_test.rs tests/agent_runtime_test.rs tests/compat_runtime_test.rs
git commit -m "test: verify lineloss ws transport without regressing pipe or zhihu"

Final verification checklist

  • The same lineloss deterministic instruction works on pipe and ws.
  • Pipe still works without any ws configuration.
  • Eval transport support remains available for deterministic lineloss execution.
  • Eval response payloads preserve the full lineloss artifact JSON string.
  • src/compat/deterministic_submit.rs business rules remain transport-neutral.
  • No ws-specific lineloss args were introduced.
  • Zhihu ws tests still pass unchanged in behavior.
  • No ordinary Zhihu request is intercepted by lineloss deterministic routing.
  • No new transport-specific business branch was added for lineloss.

Implementation notes

  • Default to changing the current transport/result seam first: src/pipe/protocol.rs and src/pipe/browser_tool.rs.
  • Treat src/compat/browser_script_skill_tool.rs and src/compat/direct_skill_runtime.rs as shared seams: change them only if a focused failing test shows a transport-neutral compatibility bug.
  • If a proposed fix requires changing src/compat/deterministic_submit.rs business logic, stop and re-evaluate; that likely means the seam fix is happening at the wrong layer.
  • If a proposed fix changes Zhihu expectations, stop and repair the seam instead.