Files
ParkingRobot/docs/superpowers/plans/2026-08-03-daily-summary-job-domain-visualization-upgrade.md
T

41 KiB
Raw Blame History

Daily Summary Job Domain Visualization Upgrade Implementation Plan

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

Goal: Upgrade daily-summary-job so it understands the current task, renders the function or algorithm's real domain effect, and connects visible objects to the current problem, cause, consequence, correction, expected result, and task-matched verification evidence.

Architecture: Extend the normalized report facts with optional algorithm views and task-specific validation facts. Keep one diagnostic interaction shell, but render its central canvas through a declarative adapter registry selected from the current task's semantics. Split maintainable CSS and JavaScript assets during skill development, then inline them into the final self-contained HTML during rendering.

Tech Stack: Python 3.12 standard library, unittest, HTML5, CSS, vanilla JavaScript, SVG/DOM, Node syntax checks.

Global Constraints

  • Implement the approved design in docs/superpowers/specs/2026-08-03-daily-summary-job-domain-visualization-upgrade-design.md.
  • Modify the personal skill at C:\Users\admin\.codex\skills\daily-summary-job; request filesystem approval when the execution environment requires it.
  • Do not hard-code trajectory planning as the meaning of algorithm visualization. Select the view from the current task's purpose, observable business objects, inputs, outputs, and correctness constraints.
  • A generic flow diagram may assist navigation, but it must not replace a domain effect view when spatial, numeric, temporal, state, search, or structured-data evidence exists.
  • Distinguish actual observation, static reconstruction, conceptual preview, verified result, and conflicting evidence in both data and presentation.
  • Build validation scenarios from the current task and its correctness constraints. Do not substitute an unrelated fixed test matrix.
  • Preserve reports that omit the new optional fields.
  • Final HTML must contain no external resource or network dependency.
  • Do not modify business code, run expensive tests by default, stage changes, or create Git commits.
  • Preserve the current UTF-8, date/module classification, checkpoint limits, stable issue IDs, and Markdown/HTML pairing behavior.

User-Approved Scope Adjustment

This implementation ships only the generic declarative composite-scene renderer and the unified diagnosis shell. Do not implement dedicated spatial-scene, cartesian-series, graph-network, state-machine, or data-flow renderers in this round. Keep the adapter registry as an extension point, so future task-specific work can add those renderers without changing the report contract.


File Structure

Modify

  • C:\Users\admin\.codex\skills\daily-summary-job\SKILL.md — task understanding, visualization-brief generation, domain-view selection, and task-matched validation workflow.
  • C:\Users\admin\.codex\skills\daily-summary-job\references\report-schema.md — optional algorithm-view, issue-target, solution-preview, verified-result, and task-validation contracts.
  • C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py — validate new facts, render the Markdown algorithm section, bundle assets, and validate rendered links.
  • C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py — schema, backward compatibility, Markdown, asset bundling, adapter, interaction, and CLI regression tests.
  • C:\Users\admin\.codex\skills\daily-summary-job\assets\interactive-report-template.html — diagnostic-shell markup and asset placeholders.
  • C:\Users\admin\.codex\skills\daily-summary-job\agents\openai.yaml — UI description and default prompt for task-matched domain visualization.

Create

  • C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-styles.css — domain canvas, view modes, diagnostic drawer, evidence states, responsiveness, and reduced-motion styles.
  • C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js — declarative scene-object renderer registry and built-in layout strategies.
  • C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js — report state, selectors, view switching, target highlighting, diagnosis rendering, and keyboard interaction.

The three development assets are embedded into every rendered report. They must never remain as runtime <link> or <script src> dependencies.


Task 1: Extend the normalized fact contract without breaking old reports

Files:

  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py:152-365
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py:32-340

Interfaces:

  • Consumes: existing validate_report_data(data: dict[str, Any]) -> None.

  • Produces: optional algorithm_views: list[dict], optional task_validation: dict, optional issue visualization fields, and visual_target_index(data) -> dict[str, set[str]].

  • Step 1: Add a complete task-matched visualization fixture

Add this helper to ReportRenderingTests and use it only in new visualization tests so the existing sample_data() remains a legacy-format fixture:

def visualization_data(self):
    data = self.sample_data()
    data["algorithm_views"] = [
        {
            "id": "local-g2-smoother",
            "name": "Local G2 路径平滑",
            "purpose": "把粗路径转换为满足连续性、曲率和安全约束的可执行路径。",
            "domain": "geometry-smoothing",
            "adapter": "spatial-scene",
            "evidence_state": "actual",
            "inputs": [
                {"id": "coarse-path", "label": "粗路径", "detail": "离散位姿序列", "source_ref": "tests/input.json"}
            ],
            "outputs": [
                {"id": "smooth-path", "label": "平滑路径", "detail": "连续候选轨迹", "source_ref": "tests/output.json"}
            ],
            "constraints": [
                {"id": "curvature-limit", "label": "曲率上限", "detail": "abs(kappa) <= 0.2", "status": "失败", "source_ref": "tests/output.json"}
            ],
            "stages": [
                {
                    "id": "candidate-evaluation",
                    "label": "候选评价",
                    "detail": "比较连续性、曲率和碰撞约束。",
                    "function_refs": ["PathSmoothing/CandidateEvaluator.cs"],
                    "target_ids": ["current-path", "curvature-peak"],
                }
            ],
            "scene": {
                "coordinate_system": "cartesian",
                "objects": [
                    {
                        "id": "current-path",
                        "kind": "polyline",
                        "label": "当前路径",
                        "evidence_state": "actual",
                        "source_ref": "tests/output.json",
                        "data": {"points": [[0, 0], [1, 0.4], [2, 1.1]]},
                    },
                    {
                        "id": "curvature-peak",
                        "kind": "annotation",
                        "label": "曲率峰值",
                        "evidence_state": "actual",
                        "source_ref": "tests/output.json",
                        "data": {"x": 1, "y": 0.4, "value": 0.31},
                    },
                    {
                        "id": "preview-path",
                        "kind": "polyline",
                        "label": "候选修正路径",
                        "evidence_state": "conceptual",
                        "source_ref": "docs/solution.md",
                        "data": {"points": [[0, 0], [1, 0.3], [2, 1.1]]},
                    },
                ],
                "layers": [
                    {"id": "baseline", "label": "正常机制", "mode": "baseline", "object_ids": ["current-path"]},
                    {"id": "current", "label": "当前问题", "mode": "current", "object_ids": ["current-path", "curvature-peak"]},
                    {"id": "proposed", "label": "修正预演", "mode": "proposed", "object_ids": ["preview-path"]},
                ],
            },
            "source_refs": ["tests/input.json", "tests/output.json"],
        }
    ]
    data["issues"][0].update(
        {
            "algorithm_view_id": "local-g2-smoother",
            "target_ids": ["curvature-peak"],
            "effect_target_ids": ["current-path"],
            "solution_preview": {
                "summary": "重新约束连接段导数。",
                "expected_result": "曲率峰值回到上限内。",
                "evidence_state": "conceptual",
                "target_ids": ["preview-path"],
            },
        }
    )
    data["task_validation"] = {
        "task": "验证 Local G2 平滑候选是否满足当前路径约束。",
        "correctness_criteria": [
            {"id": "criterion-curvature", "statement": "全路径曲率不超过 0.2。", "source_ref": "tests/output.json"}
        ],
        "checks": [
            {
                "id": "check-curvature",
                "name": "曲率扫描",
                "status": "失败",
                "criterion_ids": ["criterion-curvature"],
                "command": "verify_path_smoothing.ps1",
                "result": "max_abs_curvature=0.31",
                "evidence_ref": "tests/output.json",
            }
        ],
        "missing_evidence": [
            {
                "criterion_id": "criterion-curvature",
                "needed": "修正后的相同输入扫描结果",
                "suggested_check": "对同一输入重新运行曲率扫描。",
            }
        ],
    }
    return data
  • Step 2: Write failing contract and compatibility tests

Add tests with these exact assertions:

def test_accepts_legacy_report_without_algorithm_views(self):
    self.require_target().validate_report_data(self.sample_data())

def test_accepts_linked_algorithm_view_and_task_validation(self):
    target = self.require_target()
    data = self.visualization_data()
    target.validate_report_data(data)
    self.assertEqual(
        {"current-path", "curvature-peak", "preview-path", "candidate-evaluation"},
        target.visual_target_index(data)["local-g2-smoother"],
    )

def test_rejects_unknown_visual_target(self):
    data = self.visualization_data()
    data["issues"][0]["target_ids"] = ["missing-target"]
    with self.assertRaisesRegex(ValueError, "unknown visual target"):
        self.require_target().validate_report_data(data)

