# TQ Lineloss Deterministic Skill 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 a staged `tq-lineloss-report.collect_lineloss` browser-script skill plus a `。。。` deterministic submit path in `claw-new` that extracts and normalizes company/month/week parameters without LLM, executes through the existing pipe browser-script seam, and does not regress Zhihu hotlist behavior. **Architecture:** Keep the new behavior behind a narrow deterministic branch that activates only when the raw instruction ends with the exact suffix `。。。`. `claw-new` owns deterministic trigger detection, explicit scene matching, semantic extraction, canonical normalization, prompt-or-execute control flow, and artifact interpretation; the staged skill owns page inspection, source/API collection, row normalization, export/report-log behavior, and final artifact generation. Reuse the existing `browser_script` execution seam already used by the direct browser path so the backend can later swap from pipe to ws without changing the deterministic contract. **Tech Stack:** Rust 2021, Cargo tests, existing `BrowserPipeTool` / `execute_browser_script_tool` seam, staged skill packaging under `claw/claw/skills/skill_staging`, browser-side JavaScript, deterministic string parsing and normalization. --- ## Execution Context - Follow @superpowers:test-driven-development for every behavior change. - Follow @superpowers:verification-before-completion before claiming each task is done. - Do **not** create a git worktree unless the user explicitly asks. - Keep the new behavior as a narrow branch; do **not** redesign the whole runtime into a general registry engine in this slice. - Preserve `src/runtime/engine.rs:147-159` and `src/runtime/engine.rs:265-286` behavior unless a failing regression test proves a change is required. - Do **not** add ws runtime requirements on `main`; keep ws-readiness isolated to backend-neutral contracts only. - Never fall back to page defaults for missing company, mode, or period in deterministic mode. - If a deterministic request does not match the lineloss whitelist scene, return a deterministic mismatch prompt instead of falling through to ordinary orchestration. ## File Map ### New or modified files in `claw-new` - Create: `src/compat/deterministic_submit.rs` - suffix detection, deterministic scene match, prompt-or-execute decision - Create: `src/compat/tq_lineloss/mod.rs` - public normalization and artifact helpers - Create: `src/compat/tq_lineloss/contracts.rs` - canonical request/result data structures and status semantics - Create: `src/compat/tq_lineloss/org_resolver.rs` - alias generation, canonical label/code resolution, ambiguity handling - Create: `src/compat/tq_lineloss/period_resolver.rs` - month/week extraction, contradiction detection, canonical payload building - Create: `src/compat/tq_lineloss/org_units.rs` - checked-in canonical unit dictionary derived from the real source tree data - Modify: `src/compat/mod.rs` - export the deterministic and lineloss modules - Modify: `src/agent/mod.rs` - insert the deterministic branch before ordinary LLM interpretation, but only when the exact suffix is present - Modify only if code duplication would otherwise occur: `src/compat/direct_skill_runtime.rs` - extract narrow shared browser-script execution helpers without changing current configured direct-submit behavior - Read but avoid changing unless tests force it: `src/runtime/engine.rs` - existing Zhihu hotlist routing/prompt logic must remain intact ### New staged skill package in `claw` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/SKILL.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/SKILL.toml` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/references/collection-flow.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/references/data-quality.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/assets/scene-snapshot/index.html` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.js` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js` - Create if staging conventions require it: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/scenes/tq-lineloss-report/scene.json` ### Tests - Create: `tests/deterministic_submit_test.rs` - Modify: `tests/compat_runtime_test.rs` - Modify only if end-to-end submit coverage requires it: `tests/runtime_task_flow_test.rs` --- ## Locked contracts ### Deterministic trigger contract - Trigger only when the raw instruction ends with the exact suffix `。。。`. - No suffix: current behavior unchanged. - Suffix + unsupported scene: explicit deterministic mismatch prompt. - Suffix is not permission for arbitrary browser actions; only fixed deterministic scenes are allowed. - Negative cases must stay non-deterministic or mismatched exactly as designed: - ASCII `...` is not the trigger - `。。。。` is not the trigger - `。。。` appearing in the middle of the instruction is not the trigger - any trailing whitespace after `。。。` is not the trigger in this slice ### Canonical org contract The resolver must output both display and backend values: ```rust pub struct ResolvedOrg { pub label: String, pub code: String, } ``` Required supported inputs include: - `兰州公司` - `天水公司` - `国网兰州供电公司` - `城关供电分公司` - `榆中县供电公司` - normalized shorthand such as `榆中县公司` Rules: - derive aliases from the real unit tree data - require uniqueness before execution - ambiguous aliases prompt and stop - missing company prompts and stop ### Canonical period contract ```rust pub enum PeriodMode { Month, Week, } pub struct ResolvedPeriod { pub mode: PeriodMode, pub mode_code: String, pub value: String, pub payload: serde_json::Value, } ``` Required supported inputs include: - `月累计 2026-03` - `月累计 2026年3月` - `周累计 2026年第12周` Rules: - month and week intent are mutually exclusive - missing mode prompts and stop - missing period prompts and stop - bare `第12周` is incomplete in this slice and must prompt for year instead of guessing - derive the real backend `period_mode_code` values and request payload field names from the source page/API contract before implementation; do not ship placeholder enum echoes such as `month`/`week` unless the source materials prove those are the real backend codes - never use page-selected defaults in deterministic mode ### Artifact contract Lock the field names now so `claw-new` can interpret status without re-embedding business logic: ```json { "type": "report-artifact", "report_name": "tq-lineloss-report", "status": "ok", "org": { "label": "国网兰州供电公司", "code": "008df5db70319f73e0508eoac23e0c3c" }, "period": { "mode": "month", "mode_code": "", "value": "2026-03", "payload": { "": "" } }, "columns": [], "rows": [], "counts": { "rows": 0 }, "export": { "attempted": false, "status": "skipped", "message": null }, "reasons": [] } ``` Status mapping in `claw-new`: - `ok` -> task success - `partial` -> task success with partial summary - `blocked` -> task failure - `error` -> task failure --- ### Task 1: Scaffold the staged skill package and written contract **Files:** - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/SKILL.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/SKILL.toml` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/references/collection-flow.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/references/data-quality.md` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/assets/scene-snapshot/index.html` - Create if required: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/scenes/tq-lineloss-report/scene.json` - [ ] **Step 1: Write the failing package contract files** Create the package using `fault-details-report` as the structure reference. Lock one tool only: ```toml [[tools]] name = "collect_lineloss" kind = "browser_script" description = "Collect 台区线损月/周累计线损率 rows using normalized company and period parameters and return a structured report artifact." ``` Declare required args in `SKILL.toml`: - `expected_domain` - `org_label` - `org_code` - `period_mode` - `period_mode_code` - `period_value` - `period_payload` - [ ] **Step 2: Write `SKILL.md` before implementation** Document: - when to use / when not to use - required normalized args only - blocked/error semantics - exact returned artifact fields - no raw natural-language values passed to backend requests - [ ] **Step 3: Write the reference docs** `references/collection-flow.md` must describe: - relevant page state - month request mapping - week request mapping - export/report-log flow if retained `references/data-quality.md` must define: - canonical output columns - required field coverage - status semantics - partial/error rules - org/period normalization assumptions - [ ] **Step 4: Add scene metadata if the current staging registry needs it** Keep it narrow: one scene, one tool, one artifact type. - [ ] **Step 5: Add an automated staged-skill load/resolve check** Add `tests/deterministic_submit_test.rs` coverage that loads the staged skills root used by runtime tests, resolves `tq-lineloss-report.collect_lineloss`, and asserts the tool is discoverable with the required args: - `expected_domain` - `org_label` - `org_code` - `period_mode` - `period_mode_code` - `period_value` - `period_payload` Run: ```bash cargo test deterministic_submit_discovers_tq_lineloss_skill_contract -- --exact ``` Expected: FAIL before the package is fully wired, PASS once the staged skill contract is discoverable and complete. - [ ] **Step 6: Verify structural parity with `fault-details-report`** Run a manual file-layout diff and confirm there are no placeholder descriptions or missing required docs. - [ ] **Step 7: Commit** ```bash git add "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report" "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/scenes/tq-lineloss-report/scene.json" git commit -m "feat: scaffold tq lineloss staged skill contract" ``` --- ### Task 2: Add browser-side JS red tests and implement the staged collector **Files:** - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.js` - Create: `D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js` - [ ] **Step 1: Write the failing JS tests first** Cover deterministic pure helpers for: - missing normalized args -> blocked/error contract - month request shape uses `org_code` + canonical month payload - week request shape uses `org_code` + canonical week payload - artifact field names and counts - partial/error status shaping - no raw user-entered org text leakage into request fields Example test skeleton: ```javascript const test = require('node:test'); const assert = require('node:assert/strict'); const { validateArgs, buildMonthRequest, buildWeekRequest, normalizeRows, buildArtifact } = require('./collect_lineloss.js'); test('buildMonthRequest uses canonical org code and month payload', () => { const request = buildMonthRequest({ org_code: 'ORG-1', period_payload: { year: 2026, month: 3 } }); assert.equal(request.orgCode, 'ORG-1'); assert.equal(request.year, 2026); assert.equal(request.month, 3); }); test('buildArtifact locks field names and partial semantics', () => { const artifact = buildArtifact({ org_label: '国网兰州供电公司', org_code: 'ORG-1', period_mode: 'month', period_mode_code: 'month', period_value: '2026-03', period_payload: { year: 2026, month: 3 }, rows: [{ id: 1 }], status: 'partial', reasons: ['export_failed'] }); assert.equal(artifact.report_name, 'tq-lineloss-report'); assert.equal(artifact.org.code, 'ORG-1'); assert.equal(artifact.period.value, '2026-03'); assert.deepEqual(artifact.reasons, ['export_failed']); }); ``` - [ ] **Step 2: Run the JS test file to confirm failure** Run: ```bash node --test "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js" ``` Expected: FAIL because the script/helpers do not exist yet. - [ ] **Step 3: Write the minimal browser-side implementation** Required structure: ```javascript function validateArgs(args) { /* require normalized canonical args */ } function buildMonthRequest(args) { /* build month request from canonical values */ } function buildWeekRequest(args) { /* build week request from canonical values */ } function normalizeRows(rawRows) { /* canonical columns only */ } function buildArtifact(input) { /* locked artifact shape */ } return (async () => { const args = __SKILL_ARGS__; validateArgs(args); // validate page context // collect from page/API // normalize rows // optionally attempt export/report-log if the real business flow requires it return buildArtifact(result); })(); ``` Keep test exports behind an environment-safe guard so the file still works as browser-eval code. - [ ] **Step 4: Re-run the JS tests until they pass** Run: ```bash node --test "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js" ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.js" "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js" git commit -m "feat: add tq lineloss browser collection script" ``` --- ### Task 3: Add deterministic suffix detection and explicit scene routing **Files:** - Create: `src/compat/deterministic_submit.rs` - Modify: `src/compat/mod.rs` - Modify: `src/agent/mod.rs` - Create: `tests/deterministic_submit_test.rs` - [ ] **Step 1: Write failing routing tests** Add Rust tests for: - exact raw `。。。` suffix enables deterministic mode - no suffix leaves current routing untouched - suffix + unsupported deterministic request returns supported-scene prompt - when page URL/title context is available and does not match the lineloss scene, deterministic routing returns mismatch/block prompt instead of proceeding - Zhihu hotlist request without suffix keeps the current route - ASCII `...` does not trigger deterministic mode - `。。。。` does not trigger deterministic mode - `。。。` in the middle of the instruction does not trigger deterministic mode - trailing whitespace after `。。。` does not trigger deterministic mode in this slice Suggested tests: ```rust #[test] fn deterministic_submit_requires_exact_suffix() {} #[test] fn deterministic_submit_nonmatch_returns_supported_scene_message() {} #[test] fn deterministic_submit_rejects_page_context_mismatch() {} #[test] fn zhihu_hotlist_request_without_suffix_keeps_existing_route() {} #[test] fn deterministic_submit_rejects_non_exact_suffix_variants() {} ``` - [ ] **Step 2: Run the targeted routing tests and confirm failure** Run: ```bash cargo test deterministic_submit_requires_exact_suffix -- --exact cargo test deterministic_submit_nonmatch_returns_supported_scene_message -- --exact cargo test zhihu_hotlist_request_without_suffix_keeps_existing_route -- --exact ``` Expected: FAIL because the deterministic routing seam does not exist yet. - [ ] **Step 3: Implement the narrow deterministic routing module** Recommended public shape: ```rust pub enum DeterministicSubmitDecision { NotDeterministic, Prompt { summary: String }, Execute(DeterministicExecutionPlan), } ``` `src/agent/mod.rs` should: 1. detect deterministic suffix 2. if not deterministic, continue current flow untouched 3. if prompt, return `TaskComplete` 4. if execute, pass the plan into the browser-script execution seam - [ ] **Step 4: Re-run the routing tests** Run: ```bash cargo test deterministic_submit_requires_exact_suffix -- --exact cargo test deterministic_submit_nonmatch_returns_supported_scene_message -- --exact cargo test zhihu_hotlist_request_without_suffix_keeps_existing_route -- --exact ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add src/compat/deterministic_submit.rs src/compat/mod.rs src/agent/mod.rs tests/deterministic_submit_test.rs git commit -m "feat: add deterministic submit routing seam" ``` --- ### Task 4: Implement company/unit normalization from real source data **Files:** - Create: `src/compat/tq_lineloss/mod.rs` - Create: `src/compat/tq_lineloss/contracts.rs` - Create: `src/compat/tq_lineloss/org_resolver.rs` - Create: `src/compat/tq_lineloss/org_units.rs` - Modify: `tests/deterministic_submit_test.rs` - [ ] **Step 1: Write failing org resolver tests** Cover: - `兰州公司` -> canonical `国网兰州供电公司` + correct code - `天水公司` -> canonical `国网天水供电公司` + correct code - `城关供电分公司` -> lower-level direct match - `榆中县公司` -> normalized county alias match - ambiguous alias prompts instead of guessing - missing company prompts instead of executing Example skeleton: ```rust #[test] fn lineloss_org_resolver_matches_city_alias() {} #[test] fn lineloss_org_resolver_matches_county_alias() {} #[test] fn lineloss_org_resolver_prompts_on_ambiguity() {} ``` - [ ] **Step 2: Run the org tests and confirm failure** Run: ```bash cargo test lineloss_org_resolver_matches_city_alias -- --exact cargo test lineloss_org_resolver_matches_county_alias -- --exact cargo test lineloss_org_resolver_prompts_on_ambiguity -- --exact ``` Expected: FAIL because the resolver and checked-in unit dictionary do not exist yet. - [ ] **Step 3: Check in the canonical unit dictionary and implement alias resolution** Rules: - derive data from the real source materials, not guessed literals - keep canonical `label` and `code` - generate normalized aliases from formal names - support both city-company and district/county/sub-company levels - require uniqueness before execution - [ ] **Step 4: Implement explicit prompt messages** Examples: - `已命中台区线损报表技能,但缺少供电单位,请补充如“兰州公司”或“城关供电分公司”。` - `已命中台区线损报表技能,但供电单位存在歧义,请补充更完整名称。` - [ ] **Step 5: Re-run the org tests** Run: ```bash cargo test lineloss_org_resolver_matches_city_alias -- --exact cargo test lineloss_org_resolver_matches_county_alias -- --exact cargo test lineloss_org_resolver_prompts_on_ambiguity -- --exact ``` Expected: PASS. - [ ] **Step 6: Commit** ```bash git add src/compat/tq_lineloss/mod.rs src/compat/tq_lineloss/contracts.rs src/compat/tq_lineloss/org_resolver.rs src/compat/tq_lineloss/org_units.rs tests/deterministic_submit_test.rs git commit -m "feat: add tq lineloss org normalization" ``` --- ### Task 5: Implement period extraction and canonical payload building **Files:** - Create: `src/compat/tq_lineloss/period_resolver.rs` - Modify: `src/compat/tq_lineloss/mod.rs` - Modify: `tests/deterministic_submit_test.rs` - [ ] **Step 1: Write failing period resolver tests** Cover: - `月累计 2026-03` - `月累计 2026年3月` - `周累计 2026年第12周` - contradictory month/week expressions prompt - missing mode prompts - missing period prompts - bare `第12周` prompts for year in this slice - real backend month/week mode codes and request payload field names are derived from source materials instead of placeholder values Example skeleton: ```rust #[test] fn lineloss_period_resolver_parses_month_text() {} #[test] fn lineloss_period_resolver_parses_week_text() {} #[test] fn lineloss_period_resolver_prompts_for_missing_year_on_week() {} #[test] fn lineloss_period_resolver_rejects_contradictory_mode() {} ``` - [ ] **Step 2: Run the period tests and confirm failure** Run: ```bash cargo test lineloss_period_resolver_parses_month_text -- --exact cargo test lineloss_period_resolver_parses_week_text -- --exact cargo test lineloss_period_resolver_prompts_for_missing_year_on_week -- --exact cargo test lineloss_period_resolver_rejects_contradictory_mode -- --exact ``` Expected: FAIL because the period resolver does not exist yet. - [ ] **Step 3: Implement the minimal resolver** Output contract: ```rust pub struct ResolvedPeriod { pub mode: PeriodMode, pub mode_code: String, pub value: String, pub payload: serde_json::Value, } ``` Rules: - no page-default fallback - no implicit current-year assumptions - no mixed month/week execution - [ ] **Step 4: Re-run the period tests** Run: ```bash cargo test lineloss_period_resolver_parses_month_text -- --exact cargo test lineloss_period_resolver_parses_week_text -- --exact cargo test lineloss_period_resolver_prompts_for_missing_year_on_week -- --exact cargo test lineloss_period_resolver_rejects_contradictory_mode -- --exact ``` Expected: PASS. - [ ] **Step 5: Commit** ```bash git add src/compat/tq_lineloss/period_resolver.rs src/compat/tq_lineloss/mod.rs tests/deterministic_submit_test.rs git commit -m "feat: add tq lineloss period normalization" ``` --- ### Task 6: Wire deterministic execution through the existing browser-script seam **Files:** - Modify: `src/compat/deterministic_submit.rs` - Modify: `src/agent/mod.rs` - Modify if needed: `src/compat/direct_skill_runtime.rs` - Modify: `tests/deterministic_submit_test.rs` - Modify: `tests/compat_runtime_test.rs` - [ ] **Step 1: Write failing execution tests** Cover: - successful deterministic lineloss request builds canonical tool args - missing company/mode/period returns prompt without browser execution - `partial` artifact maps to successful partial summary - `blocked` and `error` artifacts map to failed completion Example skeleton: ```rust #[test] fn deterministic_lineloss_execution_passes_canonical_args() {} #[test] fn deterministic_lineloss_missing_company_does_not_invoke_browser() {} #[test] fn deterministic_lineloss_partial_artifact_maps_to_partial_summary() {} ``` - [ ] **Step 2: Run the execution tests and confirm failure** Run: ```bash cargo test deterministic_lineloss_execution_passes_canonical_args -- --exact cargo test deterministic_lineloss_missing_company_does_not_invoke_browser -- --exact cargo test deterministic_lineloss_partial_artifact_maps_to_partial_summary -- --exact ``` Expected: FAIL because the deterministic execution plan is not wired yet. - [ ] **Step 3: Implement execution via the existing `browser_script` seam** Build tool args only from normalized values: - `expected_domain` - `org_label` - `org_code` - `period_mode` - `period_mode_code` - `period_value` - `period_payload` Resolve the tool explicitly to: - `tq-lineloss-report.collect_lineloss` Do not introduce a new browser opcode family or second browser protocol. - [ ] **Step 4: Implement central artifact interpretation** Recommended helper: ```rust fn summarize_lineloss_artifact(artifact: &serde_json::Value) -> (bool, String) ``` Summary must include canonical org/period and row counts, and surface blocked/partial/error reasons. - [ ] **Step 5: Re-run the execution tests** Run: ```bash cargo test deterministic_lineloss_execution_passes_canonical_args -- --exact cargo test deterministic_lineloss_missing_company_does_not_invoke_browser -- --exact cargo test deterministic_lineloss_partial_artifact_maps_to_partial_summary -- --exact ``` Expected: PASS. - [ ] **Step 6: Commit** ```bash git add src/compat/deterministic_submit.rs src/agent/mod.rs src/compat/direct_skill_runtime.rs tests/deterministic_submit_test.rs tests/compat_runtime_test.rs git commit -m "feat: execute deterministic tq lineloss skill through browser script seam" ``` --- ### Task 7: Add Zhihu regression coverage and run the full verification set **Files:** - Modify: `tests/compat_runtime_test.rs` - Modify only if required: `tests/runtime_task_flow_test.rs` - Reuse: `tests/deterministic_submit_test.rs` - [ ] **Step 1: Add focused Zhihu regression tests** Required assertions: - ordinary Zhihu hotlist requests without `。。。` still use the current path - existing export/presentation requests still preserve their current behavior - deterministic suffix does not silently route unmatched requests into Zhihu logic - an existing non-lineloss direct `browser_script` path outside the new scene still behaves unchanged - [ ] **Step 2: Add end-to-end deterministic submit coverage** Required assertions: - suffix detection - scene match - page-context mismatch prompt/block behavior when URL/title contradict the lineloss scene - missing/ambiguous prompts - canonical args passed to the browser-script tool - returned summary shows canonical org and period - execution stays on the existing pipe-backed browser-script seam with no ws-only dependency introduced on `main` - [ ] **Step 3: Run the focused Rust tests** Run: ```bash cargo test --test deterministic_submit_test cargo test --test compat_runtime_test cargo test --test runtime_task_flow_test ``` Expected: PASS. - [ ] **Step 4: Run the whole Rust suite** Run: ```bash cargo test ``` Expected: PASS. - [ ] **Step 5: Re-run the staged skill JS tests** Run: ```bash node --test "D:/data/ideaSpace/rust/sgClaw/claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.test.js" ``` Expected: PASS. - [ ] **Step 6: Commit** ```bash git add tests/deterministic_submit_test.rs tests/compat_runtime_test.rs tests/runtime_task_flow_test.rs git commit -m "test: cover deterministic tq lineloss routing and zhihu regression" ``` --- ## Final verification checklist - [ ] `。。。` is the only deterministic trigger. - [ ] Non-`。。。` requests preserve current routing. - [ ] Deterministic page-context mismatch blocks or mismatches before execution when URL/title contradict the lineloss scene. - [ ] Zhihu hotlist behavior is unchanged. - [ ] Existing non-lineloss direct `browser_script` behavior is unchanged. - [ ] Deterministic non-match returns an explicit supported-scene message. - [ ] Missing company prompts. - [ ] Ambiguous company prompts. - [ ] Missing mode prompts. - [ ] Missing period prompts. - [ ] Bare `第12周` prompts for year. - [ ] Canonical org code is passed to the staged skill. - [ ] Canonical period mode code and payload are passed to the staged skill. - [ ] The staged skill returns the locked artifact shape. - [ ] Execution uses the existing `browser_script` seam only. - [ ] No ws-specific runtime dependency is added on `main`. ## Implementation notes - Prefer extracting a tiny shared execution helper from `src/compat/direct_skill_runtime.rs` if needed instead of duplicating tool lookup or browser-script invocation code. - Keep deterministic whitelist configuration in one place, but do not expand this slice into a full general scene-registry redesign. - If a failing test suggests changing Zhihu behavior, fix the deterministic branch or test harness instead of weakening the existing Zhihu path. - The checked-in unit dictionary is part of the deterministic contract; treat updates to that data as explicit behavior changes and cover them with tests.