@hobin/developer 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +61 -20
  2. package/SOURCES.md +104 -0
  3. package/extensions/developer.ts +202 -44
  4. package/extensions/references/behavior-preserving-structural-change.md +149 -0
  5. package/extensions/skills.ts +1 -16
  6. package/extensions/state.ts +96 -10
  7. package/extensions/tui.ts +140 -25
  8. package/package.json +11 -25
  9. package/skills/abstraction-review/references/field-card.md +7 -0
  10. package/skills/abstraction-review/references/recipe-cards.md +67 -0
  11. package/skills/abstraction-review/references/repair-table.md +5 -0
  12. package/skills/model/SKILL.md +6 -1
  13. package/skills/model/references/problem-modeling.md +294 -235
  14. package/skills/model/references/worked-models-and-specialized-techniques.md +218 -0
  15. package/skills/naming-judgment/SKILL.md +5 -3
  16. package/skills/naming-judgment/references/domain-naming.md +202 -0
  17. package/skills/schedule/SKILL.md +1 -1
  18. package/skills/schedule/references/structural-change-timing.md +80 -13
  19. package/skills/signal/SKILL.md +2 -2
  20. package/skills/signal/references/structural-movement.md +202 -0
  21. package/skills/sketch/SKILL.md +35 -8
  22. package/skills/sketch/references/abstraction-barriers-and-closure.md +160 -0
  23. package/skills/sketch/references/abstraction-composition-and-state.md +184 -0
  24. package/skills/sketch/references/composition-generative-recursion-and-accumulators.md +196 -0
  25. package/skills/sketch/references/data-driven-design.md +177 -0
  26. package/skills/sketch/references/data-shape-template-catalog.md +241 -0
  27. package/skills/sketch/references/generic-operations-and-languages.md +134 -0
  28. package/skills/sketch/references/processes-state-and-time.md +171 -0
  29. package/skills/sketch/references/responsibility-and-variation.md +245 -0
  30. package/skills/verify/references/verifier-selection-and-pass-but-wrong.md +61 -3
  31. package/skills/naming-judgment/references/elements-of-clojure-naming.md +0 -74
  32. package/skills/signal/references/flocking-and-structural-movement.md +0 -157
  33. package/skills/sketch/references/design-recipe-and-abstraction-barriers.md +0 -169