def test_verified_result_requires_verified_state_and_validation_reference(self):
    data = self.visualization_data()
    data["issues"][0]["verified_result"] = {
        "summary": "看起来已经改善。",
        "evidence_state": "conceptual",
        "target_ids": ["preview-path"],
        "validation_refs": [],
    }
    with self.assertRaisesRegex(ValueError, "verified_result"):
        self.require_target().validate_report_data(data)

def test_task_validation_rejects_unknown_criterion(self):
    data = self.visualization_data()
    data["task_validation"]["checks"][0]["criterion_ids"] = ["criterion-missing"]
    with self.assertRaisesRegex(ValueError, "unknown correctness criterion"):
        self.require_target().validate_report_data(data)
  • Step 3: Run the focused tests and confirm RED

Run:

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py ReportRenderingTests

Expected: new tests fail because visual_target_index and visualization validation do not exist; existing legacy tests remain green.

  • Step 4: Add validation constants and helpers

Add near the existing constants:

VISUAL_EVIDENCE_STATES = {"actual", "static", "conceptual", "verified", "conflict"}
VIEW_MODES = {"baseline", "current", "proposed", "verified"}
VISUAL_ID = re.compile(r"[a-z0-9][a-z0-9-]{1,63}")

Add helpers before validate_report_data:

def _require_visual_id(value: Any, field: str) -> str:
    text = _require_text(value, field)
    if not VISUAL_ID.fullmatch(text):
        raise ValueError(f"invalid {field}: {text}")
    return text


def _require_text_list(value: Any, field: str) -> list[str]:
    return [_require_text(item, f"{field} item") for item in _require_list(value, field)]


def _validate_named_fact(item: Any, field: str, required: tuple[str, ...]) -> None:
    if not isinstance(item, dict):
        raise ValueError(f"{field} item must be an object")
    for key in required:
        _require_text(item.get(key), f"{field}.{key}")


def visual_target_index(data: dict[str, Any]) -> dict[str, set[str]]:
    result: dict[str, set[str]] = {}
    for view in data.get("algorithm_views", []):
        targets = {stage["id"] for stage in view["stages"]}
        targets.update(obj["id"] for obj in view["scene"]["objects"])
        result[view["id"]] = targets
    return result
  • Step 5: Validate algorithm views, issue links, and task criteria

Implement _validate_algorithm_views(data) and _validate_task_validation(data) and call them from validate_report_data before issue-link validation. Require the exact fields used by visualization_data(), unique view/stage/object/layer IDs, valid evidence states, valid layer modes, stage target references, and layer object references. Require every scene object's data to be an object. Require actual and verified scene objects to carry a non-empty source_ref; static and conceptual objects may reference source or design evidence but must retain their explicit state. Permit any safe adapter slug so future tasks are not restricted to a fixed domain list.

For each issue, validate optional fields only when present:

view_id = issue.get("algorithm_view_id")
if view_id is not None:
    view_id = _require_visual_id(view_id, "issue.algorithm_view_id")
    if view_id not in targets_by_view:
        raise ValueError(f"unknown algorithm view: {view_id}")
    for field in ("target_ids", "effect_target_ids"):
        for target_id in _require_text_list(issue.get(field, []), f"issue.{field}"):
            if target_id not in targets_by_view[view_id]:
                raise ValueError(f"unknown visual target: {target_id}")

Require solution_preview.evidence_state to be conceptual or static. Require verified_result.evidence_state == "verified" and at least one non-empty validation_refs item.

  • Step 6: Run focused and full tests and confirm GREEN

Run:

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py ReportRenderingTests
python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py

Expected: focused contract tests pass; the full suite retains all existing passes plus the new tests.

  • Step 7: Review the scoped diff without staging or committing

Run:

git diff --no-index -- NUL C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py

Expected: only the intended contract helpers and validation paths are present. Do not run git add or git commit.


Task 2: Render algorithm purpose and task-matched validation in Markdown

Files:

  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py:249-285
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py:342-452

Interfaces:

  • Consumes: validated algorithm_views and task_validation from Task 1.

  • Produces: _render_algorithm_markdown(data: dict[str, Any]) -> list[str] and _render_task_validation_markdown(data: dict[str, Any]) -> list[str].

  • Step 1: Write failing Markdown assertions

