---
phase: 04-onboarding-validation
plan: '02'
type: execute
wave: 1
depends_on: []
files_modified:
  - paperforge/cli.py
  - pipeline/worker/scripts/literature_pipeline.py
autonomous: true
requirements:
  - ONBD-02

must_haves:
  truths:
    - User can run one `paperforge doctor` command and see categorized readiness status
    - Categories include Python environment, Vault structure, Zotero link, BBT export, OCR config, Worker scripts, Agent scripts
    - Each category shows pass/fail with actionable next step on failure
  artifacts:
    - path: "paperforge/cli.py"
      provides: "doctor subcommand parser"
      contains: "doctor"
    - path: "pipeline/worker/scripts/literature_pipeline.py"
      provides: "doctor check functions for each category"
      contains: "def.*doctor|def.*check.*doctor"
  key_links:
    - from: "cli.py"
      to: "literature_pipeline.py"
      via: "run_doctor(vault)"
      pattern: "run_doctor"
---

<objective>
Add `paperforge doctor` as a standalone subcommand that reports setup readiness by category: Python / Vault / Zotero / BBT Export / OCR Config / Worker Scripts / Agent Scripts.
</objective>

<execution_context>
@C:/Users/Lin/.opencode/get-shit-done/workflows/execute-plan.md
@C:/Users/Lin/.opencode/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/phases/04-onboarding-validation/04-CONTEXT.md
@.planning/STATE.md
@.planning/ROADMAP.md
@.planning/REQUIREMENTS.md
@paperforge/cli.py
@pipeline/worker/scripts/literature_pipeline.py (for existing patterns like run_status)
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add doctor subcommand to CLI parser</name>
  <files>paperforge/cli.py</files>
  <read_first>
    - paperforge/cli.py (lines 38-88 for build_parser, lines 143-178 for main dispatch)
  </read_first>
  <action>
    In paperforge/cli.py, add the doctor subcommand to build_parser() and dispatch in main().

    1. In build_parser(), after the deep-reading parser (around line 72), add:
    ```python
    sub.add_parser("doctor", help="Validate PaperForge Lite setup and configuration")
    ```

    2. In main(), add dispatch:
    ```python
    if args.command == "doctor":
        from pipeline.worker.scripts.literature_pipeline import run_doctor
        return run_doctor(vault)
    ```

    3. Import run_doctor at the top (where other worker functions are imported):
    ```python
    from pipeline.worker.scripts.literature_pipeline import (
        run_status,
        run_selection_sync,
        run_index_refresh,
        run_deep_reading,
        run_ocr,
        run_doctor,  # ADD THIS
        ensure_base_views,
    )
    ```
  </action>
  <verify>
    <automated>grep -n "doctor" paperforge/cli.py</automated>
  </verify>
  <done>doctor subcommand added to CLI parser and dispatch</done>
</task>

<task type="auto">
  <name>Task 2: Implement run_doctor with categorized checks</name>
  <files>pipeline/worker/scripts/literature_pipeline.py</files>
  <read_first>
    - pipeline/worker/scripts/literature_pipeline.py (lines 2817-2850 for run_status as reference pattern, lines 1-50 for imports)
  </read_first>
  <action>
    In pipeline/worker/scripts/literature_pipeline.py, add run_doctor function.

    The function should check these categories and print grouped output:

    1. **Python 环境** (Python environment):
       - Check Python version >= 3.10
       - Check required modules: requests, pymupdf, pillow, yaml

    2. **Vault 结构** (Vault structure):
       - Check paperforge.json exists
       - Check system_dir exists
       - Check resources_dir exists
       - Check control_dir exists

    3. **Zotero 链接** (Zotero link):
       - Check Zotero junction/symlink exists at system_dir/Zotero
       - If not a junction, warn that it should be a junction

    4. **BBT 导出** (Better BibTeX export):
       - Check exports directory exists
       - Check library.json exists and is valid JSON
       - Check library.json has entries with 'key' field
       - Check entry count is reasonable (>0, warn if <5)

    5. **OCR 配置** (OCR config):
       - Check .env has PADDLEOCR_API_KEY or OCR_TOKEN
       - Check PaddleOCR URL is configured and reachable (optional L4 check, skip unless --live)

    6. **Worker 脚本** (Worker scripts):
       - Check literature_pipeline.py exists
       - Check all worker functions are importable

    7. **Agent 脚本** (Agent scripts):
       - Check ld_deep.py exists in skill_dir
       - Check skill directory structure

    Output format:
    ```
    PaperForge Lite Doctor
    ======================

    [PASS] Python 环境 — Python 3.10+
    [FAIL] Vault 结构 — system_dir 不存在
    [WARN] Zotero 链接 — Zotero 目录是普通文件夹，不是 junction
    [PASS] BBT 导出 — library.json 正常 (12 条)
    [FAIL] OCR 配置 — 缺少 PADDLEOCR_API_KEY
    [PASS] Worker 脚本 — 所有 worker 函数就绪
    [PASS] Agent 脚本 — literature-qa skill 就绪

    修复步骤:
    1. Vault 结构: mkdir {system_dir}
    ...
    ```

    Each check function returns (status, message, fix_suggestion).
    Status is 'pass', 'fail', or 'warn'.

    Group output by category, print PASS/FAIL/WARN with color if terminal supports it.
  </action>
  <verify>
    <automated>grep -n "def run_doctor" pipeline/worker/scripts/literature_pipeline.py && python -c "import sys; sys.path.insert(0, '.'); from pipeline.worker.scripts.literature_pipeline import run_doctor; print('import ok')"</automated>
  </verify>
  <done>run_doctor implements categorized checks and outputs grouped results</done>
</task>

<task type="auto">
  <name>Task 3: Add tests for run_doctor</name>
  <files>tests/test_doctor.py</files>
  <read_first>
    - tests/test_cli_worker_dispatch.py (for test patterns)
  </read_first>
  <action>
    Create tests/test_doctor.py with:

    1. test_doctor_command_exists — verify `paperforge doctor` command is recognized
    2. test_doctor_python_check — verify Python version check works
    3. test_doctor_vault_structure_check — verify vault structure validation
    4. test_doctor_bbt_export_check — verify BBT export validation
    5. test_doctor_all_checks_return_tuple — verify each check returns (status, message, fix)

    Use tmp_vault fixture similar to other tests.
    Mock network calls for OCR URL check.
  </action>
  <verify>
    <automated>python -m pytest tests/test_doctor.py -v --tb=short 2>&1 | tail -15</automated>
  </verify>
  <done>Doctor command tests written and passing</done>
</task>

</tasks>

<verification>
- `paperforge doctor --help` works
- `paperforge doctor` outputs categorized checks with PASS/FAIL/WARN
- Each category shows fix suggestion on failure
</verification>

<success_criteria>
paperforge doctor reports categorized readiness with actionable next steps on failure
</success_criteria>

<output>
After completion, create `.planning/phases/04-onboarding-validation/04-02-SUMMARY.md`
</output>