@@ -0,0 +1,218 @@
1
+ # Worked Models And Specialized Techniques
2
+
3
+ Use this reference to calibrate the artifacts in
4
+ [Problem Modeling](problem-modeling.md). Each technique starts from a different
5
+ uncertainty. Select the smallest model that can expose the consequential mistake.
6
+
7
+ ## Boolean Policy: Access Rule
8
+
9
+ Prose: “Editors can publish their own drafts, and admins can publish anything,
10
+ unless the document is archived.”
11
+
12
+ ```text
13
+ domain: user in Users, document in Documents
14
+ facts:
15
+ role(user) in {viewer, editor, admin}
16
+ owner(document) in Users
17
+ status(document) in {draft, published, archived}
18
+
19
+ canPublish(user, document) =
20
+ status(document) != archived
21
+ && (role(user) == admin
22
+ || (role(user) == editor && owner(document) == user))
23
+
24
+ forbidden counterexample:
25
+ canPublish(user, document) && status(document) == archived
26
+ ```
27
+
28
+ | archived | admin | editor owns | result |
29
+ | --- | --- | --- | --- |
30
+ | yes | any | any | false |
31
+ | no | yes | any | true |
32
+ | no | no | yes | true |
33
+ | no | no | no | false |
34
+
35
+ Unknown: whether an editor may republish a published document. Keep it human-
36
+ owned because the prose names drafts only. Verify the four partitions and one
37
+ real authorization integration; do not leave the guarantee in a UI guard alone.
38
+
39
+ ## Relational Data And Constraints
40
+
41
+ Requirement: each department has at most one active manager at a time, and every
42
+ manager row refers to existing entities.
43
+
44
+ ```text
45
+ Employee(id)
46
+ Department(id)
47
+ Management(employeeId, departmentId, start, end?)
48
+
49
+ all m in Management:
50
+ some e in Employee: e.id == m.employeeId
51
+ some d in Department: d.id == m.departmentId
52
+ m.end is absent || m.start < m.end
53
+
54
+ all a, b in Management where a != b
55
+ && a.departmentId == b.departmentId:
56
+ intervalsDoNotOverlap(a, b)
57
+ ```
58
+
59
+ The last property may require an exclusion constraint, serialized transaction,
60
+ or application check plus locking depending on the database. A nullable `end`
61
+ needs an explicit open-interval meaning. Exercise historical, current, future,
62
+ overlapping-boundary, and missing-foreign-key instances.
63
+
64
+ ## Replacement Contract
65
+
66
+ Old API accepts any non-empty timezone string and returns a schedule or a domain
67
+ error. New API accepts only a timezone enum and throws on failure.
68
+
69
+ ```text
70
+ old.Pre: nonEmpty(timezone)
71
+ new.Pre: timezone in KnownTimezone
72
+
73
+ old.Pre => new.Pre // false for a legacy but non-empty timezone
74
+ new.Post => old.Post // false if exceptions are not old domain errors
75
+ ```
76
+
77
+ The replacement is unsafe for old callers even if current tests use only known
78
+ zones. Repair by adapting legacy strings, broadening the new precondition, or
79
+ making the break explicit.
80
+
81
+ ## Temporal Model: Retried Payment
82
+
83
+ Snapshots do not distinguish a fresh approval from a duplicated response.
84
+
85
+ ```text
86
+ states: Created | Authorizing(attempt, requestId) | Authorized(paymentId)
87
+ | Failed(reason)
88
+ initial: Created
89
+
90
+ Authorize(id): Created -> Authorizing(1, id)
91
+ Retry(id2): Authorizing(n, _) -> Authorizing(n + 1, id2)
92
+ Approved(id, payment):
93
+ Authorizing(_, id) -> Authorized(payment)
94
+ Approved(staleId, _):
95
+ Authorizing(_, currentId) -> unchanged when staleId != currentId
96
+
97
+ safety: authorization is recorded at most once
98
+ progress assumption: a live provider eventually responds and retries are finite
99
+ ```
100
+
101
+ Verification needs stale, duplicated, reordered, and retry traces, not one test
102
+ per enum value.
103
+
104
+ ## Proof Boundary: Quotient And Remainder
105
+
106
+ ```text
107
+ qr(x, y) -> (q, r)
108
+ requires: x >= 0 && y > 0
109
+ ensures: q * y + r == x; 0 <= r < y; q >= 0
110
+
111
+ q = 0
112
+ r = x
113
+ while r >= y:
114
+ r = r - y
115
+ q = q + 1
116
+ ```
117
+
118
+ Invariant: `q * y + r == x`.
119
+
120
+ - initialization: `0 * y + x == x`;
121
+ - preservation: `(q + 1) * y + (r - y) == q * y + r`;
122
+ - exit: the guard and invariant imply the required remainder relation;
123
+ - termination: non-negative integer `r` decreases by positive `y`.
124
+
125
+ The proof still assumes mathematical integer semantics and complete
126
+ postconditions. Overflow or a missing performance requirement can invalidate the
127
+ product claim without invalidating this proof.
128
+
129
+ ## Constraint Propagation
130
+
131
+ Before a solver, a relation may itself be the design. Temperature conversion is
132
+ not inherently one-way:
133
+
134
+ ```text
135
+ 9 * celsius == 5 * (fahrenheit - 32)
136
+ ```
137
+
138
+ A propagation network can accept either value, derive the other, forget a
139
+ retracted value, and reject inconsistent facts. Its model must identify
140
+ connectors, relations, who asserted each value, and conflict behavior. This is
141
+ useful when information may arrive from several directions; an ordinary
142
+ `toFahrenheit(celsius)` function is clearer when direction is fixed.
143
+
144
+ The core insight is that a relation states what values must agree, while a
145
+ procedure also chooses direction and evaluation. Do not import propagation
146
+ machinery merely to make a one-way calculation appear declarative.
147
+
148
+ ## Constraint Solver: Shift Assignment
149
+
150
+ ```text
151
+ variables: assigned(task) in Workers
152
+ hard constraints:
153
+ every task has exactly one worker
154
+ worker skill covers task requirement
155
+ overlapping tasks use different workers
156
+ objective: minimize total preference penalty
157
+ equivalence: assignments with equal penalty are acceptable
158
+ ```
159
+
160
+ Test a known satisfiable fixture, a known impossible fixture, and two equal
161
+ optima. `unknown` or timeout is neither a solution nor proof of impossibility. A
162
+ bad weight can yield a mathematically optimal but operationally absurd plan.
163
+
164
+ ## Logic Programming: Dependency Query
165
+
166
+ ```text
167
+ depends(api, domain)
168
+ depends(ui, api)
169
+
170
+ reachable(a, b) if depends(a, b)
171
+ reachable(a, c) if depends(a, b) and reachable(b, c)
172
+ ```
173
+
174
+ Query `reachable(ui, X)` should yield `api` and `domain`. State whether different
175
+ paths yield duplicate answers and how cycles terminate. If every product query
176
+ must terminate, a restricted deductive language may be better than a general
177
+ backtracking language.
178
+
179
+ ## Planning: Rolling Server Upgrade
180
+
181
+ ```text
182
+ state: set of Server(name, online, version)
183
+ initial: all online at version 1
184
+ goal: all online at version 3
185
+ invariant: at least one server is online
186
+ actions:
187
+ takeOffline(server) when another server remains online
188
+ upgrade(server) when server is offline
189
+ bringOnline(server)
190
+ cost: one per action, plus optional online-version-skew penalty
191
+ ```
192
+
193
+ Show every intermediate state so the invariant can be checked. A shortest plan
194
+ under action count may not minimize risk; changing the cost model can legitimately
195
+ change the preferred plan. Valid and preferred plans are different claims.
196
+
197
+ ## Selection And Stop
198
+
199
+ | Uncertainty | Artifact | Stop |
200
+ | --- | --- | --- |
201
+ | ambiguous rule | predicate + counterexample + cases | every partition has one result or visible policy gap |
202
+ | data integrity | relations + quantified constraints | known valid and invalid instances differ |
203
+ | compatibility | old/new pre/post implications | callers are covered or breaking scope is explicit |
204
+ | history/order | transition model + safety/progress | stale, retry, duplicate, reorder are defined |
205
+ | exhaustive implementation claim | contract + invariant/proof obligations | assumptions and remaining obligations are explicit |
206
+ | allocation/search | variables, constraints, objective | satisfiable, impossible, alternate-optimum fixtures behave as modeled |
207
+ | inference | facts, rules, query semantics | expected and cyclic cases are explained |
208
+ | action sequence | state, action, invariant, goal, cost | each intermediate state is valid |
209
+
210
+ ## Source Trace
211
+
212
+ - Hillel Wayne, *Logic for Programmers*, version 0.14.0, May 4, 2026:
213
+ predicates, contracts and replacement, formal proof boundaries, relational
214
+ data and constraints, temporal models, solvers, logic programming, planning,
215
+ and answer-set reasoning. Examples are adapted for product modeling.
216
+ - Harold Abelson and Gerald Jay Sussman with Julie Sussman, *Structure and
217
+ Interpretation of Computer Programs*, Second Edition, MIT Press, 1996:
218
+ state, constraints, and explicit evaluation models.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: naming-judgment
3
- description: "Review or create code names by separating stable domain meaning from the current implementation. Use when variables, functions, types, modules, components, APIs, fields, or abstractions are generic, misleading, filler-like, implementation-shaped, or carrying multiple product senses, including requests to apply Elements of Clojure-style naming judgment."
3
+ description: "Review or create code names by separating stable domain meaning from the current implementation. Use when variables, functions, types, modules, components, APIs, fields, or abstractions are generic, misleading, filler-like, implementation-shaped, effect-hiding, or carrying multiple product senses."
4
4
  ---
