plain-healthcheck

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Plain Healthcheck

Plain健康检查

Always use the skill
load-plain-reference
to retrieve the ***plain syntax rules — but only if you haven't done so yet.
请始终使用
load-plain-reference
技能获取***plain的语法规则——但仅在尚未获取过的情况下执行此操作。

When to run

运行时机

Run this skill **whenever anything in the *plain project is finalized and the project is about to be left in a state the user (or another skill) might render from. That includes, but is not limited to:
  • End of
    forge-plain
    (Phase 4) — before presenting the render command.
  • End of
    add-feature
    (Phase 3 final review) — before declaring the feature done.
  • End of
    debug-specs
    — after applying a fix, before telling the user to re-render.
  • After finalizing any single edit that changes the renderable surface — e.g. after
    add-concept
    ,
    add-functional-spec
    ,
    add-functional-specs
    ,
    add-implementation-requirement
    ,
    add-test-requirement
    ,
    add-acceptance-test
    ,
    add-template
    ,
    add-resource
    ,
    resolve-spec-conflict
    ,
    break-down-func-spec
    ,
    consolidate-concepts
    ,
    refactor-module
    ,
    create-import-module
    ,
    create-requires-module
    , or any of the
    implement-*-testing-script
    skills.
  • After hand-editing a
    .plain
    file, a
    config.yaml
    , or anything under
    test_scripts/
    .
  • On demand — whenever the user asks whether the project is in a renderable state.
The healthcheck is not a forge-plain-only step. Treat it as the default closing move for any workflow that finalizes something in the project.
Do not skip this skill because "the dry-run passed earlier" —
config.yaml
s, scripts, and specs can all drift between runs. The healthcheck is cheap; rendering against stale specs is expensive.
每当***plain项目中的任何内容定稿,且项目即将处于用户(或其他技能)可能进行渲染的状态时,都应运行此技能。情况包括但不限于:
  • forge-plain
    结束时
    (第4阶段)——在展示渲染命令之前。
  • add-feature
    结束时
    (第3阶段最终评审)——在宣布功能完成之前。
  • debug-specs
    结束时
    ——在应用修复之后,告知用户重新渲染之前。
  • 完成任何单次编辑后——只要修改了可渲染内容,例如执行
    add-concept
    add-functional-spec
    add-functional-specs
    add-implementation-requirement
    add-test-requirement
    add-acceptance-test
    add-template
    add-resource
    resolve-spec-conflict
    break-down-func-spec
    consolidate-concepts
    refactor-module
    create-import-module
    create-requires-module
    ,或任何
    implement-*-testing-script
    技能之后。
  • 手动编辑后——编辑
    .plain
    文件、
    config.yaml
    test_scripts/
    下的任何内容之后。
  • 按需运行——每当用户询问项目是否处于可渲染状态时。
健康检查并非仅适用于
forge-plain
的步骤。请将其视为任何定稿项目内容的工作流的默认收尾操作。
不要因为“之前预运行已经通过”就跳过此技能——
config.yaml
、脚本和规范在多次运行之间可能会发生偏差。健康检查成本很低,而基于过时规范进行渲染的成本很高。

Workflow

工作流

The skill is a detect → fix → re-run loop. It does not stop at the first failure; it surfaces everything wrong, fixes what it can, and only returns when either everything passes or a gap genuinely requires user input.
该技能是一个检测→修复→重新运行的循环。它不会在第一次失败时就停止,而是会列出所有问题,修复可自动修复的内容,直到所有检查通过或遇到确实需要用户输入的问题时才返回。

Step 1 — Inventory the project

步骤1 — 盘点项目

  1. List every
    .plain
    file in the repo root (and any subdirectories that contain
    .plain
    files). Build the module graph from each file's YAML frontmatter (
    requires
    ,
    import
    ).
  2. Identify top modules — every module that is not
    requires
    -ed by any other module. A single-stack project has one top module; a multi-part project (e.g. backend + frontend) has one top module per part.
  3. List every
    config.yaml
    in the repo (root and per-part directories such as
    backend/
    ,
    frontend/
    ).
  4. List every script under
    test_scripts/
    .
  5. Pair each top module with the
    config.yaml
    that governs it. The pairing rule is: the config file in the same directory as the top module wins; failing that, the repo-root
    config.yaml
    . A multi-part project must have one config per part — record any top module that has no governing config as a failure.
