@hobin/developer 0.1.1 → 0.1.2
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.
- package/README.md +31 -11
- package/SOURCES.md +104 -0
- package/extensions/developer.ts +67 -24
- package/extensions/references/behavior-preserving-structural-change.md +145 -0
- package/extensions/skills.ts +1 -16
- package/extensions/state.ts +9 -1
- package/package.json +2 -1
- package/skills/abstraction-review/references/field-card.md +7 -0
- package/skills/abstraction-review/references/recipe-cards.md +67 -0
- package/skills/abstraction-review/references/repair-table.md +5 -0
- package/skills/model/SKILL.md +6 -1
- package/skills/model/references/problem-modeling.md +294 -235
- package/skills/model/references/worked-models-and-specialized-techniques.md +218 -0
- package/skills/naming-judgment/SKILL.md +5 -3
- package/skills/naming-judgment/references/domain-naming.md +202 -0
- package/skills/schedule/SKILL.md +1 -1
- package/skills/schedule/references/structural-change-timing.md +80 -13
- package/skills/signal/SKILL.md +2 -2
- package/skills/signal/references/structural-movement.md +202 -0
- package/skills/sketch/SKILL.md +35 -8
- package/skills/sketch/references/abstraction-barriers-and-closure.md +160 -0
- package/skills/sketch/references/abstraction-composition-and-state.md +184 -0
- package/skills/sketch/references/composition-generative-recursion-and-accumulators.md +196 -0
- package/skills/sketch/references/data-driven-design.md +177 -0
- package/skills/sketch/references/data-shape-template-catalog.md +241 -0
- package/skills/sketch/references/generic-operations-and-languages.md +134 -0
- package/skills/sketch/references/processes-state-and-time.md +171 -0
- package/skills/sketch/references/responsibility-and-variation.md +245 -0
- package/skills/verify/references/verifier-selection-and-pass-but-wrong.md +61 -3
- package/skills/naming-judgment/references/elements-of-clojure-naming.md +0 -74
- package/skills/signal/references/flocking-and-structural-movement.md +0 -157
- 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
|
|
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/
|
|
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.
|
package/skills/schedule/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
-
-
|
|
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
|
-
|
|
44
|
-
`
|
|
45
|
-
reopen condition
|
|
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
|
-
##
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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.
|
package/skills/signal/SKILL.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|