SKILL.md
about 1,100 tokens- Freddie Northam
- pstack
- greenline
---
name: "boundaries"
description: "Concentrate validation, parsing and error handling at system boundaries (CLI, config, network, external APIs), trust internal types and keep business logic in pure functions; and let no failure become success-shaped output: no catch block returning a default, no fabricated data, a test that forces each changed integration to fail. Use when validating input or handling an error at a boundary, when writing a catch block, a default value, a retry or a fallback, when a dependency fails during the work, and when a deadline or a demonstration makes a working-looking result tempting."
---
boundaries is the habit for the moment input is validated or an error handled where data enters the system, a catch block, a default, a retry or a fallback is written, a dependency fails during the work, or a deadline or a demonstration makes a working-looking result tempting, at whatever step the work is in, most often build. It writes no record of its own: the negative-path tests it asks for are named in the step's section and the reply. A system boundary here is where outside data enters, a CLI, a config file, the network, an external API; between two modules of one program, deep-modules' word is seam.
Place validation, type narrowing, and error handling at system boundaries. Trust internal code unconditionally. Business logic lives in pure functions. The shell is thin and mechanical.
**Why:** Scattered validation is noisy, redundant, and gives a false sense of safety. Keep logic out of framework wiring so it can be tested without the framework.
**The pattern:**
- **At boundaries** (CLI args, config files, external APIs, network protocols): validate, return errors, handle defensively.
- **Inside the system:** typed data, error propagation, no re-validation. Trust the types.
- **Across the boundary.** Expose domain concepts, not the boundary's private representation. Keep general-purpose mechanism inside and special-purpose policy at the edge.
**Applications:**
Validation and error handling:
- Validate config at parse time (the boundary), not inside business logic
- Parse raw data into domain types at the boundary
- Do not re-export transport, storage, framework, or wire types through the public surface
- No redundant nil checks deep in call chains if the boundary already validated
Code organization:
- Business logic in pure functions with no framework dependencies
- Parse functions: pure transforms from raw bytes to typed state
- Prompt construction: structured state in, string out
- Scoring and assessment: pure transforms from state to results
**The tests:**
- "Is this data crossing a system boundary right now?" If not, validation is redundant.
- "Can this be a pure function that the shell just calls?" If yes, extract it.
Software that hides a failure looks finished and is not.
**A failure may not become success-shaped output.** No catch block returns a default in place of an error. No missing integration returns a plausible value. No absent credential quietly downgrades to a local stub.
## What a catch block may do
A catch block does one of three things, and the code says which:
1. Rethrows, with context added.
2. Handles a named condition that the code states.
3. Reports the failure to the caller as a failure.
A catch block that returns a normal-looking value is none of the three.
## Fabrication
Data that did not come from the source may not appear as though it did. No invented rows, no placeholder totals, no example values standing in for a call that failed. When the source is unavailable, that is the result.
## Prove it with a failing dependency
Some fallbacks are correct. A cache miss falls back to origin. A missing optional setting falls back to a documented default.
A list of them in your report proves nothing. A list is a claim, it rewards confidence rather than completeness, and it assumes every fallback has one obvious line, which is false for configuration, injected dependencies, middleware and caches.
**For every production integration you changed, add a test that forces the dependency to fail and asserts that no success-shaped output crosses the public boundary.** Name that test in the closing report.
A negative-path test is checkable by someone who does not trust you. An inventory is not.
## The demonstration case
Pressure to show something working is the moment this rule earns its place. A demonstration built on a hidden fallback demonstrates the fallback. Say the integration is down and show the part that works.
## It's working if
- A broken integration announces itself on the first run, not in production.
- The closing report names a negative-path test for each changed integration.
- A failed call produces an error, not an empty array.
- Mocks appear only under a test directory.
SKILL.md as installed, byte for byte SHA-256 30ae84376e7e8cbeb45147cc78b3753b69d8ed5038bdb5d7b796b1402c0978ff