---
name: ai-codebase-hardening
description: Use for any non-trivial code, test, spec, guardrail, harness, or repo-owned skill change in this repo, especially before editing, reviewing, or PR prep when AI-generated complexity, duplicate code, compatibility patches, low-value tests, or performance regressions could grow unless the change is intentionally simplified.
---

# AI Codebase Hardening

## Core Principle

In this repo, the default failure mode is adding more code. Before adding a module, wrapper, fallback, branch, test helper, or compatibility path, prove that reusing, deleting, or tightening an existing module would not solve the problem more clearly.

The goal is not broad cleanup. The goal is to keep each touched change smaller, faster, and easier to reason about than the code it replaces.

## When To Use

Use this skill for all non-trivial implementation, refactoring, review, PR preparation, or harness work. It is especially important when the change touches:

- AI-generated code with visible patch layering, duplicate helpers, defensive compatibility, or confusing ownership.
- API, store, worker, realtime, frontend first-paint, or other hot paths where more code can hide more runtime work.
- Tests that mostly assert mocks, incidental structure, old bugs, or generated implementation details.
- Specs, guardrails, or skills that are meant to prevent future agent drift.

Do not use it for tiny mechanical edits where no design or behavior decision is involved.

## Hard Requirements

This skill is an execution gate, not advisory reading. When it triggers, apply these requirements before editing and before reporting completion.

- **Name the owner before adding code.** Identify the package, component, guardrail, or skill that owns the behavior. If the owner is unclear, state the ambiguity and resolve it by reading call sites before adding a new owner.
- **Search for reuse before creating helpers.** Use targeted search for existing helpers, components, fixtures, API clients, store methods, converters, and guardrails. Adding a near-duplicate is only acceptable after checking semantic differences such as permissions, ordering, error handling, lifetime, and performance.
- **Run targeted checks plus the fast aggregate harness.** For code, test, harness, guardrail, or skill changes, run the narrow behavior test plus the targeted guardrail that owns the touched surface. Before opening or updating a PR, run `make harness-fast` when feasible; it is a cheap aggregate smoke check, not a replacement for targeted verification.
- **Treat harness failures as evidence.** If `make harness-fast` or a targeted guardrail is red, do not ignore it. Record the exact failing check and counts, decide whether the current change caused it, and fix current-change regressions before completion. If the aggregate harness is red because of unrelated pre-existing debt, report the failing check and keep the targeted verification for the current change explicit.
- **Do not raise baselines as a shortcut.** Ratchet baselines are ceilings, not snapshots. Increase a baseline only when the change intentionally accepts debt with a clear owner, reason, delete condition, and reviewed scope. Lower baselines in the same change when cleanup reduces debt.
- **Manual self-check still applies.** When no simple guardrail exists, inspect the touched code manually for the checklist below and report the result. Lack of an automated check is not permission to skip the concern.

## Workflow

1. **Read before deciding.** Inspect the relevant specs, code, tests, and call sites. Do not infer module behavior from names.
2. **Find the existing owner.** Name the module that already owns the behavior. If no clear owner exists, state that explicitly before creating one.
3. **Try the deletion test.** For every wrapper, adapter, facade, fallback, or helper you are about to keep or add, ask whether deleting it would concentrate complexity or just move the same complexity to callers. Keep it only when it buys locality or leverage.
4. **Prefer reuse with verified semantics.** Similar code is not automatically shared code. Reuse only after checking invariants, error handling, ordering, permissions, and performance cost.
5. **Constrain compatibility.** Keep legacy or fallback paths only when a canonical spec, active caller, or migration plan needs them. Otherwise remove the path in the touched area.
6. **Keep tests behavior-facing.** Preserve tests that check externally relevant behavior or invariants. Delete or rewrite redundant tests that only freeze generated structure, mocks, pass-through wrappers, or removed compatibility paths.
7. **Check runtime cost.** For hot paths, identify the request-bound or product-bound cost driver. Avoid broad scans, N+1 calls, eager hydration, per-item allocations, repeated parsing, hidden retries, and unbounded concurrency.
8. **Turn recurring drift into harness.** If the same mistake is likely to recur, prefer a focused guardrail, ratchet baseline, spec rule, or skill update over a one-off comment.