5
5
 
6
6
  # Naming Judgment
@@ -73,5 +73,7 @@ Reuse does not prove that a generic name is sound.
73
73
 
74
74
  ## Reference Routing
75
75
 
76
- Read [the naming reference](references/elements-of-clojure-naming.md) for
77
- subtle, disputed, or recurring naming pressure.
76
+ Read [the domain naming reference](references/domain-naming.md) for
77
+ subtle, disputed, or recurring naming pressure. Also read it when the apparent
78
+ naming problem may involve false indirection, a data-scope crossing, an effect
79
+ hidden by a pure-sounding word, or responsibility-derived vocabulary.
@@ -0,0 +1,202 @@
1
+ # Domain Naming
2
+
3
+ Use this reference when an identifier is generic, implementation-shaped,
4
+ misleading, effect-hiding, or disputed across callers. This capability judges
5
+ the word and the sense readers may rely on; it does not redesign the surrounding
6
+ module or process.
7
+
8
+ ## Narrow And Consistent
9
+
10
+ A useful name is both narrow and consistent:
11
+
12
+ - **narrow**: it excludes meanings and uses the value cannot support;
13
+ - **consistent**: it agrees with the local code, domain vocabulary, ecosystem
14
+ conventions, documentation, and intended audience.
15
+
16
+ Narrow does not mean maximally specific. A name that exposes the current storage
17
+ format, library, widget, transport, or algorithm becomes false when that detail
18
+ changes. A name that says only `data`, `item`, `manager`, or `handler` may admit
19
+ uses the contract cannot support.
20
+
21
+ ## Sign, Referent, And Sense
22
+
23
+ Separate:
24
+
25
+ ```text
26
+ sign: the identifier text
27
+ referent: the current value, function, type, or implementation
28
+ sense: the stable properties readers understand and rely on
29
+ ```
30
+
31
+ Judge the name around its sense. Complete this statement before proposing a
32
+ rename:
33
+
34
+ ```text
35
+ <old> says <current sense>, but callers rely on <actual sense>.
36
+ The current referent is <implementation detail>, which should remain
37
+ hidden/exposed because <reason>.
38
+ ```
39
+
40
+ If the relied-upon sense cannot be stated, the apparent naming problem may be a
41
+ missing product concept, invalid abstraction, or mixed responsibility.
42
+
43
+ ## Names As Useful Indirection
44
+
45
+ A name creates a place where a reader may stop descending. It succeeds only when
46
+ the reader can use the named thing without reopening details that should be
47
+ hidden.
48
+
49
+ - a data name hides the current representation while exposing role or invariant;
50
+ - a function name hides a computation or effect while exposing its result or
51
+ action;
52
+ - a module-qualified name supplies shared context;
53
+ - a public name forms vocabulary that future callers may depend on.
54
+
55
+ Indirection that only renames syntax adds lookup cost without reducing
56
+ conceptual burden. An inline expression can be more honest than a helper with no
57
+ stable sense.
58
+
59
+ ## Data Names
60
+
61
+ Name data by domain interpretation, role, or invariant rather than by field
62
+ inventory. A parameter name cannot establish the invariant it implies; validation,
63
+ types, or construction must own that guarantee.
64
+
65
+ Short local names are appropriate when scope makes the arbitrary role obvious
66
+ and they match project conventions. Long names do not repair a missing boundary.
67
+
68
+ Absence needs an honest vocabulary. Distinguish missing, `undefined`, `null`,
69
+ empty, defaulted, legacy, and invalid values when callers rely on those
70
+ differences. Do not hide a product default in an adjective such as `effective`
71
+ unless its precedence and source are stable parts of the sense.
72
+
73
+ ## Function Names And Effects
74
+
75
+ Identify whether the function primarily:
76
+
77
+ 1. pulls data from another scope;
78
+ 2. transforms data already in scope;
79
+ 3. pushes data or an effect into another scope.
80
+
81
+ A pure transformation should name the domain result or conversion. A boundary
82
+ action should state its effect or destination. Mutation, I/O, caching, logging,
83
+ network calls, retries, and persistence must not hide behind a name that reads as
84
+ a pure calculation.
85
+
86
+ When a function truly combines phases, an honest composite name may be better
87
+ than a false pure name. Whether the phases should be split is a `sketch` or
88
+ `abstraction-review` question, not a rename performed here.
89
+
90
+ ## Audience And Context
91
+
92
+ The same natural word can carry different senses in different contexts. Inspect
93
+ who must understand it:
94
+
95
+ - public and top-level names must work for newcomers and domain readers;
96
+ - local implementation names may rely on established nearby vocabulary;
97
+ - external conventions usually remain intact at adapters;
98
+ - synthetic terms improve precision only when their definition and learning cost
99
+ are acceptable.
100
+
101
+ Module placement can supply context and shorten names, but this leaf may only
102
+ recommend a placement review. It must not invent a module solely to make a word
103
+ shorter or redesign module ownership under the label of naming.
104
+
105
+ ## Responsibility-Derived Names
106
+
107
+ Choose names from what the unit knows, does, or promises, not from the conditional
108
+ or first special case that revealed it. Intermediate names may remain provisional
109
+ while horizontal movement exposes the real responsibility.
110
+
111
+ For a type or role, ask:
112
+
113
+ - which messages callers need to send;
114
+ - which knowledge the receiver owns;
115
+ - which change would belong inside it;
116
+ - which current mechanism callers should not learn.
117
+
118
+ A rich-sounding name does not make an extracted class or interface valid. Return
119
+ that candidate to `abstraction-review` when its responsibility is still disputed.
120
+
121
+ ## Worked Review
122
+
123
+ Candidate:
124
+
125
+ ```text
126
+ getEffectiveSchedule(formValues)
127
+ ```
128
+
129
+ Caller inspection shows that the function performs no I/O, chooses no fallback,
130
+ and converts editable form values into a validated domain value. The word `get`
131
+ suggests a pull from another scope; `effective` suggests precedence or default
132
+ policy that does not exist; `Schedule` hides that the result is specifically
133
+ content used by the contract boundary.
134
+
135
+ ```text
136
+ sign: getEffectiveSchedule
137
+ referent: pure mapper from ScheduleFormValues to ScheduleContent
138
+ relied-upon sense: validate and convert editable values into domain content
139
+ audience: feature callers and tests
140
+ reveal: conversion and target domain value
141
+ hide: current object literal and validation library
142
+ candidate: toScheduleContent
143
+ ```
144
+
145
+ Check callers after the rename:
146
+
147
+ ```text
148
+ toScheduleContent(values) // reads as a pure conversion
149
+ saveScheduleContent(content) // separately exposes the effect
150
+ ```
151
+
152
+ If inspection instead reveals defaults selected from account settings, the
153
+ rename cannot erase that policy. Use an honest name such as
154
+ `resolveScheduleContent` only after the precedence contract is stated, or return
155
+ the mixed operation to `sketch`.
156
+
157
+ Second contrast:
158
+
159
+ ```text
160
+ readCache(key) // honest only if it observes cache state
161
+ cachedPrice(input) // dishonest if it may call a network and write cache
162
+ loadAndCachePrice(input) // honest composite while a split remains undecided
163
+ ```
164
+
165
+ The result is a rename map plus preserved behavior checks, not a new module or
166
+ class design.
167
+
168
+ ## Review Procedure
169
+
170
+ 1. Read callers, callees, tests, and surrounding vocabulary.
171
+ 2. Identify audience, current referent, and relied-upon sense.
172
+ 3. Classify the failure: too broad, too specific, effect-hidden, verb mismatch,
173
+ sense collision, false indirection, or responsibility leak.
174
+ 4. State what the name should reveal and what it should hide.
175
+ 5. Propose the smallest rename map and affected scope.
176
+ 6. Identify checks and external conventions that must remain unchanged.
177
+ 7. Defer boundary redesign instead of smuggling it into the rename.
178
+
179
+ ## Failure Checks
180
+
181
+ Naming judgment is weak when:
182
+
183
+ - callers were not inspected;
184
+ - the word describes an algorithm rather than stable sense;
185
+ - a broad term admits unsupported uses;
186
+ - a pure-sounding verb hides effects or scope crossing;
187
+ - every intermediate value receives a name without gaining meaning;
188
+ - a rename disguises a model, responsibility, or abstraction problem;
189
+ - external vocabulary is changed without redesigning the adapter contract;
190
+ - module or process redesign is performed under naming authority.
191
+
192
+ ## Source Trace
193
+
194
+ - Zachary Tellman, *Elements of Clojure*, 2019: the Names chapter on narrow and
195
+ consistent names, sign/referent/sense, naming data, functions, and macros; the
196
+ Indirection and Composition chapters inform effect and context boundaries but
197
+ their architectural decisions are owned by `sketch` and
198
+ `abstraction-review`.
199
+ - Sandi Metz, Katrina Owen, and TJ Stankus, *99 Bottles of OOP*, Second
200
+ Edition, version 2.2.2, 2024: chapters 2, 4, 5, and 9 on exposing
201
+ responsibilities, provisional names, deriving names from responsibilities,
202
+ naming classes, and communicating with future readers.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: schedule
3
- description: "Decide whether a concrete structural change or reviewed abstraction candidate belongs now, after, or never using invariant pressure, evidence, reversibility, nested-work pressure, and cost of delay. Use when the candidate is concrete and timing is consequential, including requests to apply Tidy First-style behavior-versus-structure sequencing."
3
+ description: "Decide whether a concrete structural change or reviewed abstraction candidate belongs now, after, or never using invariant pressure, evidence, reversibility, nested-work pressure, behavior-versus-structure separation, and cost of delay. Use when the candidate is concrete and timing is consequential."
4
4
  ---
