Skip to content

Repository files navigation

residual

A CLI that helps you practice Residuality Theory on a real codebase — with your coding agent as a Socratic partner.

This project is a slight expansion of Barry O’Reilly’s Residuality Theory: the original method centers on stressors, attractors, residues, and the NKP matrix. Here, purposes are added as complements to stressors and both are generalized as forces, with extra tooling (lexicon, git integration, tagging, naïve-draft) drawn from other sources. See What is whose? and Sources of inspiration.

Most architecture work tries to predict the future (risk scores, edge cases, “what if” lists). Residuality Theory takes a different path: you walk the problem, notice the recurring situations a system falls into (attractors), and record the small changes that would let it survive those situations (residues). You do this without assigning probabilities. The goal is not a perfect forecast — it is an architecture that still works when the unexpected arrives.

residual operationalizes that method (plus the small expansions above). It stores your walks as structured project data, keeps language consistent, and hands your agent focused skill prompts. Usage is a-la-carte: pick the lens you need, mid-session, without a rigid ceremony. Verify enforces structure, not phase order.

Demos

Selected excerpts from real sessions — the methodology being used on its own codebase.

  • Naive draft on residual itself — Running the naive-draft skill on this repo: surfacing skill-stub-burden, absent-metadata-session, and residuals-incongruence as live stressors from a real architectural walk.

  • Purpose-walk: product purposes and actor terms — A full purpose-walk on this repo: discovering that P-01–P-07 only described tooling plumbing, then adding eight product purposes, eight terms (operator, residual-architecture, probability-framing, and more), and a structural change to attractors (dual positive/negative states instead of valence labels).

  • Stressor-walk: session lifecycle, write integrity, matrix identity — Walking four lanes (A–D) on the residual codebase itself: surfacing the version-mismatch stressor, the super-strict-mode edge case, the session-lock concept (S-29/P-18), and why a diagonal matrix means free-text component labels are hiding coupling.

Learn the method

Start with O’Reilly. The practical + philosophical pair is sold together:

Residues and The Philosophy of Software Architecture (Leanpub bundle) — Residues: Time, Change, and Uncertainty in Software Architecture plus The Architect’s Paradox.

Repo notes under research/ are companions for this codebase; the books are the place to learn Residuality Theory itself. For everything else this tool borrows, see Sources of inspiration.

Concepts (gentle tour)

You do not need the full theory to start. These ideas are enough to use the tool:

  1. Stressors (O’Reilly) — A coherent story of how the wider world moves the system. No scenario is too outlandish.
  2. Purposes / forces (this project) — Purposes complement stressors (what you intend vs what the world may do); together they are forces. The same abstraction runs at any scale of the hyperliminal system — not software-only. Forces carry outcomes — short, checkable statements — and a naïve change idea. They do not list components directly.
  3. Residues — The unit of architectural change: what is left after stress or intent. In this tool, a residue maps one force to one component (or to the whole system when the answer is hardware, process, organization, or policy).
  4. Attractors — Recurring states the system returns to. Here each has a positive state and a negative state.
  5. NKP matrix — A table of forces × components. Shared marks in a row reveal hidden coupling. Fusion and fission suggestions come from that pattern.
  6. Lexicon (tooling) — Shared vocabulary so outcomes and shortnames stay coherent as the project grows.

Deeper ideas (criticality, residual index, hyperliminal coupling, walks) are in O’Reilly’s books and in research/nkp-residuality-theory.md.

Quick Start

# In a Nix environment
nix develop   # enter devShell (residual is on PATH)
cargo build --release

# Initialize residual/ in your project
residual init

# Install a skill for your agent, then load project context into the session
residual skill install purpose-walk --agent claude
# Launch the /residual-purpose-walk skill once initialized
claude

Coming from an older residual/ layout? Run residual migrate to normalize lexicon, attractor ± states, and v4 shape (coupling in residues.csv, not on force rows).

Workflow

A-la-carte by design. Skills are optional analytical lenses — invoke only what the moment needs. There is no mandatory skill sequence; verify cares about residual structure, not which ceremony you ran.

purpose-walk · naive-draft · stressor-walk · integrate · FMEA · ATAM · defense-walk · tdd-implement

A common early pass is still purpose → naïve draft → stressor walk → integrate, then FMEA/ATAM when you want structured critique — but that path is a suggestion, not a gate. Record a force or residue whenever it appears.

Each step writes into residual/:

File Contents
stressors.csv / purposes.csv Forces: shortname, naïve change, outcomes, attractor (no component lists)
residues.csv NKP coupling matrix (force × component, 1/empty)
components.csv Fully-qualified component registry (proposed/actual status)
attractors.csv Attractors with positive and negative states
lexicon.csv Domain terms (with aliases) used by outcome validation
iterations/<n>.md Architecture snapshots (N, K, notes, Ri when recorded)
personas/<name>.md Stakeholder voices for walks and ATAM
research/<source>.md Research notes from external documents

Skills

