Skip to content

Connections

Every artifact-set has a controller, and most of them are good. The compiler holds {TypeScript files}. Biome holds formatting. Astro and Starlight hold {website content}.

None of them reach past the set they hold. And the couplings that matter most run between sets:

Connection Owner today
Starlight stylesheet → components rendered beneath it nobody
a skill → four vendor manifests + the files list prose in AGENTS.md
version field → four manifests scripts/sync-plugin-version.mjs, hand-built
an accepted ADR → the module it governs nobody

The gap is not at a level of granularity. It is at the connections, uniformly, at every level. That single observation is what unifies the CSS-correctness thread and the plugin thread in this repository’s backlog: they are not adjacent bodies of work, they are the same one.

Status: Settled.

Two artifact-sets, at their specifications rather than their implementations. There is no diff between a TypeScript module and a Figma frame, so a connection stated over implementations could never be evaluated; stated over criteria, both ends are written in one vocabulary.

Status: Settled. The argument is on the Specification page.

A connection is a relation between two artifact-sets. It is not an arrow.

SDD’s {spec, suite} and {code, test, stories} are connected. The mission loop traverses that connection spec-first; backfill traverses it implementation-first; build-to-learn works both ends at once. Three traversals, one relation.

Direction is a property of where the delta landed, and of the workflow that restores the relation, not of the connection. Writing direction into the connection bakes in one workflow and makes the others second-class — which is precisely the situation the model exists to fix.

Status: Settled.

A connection states a relation that must hold. It is never a handler that fires.

This is the most expensive commitment in the model to reverse, because every connection ever written encodes it.

The reason is confluence. If a connection is “when the spec changes, run this to update the implementation,” then backfill needs a second script for the reverse direction, and nothing makes the two agree. Two entry points, two code paths, two results, and the guarantee is gone before the first connection ships.

Stated as a relation, propagation means restore the relation in whichever direction is strained. Same relation, same fixed point, any entry point.

Status: Settled.

Strain is a connection whose relation does not currently hold. Working the two axes against real cases produced three distinct kinds, and the examples added a fourth. They behave differently. A strain is exactly one of them, so each is named for the defect rather than for the property it falls short of.

Intra-unit-of-change. Add a skill, also wire four manifests and the files list.

That is one commit; the strain is that the change is incomplete right now. It gates, and it blocks.

Between units of change. An accepted ADR obliges the module it governs.

These are deliberately separate changes — decide now, implement later. The strain is not “you forgot,” it is “this change created a debt.” It does not block, but it must be tracked and discharged traceably.

This kind was the last to be identified, and it explains an artifact already sitting in the repository: docs/backlog.md is a hand-maintained obligation ledger. Not all of it — some entries are genuinely new ideas — but the ADR-obliges-module chain and several others are debts created by earlier changes, recorded by hand because nothing generates them.

It also gives declining a home. Declining is how an obligation is discharged without being done, and without it any report nags forever.

Axis 2. This skill violates the agent-instruction guidelines.

State-driven, evaluable on a cold repository, and requires no delta.

Implementation ahead of its specification. A bug fix introduces a rule the spec never stated.

A controller above the change, asked in a workflow the change bypassed, answers that its set lacks a criterion the change’s intent implies. The implementation now meets something its specification does not state, and the specification is the side left behind.

Missing strain is relative to a change, which the other three are not. Every implementation shows behaviour nobody wrote down, and most of it is coordinates. Missing strain fires only for criteria a change’s intent introduced, and it is found when a controller derives them from that intent. A set too coarse to hold the criterion is not missing it; the question passes to the set above. A refactor introduces no criteria and strains nothing.

The first three are not an arbitrary list. Read through the specification relation they are the three ways a specification and its implementation can fail to meet from the specification’s side: both in hand and disagreeing, the implementation elsewhere, or no implementation in the delta at all. Missing is the relation read from the implementation’s side. That derivation is on the Specification page.

Status: Settled that the first three are distinct and block differently. Thesis on missing, found by the bug-fix example. Open: the precise boundary conditions on each, and how missing strain blocks.

A missing connection is found outside the run

Section titled “A missing connection is found outside the run”

A run settles against the connections that are declared. A controller answers for its own set from the criteria it is referred to, and a criterion reaches a set only through a connection. Where a connection should exist and does not, no criterion arrives, every controller answers correctly for what it was given, and the relation the connection would have held quietly fails.

The insulin example shows the shape. The accreditation standard is connected to the hospital policy, which lets each unit name the steps that need a second nurse. The standard is not connected to the unit’s protocol. A unit drops the check from routine rate changes, the policy still holds, the protocol only adds, and no leash fires. Declare the missing connection and the standard’s requirement reaches the protocol, the protocol write contradicts it, and the leash stops it.

A run cannot detect what the topology does not declare. That is not a defect of the run. It is the limit of settling against a declared topology, and a guard written inside one set would only patch a relation nobody declared. Missing connections are found by an audit loop that runs outside normal operation and reads across sets, comparing practice with the standards above it. An audit is a scheduled controller whose run is a change, the shape of the compliance audit in the catalog. Its finding is a connection to declare, or an obligation against a set when nothing can restore it yet. SDD runs its outer loops the same way, beside the mission loop rather than inside it.

Finding the topology is iterative. Each audit that finds a missing connection makes the next run catch what this one could not.

Status: Thesis. Open: what an audit loop reads, how often it runs, and how its finding becomes a declared connection. See Open questions.

The clearest evidence that controllers cannot all migrate to deterministic code comes from a defect in this repository’s own docs site.

An element declared top: 0rem rendered 16px lower than intended. Starlight’s markdown stylesheet gives every element following a sibling a 1rem top margin, and an absolutely positioned element offsets its margin edge — so the box sat 1rem down while getComputedStyle reported top as exactly 0px, in perfect agreement with the source.

Every static check passed. The value was wrong anyway.

The attempt to push this coupling down to deterministic code makes it worse: stylelint’s length-zero-no-unit would have autofixed 0rem0, leaving the defect intact and destroying the only forensic tell. There is no mechanical rung beneath render it and measure.

This is why the controller spectrum has an agentic end, and why the plugin is not an optional convenience.

Status: Settled — the case is verified against this repository’s configuration.