Print a one-line inventory summary so the rest of the run is easy to follow, e.g.
Top modules: backend/api.plain (config: backend/config.yaml), frontend/web.plain (config: frontend/config.yaml). Scripts in test_scripts/: 4.
  1. 列出仓库根目录(以及所有包含
    .plain
    文件的子目录)中的每个
    .plain
    文件。根据每个文件的YAML前置元数据(
    requires
    import
    )构建模块图。
  2. 识别顶级模块——所有未被其他模块
    requires
    引用的模块。单栈项目只有一个顶级模块;多部分项目(如后端+前端)每个部分有一个顶级模块。
  3. 列出仓库中(根目录以及
    backend/
    frontend/
    等各部分目录)的每个
    config.yaml
  4. 列出
    test_scripts/
    下的每个脚本。
  5. 将每个顶级模块与管辖它的
    config.yaml
    配对。配对规则为:顶级模块所在目录中的配置文件优先;如果没有,则使用仓库根目录的
    config.yaml
    。多部分项目必须每个部分对应一个配置——记录任何没有管辖配置的顶级模块作为失败项。
打印一行盘点摘要,方便后续运行查看,例如:
顶级模块:backend/api.plain(配置:backend/config.yaml)、frontend/web.plain(配置:frontend/config.yaml)。test_scripts/中的脚本数量:4。

Step 2 — Validate every
config.yaml

步骤2 — 验证每个
config.yaml

For each
config.yaml
in the inventory, check all of the following. Collect every failure — do not stop at the first.
  1. File parses. It is valid YAML.
  2. At minimum
    unittests-script
    is present.
    Every project gets a unit-test runner.
  3. For every script field that is present (
    unittests-script
    ,
    conformance-tests-script
    ,
    prepare-environment-script
    ):
    • The path is a string ending in
      .sh
      (macOS/Linux) or
      .ps1
      (Windows). The extension must match the rest of the project — do not mix
      .sh
      and
      .ps1
      in a single config.
    • The referenced file actually exists on disk under
      test_scripts/
      .
    • On Unix, the script has the executable bit set (
      -x
      ). If not, that is a fixable failure.
  4. No mixed stacks per config. Every script referenced from a single
    config.yaml
    must target the same language/stack. For example,
    backend/config.yaml
    should not reference
    run_unittests_js.sh
    . If a config crosses stacks, that is a failure — the project should have been split into multiple configs per the rule in
    PLAIN_REFERENCE.md
    .
  5. No dangling fields. Any
    *-script
    field whose target file does not exist is a failure.
  6. prepare-environment-script
    implies
    conformance-tests-script
    .
    A
    prepare-environment-script
    only makes sense in service of conformance tests — the environment is what those tests run against. If a
    config.yaml
    declares
    prepare-environment-script
    but does not declare
    conformance-tests-script
    , that is a failure. Surface it to the user and offer to either (a) invoke
    implement-conformance-testing-script
    to add the missing script, or (b) remove the
    prepare-environment-script
    field if it was added in error. Do not auto-pick.
  7. No orphan scripts. Every script under
    test_scripts/
    should be referenced by some
    config.yaml
    . If a script is never referenced, surface it as a warning (not a hard failure — the user may be in the middle of authoring).