def test_renders_algorithm_function_domain_effect_and_task_validation(self):
    markdown = self.require_target().render_markdown(self.visualization_data())
    for expected in (
        "## 2. 当前函数与算法功能",
        "Local G2 路径平滑",
        "把粗路径转换为满足连续性、曲率和安全约束的可执行路径",
        "候选评价",
        "PathSmoothing/CandidateEvaluator.cs",
        "## 8. 当前任务匹配的验证",
        "全路径曲率不超过 0.2",
        "max_abs_curvature=0.31",
        "修正后的相同输入扫描结果",
    ):
        self.assertIn(expected, markdown)

def test_legacy_markdown_keeps_original_section_numbers(self):
    markdown = self.require_target().render_markdown(self.sample_data())
    self.assertIn("## 2. 今日完成的工作", markdown)
    self.assertIn("## 7. 证据索引", markdown)
    self.assertNotIn("当前函数与算法功能", markdown)
  • Step 2: Run the two tests and confirm RED

Run:

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py ReportRenderingTests.test_renders_algorithm_function_domain_effect_and_task_validation ReportRenderingTests.test_legacy_markdown_keeps_original_section_numbers

Expected: the visualization-aware test fails; the legacy numbering test passes.

  • Step 3: Add deterministic Markdown helpers

Implement _render_algorithm_markdown so each view shows purpose, domain, evidence state, inputs, outputs, constraints, stages, function references, and source references. Implement _render_task_validation_markdown so criteria, executed checks, and missing evidence are separate lists. Do not infer pass/fail or substitute generic tests.

Use this section order only when algorithm_views is non-empty:

1. 今日结论摘要
2. 当前函数与算法功能
3. 今日完成的工作
4. 今日发现的问题
5. 问题如何被发现及证据
6. 已采取的改善和验证结果
7. 尚未解决的风险与下一步
8. 当前任务匹配的验证
9. 证据索引

Keep the current seven-section output byte-compatible in structure when algorithm_views is absent.

  • Step 4: Run focused and full tests and confirm GREEN

Run the commands from Step 2, then:

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py

Expected: all Markdown and legacy tests pass.

  • Step 5: Inspect a rendered Markdown sample

Run:

python -X utf8 -c "import importlib.util; from pathlib import Path; p=Path(r'C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py'); s=importlib.util.spec_from_file_location('daily',p); m=importlib.util.module_from_spec(s); s.loader.exec_module(m); print(m.render_markdown(__import__('json').loads(Path('sample-visual-report.json').read_text(encoding='utf-8'))))"

Before running, create sample-visual-report.json in a temporary directory from visualization_data() through the test helper or CLI fixture, then remove only that temporary file. Expected: algorithm function, task-specific criteria, run checks, and missing evidence are visibly separated.


Task 3: Split development assets and inline them into the final HTML

Files:

  • Create: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-styles.css
  • Create: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js
  • Create: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\assets\interactive-report-template.html
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\prepare_report.py:453-470,624-660
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py:286-342

Interfaces:

  • Produces: load_visual_assets(asset_dir: Path | None = None) -> dict[str, str].

  • Changes: render_html(data, template, visual_assets=None) -> str while preserving existing two-argument callers.

  • Step 1: Write failing asset-bundling tests

def test_inlines_visual_assets_without_runtime_dependencies(self):
    target = self.require_html_target()
    html = target.render_html(
        self.visualization_data(), TEMPLATE_PATH.read_text(encoding="utf-8")
    )
    self.assertNotIn("__VISUAL_STYLES__", html)
    self.assertNotIn("__VISUAL_ADAPTERS__", html)
    self.assertNotIn("__VISUAL_RUNTIME__", html)
    self.assertIn("DailySummaryVisuals", html)
    self.assertNotRegex(html, r"<link\b|<script[^>]+src=|https?://")

def test_rejects_missing_or_duplicate_asset_placeholder(self):
    target = self.require_html_target()
    template = TEMPLATE_PATH.read_text(encoding="utf-8").replace("__VISUAL_RUNTIME__", "")
    with self.assertRaisesRegex(ValueError, "visual asset placeholder"):
        target.render_html(self.visualization_data(), template)
  • Step 2: Run the focused tests and confirm RED

Run:

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py HtmlRenderingTests.test_inlines_visual_assets_without_runtime_dependencies HtmlRenderingTests.test_rejects_missing_or_duplicate_asset_placeholder

Expected: failures because the template and loader do not contain the new placeholders.

  • Step 3: Move styles and scripts into focused development files

