Files
claw/docs/superpowers/plans/2026-04-06-zhihu-hotlist-post-export-auto-open-plan.md
木炎 bdf8e12246 feat: align browser callback runtime and export flows
Consolidate the browser task runtime around the callback path, add safer artifact opening for Zhihu exports, and cover the new service/browser flows with focused tests and supporting docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 21:44:53 +08:00

29 KiB

Zhihu Hotlist Post-Export Auto-Open 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: Extend the existing Zhihu hotlist Excel and dashboard routes so each route can auto-open its own generated artifact after export, while preserving the current callback-host-backed browser boundary and route exclusivity.

Architecture: Keep orchestration in src/compat/workflow_executor.rs, but move post-export side effects into a new src/compat/artifact_open.rs helper so workflow routing stays readable. Excel auto-open is a local OS-launch side effect; dashboard auto-open reuses screen_html_export's existing presentation.url and sends one narrow, marker-based Action::Navigate request through BrowserCallbackBackend, with a matching special-case validator in MacPolicy so arbitrary file:// navigation remains blocked.

Tech Stack: Rust, serde_json, std::process::Command, std::path, Cargo tests


File Map

  • Create: src/compat/artifact_open.rs
    • Define the narrow post-export helper surface for this slice only
    • Parse and validate generated artifact payload fields passed in by the workflow layer
    • Open generated .xlsx files with the local default app
    • Build the exact approved local-dashboard navigate payload
    • Keep one testable internal seam, open_exported_xlsx_with(output_path, opener), so unit tests can prove the generated .xlsx path is handed to the launcher without starting a real spreadsheet app
    • Include unit tests in the same file for exact Excel path handoff and launcher-failure reporting
  • Modify: src/compat/mod.rs
    • Export the new artifact_open module
  • Modify: src/compat/workflow_executor.rs
    • Keep route detection and artifact generation where they are now
    • Change export_xlsx(...) and export_screen(...) so they parse tool payloads, call the route-specific opener, and produce the new success/failure summaries
  • Modify: src/browser/callback_backend.rs
    • Recognize only the approved local-dashboard navigate request shape at Action::Navigate
    • Keep normal remote navigate behavior unchanged
    • Continue emitting sgBrowerserOpenPage for the approved local-dashboard case so the helper page stays alive and the dashboard opens in a new visible tab
    • Add focused callback-backend unit tests in the existing test module for approved and malformed local-dashboard requests
  • Modify: src/security/mac_policy.rs
    • Add a narrow validator for the approved local-dashboard presentation case
    • Keep validate(...) unchanged for ordinary remote-domain flow
    • Reject malformed marker payloads, non-HTML local paths, and mismatched file:// / output-path combinations
  • Modify: tests/compat_runtime_test.rs
    • Keep the concrete hotlist workflow regressions in this existing integration test file
    • Extend existing Zhihu hotlist export/screen regressions to assert the new summaries and the dashboard marker payload
    • Keep the Excel route workflow assertion limited to summary plus “no dashboard navigate marker,” because exact launcher handoff is covered in src/compat/artifact_open.rs unit tests
  • Modify: tests/browser_tool_test.rs
    • Add MacPolicy coverage for approved local-dashboard presentation, rejected malformed presentation, and unchanged normal-domain validation in one exact file
    • Extend the existing default_rules_allow_zhihu_navigation area with the new local-dashboard validation tests rather than creating a second policy test location
  • Reference only if summary wording ripples outward: tests/agent_runtime_test.rs:173-258
    • Existing direct-runtime user-visible summary assertion for Zhihu Excel export
  • Reference only if summary wording ripples outward: tests/service_task_flow_test.rs:704-839
    • Existing CLI-to-service user-visible summary assertion for Zhihu Excel export
  • Reference only if summary wording ripples outward: tests/service_ws_session_test.rs:755-869
    • Existing service-binary user-visible summary assertion for Zhihu Excel export
  • Reference: tests/compat_screen_html_export_tool_test.rs
    • Reuse the exact test seam screen_html_export_tool_renders_dashboard_html_with_presentation_contract
    • Existing proof that screen_html_export already returns presentation.url
  • Reference: docs/superpowers/specs/2026-04-06-zhihu-hotlist-post-export-auto-open-design.md

