bug-reproduce
Turn a known bug into a tight, red-capable reproducer, then prove the reproducer locks that…
Diagnose the local dev machine before any APC loop step — run apc env doctor, classify each failure into a fault domain, apc env up to auto-fix what is safe, then fingerprint. Keeps env faults out of SUT verdicts.
$ npx -y skills add Prismer-AI/PrismerCloud --skill env-doctor --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/env-doctorContext preview
The summary Claude sees to decide when to auto-load this skill.
Diagnose the local dev machine before any APC loop step — run apc env doctor, classify each failure into a fault domain, apc env up to auto-fix what is safe, then fingerprint. Keeps env faults out of SUT verdicts.
name: env-doctor description: Diagnose the local dev machine before any APC loop step — run apc env doctor, classify each failure into a fault domain, apc env up to auto-fix what is safe, then fingerprint. Keeps env faults out of SUT verdicts. license: MIT scope: common compatibility: - claude-code - prismer-sdk allowed-tools: - Bash metadata: category: environment
诊断本机开发环境,把**环境故障**与**被测代码红(SUT red)**彻底分域——这是 APC 一切循环步骤的地基(`apc/06` 环境脚手架 · `apc/00` §3 不变量 5)。
**什么时候用**:任何 APC 循环步骤开工前;或 test-runner 报出 `env_blocked`、dispatch 失败、诊断"为什么这台机器跑不起来"时。
铁律:`apc env doctor` 判红是**环境红**,不是产品 bug。你的产出是一份逐项 pass/fail 的诊断 + 每个红项的**故障域分类** + 可自动化项已拉起的证据。绝不把环境红说成"代码坏了"。
> **命令形态(承重,别猜)**:`apc` 不在 PATH——它是 `package.json` 的 npm script(`tsx sdk/apc/bin/apc.ts`)。 > 在 agent 的 cwd(仓库根)里,**一律用 `npx tsx sdk/apc/bin/apc.ts <sub>` 直接跑**(stdout 是纯 JSON,不被 npm banner 污染)。下表用 `apc` 作简写,实跑请替换成 `npx tsx sdk/apc/bin/apc.ts`。
| 命令 | 作用 | stdout | 退出码 | | --- | --- | --- | --- | | `apc env doctor` | 只读跑完 env-manifest 四段,逐项 pass/fail + fix-hint | **结构化 JSON**(消费者契约) | `0` 全绿 · `78` env_blocked(存在环境红) | | `apc env up --safe [--dry-run] [--only=a,b]` | 幂等拉起**可自动化的轻量项**;`--safe` 下 heavy 步(colima / dev-stack / kind / npm ci / prisma / migrations)**不自动跑**,只归 `manual[]` 出 fix-hint | JSON 报告 | `0` ok · `1` 有步骤 failed | | `apc env fingerprint` | 环境指纹(机器等价性证明) | JSON 指纹 | `0` |
npx tsx sdk/apc/bin/apc.ts env doctor > /tmp/apc-doctor.json echo "doctor exit=$?"
从 `/tmp/apc-doctor.json` 读结构化结果,真实 schema(**字段名以此为准**):
判据:`summary.total == summary.pass + summary.fail + summary.skip == items.length`——一项崩不塌全轮。
**故障域 = item 的 `section` 字段**(不是另算的)。把每个 `status:fail` 的 item 按 `section` 归组,逐项列出 `{ item, section, detail, fixHint }`:
| 故障域(section) | 典型 item | 处置 | | --- | --- | --- | | `infra`(本机基础设施) | `infra.mysql-3307` / `infra.redis-6380` / `infra.nacos` / `infra.kind-<cluster>` / `infra.cloud-dev-server` 未起 | `apc env up` 可拉起 | | `toolchain`(工具链版本) | `toolchain.node` major / 锁定 claude binary 版本不符 / 网关口径 | `apc env up` 装锁定 binary;node 需人手 | | `secrets`(凭据/密钥) | `secrets.env-local-required-keys` 缺 `SKILL_CONFIG_ENC_KEY` / `IDENTITY_KMS_KEY` 等 | **不代办**——只报 `fixHint`,等人按提示补 | | `project`(工程态) | `project.node-modules-lockfile` / `project.prisma-clients` / `project.mysql-migrations-pending` / `project.version-alignment` | 多数是 heavy 步,`--safe` 下归 `manual[]` 出 fix-hint |
> **段是四段不是三段**:`sdk/apc/env/manifest.ts` 的四段清单是 `infra` / `toolchain` / `secrets` / `project`(`ENV_MANIFEST` 由这四组拼成)。分类只认 item 的 `section` 字段,别把 `project` 项硬塞进前三域。
**判据**:`secrets` 域的红**永远不自动修**(`apc env up` 只出 fix-hint,凭据不代办,`apc/00` §3)。别声称已修一个 secrets 项。
npx tsx sdk/apc/bin/apc.ts env up --safe echo "up exit=$?"
npx tsx sdk/apc/bin/apc.ts env fingerprint > /tmp/apc-fingerprint.json echo "fingerprint exit=$?"
指纹是机器等价性证明——同一环境两台机器指纹应等价。收工时附上它。
本 skill 的验收判据不再是「报告里出现了 `infra` / `fail: 2` 这些词」——旧判据里 `\b(infra|toolchain|secrets?)\b` 一个词就能让「故障域已分类」变绿,`(pass|fail|skip)…\d+` 一个数字就能冒充「逐项报告」。现在判据找的是**每一个 item 自己那一行**,并把该行的引用**读回磁盘复核**(`structured-criteria.ts` 的 `dimension-coverage`)。
**逐项作答**(每个 item **独占一行 + 用它的 item id 当 key**,值给:真实 status → 故障域 → 关键 detail/fixHint → 该 item 在 manifest 里的**声明行**):
- infra.docker-daemon: pass | domain=infra | sdk/apc/env/manifest.ts:165 - infra.mysql-3307: pass | domain=infra | MySQL 8.0.46 真握手 | sdk/apc/env/manifest.ts:178 - toolchain.node: fail | domain=toolchain | node 23.9.0 major 23 ≠ pin 20 | fixHint: nvm use 20 | sdk/apc/env/manifest.ts:318 - toolchain.hermes-gateway-models: skip | domain=toolchain | 未检测(无凭据)| sdk/apc/env/manifest.ts:408 - secrets.env-local-required-keys: fail | domain=secrets | 本地凭据缺失,只出 fixHint 不代办 | sdk/apc/env/manifest.ts:449 - project.mysql-migrations-pending: fail | domain=project | 1 条 pending | fixHint: npm run db:migrate | sdk/apc/env/manifest.ts:603
**判据钉住的 21 个 item id**(= `ENV_MANIFEST` 除 `infra.kind-<cluster>`):`infra.docker-daemon` · `infra.mysql-3307` · `infra.mysql-migration-ledger` · `infra.redis-6380` · `infra.nacos` · `infra.cloud-dev-server` · `toolchain.node` · `toolchain.docker-compose` · `toolchain.kubectl` · `toolchain.kind-cli` · `toolchain.claude-code-binary-pin` · `toolchain.hermes-binary` · `toolchain.hermes-gateway-models` · `secrets.env-local-required-keys` · `secrets.ota-ui-signing-key` · `project.node-modules-lockfile` · `project.prisma-clients` · `project.mysql-migrations-pending` · `project.version-alignment` · `project.claude-config-dir` · `project.bare-repo-mirror`。
> `infra.kind-<cluster>` 的 i
Repo: Prismer-AI/PrismerCloud
Turn a known bug into a tight, red-capable reproducer, then prove the reproducer locks that…
Review a diff against its acceptance criteria in four segments (convention adherence, bug…
Five-dimension design audit (frontend UI/UX · server data-model & flow · endpoint spec ·…
Before merge, mechanize Documentation-First — derive the code delta from git diff, then…
Close out a local coding task on the bound daemon — stage, commit, branch, merge, push via…
For a change point (function / type / endpoint / SQL column), enumerate its real blast radius…