For each failure, record the offending config path, the offending field, and the concrete problem (
file missing
,
not executable
,
mixed stack
, etc.).
对于盘点中的每个
config.yaml
,检查以下所有内容。收集所有失败项——不要在第一次失败时停止。
  1. 文件可解析:它是有效的YAML格式。
  2. 至少包含
    unittests-script
    字段
    :每个项目都需要单元测试运行器。
  3. 对于每个存在的脚本字段
    unittests-script
    conformance-tests-script
    prepare-environment-script
    ):
    • 路径是以
      .sh
      (macOS/Linux)或
      .ps1
      (Windows)结尾的字符串。扩展名必须与项目其余部分一致——不要在单个配置中混合
      .sh
      .ps1
    • 引用的文件确实存在于
      test_scripts/
      目录下的磁盘中。
    • 在Unix系统上,脚本设置了可执行权限位(
      -x
      )。如果没有,这是可修复的失败项。
  4. 单个配置中无混合栈:单个
    config.yaml
    引用的所有脚本必须针对同一语言/技术栈。例如,
    backend/config.yaml
    不应引用
    run_unittests_js.sh
    。如果配置跨栈,这是一个失败项——根据
    PLAIN_REFERENCE.md
    中的规则,项目应拆分为多个配置。
  5. 无悬空字段:任何目标文件不存在的
    *-script
    字段都是失败项。
  6. prepare-environment-script
    意味着需要
    conformance-tests-script
    prepare-environment-script
    只有在为一致性测试服务时才有意义——环境是这些测试运行的基础。如果
    config.yaml
    声明了
    prepare-environment-script
    声明
    conformance-tests-script
    ,这是一个失败项。将此问题告知用户,并提供两个选项:(a) 调用
    implement-conformance-testing-script
    添加缺失的脚本,或(b) 如果是错误添加的,则移除
    prepare-environment-script
    字段。不要自动选择。
  7. 无孤立脚本
    test_scripts/
    下的每个脚本都应被某个
    config.yaml
    引用。如果某个脚本从未被引用,将其标记为警告(不是严重失败——用户可能正在编写脚本)。
对于每个失败项,记录违规的配置路径、违规字段以及具体问题(如
文件缺失
无执行权限
混合栈
等)。

Auto-fixes you may apply

可自动执行的修复

  • Missing executable bit on a script that otherwise looks fine →
    chmod +x <path>
    .
  • Stale path that points at a renamed script that clearly exists under a different name in
    test_scripts/
    → only if there is exactly one obvious candidate (same language tag, same script kind). When in doubt, leave it for the user.
Anything else (missing script, mixed stacks, missing
config.yaml
) must be surfaced to the user — do not silently regenerate scripts here. Re-invoking
implement-unit-testing-script
,
implement-conformance-testing-script
, or
implement-prepare-environment-script
from inside the healthcheck is allowed only if the user explicitly approves it after being shown the gap.
  • 脚本缺少可执行权限位但其他方面正常 → 执行
    chmod +x <path>
  • 陈旧路径指向已重命名的脚本,且
    test_scripts/
    下有且仅有一个明显匹配的候选脚本(相同语言标签、相同脚本类型)→ 自动更新路径。如有疑问,留给用户处理。
其他任何问题(缺失脚本、混合栈、缺失
config.yaml
)必须告知用户——不要在此处静默重新生成脚本。只有在用户明确批准显示的问题后,才允许在健康检查中重新调用
implement-unit-testing-script
implement-conformance-testing-script
implement-prepare-environment-script
技能。

Step 3 — Dry-run every top module

步骤3 — 预运行每个顶级模块

For each
(top_module, config.yaml)
pair from Step 1, run a dry-run from the project root via the
terminal
tool:
bash
codeplain <top_module>.plain --dry-run
Match the dry-run to how the user will actually render. Pass the flags the user would pass for the real render so what you validate is what they will run:
  • --config-name <name>
    — required whenever the governing config file is not the default
    config.yaml
    , or when the project has multiple
    config.yaml
    s and the dry-run is being launched from somewhere that isn't the part's directory.
    --config-name
    takes a file name, not a path; if needed,
    cd
    into the part's directory before running so the right
    config.yaml
    is found.
  • --template-dir <path>
    — only when templates live outside
    template/
    and
    template_dir
    is not already set in the relevant config.
  • --full-plain
    — useful when an
    import
    /
    requires
    chain is suspect.
  • --verbose
    /
    -v
    — strongly recommended on a failed dry-run; the extra log output usually pinpoints the offending
    .plain
    file and spec.
