Uncomplect rat-stack

Uncomplect means separate responsibilities that currently change together. Preserve behavior proved by tests or runtime observations. Replace structure that combines unrelated responsibilities. Make the separation hold under the next change.

Rich Hickey’s Simple Made Easy (2011) distinguishes simplicity from familiarity.

Greg Young’s The Art of Destroying Software argues for replaceable programs. Optimise for deletion.

Read first

Read AGENTS.md, VISION.md, and the relevant .brain/ decisions. Inspect the design’s source, tests, and recorded runtime results. Check library APIs against matching pinned sources before changing Effect, XState, or Alchemy code. Every recommendation must name its source file, preserved behavior, deleted complexity, and enforced check.

A held connection, a request, and a provider call in one scope34 is a braid. Separate them with durability.

Terms used here

CLI means command-line interface. MCP lets agents discover and call tools. RPC lets a client call named server operations.

Atoms hold observable client values. A property test23 checks a rule across generated inputs. A model test checks stateful rules across generated command sequences.

Find combined responsibilities

Behavior in a projection

Network calls and retries in a feature

Provider code in a caller

Resources separate from the code that uses them

Infrastructure setup in runtime code

Approval and retry rules inside handlers

Lifecycle encoded in scattered flags

Two places approving writes

Service wrapper that hides nothing

Unchecked external input

Crash folded into an outcome

PR #9 (37b8ba9) removed onError: { target: "settled" }. A first-attempt crash had stored refused permanently. The fix propagates the crash and leaves contact delivery pending.

Duplicated API definitions

Deployment configuration or live flag

Undeclared deployment inputs

On 2026-10-04, missing EVENTS_* deployment configuration produced three analytics deletes without a code change. Schema validation alone cannot prove the intended set of resources. Read the plan before applying it.

Hide implementation details behind the interface

A capability hides schemas, behavior, approval, and projections. A cartridge hides its provider implementation and resources.

For each proposed service tag, Layer, or state, name what it removes. For consequential changes, compare two function signatures: their inputs, outputs, failures, and required services. Choose the one requiring less caller knowledge while preserving failures and behavior.

Run the cartridge test

Apply VISION.md’s cartridge test:

  1. In an isolated checkout, remove the package and the line that provides its Layer or adds its resources to the Alchemy Stack. Run pnpm turbo run check test build.
  2. Check that callers use its public interface, not internal implementation details.
  3. Ask whether its schemas, tests, and recorded runtime results support replacement within about one week.

Use the week to pressure-test replacement. Keep each service responsible for its named job.

Enforce the separation

Use the strongest available check: types and APIs first, then lint and behavior tests, then project rules.

  1. Follow gardener: add a rule before cleaning up the pattern. Plant a bug before trusting a new property.
  2. Verify existing names in oxlint.config.ts, scripts/oxlint-plugin-*.ts, and packages/*/test/.
  3. Mark missing coverage No fence yet. Label candidates; do not present them as shipped rules.

Output

Lead with More complicated locally, simpler overall or More machinery, no net simplification. Give each combined responsibility’s source, preserved behavior, smallest interface, deleted complexity, and existing check or proposed check. Include the signature, any machine, cartridge-test result, deletion list, and one material question. State what becomes impossible, what becomes obvious, and what disappears.


Last changed 2026-10-24 in abefe39. Source on GitHub. Change log.

Unlinked mentions (33)