Scope Guardrails

  • Do not modify frontend/service-console/sg_claw_service_console.html.
  • Do not modify src/service/protocol.rs.
  • Do not modify browser-helper.html.
  • Do not modify /sgclaw/callback/* endpoint contracts.
  • Do not modify websocket protocol framing or src/browser/ws_protocol.rs.
  • Do not turn Excel-open and dashboard-open into a combined mode.
  • Do not add a general-purpose local file browser or generic file:// allowlist.
  • Do not move post-export decisions into the frontend service console.
  • Do not require websocket-backend parity in this slice.

Task 1: Add failing workflow tests for route-specific post-export actions

Files:

  • Modify: tests/compat_runtime_test.rs:2154-2304

  • Reference: src/compat/workflow_executor.rs:375-446

  • Reference: docs/superpowers/specs/2026-04-06-zhihu-hotlist-post-export-auto-open-design.md

  • Step 1: Rewrite the Excel hotlist assertion as a red test for the new summary only

Keep the current flow setup, but tighten the expectation so it proves the workflow route now reports post-export open success while staying exclusive from the dashboard path.

Target shape:

#[test]
fn handle_browser_message_chains_hotlist_skill_into_xlsx_export_and_auto_open() {
    // existing setup
    assert!(summary.contains("已导出并打开知乎热榜 Excel"));
    assert!(generated.exists());
    assert!(!sent.iter().any(|message| {
        matches!(
            message,
            AgentMessage::Command { action, params, .. }
                if action == &Action::Navigate
                    && params.get("sgclaw_local_dashboard_open").is_some()
        )
    }));
}

Do not try to prove real OS launching in this workflow test. The exact .xlsx path handoff to the launcher belongs in src/compat/artifact_open.rs unit tests from Task 2.

  • Step 2: Rewrite the dashboard hotlist assertion as a red test for browser auto-open

Tighten the existing dashboard test so it proves the workflow consumes presentation.url and emits the approved compat marker payload.

Target shape:

#[test]
fn handle_browser_message_chains_hotlist_skill_into_screen_export_and_auto_open() {
    // existing setup
    assert!(summary.contains("已在浏览器中打开知乎热榜大屏"));
    let navigate = sent.iter().find_map(|message| match message {
        AgentMessage::Command { action, params, security, .. }
            if action == &Action::Navigate
                && security.expected_domain == "__sgclaw_local_dashboard__" => Some((params, security)),
        _ => None,
    }).expect("dashboard route should emit local-dashboard navigate request");

    assert!(navigate.0["url"].as_str().unwrap().starts_with("file://"));
    assert_eq!(navigate.0["sgclaw_local_dashboard_open"]["source"], json!("compat.workflow_executor"));
    assert_eq!(navigate.0["sgclaw_local_dashboard_open"]["kind"], json!("zhihu_hotlist_screen"));
    assert_eq!(navigate.0["sgclaw_local_dashboard_open"]["presentation_url"], navigate.0["url"]);
}

Also assert that this route still logs call screen_html_export and does not invoke the Excel opener path.

  • Step 3: Add a missing-presentation.url regression in the workflow test module if none exists

Put this close to the existing hotlist tests and keep it narrow:

#[test]
fn handle_browser_message_reports_dashboard_auto_open_protocol_error_when_presentation_url_is_missing() {
    // mock screen_html_export success payload with output_path but no presentation.url
    // assert summary contains 已生成知乎热榜大屏 <path>,但浏览器自动打开失败:
}

Use the existing summary/path helpers in the file instead of inventing new parsing helpers.

  • Step 4: Run the focused compat runtime tests to verify they fail

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_xlsx_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_screen_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_reports_dashboard_auto_open_protocol_error_when_presentation_url_is_missing --test compat_runtime_test -- --exact

Expected: FAIL because the workflow still returns artifact-only summaries and has no post-export open handling.

  • Step 5: Commit the red workflow tests
git add tests/compat_runtime_test.rs
git commit -m "test: add hotlist post-export auto-open regressions"

Task 2: Implement the compat post-export opener and update workflow summaries

Files:

  • Create: src/compat/artifact_open.rs

  • Modify: src/compat/mod.rs

  • Modify: src/compat/workflow_executor.rs:375-446

  • Test: src/compat/artifact_open.rs

  • Test: tests/compat_runtime_test.rs

  • Step 1: Add the red unit tests in src/compat/artifact_open.rs before writing production code

Create the new module with a #[cfg(test)] block first so the Excel opener has an exact, non-UI verification seam.

Target tests:

#[test]
fn open_exported_xlsx_with_passes_generated_path_to_launcher() {
    let mut seen = None;
    let result = open_exported_xlsx_with(Path::new("C:/tmp/zhihu-hotlist.xlsx"), |path| {
        seen = Some(path.to_path_buf());
        Ok(())
    });
    assert!(matches!(result, PostExportOpen::Opened));
    assert_eq!(seen.unwrap(), PathBuf::from("C:/tmp/zhihu-hotlist.xlsx"));
}

#[test]
fn open_exported_xlsx_with_reports_launcher_failure() {
    let result = open_exported_xlsx_with(Path::new("C:/tmp/zhihu-hotlist.xlsx"), |_path| {
        Err("launcher failed".to_string())
    });
    assert!(matches!(result, PostExportOpen::Failed(reason) if reason.contains("launcher failed")));
}

Add one matching dashboard payload test in the same file:

#[test]
fn open_local_dashboard_uses_exact_approved_marker_payload() {
    // FakeBrowserBackend records invoke(action, params, expected_domain)
    // assert expected_domain == "__sgclaw_local_dashboard__"
    // assert params.url == params.sgclaw_local_dashboard_open.presentation_url
    // assert source/kind/output_path all match the approved contract
}

This step is mandatory so the Excel route is proven to hand the generated path to the opener without launching a real application.

  • Step 2: Run the new unit tests to verify they fail

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_passes_generated_path_to_launcher --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_reports_launcher_failure --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_local_dashboard_uses_exact_approved_marker_payload --lib -- --exact

Expected: FAIL because src/compat/artifact_open.rs does not exist yet.

  • Step 3: Create the small compat opener module

Add one focused helper module rather than embedding side effects directly into workflow_executor.rs.

Target shape:

pub const LOCAL_DASHBOARD_EXPECTED_DOMAIN: &str = "__sgclaw_local_dashboard__";
pub const LOCAL_DASHBOARD_SOURCE: &str = "compat.workflow_executor";
pub const LOCAL_DASHBOARD_KIND_ZHIHU_HOTLIST_SCREEN: &str = "zhihu_hotlist_screen";

pub enum PostExportOpen {
    Opened,
    Failed(String),
}

pub fn open_exported_xlsx(output_path: &Path) -> PostExportOpen {
    open_exported_xlsx_with(output_path, launch_with_default_xlsx_app)
}

fn open_exported_xlsx_with<F>(output_path: &Path, opener: F) -> PostExportOpen
where
    F: FnOnce(&Path) -> Result<(), String>,
{ /* test seam */ }