## Completion Self-Check

Before opening or updating a PR, or before reporting implementation work as complete, perform this checklist for the touched area. If an item cannot be checked by an existing guardrail or test, inspect it manually and mention the result in the PR or final report. This checklist is required even when all tests pass.

- **Large files and functions.** Check whether touched production files or tests became oversized. Split only when it clarifies ownership; otherwise state why the touched owner remains the right boundary.
- **Diff scope.** Re-read the final diff and remove unrelated churn, speculative scaffolding, unused exports, temporary helpers, stale TODOs, and compatibility code made unnecessary by the change.
- **Reuse before new code.** Search for an existing owner, helper, component, API client, store method, fixture, or test helper before adding a new one. Do not create a near-duplicate unless the semantic differences are verified and documented.
- **Frontend component reuse.** Prefer shared primitives from the owning UI package and existing domain components. Avoid recreating buttons, dialogs, selects, tables, cards, empty states, loading states, or data-fetch wrappers with only local naming changes.
- **Data and permission boundaries.** Verify that API handlers, store code, DTO converters, and frontend clients keep wire contracts, persistence models, authorization checks, workspace/org scoping, and secret handling in their owning layers.
- **Compatibility and deletion.** Every fallback, legacy branch, migration bridge, or compatibility route must have a known caller, a removal condition, and tests for both the intended path and the failure/retirement path.
- **Test value.** Delete or rewrite tests made obsolete by the change. Avoid tests that only freeze mock call order, pass-through wrappers, generated structure, incidental snapshots, or compatibility paths being removed.
- **Hot-path cost.** For API, store, worker, realtime, search, scheduler, and first-paint paths, check for N+1 calls, broad SQL scans, `SELECT *`, missing limits, repeated encode/decode, unbounded `Promise.all`, unbounded goroutines, unnecessary hydration, and hidden retries.
- **Failure modes and backpressure.** Check timeouts, cancellation, retry/backoff, partial failure, queue limits, concurrency caps, and behavior under slow or unavailable dependencies. Avoid fail-open fallbacks at authorization, storage, or delivery boundaries.
- **Resource lifecycle.** Check that goroutines, timers, tickers, HTTP responses, SQL rows, files, subscriptions, sockets, and background workers have a clear cancellation or close path. Do not rely on process exit for ordinary cleanup.
- **Observability cost and usefulness.** Ensure logs, metrics, traces, and debug output are low-cardinality, bounded, privacy-safe, and tied to actionable failure modes instead of adding noisy per-item instrumentation.
- **Coupling and abstraction.** Remove single-use facades, single-implementation interfaces, pass-through adapters, circular ownership, and upward imports introduced by the change unless they enforce a real boundary.
- **Documentation and harness.** If the issue is likely to recur, add or update a focused guardrail, ratchet baseline, durable spec rule, or this skill. Keep baselines explicit about current debt and lower them when cleanup removes debt.

## Red Flags

- A new helper only calls another helper with renamed parameters.
- A compatibility branch has no known caller or no removal condition.
- A fallback silently changes behavior instead of failing at the owning seam.
- A test creates large mocks to assert private call order.
- A frontend first-paint path adds optional data that could load on explicit intent.
- A store or API path fetches objects wider than the request needs.
- A guardrail only reports a problem but has no threshold, failure condition, or documented baseline.

## Reporting

When finishing a change that used this skill, report:

- Which module owns the behavior after the change.
- What was reused, deleted, or deliberately not added.
- Any remaining debt that was observed but left untouched.
- The exact verification command and result.
