--- name: doctor description: Health-check the execution environment in one pass and record the result, changing nothing. Four checks - plugin versions from jsc-hooks/hooks/version-guard.sh report, hook wiring from jsc-hooks/tools/wire-cli.sh status, global settings and current-directory settings from tools/scan-config.sh against tools/config-spec.tsv. Report one findings table per check, then write the whole run to wiki CHECK_{HASH} where HASH comes from {hostname}/{user}; the page keeps only the latest run. Use after installing or updating the skill set, when a skill fails on a settings or wiring problem, or before handing a machine over; not for applying fixes, which is jsc-cli:setup. --- # doctor — execution environment health check Read-only. Every command below either reads a file or asks Gitea; none of them writes a setting. That is the contract with `jsc-cli:setup`: doctor states the facts, setup changes things. Collection (steps 1 to 4) **MUST run as a sub agent** — one sub agent for all four, returning the raw TSV lines. Only the report and the wiki write stay in the main agent. ## 1. Skill versions Run `jsc-hooks/hooks/version-guard.sh report`. It prints `{domain}{本機}{遠端}{落後|最新|超前|查詢失敗}` per plugin, then `behind{count}`. A report with no `{domain}` row, or one carrying `noregistry{path}`, means this CLI has no local plugin registry. Report it as 無法驗證 — never as 最新. `behind0` proves nothing when no domain row precedes it. Done when every installed domain has a status literal, or the CLI is reported as unverifiable. ## 2. Hook wiring Run `jsc-hooks/tools/wire-cli.sh status {cli}` for every CLI that `tools/detect-clis.sh` found. Use `status` and nothing else: `wire-cli.sh` without a subcommand rewires, `purge` deletes, and `smoke` executes hooks — all three break the read-only contract. Exit codes: 0 wired, 1 degraded, 3 skipped (CLI not installed), 5 unwired. Each `item` line names one wiring point and whether it is present. Only claude reaches `wired`. The other four have no pre-tool hook, so `degraded` is their healthy state — report the degradation reason as-is and never present it as a defect to fix. Done when every detected CLI has a status and its missing items are listed. ## 3. Global settings Run `tools/scan-config.sh scan global`. It checks every `scope=global` row of `tools/config-spec.tsv` and prints `itemscoperequiredactualexpectfixverdict`, closing with `summary{missing}{invalid}{unset}{skipped}`. Verdicts: `ok`, `default` (unset, default works), `unset` (optional, feature degrades), `missing` (required, skills break), `invalid` (set but fails verification), `skipped` (offline). Add `-o` when Gitea is unreachable; the Gitea-dependent rows then come back `skipped`. Report those rows as 未取得結論 and never as passes. Also run `tools/scan-config.sh orphans` — variables used in the source but absent from the spec table. They are a maintenance note for the skill set, not a fault on this machine. Done when the summary line is read and every `missing` and `invalid` row is named. ## 4. Own settings Run `tools/scan-config.sh scan project` from the current working directory. Same output format, `scope=project` rows only. Say which directory was scanned in the report. A project-scope result is meaningless without it, because the answer changes with every `cd`. When `.env` or `.envrc` exists, name the spec-table variables it overrides and state the value actually in effect. A global setting silently overridden here is the failure this check exists to catch. Done when the scanned directory is stated and every project row has a verdict. ## 5. Report and record Report all four tables per `templates/check-page.md`. Then build the 待修項目 table from every `missing`, `invalid` and `unwired` item, plus every domain reported 落後. Order them `missing` → `invalid` → `unwired` → `落後`. Nothing wrong → one row reading 無. Write the page through `jsc-gitea:wiki`: - Wiki repo: `jsc-gitea/tools/gitea.sh wiki-repo CHECK`. - Page name: `CHECK_` plus `gitea.sh hash-id "{hostname}/{user}"` — the host and the login account, not `{owner}/{repo}`. Doctor checks a machine, and it has to work in directories that are not repositories at all. - Overwrite the whole page. This page type keeps only the latest run. - Update `CHECK_CONTENTS` from `templates/check-contents.md` in the same pass. `wiki-repo` exiting 3 means no wiki repo is configured for CHECK. Print the tables, skip the wiki write, and put `JSC_WIKI_REPO_CHECK` at the top of 待修項目 — that unset variable is itself a finding, so a failed write never fails the health check. Done when either the wiki page URL is reported, or the skipped write is reported together with the reason. ## 6. Hand off State the counts: required items missing, settings invalid, CLIs unwired, domains behind. Recommend `/jsc-cli:setup` when any of those is above zero. Never fix anything here. Done when the counts are stated and the recommendation is given or explicitly withheld.