Craftsman standard for automated testing: strategy, unit/integration/e2e selection, refactor-proof design, flaky tests, mocking boundaries, deterministic data, and merge-gate policy. Use WHENEVER work touches tests: writing/reviewing tests, strategy, "add tests", "why is this flaky", "what should I test", "tests pass but prod breaks", Testing Library / Playwright / Vitest / Jest / Pytest, mocks, fixtures, or adequacy. Trigger on "add tests", "write a test", "is this tested enough", or "make the tests reliable". Owns which suites gate merge and what "green" means — see "Scope boundaries" in the body for handoffs to craft-infra, craft-security, and craft-ux.
This skill encodes one engineer's standard for testing software so the suite is actually trusted —
fast, deterministic, and catching real regressions rather than decorating the coverage badge. The
method and opinions live here; the project specifics (test runner, framework, what's already
covered) live in the target repo — always discover them, never assume or hardcode.
The persona this serves usually arrives at one of two extremes: no tests at all, or a pile of
AI-generated tests that don't test anything — they assert that a mock was called, pin
implementation details, or cover trivial getters to hit a number while the payment path has zero
coverage. Both feel like "we have testing." Neither catches the bug that takes the app down. The job
is to move them to a small set of tests they can trust, on the paths that actually matter.
Operating principle — discover before you build
Different repos already have different pieces in place. Before adding anything, map what exists so you
extend rather than duplicate or fight it:
package.json / lockfile → test runner (vitest, jest, playwright, @testing-library/*,
pytest), test/test:e2e/coverage scripts, and whether tests even run. Coverage tooling or
a configured percentage is context, not proof that the tests are adequate.
Existing tests (*.test.*, *.spec.*, __tests__/, e2e/, tests/) → conventions, what's
covered, and the quality of what's there (real assertions vs. tautologies — read a few).
Read CI config files (package.json scripts, .github/workflows) — read-only context for
understanding which suites currently gate a merge; wiring changes → craft-infra.
State what you found — including "the tests that exist don't assert anything real" — then propose the
smallest set of additions that closes the gap on the paths that matter.
The testing layers (work in this order)
Strategy — decide what deserves a test before writing one. Spend the budget on the paths
where a bug means a breach, data loss, or money: auth, authorization, payments, data mutations.
A handful of integration tests on the critical path beats two hundred shallow unit tests. Coverage
is a signal of what's untested, never a target to chase. See references/strategy.md.
Test design — write tests that survive a refactor: assert observable behavior, not internal
calls; make them deterministic (frozen clock, seeded randomness, no real network); build data with
factories, not shared mutable fixtures. A test that breaks when you rename a private method is
testing the wrong thing. See references/test-design.md.
Flake — a test that fails randomly is worse than no test: it trains the team to ignore red.
Find the source (time, order-dependence, async races, shared state, real I/O), fix it, and
quarantine rather than paper over it with blanket retries. See references/flake.md.
Frontend / component testing — test components the way a user drives them: query by role and
label, not test-ids; userEvent over fireEvent; mock the network (MSW), not your own modules.
See references/frontend-testing.md.
Backend & data testing — exercise the real boundary: integration tests against a real database
(testcontainers / transactional rollback), contract tests at service edges, seeded deterministic
data. Mocking the database makes tests pass while production breaks. See
references/backend-data-testing.md.
Standing opinions (the non-negotiables)
Apply these unless the user overrides — they're what makes the suite worth trusting:
Test behavior, not implementation. Assert what the user or caller observes, not which internal
function ran. Tests that mirror the implementation break on every refactor and catch no real bugs —
they're a tax, not a safety net.
Coverage is a signal, not a target. Use it to find untested critical paths; never mandate a
global percentage. A coverage target is a Goodhart magnet — it produces tautological tests that
raise the number and catch nothing. Care about the money path being covered, not the repo average.
Mock at the boundary you own's edge, not inside it. Mock the network and external services;
don't mock your own database, your ORM internals, or the unit under test. A test built on mocked
internals proves the mocks agree with each other, not that the code works.
A flaky test is a bug — fix or delete it, don't retry it. Blanket test retries hide real race
conditions and erode trust in the whole suite. Quarantine a flake, find the nondeterminism, fix it.
Write the test that would have caught the bug. Every production incident and every fixed bug
earns a regression test reproducing it. This is how a suite gets sharp over time instead of bloated.
Workflow
Discover — map the runner, existing tests, and their real quality; report what matters and
isn't covered.
Prioritize — critical-path / high-blast-radius behavior first (strategy.md tiers), not whatever
is easiest to test.
Write — behavior-asserting, deterministic, boundary-correct tests against the repo's existing
conventions.
Verify — run them, and confirm they fail when the behavior breaks. For a test that is credited
with protecting a Tier A invariant, gather direct discriminative evidence as described below. A test
you haven't seen fail is not yet a test.
Discriminative evidence for critical tests
Source review can establish that a test has a meaningful-looking assertion; it cannot establish that
the test distinguishes the protected behavior from a realistic regression. Do not credit a Tier A test
as adequate on source review alone.
For each distinct Tier A invariant the audit credits as covered, identify the existing enforcement
predicate and obtain direct evidence that the relevant test detects it being broken. Examples of
invariants and predicates include tenant/owner/role checks, payment amount or idempotency checks,
irreversible-mutation guards, and an entitlement or token expiry comparison.
The usual evidence is one bounded local fault-injection probe per distinct invariant: temporarily
remove, relax, or invert that existing predicate; run the directly relevant test; verify that it fails
on its behavioral assertion; restore the source; and rerun the test green. Record the invariant,
predicate, named test, observed red result, and restored-green result in the audit evidence. The probe
must change production code only — never the test, its assertion, a mock, typechecking, or unrelated
setup — and must run against isolated test data and provider fakes, never production or a live payment
provider.
This is a small verification step, not exhaustive mutation testing: do not mutate every conditional,
set a mutation score, or install a mutation-testing tool merely to conduct a Tier 1 audit. Existing
verified evidence from a regression test may substitute only when it identifies the same invariant,
the named test, and the expected behavioral failure. If direct evidence cannot be safely obtained (for
example, a strictly read-only audit or an unavailable test environment), report that
invariant-coverage claim as unverified; do not grade it adequate or use it to close a critical-path
coverage finding.
Scope boundaries
This skill owns which suites gate merge and what "green" means, including e2e. Hand off at these
lines:
CI pipeline mechanism (how the pipeline is wired, where jobs run) → craft-infra. The split
is by defect, not by topic: a missing e2e suite is a TEST finding; an e2e suite that exists but
isn't wired into CI is an INFRA finding.
Security correctness of what a test asserts → craft-security.
Read the one matching the current task — they hold the concrete patterns, not this overview:
references/strategy.md — what to test, the testing trophy/pyramid, the two persona tiers, what
not to test, coverage-as-signal, and the test-gate policy (the CI pipeline mechanism is
craft-infra → ci-cd.md; this defines which suites gate and what green means)
references/flake.md — the flake taxonomy and concrete fixes, retries vs. quarantine policy
references/frontend-testing.md — Testing Library (role/label queries, userEvent), MSW for the
network, what to mock; the visual/rendered audit of a running UI is craft-ux → live-audit.md
references/backend-data-testing.md — integration/contract tests, testcontainers, transactional
rollback, seeding; schema/query correctness is craft-db, the API contract is craft-backend,
and a test that proves a security fix pairs with craft-security
Audit checklist (for craft-audit)
Python projects: substitute pytest for Vitest, httpx for supertest, and the SQLAlchemy
rollback fixture (yield fixture with session.rollback()) for the Drizzle transaction rollback
pattern. All other checklist items apply unchanged.
When craft-audit plans a testing pass for a scope, it turns this checklist into the plan.md
todo list — the checklist is owned by this skill, not improvised by the orchestrator. Tailor to what
discovery found: skip a step that genuinely doesn't apply with a one-line reason; never silently drop
one. Emit findings using craft-audit workspace.md → "Canonical findings.md emission format"
(authority). Heading grammar (variables required — do not hardcode NNN/severity/status):
## <scopeLabel>-TEST-<NNN> · severity <🔴|🟡|🟢> · status <open|fixed|wontfix (reason)|regressed|fixed (merged into <ID>)>
Example only: ## <scopeLabel>-TEST-001 · severity 🔴 · status open
Required fields under each heading, in order, with these exact labels:
**What breaks (plain language):** · **Technical:** · **Fix:** · **Fingerprint:** ·
**Last-checked:** (optional **Confidence:** — verified | inferred | unverified-from-repo, absent
means verified — then optional **Fix-attempt:** only from craft-fix).
Assign sequential NNN per (scope, domain); judge severity with craft-audit prioritization.md.
Forbidden: ### headings; ## ID · 🔴 · open shorthand; severity/status as body bullets.
Map the runner, configs, existing tests, and any coverage command/report; flag tests that assert
nothing real (mock-was-called, pinned internals, trivial getters) as if untested. The absence of a
repo-wide coverage percentage or coverage configuration is an observation, not itself a TEST
finding → SKILL.md (Operating principle)
Check the critical paths (auth, authorization, payments, data mutations) actually have tests; flag
coverage spent on trivia while the money path is bare. If a coverage report is available, use its
Tier A branch gaps as leads; do not grade from a global percentage → references/strategy.md
Verify tests assert observable behavior, not internal calls — flag suites that break on a private
rename or mirror the implementation → references/test-design.md
Check determinism: frozen clock, seeded randomness, no real network; flag wall-clock/random/live-I/O
tests and shared mutable fixtures over factories → references/test-design.md
Hunt flake and its cover-ups; flag blanket retries papering over time, order-dependence, async
races, or shared state instead of a real fix → references/flake.md
Check component tests drive the UI like a user — role/label queries and userEvent, network mocked
via MSW; flag test-id queries, fireEvent, or mocked own modules → references/frontend-testing.md
Verify backend/data tests hit the real boundary (real DB via testcontainers/transactional rollback,
contract tests, seeded data); flag a mocked database → references/backend-data-testing.md
For every Tier A invariant credited as covered, record discriminative evidence: name the existing
enforcement predicate and directly relevant test; run one bounded local fault-injection probe (or
cite equivalent verified regression evidence); observe the behavioral assertion fail; restore and
rerun green. One representative probe per distinct invariant is enough — this is not a mutation
score. If it cannot be safely run, mark the claim unverified, not adequate; flag tests never
seen red and incidents without a reproducing test → SKILL.md (Discriminative evidence)
For prose promises that are material and mechanically verifiable, check a structural test
pins the declared value to the config or implementation it describes (retention windows,
tenant-scope filters on query modules, privacy-policy claims vs SDK init literals). Treat these
as consistency evidence, not runtime proof — asserting RETENTION_DAYS === 30 and that a
job is registered says nothing about whether deletion runs, so pair it with a behavioral test
(aged fixture data, real job invocation) and pair tenant-scope scans with integration tests of
reads and writes. Legitimate deviations belong in an allowlist with a one-line written
justification each. Do not report a missing structural test as a defect where the promise is
immaterial or not mechanically checkable → craft-audit references/claim-verification.md
TEST ↔ INFRA handoff: this pass owns which suites must gate merge and what "green" means
(including whether critical-flow e2e exists). Missing e2e suite is a TEST finding; if the
suite exists but is not wired into CI, note it and route to craft-infra (pipeline mechanism)
→ references/strategy.md · craft-infra ci-cd.md
1---2name: craft-testing3description: Craftsman standard for automated testing: strategy, unit/integration/e2e selection, refactor-proof design, flaky tests, mocking boundaries, deterministic data, and merge-gate policy. Use WHENEVER work touches tests: writing/reviewing tests, strategy, "add tests", "why is this flaky", "what should I test", "tests pass but prod breaks", Testing Library / Playwright / Vitest / Jest / Pytest, mocks, fixtures, or adequacy. Trigger on "add tests", "write a test", "is this tested enough", or "make the tests reliable". Owns which suites gate merge and what "green" means — see "Scope boundaries" in the body for handoffs to craft-infra, craft-security, and craft-ux.4---56# Testing Craft78This skill encodes one engineer's standard for testing software so the suite is actually trusted —9fast, deterministic, and catching real regressions rather than decorating the coverage badge. The10**method and opinions** live here; the **project specifics** (test runner, framework, what's already11covered) live in the target repo — always discover them, never assume or hardcode.1213The persona this serves usually arrives at one of two extremes: **no tests at all**, or a pile of14**AI-generated tests that don't test anything** — they assert that a mock was called, pin15implementation details, or cover trivial getters to hit a number while the payment path has zero16coverage. Both feel like "we have testing." Neither catches the bug that takes the app down. The job17is to move them to a small set of tests they can *trust*, on the paths that actually matter.1819## Operating principle — discover before you build2021Different repos already have different pieces in place. Before adding anything, map what exists so you22extend rather than duplicate or fight it:2324- `package.json` / lockfile → test runner (`vitest`, `jest`, `playwright`, `@testing-library/*`,25 `pytest`), `test`/`test:e2e`/`coverage` scripts, and whether tests even run. Coverage tooling or26 a configured percentage is context, not proof that the tests are adequate.27- Test config (`vitest.config.*`, `jest.config.*`, `playwright.config.*`, `pytest.ini`,28 `conftest.py`) → environment, setup files, coverage thresholds already set.29- Existing tests (`*.test.*`, `*.spec.*`, `__tests__/`, `e2e/`, `tests/`) → conventions, what's30 covered, and the *quality* of what's there (real assertions vs. tautologies — read a few).31- Read CI config files (`package.json` scripts, `.github/workflows`) — read-only context for32 understanding which suites currently gate a merge; wiring changes → craft-infra.3334State what you found — including "the tests that exist don't assert anything real" — then propose the35smallest set of additions that closes the gap on the paths that matter.3637## The testing layers (work in this order)38391. **Strategy** — decide *what* deserves a test before writing one. Spend the budget on the paths40 where a bug means a breach, data loss, or money: auth, authorization, payments, data mutations.41 A handful of integration tests on the critical path beats two hundred shallow unit tests. Coverage42 is a signal of what's *untested*, never a target to chase. See `references/strategy.md`.432. **Test design** — write tests that survive a refactor: assert observable behavior, not internal44 calls; make them deterministic (frozen clock, seeded randomness, no real network); build data with45 factories, not shared mutable fixtures. A test that breaks when you rename a private method is46 testing the wrong thing. See `references/test-design.md`.473. **Flake** — a test that fails randomly is worse than no test: it trains the team to ignore red.48 Find the source (time, order-dependence, async races, shared state, real I/O), fix it, and49 quarantine rather than paper over it with blanket retries. See `references/flake.md`.504. **Frontend / component testing** — test components the way a user drives them: query by role and51 label, not test-ids; `userEvent` over `fireEvent`; mock the *network* (MSW), not your own modules.52 See `references/frontend-testing.md`.535. **Backend & data testing** — exercise the real boundary: integration tests against a real database54 (testcontainers / transactional rollback), contract tests at service edges, seeded deterministic55 data. Mocking the database makes tests pass while production breaks. See56 `references/backend-data-testing.md`.5758## Standing opinions (the non-negotiables)5960Apply these unless the user overrides — they're what makes the suite worth trusting:6162- **Test behavior, not implementation.** Assert what the user or caller observes, not which internal63 function ran. Tests that mirror the implementation break on every refactor and catch no real bugs —64 they're a tax, not a safety net.65- **Coverage is a signal, not a target.** Use it to *find* untested critical paths; never mandate a66 global percentage. A coverage target is a Goodhart magnet — it produces tautological tests that67 raise the number and catch nothing. Care about the money path being covered, not the repo average.68- **Mock at the boundary you own's edge, not inside it.** Mock the network and external services;69 don't mock your own database, your ORM internals, or the unit under test. A test built on mocked70 internals proves the mocks agree with each other, not that the code works.71- **A flaky test is a bug — fix or delete it, don't retry it.** Blanket test retries hide real race72 conditions and erode trust in the whole suite. Quarantine a flake, find the nondeterminism, fix it.73- **Write the test that would have caught the bug.** Every production incident and every fixed bug74 earns a regression test reproducing it. This is how a suite gets sharp over time instead of bloated.7576## Workflow77781. **Discover** — map the runner, existing tests, and their *real* quality; report what matters and79 isn't covered.802. **Prioritize** — critical-path / high-blast-radius behavior first (strategy.md tiers), not whatever81 is easiest to test.823. **Write** — behavior-asserting, deterministic, boundary-correct tests against the repo's existing83 conventions.844. **Verify** — run them, and confirm they *fail when the behavior breaks*. For a test that is credited85 with protecting a Tier A invariant, gather direct discriminative evidence as described below. A test86 you haven't seen fail is not yet a test.8788## Discriminative evidence for critical tests8990Source review can establish that a test has a meaningful-looking assertion; it cannot establish that91the test distinguishes the protected behavior from a realistic regression. Do not credit a Tier A test92as adequate on source review alone.9394For each distinct Tier A invariant the audit credits as covered, identify the existing enforcement95predicate and obtain direct evidence that the relevant test detects it being broken. Examples of96invariants and predicates include tenant/owner/role checks, payment amount or idempotency checks,97irreversible-mutation guards, and an entitlement or token expiry comparison.9899The usual evidence is one **bounded local fault-injection probe** per distinct invariant: temporarily100remove, relax, or invert that existing predicate; run the directly relevant test; verify that it fails101on its behavioral assertion; restore the source; and rerun the test green. Record the invariant,102predicate, named test, observed red result, and restored-green result in the audit evidence. The probe103must change production code only — never the test, its assertion, a mock, typechecking, or unrelated104setup — and must run against isolated test data and provider fakes, never production or a live payment105provider.106107This is a small verification step, not exhaustive mutation testing: do not mutate every conditional,108set a mutation score, or install a mutation-testing tool merely to conduct a Tier 1 audit. Existing109verified evidence from a regression test may substitute only when it identifies the same invariant,110the named test, and the expected behavioral failure. If direct evidence cannot be safely obtained (for111example, a strictly read-only audit or an unavailable test environment), report that112invariant-coverage claim as `unverified`; do not grade it adequate or use it to close a critical-path113coverage finding.114115## Scope boundaries116117This skill owns which suites gate merge and what "green" means, including e2e. Hand off at these118lines:119120- **CI pipeline mechanism** (how the pipeline is wired, where jobs run) → `craft-infra`. The split121 is by defect, not by topic: a *missing* e2e suite is a TEST finding; an e2e suite that exists but122 isn't wired into CI is an INFRA finding.123- **Security correctness** of what a test asserts → `craft-security`.124- **Live visual audit** of rendered UI → `craft-ux`.125- **Whole-project readiness** → `craft-audit`.126- **Existing tracked findings** ("fix TEST-004") → `craft-fix`.127128## Reference index129130Read the one matching the current task — they hold the concrete patterns, not this overview:131132- `references/strategy.md` — what to test, the testing trophy/pyramid, the two persona tiers, what133 *not* to test, coverage-as-signal, and the test-gate policy (the CI *pipeline* mechanism is134 `craft-infra` → `ci-cd.md`; this defines which suites gate and what green means)135- `references/test-design.md` — trustworthy-test anatomy, behavior-vs-implementation, determinism136 (clock/seed), assertion quality, factories over fixtures137- `references/flake.md` — the flake taxonomy and concrete fixes, retries vs. quarantine policy138- `references/frontend-testing.md` — Testing Library (role/label queries, `userEvent`), MSW for the139 network, what to mock; the *visual/rendered* audit of a running UI is `craft-ux` → `live-audit.md`140- `references/backend-data-testing.md` — integration/contract tests, testcontainers, transactional141 rollback, seeding; schema/query *correctness* is `craft-db`, the API *contract* is `craft-backend`,142 and a test that *proves a security fix* pairs with `craft-security`143144## Audit checklist (for craft-audit)145146> **Python projects:** substitute pytest for Vitest, httpx for supertest, and the SQLAlchemy147> rollback fixture (yield fixture with `session.rollback()`) for the Drizzle transaction rollback148> pattern. All other checklist items apply unchanged.149150When `craft-audit` plans a testing pass for a scope, it turns this checklist into the `plan.md`151todo list — the checklist is owned by this skill, not improvised by the orchestrator. Tailor to what152discovery found: skip a step that genuinely doesn't apply with a one-line reason; never silently drop153one. Emit findings using craft-audit `workspace.md` → "Canonical findings.md emission format"154(authority). Heading grammar (variables required — do not hardcode NNN/severity/status):155156`## <scopeLabel>-TEST-<NNN> · severity <🔴|🟡|🟢> · status <open|fixed|wontfix (reason)|regressed|fixed (merged into <ID>)>`157158Example only: `## <scopeLabel>-TEST-001 · severity 🔴 · status open`159160Required fields under each heading, in order, with these exact labels:161`**What breaks (plain language):**` · `**Technical:**` · `**Fix:**` · `**Fingerprint:**` ·162`**Last-checked:**` (optional `**Confidence:**` — `verified | inferred | unverified-from-repo`, absent163means `verified` — then optional `**Fix-attempt:**` only from craft-fix).164Assign sequential NNN per (scope, domain); judge severity with craft-audit `prioritization.md`.165Forbidden: `###` headings; `## ID · 🔴 · open` shorthand; severity/status as body bullets.166167- [ ] Map the runner, configs, existing tests, and any coverage command/report; flag tests that assert168 nothing real (mock-was-called, pinned internals, trivial getters) as if untested. The absence of a169 repo-wide coverage percentage or coverage configuration is an observation, not itself a TEST170 finding → `SKILL.md` (Operating principle)171- [ ] Check the critical paths (auth, authorization, payments, data mutations) actually have tests; flag172 coverage spent on trivia while the money path is bare. If a coverage report is available, use its173 Tier A branch gaps as leads; do not grade from a global percentage → `references/strategy.md`174- [ ] Verify tests assert observable behavior, not internal calls — flag suites that break on a private175 rename or mirror the implementation → `references/test-design.md`176- [ ] Check determinism: frozen clock, seeded randomness, no real network; flag wall-clock/random/live-I/O177 tests and shared mutable fixtures over factories → `references/test-design.md`178- [ ] Hunt flake and its cover-ups; flag blanket retries papering over time, order-dependence, async179 races, or shared state instead of a real fix → `references/flake.md`180- [ ] Check component tests drive the UI like a user — role/label queries and `userEvent`, network mocked181 via MSW; flag test-id queries, `fireEvent`, or mocked own modules → `references/frontend-testing.md`182- [ ] Verify backend/data tests hit the real boundary (real DB via testcontainers/transactional rollback,183 contract tests, seeded data); flag a mocked database → `references/backend-data-testing.md`184- [ ] For every Tier A invariant credited as covered, record discriminative evidence: name the existing185 enforcement predicate and directly relevant test; run one bounded local fault-injection probe (or186 cite equivalent verified regression evidence); observe the behavioral assertion fail; restore and187 rerun green. One representative probe per distinct invariant is enough — this is not a mutation188 score. If it cannot be safely run, mark the claim `unverified`, not adequate; flag tests never189 seen red and incidents without a reproducing test → `SKILL.md` (Discriminative evidence)190- [ ] For prose promises that are **material and mechanically verifiable**, check a structural test191 pins the declared value to the config or implementation it describes (retention windows,192 tenant-scope filters on query modules, privacy-policy claims vs SDK init literals). Treat these193 as **consistency evidence, not runtime proof** — asserting `RETENTION_DAYS === 30` and that a194 job is registered says nothing about whether deletion runs, so pair it with a behavioral test195 (aged fixture data, real job invocation) and pair tenant-scope scans with integration tests of196 reads and writes. Legitimate deviations belong in an allowlist with a one-line written197 justification each. Do not report a missing structural test as a defect where the promise is198 immaterial or not mechanically checkable → craft-audit `references/claim-verification.md`199- [ ] **TEST ↔ INFRA handoff:** this pass owns which suites must gate merge and what "green" means200 (including whether critical-flow e2e exists). Missing e2e *suite* is a TEST finding; if the201 suite exists but is not *wired into CI*, note it and route to craft-infra (pipeline mechanism)202 → `references/strategy.md` · craft-infra `ci-cd.md`
Run npx skillmds@latest add gul-labs/craft-testing in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Craftsman standard for automated testing: strategy, unit/integration/e2e selection, refactor-proof design, flaky tests, mocking boundaries, deterministic data, and merge-gate policy. Use WHENEVER work touches tests: writing/reviewing tests, strategy, "add tests", "why is this flaky", "what should I test", "tests pass but prod breaks", Testing Library / Playwright / Vitest / Jest / Pytest, mocks, fixtures, or adequacy. Trigger on "add tests", "write a test", "is this tested enough", or "make the tests reliable". Owns which suites gate merge and what "green" means — see "Scope boundaries" in the body for handoffs to craft-infra, craft-security, and craft-ux. It is listed under DevOps & Infra on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
gul-labs (@gul-labs) published this skill. Their other Agent Skills are listed on their SkillMD profile.