Skills are agent-agnostic prompt documents embedded in the binary. Install a-la-carte — only the lenses you actually use.

residual skill list                          # list skills with version + token estimate
residual skill show purpose-walk             # print skill definition
residual skill install purpose-walk \
  --agent claude                             # install for that agent
residual skill install all --agent claude    # install every skill for that agent
residual skill install all --agent all       # install every skill for every agent
residual skill check-install purpose-walk \
  --agent claude                             # verify installed version matches binary
residual skill data purpose-walk             # print current project context for this skill

Supported agents: claude, cursor, copilot, agnostic. Installed skills are passthrough stubs (a few lines pointing at residual skill show <name>) — methodology lives in the binary, so a stub never drifts out of date; residual skill check-install just confirms the stub is in that shape.

Every skill session's residual skill data <name> output is stitched together with a guru block: short, embedded guidance snippets (definitions of attractor/stressor/purpose/persona, the ergodic boundary, whole-system-residue, walk cadence) auto-attached per skill so the operator and agent share the same primitives without re-deriving them each session. residual skill list shows the token cost each skill's guru block adds.

Live-Editing View

residual view                 # render a self-contained HTML snapshot of the force landscape, print its path
residual view --defense       # include the defense ledger (meta forces + defense artifacts)
residual serve                # serve the same view on loopback (default port 8787) for live browsing

The view is read-only and ephemeral: it never mutates residual/ directly. Instead it lets you edit forces, components, and couplings in the browser and stages the equivalent residual add/update/remove commands (or a ready-to-run bash script) for you to copy and execute — the CLI remains the sole write path. It also accepts pasting CLI output back in (bidirectional import) to merge external edits into the same staged-command view.

Editing Existing Records

residual update stressor --shortname my-stressor --description "..."
residual update purpose --shortname my-purpose --outcomes "..."
residual update attractor A-01 --positive-state "..."
residual update component my-component --status actual
residual update term my-term --definition "..."
residual update persona my-persona --concerns "..."

add/update/remove all guard against concurrent drift: each records a snapshot hash of residual/ at the start of a mutating session, and refuses to write if the files changed outside that session (pass --force to overwrite after inspecting the diff yourself).

NKP Matrix

residual matrix show          # table: force shortnames × components
residual matrix calc          # N, K, K/N
residual matrix criticality   # criticality assessment
residual matrix fusion        # components safe to merge (identical stress patterns)
residual matrix fission       # components under excessive stress (high K)
residual matrix ri \
  --stressors 10 \
  --naive-survived 3 \
  --residual-survived 8       # Ri = (8-3)/10 = 0.5

Data Management

Prefer force then residue: record the purpose or stressor, then map which components (or the whole system) carry the change.

residual add attractor --name "..." --description "..." \
  --positive-state "..." --negative-state "..."

residual add stressor --description "..." --attractor-shortname A-01 \
  --naive-change "..." --outcomes "..." --shortname "..."
residual add residue --shortname "..." --component-shortname my-component

# When the surviving change is not software
residual add stressor --description "..." --attractor-shortname A-01 \
  --naive-change "..." --outcomes "..." \
  --whole-system --notes "policy zig: ..."

residual add purpose --description "..." --attractor-shortname A-01 \
  --feature "..." --outcomes "..."
residual add term --term "..." --definition "..."

residual list stressors / purposes / attractors / terminology / residues / personas / iterations

Metadata writes require a short-lived authorization when the git sidecar is enabled: residual write authorize (default 30 minutes) before your first add/update/remove of a session. This is a deliberate friction point, not a bug — it keeps agents from mutating the ledger outside an intentional working session.

Defense Ledger

A parallel, isolated ledger for meta forces — pressure on the practice of residuality itself (management skepticism, org friction, prospect objections) rather than on the project under architecture. It never mixes with the main stressors/purposes/attractors:

residual add meta-attractor --name "..." --positive-state "..." --negative-state "..." --description "..."
residual add meta-stressor  --description "..." --shortname "..."
residual add meta-purpose   --description "..." --attractor-id MA-01 --naive-change "..." --outcomes "..." --shortname "..."

residual add defense-persona   --name "..." --body "..."   # a simulated outside audience, not a project stakeholder
residual add defense-strategy  --name "..." --body "..."   # brainstorming an argument for a specific audience
residual add defense-progress  --name "..." --body "..."   # history of how a pitch landed
residual add defense-pitch     --name "..." --body "..."   # the refined, reusable communication artifact

residual view --defense       # include defense/* alongside the main landscape

Use the defense-walk skill to rehearse how residuality artifacts and pitches will land with a specific outside audience, distinguishing defense-persona (simulated outsider) from the walk-time persona (project stakeholder).

Verification + Git Hook

residual verify all           # outcomes, links, tags, and related integrity checks
residual generate hook        # install pre-commit hook to .git/hooks/

