# Check configuration and suite coverage `devkit coverage` explains what a selected plan intends to run. It does not run tests, start servers, or report successful verification: ```sh ./devkit coverage --profile quick --repo campaign ./devkit coverage --profile ui --repo portal --json ./devkit coverage --profile full --json ./devkit --project /path/to/project.json coverage --profile quick ``` The inventory accounts for declared `test` and `test:*` scripts in each registered repository's root and `webui/package.json`, discovered UI structural checks, and explicitly configured project checks. It is a suite inventory, not an enumeration of every test function or recursive dependency. Unselected suites remain visible; every row has a disposition and reason: | Disposition | Meaning | | --- | --- | | `planned` | A selected stage directly invokes the suite. | | `covered_elsewhere` | An exact equivalent invocation or an explicitly selected shared batch owns it; the covering stage is named. | | `excluded` | The suite is outside the actual selected plan. | | `unsupported` | Scoped discovery cannot safely interpret or locate the command; no command is guessed or executed. | `full` means the existing canonical `check-focused.sh` gate. It does **not** mean every package script or every component suite. Coverage reads the current script's explicit npm/Node commands inside its seven registered marked phase bodies, without executing shell code or inferring arbitrary functions, nested scripts, npm hooks, branches or here-document contents. Each covered suite names the `focused.` that owns it. The current gate names four of the sixteen Core component suites: layout primitives, page layout, DataGrid actions/sizing, and Mail components. The other twelve stay explicitly excluded from that gate's component batch. `ui` runs the shared sixteen-suite batch once; `quick` does not compile component tests. Only Core's exact known component aliases receive that shared-batch treatment. A different repository using the same filename, an unknown alias, or a compound command containing the runner is not silently credited or launched. Ordinary scoped source discovery accepts bounded direct `node`/`node --test` commands targeting regular package-owned `.mjs` files in `scripts` or `tests`; shell chains, extra flags, missing targets and symlinked targets are not rewritten. An explicit invocation already present in the canonical full gate remains part of that gate, even when the narrower discovery profile does not support it. Coverage rows retain a command hash and, for supported commands, redacted argv. Unsupported shell bodies are not copied into the inventory. This is display hygiene, not permission to put secrets into project commands. Coverage is attached to check plans/receipts; it never turns an excluded suite into a pass. ## Portable-project validation The runtime validates custom project metadata against the published [`project.schema.json`](../../tools/devkit/project.schema.json) using a small dependency-free validator. All checks and profiles are validated before selection, including checks the chosen profile does not execute. Unknown nested fields such as `resource` or `timout_seconds`, malformed types, oversized values, duplicate references, missing dependencies, unknown profiles and dependency cycles fail with controlled errors. Repository aliases and resolved paths must be unambiguous and confined to the workspace. Check `cwd` defaults to `.` when omitted; configured paths cannot escape the workspace. Package JSON is bounded to 1 MiB and 512 scripts; duplicate JSON keys, excessive nesting and malformed script objects fail before planning. Command strings are bounded to 8,192 characters. This validates configuration, not the safety of its code: run only project manifests and test scripts you trust. Checks may declare repository-scoped `inputs`, true data `deps`, order-only `after`, and `reuse: "never"` for setup/output-producing work. Unknown repositories, empty/duplicate scopes, overlapping edge types and cycles fail before execution. Missing inputs deliberately fall back to all registered repositories. See [checkpoint and input contracts](DEVKIT.md#canonical-phases-and-narrower-inputs).