5
5
 
6
6
  # Schedule
@@ -7,14 +7,16 @@ invariant pressure, or the cost of delay.
7
7
  ## Contents
8
8
 
9
9
  - Behavior And Structure
10
+ - Small And Separate Structural Moves
10
11
  - Timing Vocabulary
11
12
  - Decision Procedure
12
13
  - Guarantee And Ability Tradeoff
13
14
  - Reversibility And Cost Of Delay
14
15
  - Nested Work Pressure
16
+ - Worked Timing Decision
15
17
  - Reopen Conditions
16
18
  - Failure Checks
17
- - Conceptual Lineage
19
+ - Source Trace
18
20
 
19
21
  ## Behavior And Structure
20
22
 
@@ -29,6 +31,19 @@ committed together. A structural candidate belongs now only when its timing can
29
31
  be justified by the current behavior or invariant—not merely by aesthetic
30
32
  preference.
31
33
 
34
+ ## Small And Separate Structural Moves
35
+
36
+ A tidying is a small, behavior-preserving structural move. Keep it small enough
37
+ that the intended rearrangement, affected behavior evidence, and rollback are
38
+ obvious. Separate it from behavior change in reasoning and, when practical, in
39
+ the change history.
40
+
41
+ Small does not mean arbitrary. A chain of tidyings can quietly become a redesign.
42
+ After each move, ask whether the next one still lowers the cost of the accepted
43
+ behavior change or has become an independent aspiration. When structural and
44
+ behavior changes become tangled, return to the last green state and separate the
45
+ two purposes before continuing.
46
+
32
47
  ## Timing Vocabulary