Treat the dry-run as a hard gate: the healthcheck only passes when every top module's dry-run exits successfully.
对于步骤1中的每个
(顶级模块, config.yaml)
配对,从项目根目录通过
terminal
工具运行预运行命令:
bash
codeplain <top_module>.plain --dry-run
预运行需匹配用户实际渲染的方式。传递用户实际渲染时会使用的标志,确保验证的内容与用户将运行的内容一致:
  • --config-name <name>
    ——当管辖配置文件不是默认的
    config.yaml
    ,或项目有多个
    config.yaml
    且预运行从非对应部分的目录启动时,必须使用此标志。
    --config-name
    接受文件名,而非路径;如有需要,先进入对应部分的目录再运行命令,以便找到正确的
    config.yaml
  • --template-dir <path>
    ——仅当模板位于
    template/
    目录之外,且相关配置中未设置
    template_dir
    时使用。
  • --full-plain
    ——当
    import
    /
    requires
    链存在疑问时很有用。
  • --verbose
    /
    -v
    ——强烈建议在预运行失败时使用;额外的日志输出通常能指出违规的
    .plain
    文件和规范。
将预运行视为严格关卡:只有当所有顶级模块的预运行都成功退出时,健康检查才通过

When a dry-run fails

预运行失败时

Iterate until it passes:
  1. Read the error output. If the first run was not verbose, immediately re-run with
    --verbose
    . Identify the offending
    .plain
    file, the line (if reported), and the kind of issue: missing concept, syntax error, cyclic definition, complexity violation (
    Functional spec too complex!
    ), conflicting reqs, missing template, broken
    import
    /
    requires
    , missing config field, etc.
  2. Fix only the
    .plain
    files (or the relevant
    config.yaml
    / template) using the appropriate edit skill —
    add-concept
    ,
    add-functional-spec
    ,
    add-functional-specs
    ,
    add-implementation-requirement
    ,
    resolve-spec-conflict
    ,
    break-down-func-spec
    ,
    consolidate-concepts
    , or an inline edit. Never modify generated code under
    plain_modules/
    or
    conformance_tests/
    .
  3. If you are uncertain about ***plain syntax for the failing construct, re-load
    load-plain-reference
    before fixing.
  4. Re-run the same
    codeplain <top_module>.plain --dry-run …
    command with the same flags. Repeat until it exits successfully.