Move the current <style> content to visualization-styles.css and the current inline behavior to visualization-runtime.js. Initialize visualization-adapters.js with this stable public namespace:

'use strict';
globalThis.DailySummaryVisuals = (() => {
  const registry = new Map();

  function register(name, renderer) {
    if (!/^[a-z0-9][a-z0-9-]+$/.test(name) || typeof renderer !== 'function') {
      throw new TypeError('invalid visualization adapter');
    }
    registry.set(name, renderer);
  }

  function select(name) {
    return registry.get(name) || registry.get('composite-scene');
  }

  function render(view, root, context) {
    const renderer = select(view.adapter);
    if (!renderer) throw new Error('composite-scene adapter is not registered');
    return renderer(view, root, context);
  }

  return { register, select, render };
})();

Replace template bodies with exact single placeholders:

<style>__VISUAL_STYLES__</style>
...
<script id="report-data" type="application/json">__REPORT_DATA__</script>
<script>__VISUAL_ADAPTERS__</script>
<script>__VISUAL_RUNTIME__</script>
  • Step 4: Implement the asset loader and renderer replacement
VISUAL_ASSET_FILES = {
    "__VISUAL_STYLES__": "visualization-styles.css",
    "__VISUAL_ADAPTERS__": "visualization-adapters.js",
    "__VISUAL_RUNTIME__": "visualization-runtime.js",
}


def load_visual_assets(asset_dir: Path | None = None) -> dict[str, str]:
    root = Path(asset_dir or Path(__file__).parent.parent / "assets")
    return {
        placeholder: (root / filename).read_text(encoding="utf-8")
        for placeholder, filename in VISUAL_ASSET_FILES.items()
    }


def render_html(
    data: dict[str, Any],
    template: str,
    visual_assets: dict[str, str] | None = None,
) -> str:
    validate_report_data(data)
    replacements = {
        "__REPORT_DATA__": safe_json_for_html(data),
        **(visual_assets or load_visual_assets()),
    }
    rendered = template
    for placeholder, value in replacements.items():
        if rendered.count(placeholder) != 1:
            label = "report data placeholder" if placeholder == "__REPORT_DATA__" else "visual asset placeholder"
            raise ValueError(f"template must contain exactly one {label}: {placeholder}")
        rendered = rendered.replace(placeholder, value)
    return rendered

When --template points to a custom template, continue loading the trusted bundled assets from the skill's assets directory unless a future explicit CLI option changes that contract.

  • Step 5: Run bundling tests, full tests, and syntax checks
python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js

Expected: Python suite passes; both Node checks exit 0.


Task 4: Implement the generic declarative domain-effect renderer

Files:

  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py

Interfaces:

  • Consumes: algorithm_views[].scene.objects, scene.layers, and the selected view mode.

  • Produces: SVG/DOM elements carrying data-target-id, data-evidence-state, and accessible labels.

  • Public JS API: DailySummaryVisuals.register(name, renderer), .select(name), and .render(view, root, context).

  • Step 1: Add task-derived adapter assertions

Use visualization_data() as the business fixture. Add static and generated-HTML assertions:

def test_domain_adapter_renders_task_objects_not_fixed_demo_content(self):
    html = self.require_html_target().render_html(
        self.visualization_data(), TEMPLATE_PATH.read_text(encoding="utf-8")
    )
    for value in ("local-g2-smoother", "current-path", "curvature-peak", "preview-path"):
        self.assertIn(value, html)
    self.assertNotIn("固定轨迹示例", html)

def test_unknown_safe_adapter_has_composite_fallback(self):
    data = self.visualization_data()
    data["algorithm_views"][0]["adapter"] = "custom-business-domain"
    html = self.require_html_target().render_html(
        data, TEMPLATE_PATH.read_text(encoding="utf-8")
    )
    self.assertIn("custom-business-domain", html)
    self.assertIn("composite-scene", html)
  • Step 2: Run the focused tests and confirm RED

Expected: the fallback or declarative object hooks are missing.

  • Step 3: Add safe DOM/SVG construction helpers

Implement helpers that assign text through textContent and SVG attributes through setAttribute; never concatenate untrusted labels into innerHTML:

const SVG_NS = 'http://www.w3.org/2000/svg';

function element(name, attrs = {}, text = '') {
  const node = document.createElement(name);
  Object.entries(attrs).forEach(([key, value]) => node.setAttribute(key, String(value)));
  if (text) node.textContent = text;
  return node;
}

