# 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: ```rust #[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: ```rust #[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: ```bash 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** ```bash 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: ```rust #[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: ```bash 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: ```bash 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: ```bash cargo test ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact -- --exact ``` Expected: PASS. - [ ] **Step 6: Commit** ```bash 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: ```rust #[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: ```bash 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: ```bash 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: ```bash cargo test ws_deterministic_lineloss_submit_executes_browser_script_and_summarizes_artifact -- --exact ``` Expected: PASS. - [ ] **Step 6: Commit** ```bash 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: ```rust #[test] fn deterministic_lineloss_pipe_and_ws_paths_share_summary_contract() {} ``` - [ ] **Step 2: Run the parity test to confirm failure or gap** Run: ```bash 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: ```bash cargo test deterministic_lineloss_pipe_and_ws_paths_share_summary_contract -- --exact ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash 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: ```bash 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: ```bash 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: ```bash 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** ```bash 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.