Project baseline
A presence check, not a code review: each practice has a probe, and a missing practice becomes a backlog item. Read-only until the user approves.
1. Context
- Detect the stack, the lockfile-selected package manager, the CI workflows, and the validation commands.
- Find the backlog paths exactly as audit-to-backlog does: a
Backlog: <todo path>, <done path> line in AGENTS.md or CLAUDE.md, otherwise TODO.md and TODO-done.md. Read both if they exist and continue their category numbering under the ID prefix BASE.
- Read the project's
AGENTS.md, docs/pitfalls.md, and decision records: a practice the project rejected or deferred on purpose is reported as deliberate, never proposed.
2. Probe each practice
| Practice |
Present when |
Missing → |
| Env read through one validated module |
a single module parses process.env (or the stack's equivalent) with a schema (zod or similar), and rg finds no direct env reads elsewhere in app code |
P2 |
| Agent deny-list for secrets |
.claude/settings.json permissions.deny covers .env* and key files (*.pem, *.key) |
P2 |
| Secret scanning in CI |
a CI step runs gitleaks, trufflehog, or the host's secret scanning |
P2 |
| Coverage floor that only rises |
the test config sets coverage thresholds and CI enforces them |
P2 |
| Additive-only migration guard |
CI fails on destructive migrations (drop/rename) without an explicit marker |
P2; skip without a database |
| Dependency/boundary rules |
dependency-cruiser, eslint boundaries, or a layer test that fails CI |
P3 |
| Real-database test tier |
tests run against a real database (Docker or a CI service), not only mocks |
P2; skip without a database |
| Safe error responses |
API errors return one envelope with a code and a message (details optional), as error-handling-conventions defines; no stack traces or internal fields |
P1 when a stack trace or internal error reaches a response, otherwise P2; skip without an API |
| CHANGELOG |
CHANGELOG.md in Keep a Changelog format |
P3 |
| Docs-vs-code consistency check |
a script or CI step checks docs against code (commands, paths, versions) |
P3 |
| Design system file |
a project with a UI (components, pages or stylesheets in app code) has a root DESIGN.md in the DESIGN.md format (YAML tokens, then Overview … Do's and Don'ts) |
P3; skip without a UI. When present, suggest npx @google/design.md lint DESIGN.md for the user to run; never run or install it |
| No runtime dependency two majors behind |
the package manager's outdated report (pnpm outdated --prod, npm outdated --omit=dev, yarn outdated, uv pip list --outdated limited to the pyproject.toml dependencies, bundle outdated) lists no runtime dependency two or more major versions behind its latest release |
P2 for a framework or runtime dependency, otherwise P3; skip when the report needs credentials or the network is unavailable, and say so; a nonzero exit from the outdated command alone is not a failure. bundle outdated evaluates the Gemfile and yarn runs the file a .yarnrc* names in yarnPath/yarn-path: both run repository code, so ask before either. Each item's Done when names the target version; its Check fails until the lockfile resolves that major, written for the lockfile's format (for example rg -q '/next@15\.' pnpm-lock.yaml). Dispatch nothing during the probe: the report offers upgrade plans (step 5) |
| Dependency release-age cooldown |
the update bot or package manager enforces a minimum release age before a new version is taken (Dependabot cooldown, Renovate minimumReleaseAge, pnpm minimumReleaseAge, uv exclude-newer) |
P3; skip without dependencies |
| After-edit lint hook |
.claude/settings.json has a PostToolUse hook on Edit|Write that reads tool_input.file_path from stdin, lints that file, and exits 2 with only the failures on stderr |
P3; skip without a linter |
| Agent sandbox |
.claude/settings.json sets sandbox.enabled: true and ~/.ssh and ~/.aws are denied to it, in sandbox.filesystem.denyRead or as sandbox.credentials.files entries with "mode": "deny" (the sandbox reads them by default); the guard and permission rules match text, the sandbox restricts every command |
P2 |
| Pinned MCP servers |
every stdio server in .mcp.json runs a pinned version (npx -y pkg@1.2.3, uvx pkg==1.2.3, an image digest), with no @latest and no bare package name; a server's tool descriptions reach the model, so a version bump is reviewed like a dependency |
P2; skip without .mcp.json |
| Gate verdict in the exit code |
every CI and validation script exits non-zero on failure (no || true, no continue-on-error on gates) |
P2 |
Record each probe and its result as the evidence: the command or file checked, and what it found. Unsure counts as unsure, not missing: list it under questions.
3. Decisions, not defaults
Never propose a default for these; when the repository is inconsistent (two lockfiles, two test runners, mixed commit languages), list the evidence and ask the user to choose:
- Package manager (npm vs pnpm)
- Test runner (Jest vs Vitest)
- Authentication library
- Monitoring stack
- Commit message language
4. Draft the backlog items
One item per missing practice, in audit-to-backlog's shape, filed under its severity section and deduplicated against both backlog files:
- [ ] BASE-03 · P2 · Secret scanning in CI
- Where: `.github/workflows/ci.yml:1`
- Problem: no CI step scans for committed secrets.
- Evidence: `rg -l 'gitleaks|trufflehog' .github/` → no match.
- Fix: add a gitleaks step to the CI workflow that fails the job on a finding.
- Size: S
- Done when: CI fails on a commit that contains a secret.
- Check: `rg -q 'gitleaks' .github/workflows/`
5. Report and ask
Project baseline — <repo>
Present: 6 Missing: 4 (P2 3, P3 1) Deliberate: 1 Not applicable: 1
Needs your decision: test runner — package.json has both jest and vitest
Write the 4 items to TODO.md? A: all (recommended) B: list IDs C: none
Plan the 2 upgrades with dependency-upgrader first (reads changelogs on the web)? yes / no
The second question appears only when the dependency probe found items. On a yes, dispatch developer-os:dependency-upgrader once per dependency, for at most the three furthest behind, and put its steps into the item's Fix and its estimate into its Size before writing; mark its ASSUMPTION: lines as such in the item. The install commands in a plan are text for the user to run, never commands this skill runs.
If the backlog files do not exist yet, ask for the paths and record them as a Backlog: <todo path>, <done path> line in AGENTS.md (or CLAUDE.md), with its git-ignored path warning, as audit-to-backlog does.
Stop point
Stop after the report and the question. After approval, merge the approved items into the backlog file with Session N: <ID>, … lines of 5–7 items each (fewer than 5 items: one session) under ## Implementation sessions, grouped as audit-to-backlog groups them, show git diff --stat, and stop; implementation is implement-backlog's job.
Never
- Write or create any file before the user approves.
- Pick a default for a "needs your decision" item.
- Install dependencies, add CI steps, or change configuration; this skill only proposes.
- Commit, push, or open a pull request.
- Propose a practice the project rejected on purpose.
1---2name: project-baseline3description: Check a repository against a baseline of engineering practices (validated env module, secret scanning, coverage ratchet and more) and propose each missing one as a backlog item, after approval; not a code audit (audit-to-backlog). Use when starting work in a repository or when the user asks what the project is missing; for example "what is the repo missing", "project baseline".4license: MIT5compatibility: "Claude Code"6metadata:7 source: https://skillmd.com/skills/msolecki/project-baseline8---910# Project baseline1112A presence check, not a code review: each practice has a probe, and a missing practice becomes a backlog item. Read-only until the user approves.1314## 1. Context1516- Detect the stack, the lockfile-selected package manager, the CI workflows, and the validation commands.17- Find the backlog paths exactly as audit-to-backlog does: a `Backlog: <todo path>, <done path>` line in `AGENTS.md` or `CLAUDE.md`, otherwise `TODO.md` and `TODO-done.md`. Read both if they exist and continue their category numbering under the ID prefix `BASE`.18- Read the project's `AGENTS.md`, `docs/pitfalls.md`, and decision records: a practice the project rejected or deferred on purpose is reported as `deliberate`, never proposed.1920## 2. Probe each practice2122| Practice | Present when | Missing → |23|---|---|---|24| Env read through one validated module | a single module parses `process.env` (or the stack's equivalent) with a schema (zod or similar), and `rg` finds no direct env reads elsewhere in app code | P2 |25| Agent deny-list for secrets | `.claude/settings.json` `permissions.deny` covers `.env*` and key files (`*.pem`, `*.key`) | P2 |26| Secret scanning in CI | a CI step runs gitleaks, trufflehog, or the host's secret scanning | P2 |27| Coverage floor that only rises | the test config sets coverage thresholds and CI enforces them | P2 |28| Additive-only migration guard | CI fails on destructive migrations (drop/rename) without an explicit marker | P2; skip without a database |29| Dependency/boundary rules | dependency-cruiser, eslint boundaries, or a layer test that fails CI | P3 |30| Real-database test tier | tests run against a real database (Docker or a CI service), not only mocks | P2; skip without a database |31| Safe error responses | API errors return one envelope with a code and a message (`details` optional), as error-handling-conventions defines; no stack traces or internal fields | P1 when a stack trace or internal error reaches a response, otherwise P2; skip without an API |32| CHANGELOG | `CHANGELOG.md` in Keep a Changelog format | P3 |33| Docs-vs-code consistency check | a script or CI step checks docs against code (commands, paths, versions) | P3 |34| Design system file | a project with a UI (components, pages or stylesheets in app code) has a root `DESIGN.md` in the DESIGN.md format (YAML tokens, then Overview … Do's and Don'ts) | P3; skip without a UI. When present, suggest `npx @google/design.md lint DESIGN.md` for the user to run; never run or install it |35| No runtime dependency two majors behind | the package manager's outdated report (`pnpm outdated --prod`, `npm outdated --omit=dev`, `yarn outdated`, `uv pip list --outdated` limited to the `pyproject.toml` dependencies, `bundle outdated`) lists no runtime dependency two or more major versions behind its latest release | P2 for a framework or runtime dependency, otherwise P3; skip when the report needs credentials or the network is unavailable, and say so; a nonzero exit from the outdated command alone is not a failure. `bundle outdated` evaluates the `Gemfile` and `yarn` runs the file a `.yarnrc*` names in `yarnPath`/`yarn-path`: both run repository code, so ask before either. Each item's `Done when` names the target version; its Check fails until the lockfile resolves that major, written for the lockfile's format (for example `rg -q '/next@15\.' pnpm-lock.yaml`). Dispatch nothing during the probe: the report offers upgrade plans (step 5) |36| Dependency release-age cooldown | the update bot or package manager enforces a minimum release age before a new version is taken (Dependabot `cooldown`, Renovate `minimumReleaseAge`, pnpm `minimumReleaseAge`, uv `exclude-newer`) | P3; skip without dependencies |37| After-edit lint hook | `.claude/settings.json` has a `PostToolUse` hook on `Edit\|Write` that reads `tool_input.file_path` from stdin, lints that file, and exits 2 with only the failures on stderr | P3; skip without a linter |38| Agent sandbox | `.claude/settings.json` sets `sandbox.enabled: true` and `~/.ssh` and `~/.aws` are denied to it, in `sandbox.filesystem.denyRead` or as `sandbox.credentials.files` entries with `"mode": "deny"` (the sandbox reads them by default); the guard and permission rules match text, the sandbox restricts every command | P2 |39| Pinned MCP servers | every stdio server in `.mcp.json` runs a pinned version (`npx -y pkg@1.2.3`, `uvx pkg==1.2.3`, an image digest), with no `@latest` and no bare package name; a server's tool descriptions reach the model, so a version bump is reviewed like a dependency | P2; skip without `.mcp.json` |40| Gate verdict in the exit code | every CI and validation script exits non-zero on failure (no `\|\| true`, no `continue-on-error` on gates) | P2 |4142Record each probe and its result as the evidence: the command or file checked, and what it found. Unsure counts as unsure, not missing: list it under questions.4344## 3. Decisions, not defaults4546Never propose a default for these; when the repository is inconsistent (two lockfiles, two test runners, mixed commit languages), list the evidence and ask the user to choose:4748- Package manager (npm vs pnpm)49- Test runner (Jest vs Vitest)50- Authentication library51- Monitoring stack52- Commit message language5354## 4. Draft the backlog items5556One item per missing practice, in audit-to-backlog's shape, filed under its severity section and deduplicated against both backlog files:5758```markdown59- [ ] BASE-03 · P2 · Secret scanning in CI60 - Where: `.github/workflows/ci.yml:1`61 - Problem: no CI step scans for committed secrets.62 - Evidence: `rg -l 'gitleaks|trufflehog' .github/` → no match.63 - Fix: add a gitleaks step to the CI workflow that fails the job on a finding.64 - Size: S65 - Done when: CI fails on a commit that contains a secret.66 - Check: `rg -q 'gitleaks' .github/workflows/`67```6869## 5. Report and ask7071```72Project baseline — <repo>73Present: 6 Missing: 4 (P2 3, P3 1) Deliberate: 1 Not applicable: 174Needs your decision: test runner — package.json has both jest and vitest7576Write the 4 items to TODO.md? A: all (recommended) B: list IDs C: none77Plan the 2 upgrades with dependency-upgrader first (reads changelogs on the web)? yes / no78```7980The second question appears only when the dependency probe found items. On a yes, dispatch `developer-os:dependency-upgrader` once per dependency, for at most the three furthest behind, and put its steps into the item's Fix and its estimate into its Size before writing; mark its `ASSUMPTION:` lines as such in the item. The install commands in a plan are text for the user to run, never commands this skill runs.8182If the backlog files do not exist yet, ask for the paths and record them as a `Backlog: <todo path>, <done path>` line in `AGENTS.md` (or `CLAUDE.md`), with its git-ignored path warning, as audit-to-backlog does.8384## Stop point8586Stop after the report and the question. After approval, merge the approved items into the backlog file with `Session N: <ID>, …` lines of 5–7 items each (fewer than 5 items: one session) under `## Implementation sessions`, grouped as audit-to-backlog groups them, show `git diff --stat`, and stop; implementation is implement-backlog's job.8788## Never8990- Write or create any file before the user approves.91- Pick a default for a "needs your decision" item.92- Install dependencies, add CI steps, or change configuration; this skill only proposes.93- Commit, push, or open a pull request.94- Propose a practice the project rejected on purpose.