33
48
 
34
49
  This skill uses three outcomes:
@@ -40,9 +55,9 @@ This skill uses three outcomes:
40
55
  - `never`: reject the candidate for the current scope because it is speculative,
41
56
  harmful, or has no evidence-backed pressure.
42
57
 
43
- Kent Beck's broader vocabulary sometimes separates `later` from `after`. Here,
44
- `after` covers both immediate follow-up and evidence-triggered deferral. The
45
- reopen condition makes the distinction explicit.
58
+ The book distinguishes `first`, `after`, `later`, and `never`. This skill maps
59
+ `first` to `now` and folds immediate follow-up and evidence-triggered `later`
60
+ into `after`; the reopen condition preserves the important distinction.
46
61
 
47
62
  ## Decision Procedure
48
63
 
@@ -112,6 +127,54 @@ Bias toward `after` when the candidate opens a chain of nested work without
112
127
  protecting the current invariant. If a small prerequisite is genuinely needed,
113
128
  schedule that prerequisite rather than the full idealized architecture.
114
129
 
130
+ Also watch batch size and rhythm. Several individually safe moves can create a
131
+ large review and debugging surface when chained without checkpoints. Prefer a
132
+ rhythm of small structural movement, evidence, then behavior progress over a long
133
+ cleanup prelude whose payoff cannot yet be observed.
134
+
135
+ ## Worked Timing Decision
136
+
137
+ Accepted behavior change: add a locker fulfillment method. Current code has a
138
+ small conditional for pickup and delivery copy. Candidate structure: introduce
139
+ a public `FulfillmentStrategy` registry before adding the branch.
140
+
141
+ ```text
142
+ Candidate:
143
+ public strategy registry
144
+ Current dependency:
145
+ none; one local conditional can express the accepted third case
146
+ Evidence of stability:
147
+ variants share a result but have different fields; no independent provider or
148
+ registration lifecycle exists
149
+ Guarantee gained:
150
+ future variants could register without editing central dispatch
151
+ Ability lost:
152
+ exhaustiveness and one visible owner; load order and duplicate registration
153
+ become new failure modes
154
+ Reversibility:
155
+ registry is easy to add later but a public API is hard to retract
156
+ Cost of delay:
157
+ one additional local branch
158
+ Nested work:
159
+ registry errors, startup wiring, documentation, and plugin tests
160
+ Decision:
161
+ after
162
+ Reopen:
163
+ a separately deployed provider must add a variant without changing the core
164
+ ```
165
+
166
+ The accepted behavior proceeds with the direct branch. This is not a claim that
167
+ registries are bad; the present guarantee does not justify their present cost.
168
+
169
+ Contrast: if the new method must be supplied by an independently deployed
170
+ package and core releases cannot change with it, that pressure makes the
171
+ extension boundary a current invariant. The decision can become `now`, but only
172
+ the smallest boundary required by that invariant should precede behavior.
173
+
174
+ `never` example: renaming every local `result` solely for stylistic uniformity
175
+ has no relation to the accepted change and no evidence-triggered future value.
176
+ Reject it for this scope rather than disguising it as `after`.
177
+
115
178
  ## Reopen Conditions