pub fn open_local_dashboard(
    browser_backend: &dyn BrowserBackend,
    output_path: &Path,
    presentation_url: &str,
) -> PostExportOpen { /* invoke Action::Navigate with exact marker payload */ }

Keep the module tiny. The only dedicated test seam in this file should be open_exported_xlsx_with(...); do not introduce a general launcher trait.

  • Step 4: Implement the Windows-first .xlsx opener minimally

Use a focused local launcher that targets the current environment first.

Preferred target shape:

Command::new("cmd")
    .args(["/C", "start", "", output_path_as_windows_string])

Requirements:

- fail if the path does not exist
- do not swallow command-spawn errors
- do not open arbitrary user-selected files from outside this workflow
- keep cross-platform behavior minimal; only add a fallback branch if required to keep tests/build portable

If you need a non-Windows fallback for compilation, keep it obviously minimal and out of the hot path.

  • Step 5: Parse payloads in workflow_executor.rs and call the new helper

Refactor export_xlsx(...) and export_screen(...) just enough to separate:

- tool execution
- payload parsing
- route-specific post-export open
- summary formatting

Minimal target behavior:

match open_exported_xlsx(&output_path) {
    PostExportOpen::Opened => format!("已导出并打开知乎热榜 Excel {output_path}"),
    PostExportOpen::Failed(reason) => format!("已导出知乎热榜 Excel {output_path},但自动打开失败:{reason}"),
}
match open_local_dashboard(browser_backend, &output_path, &presentation_url) {
    PostExportOpen::Opened => format!("已在浏览器中打开知乎热榜大屏 {output_path}"),
    PostExportOpen::Failed(reason) => format!("已生成知乎热榜大屏 {output_path},但浏览器自动打开失败:{reason}"),
}