function svgElement(name, attrs = {}) {
  const node = document.createElementNS(SVG_NS, name);
  Object.entries(attrs).forEach(([key, value]) => node.setAttribute(key, String(value)));
  return node;
}

function markTarget(node, object) {
  node.dataset.targetId = object.id;
  node.dataset.evidenceState = object.evidence_state;
  node.setAttribute('tabindex', '0');
  node.setAttribute('role', 'button');
  node.setAttribute('aria-label', `${object.label}${object.evidence_state}`);
  return node;
}
  • Step 4: Implement adapter strategies over shared primitives

Register these layout strategies, while keeping their data task-driven:

  • composite-scene: render supplied points, polylines, curves, regions, nodes, edges, state blocks, data items, annotations, and clear unsupported-kind cards for the remainder.

The generic renderer must filter visible objects from the selected scene.layers[].object_ids; it must not invent domain samples. Unknown adapter names must select composite-scene. Do not add dedicated renderer implementations in this task.

  • Step 5: Add evidence-state and target CSS

In visualization-styles.css, use line style, icon/text, and color together:

[data-evidence-state="actual"] { --state-color: var(--blue); }
[data-evidence-state="static"] { --state-color: var(--amber); }
[data-evidence-state="conceptual"] { --state-color: var(--amber); stroke-dasharray: 8 6; opacity: .82; }
[data-evidence-state="verified"] { --state-color: var(--green); }
[data-evidence-state="conflict"] { --state-color: var(--red); stroke-dasharray: 3 4; }
[data-target-id].is-highlighted { filter: drop-shadow(0 0 5px var(--state-color)); }
[data-target-id]:focus-visible { outline: 3px solid #e7a628; outline-offset: 3px; }
  • Step 6: Run Python tests and Node syntax checks

Use the commands from Task 3 Step 5. Expected: all pass, and no test claims business correctness beyond the current fixture's actual evidence.


Task 5: Build the four-mode interactive diagnosis shell

Files:

  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\assets\interactive-report-template.html
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-styles.css
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py

Interfaces:

  • State: { algorithmId, issueId, mode, solutionIndex }.

  • Modes: baseline, current, proposed, verified.

  • Consumes: Task 1 issue links and Task 4 adapter API.

  • Step 1: Write failing interaction-hook tests

def test_renders_algorithm_selector_four_modes_domain_canvas_and_diagnosis_card(self):
    html = self.require_html_target().render_html(
        self.visualization_data(), TEMPLATE_PATH.read_text(encoding="utf-8")
    )
    for hook in (
        'id="algorithm-selector"',
        'data-view-mode="baseline"',
        'data-view-mode="current"',
        'data-view-mode="proposed"',
        'data-view-mode="verified"',
        'id="domain-canvas"',
        'id="diagnosis-current"',
        'id="diagnosis-cause"',
        'id="diagnosis-impact"',
        'id="diagnosis-solution"',
        'id="diagnosis-expected"',
        'id="task-validation"',
    ):
        self.assertIn(hook, html)

def test_verified_mode_is_guarded_by_verified_result(self):
    runtime = (TEMPLATE_PATH.parent / "visualization-runtime.js").read_text(encoding="utf-8")
    self.assertIn("hasVerifiedResult", runtime)
    self.assertIn("button.disabled", runtime)
    self.assertIn("尚无修正后的匹配验证证据", runtime)
  • Step 2: Run the focused tests and confirm RED

Expected: the new shell hooks and verified-result guard are absent.

  • Step 3: Replace the two-column issue workbench with the approved shell

Add:

  • algorithm and issue selectors;
  • four mode buttons with aria-pressed;
  • layer toggles;
  • central #domain-canvas;
  • algorithm-stage navigation;
  • object diagnosis card;
  • expandable source/test evidence;
  • existing solution steps, validation gates, and roadmap below the canvas.

When algorithm_views is absent, hide the algorithm controls and retain the legacy text diagnosis behavior.

  • Step 4: Implement one state-driven render path

In visualization-runtime.js, use one render function so selectors, modes, canvas, diagnosis, validation, and buttons never drift:

const report = JSON.parse(document.getElementById('report-data').textContent);
const views = Array.isArray(report.algorithm_views) ? report.algorithm_views : [];
const issues = Array.isArray(report.issues) ? report.issues : [];
const state = {
  algorithmId: views[0]?.id || '',
  issueId: issues[0]?.id || '',
  mode: views.length ? 'baseline' : 'current',
  solutionIndex: 0,
};

function currentView() {
  return views.find((view) => view.id === state.algorithmId) || null;
}

function currentIssue() {
  return issues.find((issue) => issue.id === state.issueId) || null;
}

function hasVerifiedResult(issue) {
  return Boolean(issue?.verified_result?.evidence_state === 'verified' && issue.verified_result.validation_refs?.length);
}

function renderApp() {
  const view = currentView();
  const issue = currentIssue();
  renderSelectors(view, issue);
  renderModeButtons(issue);
  renderDomainCanvas(view, issue);
  renderDiagnosis(issue);
  renderTaskValidation(report.task_validation);
  renderExistingReportSections(issue);
}
  • Step 5: Implement mode-to-layer and diagnosis behavior

  • baseline: show the normal algorithm layer and purpose/input/output/constraints.

  • current: show current layer, highlight target_ids, then effect_target_ids in propagation order.

  • proposed: show solution_preview.target_ids, expected result, and conceptual/static label.

  • verified: enable only when hasVerifiedResult(issue); show verified targets and validation references.

Clicking or pressing Enter/Space on a visual target must select the linked issue. Arrow keys change issues only when focus is not in a form control; mode buttons and targets retain visible focus.

  • Step 6: Add responsive and reduced-motion behavior

At desktop width use mode rail + canvas + diagnosis drawer. Under 900px stack the drawer below the canvas. Under 560px use single-column selectors and controls. When prefers-reduced-motion: reduce is active, reveal the complete impact path immediately rather than animating it.

  • Step 7: Extend rendered-pair validation to cover algorithm facts

Update _validate_rendered_text so every algorithm view ID, view evidence state, linked issue target ID, correctness criterion ID, and executed check ID exists in the generated HTML. Require the view name, purpose, criterion statement, and check result in Markdown. Keep the existing issue ID/evidence checks and external-resource rejection.

Add a negative test that removes curvature-peak from rendered HTML and expects validate to fail with HTML is missing visual target: curvature-peak.

  • Step 8: Run the full suite and generated-HTML validation
python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js

Expected: all tests and syntax checks pass; generated HTML contains no external resource.


Task 6: Teach the skill the task-understanding and dynamic-validation workflow

Files:

  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\SKILL.md
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\references\report-schema.md
  • Modify: C:\Users\admin\.codex\skills\daily-summary-job\agents\openai.yaml

Interfaces:

  • Consumes: data contract and renderer from Tasks 1-5.

  • Produces: repeatable Agent instructions that create task-matched views and validation facts without requiring the user to fill JSON manually.

  • Step 1: Add the mandatory understanding sequence to SKILL.md

Insert a concise workflow before report JSON construction:

## Build a task-matched algorithm view

When today's work changes, diagnoses, or discusses a function or algorithm:

1. Identify its business purpose, inputs, outputs, stages, observable objects, and correctness constraints from current evidence.
2. Decide what domain effect lets a reader see the algorithm working. Prefer spatial scenes, numeric plots, search/state structures, timelines, or transformed data over a generic flowchart when the evidence supports them.
3. Build one `algorithm_views` entry from actual run/test data when available. Label source reconstruction as `static` and solution prediction as `conceptual`.
4. Link every visual issue to existing stage/object IDs. Show current targets, effect propagation, candidate changes, and verified results as separate states.
5. If the evidence cannot support a credible domain view, list the missing evidence and omit the invented scene.
  • Step 2: Replace generic validation wording with task-matched validation
## Match validation to the current task

Derive correctness criteria from the selected function or algorithm, then locate only tests, commands, samples, and runtime evidence that directly evaluate those criteria. Record checks actually run, their exact results, and missing evidence separately. If no matching test exists, propose a task-specific check and keep the conclusion unverified. Never claim coverage from an unrelated fixed scenario.

Retain the existing safety rule against expensive tests by default.

  • Step 3: Document the complete schema and one non-prescriptive example

In references/report-schema.md, document every Task 1 field, allowed evidence states, object/layer linking rules, task-validation shape, verified-result requirements, and legacy behavior. Use one example only to illustrate the contract, and state explicitly that its domain does not constrain adapter selection.

  • Step 4: Regenerate UI metadata from the updated skill

Run:

python -X utf8 C:\Users\admin\.codex\skills\.system\skill-creator\scripts\generate_openai_yaml.py C:\Users\admin\.codex\skills\daily-summary-job --interface 'display_name=Daily Summary Job' --interface 'short_description=按当前任务生成带领域算法诊断的交互日报' --interface 'default_prompt=使用 $daily-summary-job 理解当前任务和算法,以匹配的领域效果图展示正常机制、问题、影响、修正方案与验证结果,并更新今日日报。'

Expected: agents/openai.yaml contains only the interface block with the three supplied values and valid UTF-8 Chinese.

  • Step 5: Validate skill structure and concise loading behavior
python -X utf8 C:\Users\admin\.codex\skills\.system\skill-creator\scripts\quick_validate.py C:\Users\admin\.codex\skills\daily-summary-job

Expected: Skill is valid!. Confirm SKILL.md stays under 500 lines and keeps detailed field definitions in references/report-schema.md.


Task 7: End-to-end verification on the current task and backward compatibility

Files:

  • Test: all files under C:\Users\admin\.codex\skills\daily-summary-job
  • Generate temporary outputs only under a verified temporary directory or this project's dailywork_report when explicitly updating the real report.

Interfaces:

  • Consumes: completed skill from Tasks 1-6.

  • Produces: fresh verification evidence for schema, rendering, interaction hooks, self-containment, task matching, and legacy reports.

  • Step 1: Run the complete automated suite

python -X utf8 C:\Users\admin\.codex\skills\daily-summary-job\scripts\test_prepare_report.py

Expected: every test passes with zero failures. Record the actual test count; do not reuse the previous count of 31.

  • Step 2: Run skill and JavaScript validation
python -X utf8 C:\Users\admin\.codex\skills\.system\skill-creator\scripts\quick_validate.py C:\Users\admin\.codex\skills\daily-summary-job
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-adapters.js
node --check C:\Users\admin\.codex\skills\daily-summary-job\assets\visualization-runtime.js

Expected: skill valid; both JavaScript files exit 0.

  • Step 3: Run a temporary legacy report round trip

Use the existing sample_data() shape without algorithm_views. Run render, validate, and render --update in a new temporary project. Expected: Markdown and HTML are created, validate returns valid: true, and update reuses the same pair.

  • Step 4: Run a temporary current-task domain-view round trip

Use the Task 1 visualization_data() facts, which match the current path-smoothing work rather than an unrelated generic test. Run render, then validate. Assert:

  • valid is true;

  • HTML contains the task's actual object IDs and values;

  • current, proposed, and verified controls are present;

  • verified mode is disabled because this fixture has no verified result;

  • Markdown contains the task-specific criterion and missing evidence;

  • no external URL, <link>, or <script src> exists.

  • Step 5: Verify failure gates with mutations

Starting from the same task facts, independently mutate and reject:

  • an unknown target_id;
  • a proposed view marked verified without validation references;
  • a check referencing an unknown correctness criterion;
  • a layer referencing an unknown object;
  • a rendered HTML file containing an external URL.

Expected: each mutation returns a non-zero CLI status and an error naming the violated contract.

  • Step 6: Perform live visual and interaction QA when a browser runtime is available

Open the generated domain-view HTML and verify:

  • algorithm and issue selection;
  • all four mode controls;
  • task-specific domain objects, not a fixed demo;
  • click/keyboard target selection;
  • cause and effect highlighting;
  • solution-step preview;
  • verified-mode guard;
  • desktop and narrow-screen layout;
  • reduced-motion behavior.

If the browser runtime is unavailable, record this exact check as 待验证风险; source inspection and syntax checks do not replace visual QA.

  • Step 7: Review only skill and report artifacts; do not commit

Run scoped file listings and diffs. Confirm no business source file, staging index, or Git commit was changed. Report created/modified skill files, verification commands, exact pass counts, and any remaining visual-QA risk.


Plan Completion Criteria

  • All seven tasks satisfy their focused tests before the next task begins.
  • The full suite passes after each task that changes Python or JavaScript behavior.
  • A legacy report and a task-matched domain report both pass CLI validation.
  • The task-matched report visibly connects domain objects to problem, cause, consequence, solution preview, expected result, and available verification evidence.
  • No fixed domain example is presented as a universal validation scenario.
  • No external dependency, business-code edit, Git staging, or Git commit is introduced.