If the failure is something the healthcheck cannot reasonably fix on its own (e.g. the user has to choose between two contradictory specs and neither side was pre-approved, or a missing concept whose semantics aren't clear), stop and surface it to the user with the offending snippet and a concrete question. Do not invent behavior.
重复操作直到通过:
  1. 读取错误输出。如果第一次运行未使用verbose模式,立即重新运行并添加
    --verbose
    。识别违规的
    .plain
    文件、行号(如果有报告)以及问题类型:缺失概念、语法错误、循环定义、复杂度违规(
    Functional spec too complex!
    )、需求冲突、缺失模板、
    import
    /
    requires
    断裂、缺失配置字段等。
  2. 使用适当的编辑技能修复
    .plain
    文件(或相关的
    config.yaml
    /模板)——
    add-concept
    add-functional-spec
    add-functional-specs
    add-implementation-requirement
    resolve-spec-conflict
    break-down-func-spec
    consolidate-concepts
    ,或直接编辑。切勿修改
    plain_modules/
    conformance_tests/
    下的生成代码。
  3. 如果对失败结构的***plain语法不确定,在修复前重新加载
    load-plain-reference
  4. 使用相同的标志重新运行
    codeplain <top_module>.plain --dry-run …
    命令。重复直到成功退出。
如果失败是健康检查无法自行合理修复的问题(例如用户必须在两个矛盾的规范之间选择,且双方均未预先批准,或语义不明确的缺失概念),停止并将问题告知用户,同时提供违规代码片段和具体问题。不要自行创造行为逻辑。

Environment failures

环境失败

If
codeplain
is not on PATH, or
CODEPLAIN_API_KEY
is not set:
  • Do not pretend the dry-run passed.
  • Tell the user exactly what's missing and how to fix it (install the CLI, export the env var) and stop the healthcheck with a clearly-marked environment failure. This is the only kind of failure that may legitimately remain unresolved at the end of the skill.
如果
codeplain
不在PATH中,或未设置
CODEPLAIN_API_KEY
  • 不要假装预运行通过。
  • 准确告知用户缺失的内容以及修复方法(安装CLI、导出环境变量),并以明确标记的环境失败结束健康检查。这是唯一可能在技能结束时仍未解决的失败类型。

Step 4 — Report

步骤4 — 报告

Emit one of:
  • PASS
    — followed by a short summary of what was checked:
    N config.yaml(s) validated
    ,
    M top module(s) dry-run
    ,
    K scripts referenced
    . The caller (
    forge-plain
    ,
    add-feature
    ,
    debug-specs
    ) can then continue to its hand-off step.
  • FAIL
    — followed by a numbered list of every unresolved problem. Each entry must include: the file (config /
    .plain
    / script) it applies to, the concrete issue, and what the user needs to decide if the healthcheck couldn't resolve it.
The verdict goes on the first line so callers can pattern-match without parsing the whole report.
输出以下结果之一:
  • PASS
    ——后跟检查内容的简短摘要:
    已验证N个config.yaml
    已预运行M个顶级模块
    已引用K个脚本
    。调用者(
    forge-plain
    add-feature
    debug-specs
    )可继续执行后续步骤。
  • FAIL
    ——后跟未解决问题的编号列表。每个条目必须包含:涉及的文件(配置/
    .plain
    /脚本)、具体问题,以及如果健康检查无法解决时用户需要做出的决定。
verdict(
PASS
/
FAIL
)必须放在第一行,以便调用者无需解析整个报告即可匹配模式。

What this skill does NOT do

此技能不执行的操作

  • It does not author new specs from scratch — use
    forge-plain
    /
    add-feature
    for that.
  • It does not run the real render — only
    --dry-run
    .
  • It does not execute the testing scripts (
    run_unittests
    ,
    run_conformance_tests
    ,
    prepare_environment
    ). It only verifies that the scripts are wired up correctly via
    config.yaml
    . The user runs the scripts themselves.
  • It does not silently regenerate config files or scripts. The most it does is
    chmod +x
    and (with user approval) re-invoke the relevant
    implement-*-testing-script
    skill.
  • 从头编写新规范——请使用
    forge-plain
    /
    add-feature
    完成此操作。
  • 执行实际渲染——仅执行
    --dry-run
  • 执行测试脚本(
    run_unittests
    run_conformance_tests
    prepare_environment
    )。仅验证脚本是否通过
    config.yaml
    正确关联。用户需自行运行脚本。
  • 静默重新生成配置文件或脚本。最多执行
    chmod +x
    ,并在用户批准后重新调用相关的
    implement-*-testing-script
    技能。

Validation Checklist

验证清单

  • Every
    .plain
    module was inventoried and every top module was identified
  • Every top module is governed by exactly one
    config.yaml
  • Every
    config.yaml
    parses as YAML and has at least
    unittests-script
  • Every
    *-script
    field points at a file that exists under
    test_scripts/
  • No
    config.yaml
    mixes stacks (e.g. Python + JS scripts in the same file)
  • No
    config.yaml
    declares
    prepare-environment-script
    without also declaring
    conformance-tests-script
  • Every
    test_scripts/*
    file is referenced by some
    config.yaml
    (or surfaced as a warning)
  • codeplain <top>.plain --dry-run
    exits successfully for every top module, with the right
    --config-name
    for multi-part projects
  • Verdict (
    PASS
    /
    FAIL
    ) is on the first line, with a numbered list of remaining problems if it failed
  • 已盘点所有
    .plain
    模块并识别所有顶级模块
  • 每个顶级模块恰好由一个
    config.yaml
    管辖
  • 每个
    config.yaml
    可解析为YAML且至少包含
    unittests-script
  • 每个
    *-script
    字段指向
    test_scripts/
    下存在的文件
  • config.yaml
    混合技术栈(如同一文件中包含Python和JS脚本)
  • config.yaml
    声明
    prepare-environment-script
    但未声明
    conformance-tests-script
  • 每个
    test_scripts/*
    文件都被某个
    config.yaml
    引用(或已标记为警告)
  • 所有顶级模块的
    codeplain <top>.plain --dry-run
    命令均成功退出,多部分项目使用正确的
    --config-name
  • verdict(
    PASS
    /
    FAIL
    )位于第一行,失败时附带未解决问题的编号列表