Change signatures only as much as needed to pass browser_backend into the dashboard route. Do not broaden unrelated call chains.

  • Step 6: Export the helper module

Update src/compat/mod.rs:

pub mod artifact_open;

Do not reorder unrelated module exports unless rustfmt does it.

  • Step 7: Run the focused library and workflow regressions to verify green

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_passes_generated_path_to_launcher --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_reports_launcher_failure --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_local_dashboard_uses_exact_approved_marker_payload --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_xlsx_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_screen_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_reports_dashboard_auto_open_protocol_error_when_presentation_url_is_missing --test compat_runtime_test -- --exact

Expected: PASS for the new library tests and the workflow regressions, unless the dashboard-open path still fails at backend/policy validation.

  • Step 8: Commit the compat opener and workflow changes
git add src/compat/artifact_open.rs src/compat/mod.rs src/compat/workflow_executor.rs tests/compat_runtime_test.rs
git commit -m "feat: auto-open zhihu hotlist export artifacts"

Task 3: Add failing backend and security tests for the narrow local-dashboard allowance

Files:

  • Modify: src/browser/callback_backend.rs:536-840

  • Modify: tests/browser_tool_test.rs (default_rules_allow_zhihu_navigation section plus new local-dashboard validation tests)

  • Reference: src/security/mac_policy.rs:56-132

  • Step 1: Add a red callback-backend acceptance test for the approved local-dashboard request shape

Extend the existing src/browser/callback_backend.rs test module with one focused navigate test.

Target shape:

#[test]
fn callback_backend_accepts_approved_local_dashboard_navigate_request() {
    let host = Arc::new(FakeCallbackHost::new(vec![success_reply(json!({ "navigated": true }))]));
    let backend = BrowserCallbackBackend::new(
        host.clone(),
        test_policy(),
        "http://127.0.0.1:17888/sgclaw/browser-helper.html",
    );

    let output = backend.invoke(
        Action::Navigate,
        json!({
            "url": "file:///C:/tmp/zhihu-hotlist-screen.html",
            "sgclaw_local_dashboard_open": {
                "source": "compat.workflow_executor",
                "kind": "zhihu_hotlist_screen",
                "output_path": "C:/tmp/zhihu-hotlist-screen.html",
                "presentation_url": "file:///C:/tmp/zhihu-hotlist-screen.html"
            }
        }),
        "__sgclaw_local_dashboard__",
    );

    assert!(output.unwrap().success);
    assert_eq!(host.requests()[0].command, json!([
        "http://127.0.0.1:17888/sgclaw/browser-helper.html",
        "sgBrowerserOpenPage",
        "file:///C:/tmp/zhihu-hotlist-screen.html"
    ]));
}

Do not weaken any existing normal-domain tests.

  • Step 2: Add red rejection tests in exact files

Put malformed-request rejection in src/browser/callback_backend.rs next to the acceptance test:

#[test]
fn callback_backend_rejects_local_dashboard_navigate_without_required_marker_fields() {}

Put policy-only validation in tests/browser_tool_test.rs so all public MacPolicy assertions stay in one place:

#[test]
fn mac_policy_rejects_non_html_local_dashboard_presentation() {}

#[test]
fn default_rules_allow_zhihu_navigation() {
    let policy = MacPolicy::load_from_path(...).unwrap();
    policy.validate(&Action::Navigate, "www.zhihu.com").unwrap();
}

