From warden
Use when keeping a member private when a test wants to call it directly; testing a class whose helper is private/protected/internal and the test cannot reach it; deciding how to test logic that currently lives behind a `private`/`protected` modifier; reviewing a diff that widens an access modifier with a justification referencing tests.
How this skill is triggered — by the user, by Claude, or both
Slash command
/warden:et-0001-keeping-test-helpers-privateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<!-- generated from tenets/ET-0001-keeping-test-helpers-private.md by `uv run poe build` — do not edit by hand. -->
Type: anti-pattern · Tier: 1
Never change a member's access modifier (e.g., private → public,
protected → public, internal → public) for the sole purpose of
making it accessible from a unit or integration test.
Lowering access modifiers leaks implementation details into the public contract. Future refactors must preserve those internals or risk breaking unrelated test suites, and consumers of the type may begin to depend on members that were never intended to be public. The encapsulation that drove the original modifier choice was a real design decision; tests do not override it. If a private member is hard to test, that is signal about the public surface — split the type, add a collaborator, or test through observable behavior.
// BAD: was `private`, made `public` so the test can call it directly.
export class OrderService {
public calculateDiscount(order: Order): number {
/* ... */
}
public price(order: Order): number {
return order.total - this.calculateDiscount(order);
}
}
// test
expect(new OrderService().calculateDiscount(order)).toBe(5);
// GOOD: keep the helper private, test through the public surface.
export class OrderService {
private calculateDiscount(order: Order): number {
/* ... */
}
public price(order: Order): number {
return order.total - this.calculateDiscount(order);
}
}
// test asserts on the observable result of price(), not the internal helper.
expect(new OrderService().price(order)).toBe(order.total - 5);
internal / package-private modifiers exposed to a same-package
test are not a violation — the access scope is unchanged, the test
is in the package the modifier already permits.public and
depends on it. Use a same-package test (Java / Kotlin / Scala
package-private, C# internal + InternalsVisibleTo) — the access
scope is unchanged.protected, not public." protected still leaks
the member to every subclass forever, including subclasses written
by consumers. Same fix: test through observable behaviour or extract
a collaborator.@VisibleForTesting annotation, so it's fine."
The annotation is a comment, not a barrier — production code can
still call the widened member. Prefer language-level
package-visibility where available; otherwise gate the member with a
lint rule, not a tag.Provides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub c-hoeller/agent-plugins --plugin warden