counterfactual

Generated source view for the actual executable engineering/counterfactual skill. The durable routing article is Security and Review Skills. Source: skills/engineering/counterfactual/SKILL.md

Runtime Source

Field Value
Category engineering
Origin personal
Slug counterfactual
Source slug counterfactual
Family Security and Review Skills
Source skills/engineering/counterfactual/SKILL.md

Bundled Resources

No bundled resource files.

Description

Compare the current implementation against the minimal correct algorithm. Use when debugging regressions, reviewing complex fixes, or when the user asks what should happen versus what is happening now.

Skill Source

---
name: counterfactual
description: Compare the current implementation against the minimal correct algorithm. Use when debugging regressions, reviewing complex fixes, or when the user asks what should happen versus what is happening now.
origin: personal
source_slug: counterfactual
---

# Counterfactual

Use this to avoid patching symptoms. The output must separate the
**minimal correct algorithm** from the **current algorithm**, then name
the smallest intervention that moves current toward correct.

## Output shape

Use exactly these sections:

1. **Goal:** one sentence stating the invariant we need.
2. **Minimal algorithm:** pseudocode or numbered steps for the ideal
   implementation. No library constraints yet.
3. **Current algorithm:** what the code actually does today, including
   ownership, blocking points, and cleanup boundaries.
4. **Gap:** the first point where current diverges from minimal.
5. **Smallest fix:** one intervention. Preserve working invariants.
6. **Falsifier:** the test or measurement that proves the fix wrong.

## Rules

- Do not start with a proposed patch. Start with the invariant.
- Do not compare against a strawman. Read the code and name exact
  functions, fields, and blocking calls.
- Preserve constraints that are already correct. If a prior commit fixed
  a deadlock, do not revert it to fix a leak.
- Prefer ownership/cancellation changes over retries, sleeps, or cleanup
  after the fact.
- A good fix reduces the gap; a great fix removes an entire class of
  impossible states.

## Checklist

- Where is ownership supposed to live?
- What wakes every blocking syscall?
- Who joins or intentionally detaches each thread?
- Which fd owner closes each fd?
- What happens if the happy-path event never occurs?
- What is the failure mode under load?

## Example

Goal: Dropping a per-machine vhost-user server must not block the
registry actor and must not leak fds when no VM ever connects.

Minimal algorithm: bind listener; spawn accept loop cancellable by a
shutdown token; Drop fires token, wakes listener, signals workers, joins
threads with a bound, and closes all owned fds.

Current algorithm: `start()` moves `VhostUserDaemon` into an accept
thread and calls `daemon.start(&mut listener)`. Drop removes the socket
path, then tries to take the daemon from `Arc<Mutex<Option<_>>>`. If the
thread is blocked in `accept()`, the option is `None`, so cleanup is
skipped.

Gap: unlinking a Unix socket path does not wake a blocked `accept()`,
so the daemon owner never returns to Drop.

Smallest fix: keep Drop nonblocking, but spawn a bounded reaper that
self-connects to wake `accept()`, waits for daemon handoff, signals
workers, and joins the protocol thread off the actor thread.

Falsifier: create and drop N servers without clients, then assert the
fd delta over a control arm stays below the regression threshold. If fd
count grows linearly with N, the fix is wrong.

Timeline

1 page links here