Do not create a second MacPolicy regression location.

  • Step 3: Run the focused backend/policy tests to verify red

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_accepts_approved_local_dashboard_navigate_request --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_rejects_local_dashboard_navigate_without_required_marker_fields --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" mac_policy_rejects_non_html_local_dashboard_presentation --test browser_tool_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" default_rules_allow_zhihu_navigation --test browser_tool_test -- --exact

Expected: the new local-dashboard tests FAIL; default_rules_allow_zhihu_navigation should still PASS.

  • Step 4: Commit the red backend/security tests
git add src/browser/callback_backend.rs tests/browser_tool_test.rs
git commit -m "test: lock local dashboard navigate boundary"

Task 4: Implement the narrow callback-backend and MacPolicy allowance

Files:

  • Modify: src/browser/callback_backend.rs:300-351

  • Modify: src/security/mac_policy.rs:56-132

  • Maybe modify: src/security/mod.rs:9-27

  • Test: src/browser/callback_backend.rs:536-840

  • Test: tests/browser_tool_test.rs (default_rules_allow_zhihu_navigation section plus new local-dashboard validation tests)

  • Step 1: Add a narrow local-dashboard validation helper in MacPolicy

Keep validate(...) unchanged for ordinary domain flow. Add one small explicit helper instead.

Target shape:

pub fn validate_local_dashboard_presentation(
    &self,
    action: &Action,
    expected_domain: &str,
    presentation_url: &str,
    output_path: &str,
) -> Result<(), SecurityError> {
    // require Action::Navigate
    // require expected_domain == "__sgclaw_local_dashboard__"
    // require file:// URL
    // require .html path
    // require normalized file URL path matches output_path
}

If you need a new SecurityError variant for malformed local-dashboard input, add the smallest one that keeps error text clear.

  • Step 2: Recognize only the exact approved request shape in BrowserCallbackBackend::invoke(...)

Before the normal self.mac_policy.validate(&action, expected_domain)? path runs, detect the one approved special case.

Minimal target behavior:

if let Some(local_dashboard) = approved_local_dashboard_request(&action, &params, expected_domain) {
    self.mac_policy.validate_local_dashboard_presentation(
        &action,
        expected_domain,
        &local_dashboard.presentation_url,
        &local_dashboard.output_path,
    )?;
} else {
    self.mac_policy.validate(&action, expected_domain)?;
}

The helper should require all of these fields exactly:

- action == Action::Navigate
- expected_domain == "__sgclaw_local_dashboard__"
- params.url exists
- params.sgclaw_local_dashboard_open.source == "compat.workflow_executor"
- params.sgclaw_local_dashboard_open.kind == "zhihu_hotlist_screen"
- params.sgclaw_local_dashboard_open.output_path exists
- params.sgclaw_local_dashboard_open.presentation_url exists and equals params.url

Anything else must continue down the normal rejection path.

  • Step 3: Keep build_command(Action::Navigate, ...) simple

Do not add a second browser opcode or change the callback-host runtime contract. The approved local-dashboard case should still flow into the existing navigate command builder so the emitted command stays:

json!([
    self.helper_page_url,
    "sgBrowerserOpenPage",
    target_url,
])
  • Step 4: Run the focused backend/security tests to verify green

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_accepts_approved_local_dashboard_navigate_request --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_rejects_local_dashboard_navigate_without_required_marker_fields --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" mac_policy_rejects_non_html_local_dashboard_presentation --test browser_tool_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" default_rules_allow_zhihu_navigation --test browser_tool_test -- --exact

Expected: PASS

  • Step 5: Re-run the dashboard workflow regression after backend validation lands

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_screen_export_and_auto_open --test compat_runtime_test -- --exact

Expected: PASS

  • Step 6: Commit the backend/security implementation
git add src/browser/callback_backend.rs src/security/mac_policy.rs src/security/mod.rs tests/browser_tool_test.rs tests/compat_runtime_test.rs
git commit -m "fix: allow approved local dashboard auto-open"

If src/security/mod.rs did not change, omit it from the commit.

Task 5: Run the focused verification sweep