The pre-commit hook runs residual verify all before commits that touch residual/ files. Verification policy (super_strict, token_warn, and related keys) lives in residual/config.toml. Commit subjects follow Scoped Commits<scope>: <description> — with scopes drawn from your lexicon and component registry (or general - … when no project term fits), not Conventional Commit type prefixes like feat: or fix:.

Codebase Tagging

// @component: skills-phases
// @stressor: skill-stub-burden, lexicon-alias-gap
// @purpose: fluent-metadata-capture

Tags are shortname-only (not IDs — S-07 won't match, skill-stub-burden will). Comment syntax is detected per file type via tokei's language database, not a hand-maintained list — any language tokei recognizes works out of the box. Attractors aren't taggable; they describe system states, not code-adjacent detail.

residual tag scan     # find dangling tags + untagged forces
residual tag report   # map each tag to its file:line

Metadata-only tags are fine; tags in code without matching metadata are the case verification cares about. residual verify all warns (non-fatally) on any tag-shaped comment that doesn't resolve to a real stressor, purpose, or component.

Nix / NixOS

nix develop           # enter devShell (cargo, rust-analyzer, cargo-watch, cargo-audit; residual on PATH)
nix build             # build the binary

Add to your NixOS flake:

inputs.residual.url = "github:mikenrafter/residual";
# Then: pkgs.residual or residual.packages.${system}.default

Development

nix develop
cargo test
cargo watch -x check
cargo audit

Prototype layout and naming rules for the current architecture set are in ARCHITECTURE.md.

What is whose?

From Residuality Theory (Barry O’Reilly)

These ideas are the core of the method. Learn them properly from the books linked in Sources of inspiration:

  • Stressors — coherent narratives of how the wider business system moves; no probabilities required
  • Attractors — recurring states a system returns to
  • Residues — what remains after stress; the unit of architectural change
  • Naïve vs residual architecture — start simple, then integrate residues
  • NKP matrix — stressors × components; fusion/fission; criticality; residual index (Ri)
  • Walks — iterative, multi-perspective exploration (e.g. stressor-walk)
  • FMEA / ATAM — late validation layers as framed in the Residuality workflow (FMEA for technical failure modes; ATAM for stakeholder tradeoffs)

In the original framework, the force that drives residue work is the stressor. Purposes-as-forces are not part of that core.

Added in this project (framework)

A small conceptual overlay on top of the theory — deliberately scale-independent. Forces apply to the whole hyperliminal system (the ordered software executing inside a disordered business/world context), not only to software features. That breadth is counterintuitive and hard; it is also what makes the results meaningful.

  • Purposes — complements to stressors: what the system is for, at whatever scale you are walking (product, org, policy, hardware, code, …)
  • Forces — generalization: a force is a purpose or a stressor, carrying a naïve change and checkable outcomes
  • Residue as force × component — explicit mapping (including a whole-system residue when the surviving answer is not software)
  • Attractor ± states — each attractor recorded with a positive state and a negative state, rather than a single valence label

Added in this project (tooling, from other sources)

Programmatic and process pieces integrated so the method sticks in a real repo:

  • Lexicon — shared vocabulary with alias-aware validation of outcomes
  • Git integration — verify hooks and commit-message checks in Scoped Commits form: scope-first subjects tied to lexicon and components, with Conventional Commit type prefixes rejected
  • Code tagging@stressor / @purpose / @component markers linked to metadata, shortname-only, comment syntax detected per language via tokei
  • Naïve-draft phase — agent skill that drafts a naïve architecture using deep modules (APOSD) and vertical slices, then TDD-first scaffolding

Sources of inspiration

Source Role in this project
Residues and The Philosophy of Software Architecture (Leanpub bundle by Barry M. O’Reilly) Residuality Theory proper: stressors, attractors, residues, NKP, walks, Ri, criticality; FMEA/ATAM placement in the workflow
A Philosophy of Software Design — John Ousterhout, Yaknyam Press (2nd ed. on Amazon) Deep modules / information hiding informing the naive-draft skill
Vertical Slice Architecture — Jimmy Bogard Feature-shaped slices (maximize coupling in a slice) in naive-draft
Scoped Commits Scope-first commit subjects (<scope>: <description>); this tool defines valid scopes from the lexicon and component registry and rejects generic Conventional Commit type prefixes (feat:, fix:, …)
SEI Architecture Tradeoff Analysis Method (ATAM) Stakeholder tradeoff analysis skill (atam), as used after residual integration
Failure Mode and Effects Analysis (FMEA) Technical failure-mode skill (fmea), as framed after residual integration in O’Reilly’s workflow

Local digests of several of these live under research/.

Research

Background reading is in research/:

  • nkp-residuality-theory.md — NKP framework, verbatim definitions
  • aposd.md — A Philosophy of Software Design key insights
  • vertical-slice-arch.md — Vertical Slice Architecture synthesis
  • fmea-notes.md — FMEA methodology notes
  • atam-notes.md — ATAM methodology notes

License

MIT

About

Unbreakable | Residual Architecture | CLI | Socratic, semantic - guides you through the process of making your software architecture unbreakable.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Contributors

Languages