116
179
 
117
180
  An `after` decision must state observable evidence that reopens it, such as:
@@ -139,12 +202,16 @@ The timing judgment is weak when:
139
202
  - large nested work is hidden inside a small-sounding abstraction;
140
203
  - timing substitutes for product prioritization that only a human can decide.
141
204
 
142
- ## Conceptual Lineage
143
-
144
- This reference adapts Kent Beck's distinction between behavior and structure,
145
- and his timing vocabulary of first, after, later, and never. The package reduces
146
- the vocabulary to `now`, `after`, and `never` while preserving reversibility,
147
- optionality, and cost-of-delay reasoning.
148
-
149
- - Structure and behavior: https://newsletter.kentbeck.com/p/structure-and-behavior
150
- - First, after, later, never: https://newsletter.kentbeck.com/p/first-after-later-never
205
+ ## Source Trace
206
+
207
+ - Kent Beck, *Tidy First?: A Personal Exercise in Empirical Software Design*,
208
+ O'Reilly Media, 2023: behavior/structure separation, small tidyings,
209
+ first/after/later/never decisions, batching, optionality, reversibility, and
210
+ the economics of structural change.
211
+ - Sandi Metz, Katrina Owen, and TJ Stankus, *99 Bottles of OOP*, Second
212
+ Edition, version 2.2.2, 2024: waiting for real change pressure, tolerating
213
+ duplication, selecting a point of attack, gradual movement, and stable
214
+ landings.
215
+ - Hillel Wayne, *Logic for Programmers*, version 0.14.0, May 4, 2026:
216
+ ability-guarantee tradeoffs and replacement obligations that affect the cost
217
+ and reversibility of a structural choice.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: signal
3
- description: "Inspect requirements, code, diffs, tests, UI states, names, or recent changes for observable structural movement and classify it as absent, horizontal, vertical, or ambiguous. Use when evidence suggests duplication, model-code mismatch, boundary pressure, or an emerging refactoring candidate, including requests for flocking-style small behavior-preserving refactoring."
3
+ description: "Inspect requirements, code, diffs, tests, UI states, names, or recent changes for observable structural movement and classify it as absent, horizontal, vertical, or ambiguous. Use when duplication, model-code mismatch, boundary pressure, parallel cases, or an emerging refactoring candidate needs a smallest evidence-backed observation."
4
4
  ---
5
5
 
6
6
  # Signal
@@ -20,7 +20,7 @@ What structural movement is actually visible in the evidence?
20
20
 
21
21
  ## Reference Routing
22
22
 
23
- Read [the flocking and structural movement reference](references/flocking-and-structural-movement.md)
23
+ Read [the structural movement reference](references/structural-movement.md)
24
24
  when duplication, parallel branches, similar tests, repeated UI states,
25
25
  conditionals, or a recent refactor need a behavior-preserving next move. Also
26
26
  read it when the horizontal/vertical distinction is consequential or the