Files:

  • Verify: src/compat/artifact_open.rs

  • Verify: tests/compat_runtime_test.rs

  • Verify: tests/compat_screen_html_export_tool_test.rs

  • Verify: tests/browser_tool_test.rs

  • Verify: src/browser/callback_backend.rs test module

  • Reference only if summary wording ripples outward: tests/agent_runtime_test.rs:173-258

  • Reference only if summary wording ripples outward: tests/service_task_flow_test.rs:704-839

  • Reference only if summary wording ripples outward: tests/service_ws_session_test.rs:755-869

  • Step 1: Re-run the library and workflow regressions

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_passes_generated_path_to_launcher --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_exported_xlsx_with_reports_launcher_failure --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" open_local_dashboard_uses_exact_approved_marker_payload --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_xlsx_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_chains_hotlist_skill_into_screen_export_and_auto_open --test compat_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" handle_browser_message_reports_dashboard_auto_open_protocol_error_when_presentation_url_is_missing --test compat_runtime_test -- --exact

Expected: PASS

  • Step 2: Re-run the tool contract regression that the dashboard route depends on

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" screen_html_export_tool_renders_dashboard_html_with_presentation_contract --test compat_screen_html_export_tool_test -- --exact

Expected: PASS

  • Step 3: Re-run the callback-backend and policy boundary tests

Run:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_accepts_approved_local_dashboard_navigate_request --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" callback_backend_rejects_local_dashboard_navigate_without_required_marker_fields --lib -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" mac_policy_rejects_non_html_local_dashboard_presentation --test browser_tool_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" default_rules_allow_zhihu_navigation --test browser_tool_test -- --exact

Expected: PASS

  • Step 4: Re-run outward-facing summary regressions only if needed

Only if the updated summary text breaks existing assertions, run exactly these existing regressions and adjust only the affected expectation text:

cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" production_submit_task_routes_zhihu_through_ws_backend_without_helper_bootstrap --test agent_runtime_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" client_to_service_regression_routes_zhihu_without_helper_bootstrap_or_invalid_hmac_seed_output --test service_task_flow_test -- --exact
cargo test --manifest-path "D:/data/ideaSpace/rust/sgClaw/claw-new/Cargo.toml" service_binary_submit_flow_routes_zhihu_without_helper_bootstrap --test service_ws_session_test -- --exact

Expected: PASS for any test you had to touch. Skip this step entirely if those files needed no edits.

  • Step 5: Inspect scope before finishing with exact git commands

Run:

git diff --name-only -- src/compat/artifact_open.rs src/compat/mod.rs src/compat/workflow_executor.rs src/browser/callback_backend.rs src/security/mac_policy.rs src/security/mod.rs tests/compat_runtime_test.rs tests/browser_tool_test.rs tests/agent_runtime_test.rs tests/service_task_flow_test.rs tests/service_ws_session_test.rs
git diff --stat -- src/compat/artifact_open.rs src/compat/mod.rs src/compat/workflow_executor.rs src/browser/callback_backend.rs src/security/mac_policy.rs src/security/mod.rs tests/compat_runtime_test.rs tests/browser_tool_test.rs tests/agent_runtime_test.rs tests/service_task_flow_test.rs tests/service_ws_session_test.rs

Confirm the diff only touches:

- compat workflow/orchestration
- compat post-export helper module
- callback backend narrow local-dashboard acceptance
- MacPolicy narrow local-dashboard validation
- focused related tests

Confirm it does not touch:

- frontend/service-console/
- src/service/protocol.rs
- browser-helper.html
- callback-host endpoint contracts
- websocket transport/protocol files
  • Step 6: Commit only if verification required additional code changes
git add src/compat/artifact_open.rs src/compat/mod.rs src/compat/workflow_executor.rs src/browser/callback_backend.rs src/security/mac_policy.rs tests/compat_runtime_test.rs tests/browser_tool_test.rs tests/agent_runtime_test.rs tests/service_task_flow_test.rs tests/service_ws_session_test.rs
git commit -m "test: tighten hotlist post-export auto-open verification"

If verification required no further code changes, do not create an extra commit.