Files
claw/docs/superpowers/plans/2026-04-11-tq-lineloss-deterministic-skill-plan.md
木炎 72b79feca9 docs: add tq lineloss design and plan
Add the tq lineloss design spec and implementation plan documents used for the deterministic submit work.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:12:35 +08:00

28 KiB

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:

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

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:

{
  "type": "report-artifact",
  "report_name": "tq-lineloss-report",
  "status": "ok",
  "org": {
    "label": "国网兰州供电公司",
    "code": "008df5db70319f73e0508eoac23e0c3c"
  },
  "period": {
    "mode": "month",
    "mode_code": "<real-backend-mode-code>",
    "value": "2026-03",
    "payload": {
      "<real-backend-field>": "<real-backend-value>"
    }
  },
  "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:

[[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:

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
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:

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:

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:

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:

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
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:

#[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:

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:

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:

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
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:

#[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:

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:

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
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:

#[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:

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:

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:

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
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:

#[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:

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:

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:

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
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:

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:

cargo test

Expected: PASS.

  • Step 5: Re-run the staged skill JS tests

Run:

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
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.