Skip to content

Commit 4468d8d

Browse files
authored
Add design rules and review questions (#4)
Fold maintainability practices into the skill: a Design section in SKILL.md (ownership, boundaries, effects, failure, dependencies, change surface, tests, plus a conflict priority order), domain-specific items in the matching quality-gate rows, and a review-questions list applied to Substantial work and above. README mirrors the new behavior.
1 parent e6da630 commit 4468d8d

3 files changed

Lines changed: 84 additions & 10 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ the risk, and an honest `COMPLETE` / `PARTIAL` / `BLOCKED` report.
1919
to the matching step.
2020
- **Evidence scaled to risk.** Pre-fix evidence, recorded commands, and independent review
2121
scale with the mode. A skipped or unavailable check never counts as a pass.
22+
- **Design rules.** Seven rule groups for the code the agent writes (ownership, boundaries,
23+
effects, failure, dependencies, change surface, tests) with a priority order for when
24+
they conflict, and review questions to answer against non-trivial diffs.
2225
- **References on demand.** [Quality gates](references/quality-gates.md) for affected
2326
domains and a [report template](references/report-template.md) for non-trivial work.
2427

‎SKILL.md‎

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ deterministic reproducer or directly observed failure. Never fabricate a red run
5656

5757
**Implement.** Fix the invariant at the smallest correct shared layer. Infer architecture
5858
from the code and reuse its conventions and helpers; do not impose patterns because they
59-
are familiar. Wire every required path: unused helpers and fake success paths are not
59+
are familiar, and apply the design rules in section 3 to the code you add. Wire every
60+
required path: unused helpers and fake success paths are not
6061
delivery. Validate untrusted input at boundaries and make failure explicit; never swallow
6162
errors, fabricate data, or weaken authorization. Preserve compatibility unless the change
6263
is meant to break it. Regenerate derived files with project tooling. Add a dependency only
@@ -82,10 +83,61 @@ correctness when available, without blocking required work; its absence is a rep
8283
limitation, not by itself a reason for `PARTIAL`. Self-review, including of a child agent's
8384
work, is not independent. Rerun affected checks after the last relevant edit; an old green
8485
run does not verify a new tree. When available, load
85-
[quality gates](references/quality-gates.md) only for affected domains; if a reference is
86+
[quality gates](references/quality-gates.md) only for affected domains, and for Substantial
87+
work and above answer its review questions against the final diff; if a reference is
8688
missing, use this protocol and note it only when it materially reduces verification.
8789

88-
## 3. Safety
90+
## 3. Design
91+
92+
Rules for the code you write, applied within the repository's own structure. The test for
93+
every addition: am I adding code, or a new place future readers must understand?
94+
95+
- **Ownership.** One coherent responsibility per function, class, and module, named after
96+
the concept it owns. Every rule (threshold, validation, mapping, permission, option
97+
list, formula, schema, retry policy) has one authoritative owner: duplicated code is
98+
tolerable, duplicated rules are defects. Keep policy (what should happen) apart from
99+
mechanism (how it happens).
100+
- **Boundaries.** Parse, validate, and normalize once where data crosses a network, file,
101+
database, process, trust, or serialization boundary, then pass a typed canonical value
102+
inward. Choose types that make invalid states unrepresentable: one status enum over
103+
several booleans. Model lifecycles as explicit state machines with named transitions.
104+
- **Effects.** Compute first, mutate second. For consequential operations, prepare →
105+
validate → commit, with the irreversible step as small as possible. Side effects show in
106+
names and signatures. Every resource has an owner whose cleanup runs on success,
107+
exception, cancellation, timeout, and partial initialization.
108+
- **Failure.** Every external call has a deliberate timeout. Bound anything that grows:
109+
retries, queues, concurrency, input and payload size, batches, recursion, caches,
110+
request duration, log volume. Retry only transient failures (timeout, rate limit,
111+
unavailable), never permanent ones (invalid input, authorization, violated invariant),
112+
and make retried operations idempotent. Errors carry what failed, where, on which
113+
input, whether retry is appropriate, and the cause; expected outcomes are values,
114+
exceptions are for the exceptional.
115+
- **Dependencies.** Pass volatile dependencies in (clock, randomness, identifiers,
116+
filesystem, network, database, providers) instead of reading globals. Keep interfaces
117+
smaller than implementations and translate provider-specific details at the owning
118+
boundary. An abstraction earns its place by removing knowledge from callers; otherwise
119+
delete it. Generalize recurring concepts, not hypothetical requirements: one focused
120+
module beats a configurable internal framework.
121+
- **Change surface.** One feature touches few places: a new provider adds an
122+
implementation, a new status adds an enum member. Name constants beside the policy that
123+
owns them; use enums for closed domains, keyword arguments over positional booleans, and
124+
tables when behavior varies only by configuration. Comments explain why: constraints,
125+
tradeoffs, external requirements. Consolidate overlapping implementations and give every
126+
compatibility layer a deletion condition.
127+
- **Tests.** Capture existing behavior before restructuring; change behavior in a separate
128+
step. Test observable behavior over private internals. Test boundaries (invalid,
129+
malformed, empty, maximum, timeout, cancellation, duplicate execution, partial failure,
130+
missing resource, permission failure, concurrent access) and invariants (balance never
131+
negative, path never escapes root, completed job never reruns, duplicate request yields
132+
one effect, resource always released). Control clocks, randomness, identifiers, and
133+
external services so tests fail only when code is wrong, through the same architecture
134+
production uses.
135+
136+
When rules conflict: correctness → explicit invariants → clear ownership → controlled side
137+
effects → bounded resources → failure safety → locality → replaceability → extensibility →
138+
optimization.
139+
140+
## 4. Safety
89141

90142
- Stay inside the workspace and task scope. Never print environment values, credentials,
91143
or secret files; check a variable's presence, not its value.
@@ -96,7 +148,7 @@ missing, use this protocol and note it only when it materially reduces verificat
96148
- Commit, push, open a PR, merge, and deploy are separate permissions. When committing,
97149
stage exact paths and inspect the staged diff.
98150

99-
## 4. Findings and evidence
151+
## 5. Findings and evidence
100152

101153
Record material defects you discover as you go. Interrupt only when one changes scope,
102154
safety, strategy, or completion status; otherwise list it in the report with a next action.
@@ -108,7 +160,7 @@ Keep enough evidence to reproduce each material claim. For performance, migratio
108160
security, or environment-dependent results, record exact commands, environment, and
109161
revision. Report only results you observed.
110162

111-
## 5. Report
163+
## 6. Report
112164

113165
| Status | Meaning |
114166
| --- | --- |

‎references/quality-gates.md‎

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ Apply only the rows the change touches. Use the repository's own commands. A gat
66
| Surface | Requirements | Evidence |
77
| --- | --- | --- |
88
| Architecture | Preserve dependency direction; one owner per invariant and state transition; explicit, cohesive interfaces; no speculative abstraction. | Trace entry points and callers; check the final diff for duplicated policy or dead wiring. |
9-
| APIs and inputs | Validate type, size, range, encoding, ownership; preserve error semantics and compatibility; bound pagination and uploads. | Malformed, oversized, empty, and boundary inputs; consumer compatibility; unauthorized and cross-tenant access. |
9+
| APIs and inputs | Validate type, size, range, encoding, ownership; preserve error semantics and compatibility; keep public contracts (schemas, interfaces, event and persisted formats, command behavior) stable and version incompatible changes explicitly; bound pagination and uploads. | Malformed, oversized, empty, and boundary inputs; consumer compatibility; unauthorized and cross-tenant access. |
1010
| State and persistence | Atomicity, constraints, uniqueness, and concurrency control; exact representations where required. | Duplicate requests, lost updates, partial failure, recovery, realistic migration data. |
11-
| Concurrency | Clear ownership of shared state; atomic check-then-act; cancellation and deadlines propagate; ordering assumptions stated; operations idempotent where retried or redelivered. | Races, duplicate and out-of-order delivery, retry exhaustion, cancellation mid-operation, shutdown, deadlock. |
11+
| Concurrency | Clear ownership of shared state; atomic check-then-act; cancellation and deadlines propagate; ordering assumptions stated; operations idempotent where retried or redelivered; locks released before network, disk, inference, subprocess, or callback work; immutable values, message passing, and ownership transfer over shared mutable state. | Races, duplicate and out-of-order delivery, retry exhaustion, cancellation mid-operation, shutdown, deadlock. |
1212
| Resources | Pair acquisition with release; bound memory, files, sockets, tasks, queues, and pools. | Cleanup on error and cancel, repeated runs, leak checks. |
13-
| Security and privacy | Least privilege; authorize each sensitive operation; safe parsing and encoding; no embedded secrets; minimal sensitive data in logs. | Negative access tests; injection, path traversal, SSRF where relevant; log redaction. |
13+
| Security and privacy | Least privilege; secure defaults; authorize each sensitive operation in one central place regardless of entry interface; stronger validation on delete, overwrite, publish, and charge than on reads; safe parsing and encoding; no embedded secrets; minimal sensitive data in logs. | Negative access tests; injection, path traversal, SSRF where relevant; log redaction. |
1414
| UI and accessibility | Semantic controls, keyboard and focus, labels, responsive layout; loading, empty, error, success states; no duplicate destructive submits. | Component or browser tests, keyboard checks, supported viewports, accessibility tooling. |
15-
| Performance | Find the bottleneck before optimizing; keep correctness checks alongside speed. | Before/after on a representative workload with warmup, repetitions, variance, and comparable hardware and versions. |
15+
| Performance | Find the bottleneck before optimizing; algorithmic and architectural wins before micro-optimizations; optimize behind existing interfaces, with every fast path keeping a correct generic fallback; keep correctness checks alongside speed. | Before/after on a representative workload with warmup, repetitions, variance, and comparable hardware and versions. |
1616
| Build and supply chain | Honor pinned versions, lockfiles, generated sources, licenses; minimal dependencies and permissions. | Clean build, lockfile consistency, dependency review. |
17-
| Operations | Actionable config errors; defined rollout and rollback; no secrets or unbounded cardinality in telemetry. | Health checks, structured errors, metrics or traces, rollback steps. |
17+
| Operations | Typed configuration loaded and validated once at startup, with business logic receiving values rather than reading the environment; actionable config errors; defined rollout and rollback; structured logs and metrics designed with the feature that report decisions without determining them; no secrets or unbounded cardinality in telemetry. | Health checks, structured errors, metrics or traces, rollback steps. |
1818

1919
## Migration and rollback
2020

@@ -28,3 +28,22 @@ credential changes, or deployments without explicit authorization.
2828

2929
Characterize existing behavior before changing it. Map each affected package to its own
3030
toolchain; a green root command may not cover every package.
31+
32+
## Review questions
33+
34+
For Substantial work and above, answer each against the final diff:
35+
36+
1. What responsibility changed, where does it live, and does another part of the code
37+
already know the same rule?
38+
2. Does the change stay local, with dependencies pointing inward and no external
39+
representation leaking into core logic?
40+
3. Which additions are policy and which are mechanism, and are they kept apart?
41+
4. What new invariant exists, and what invalid states are now possible?
42+
5. What happens on failure, timeout, cancellation, and duplicate execution?
43+
6. Who owns cleanup, what can grow without a bound, and what happens under concurrency?
44+
7. Is each interface smaller and more stable than its implementation, and does each
45+
abstraction remove knowledge from callers?
46+
8. Does this make the next related change easier, and can obsolete code now be deleted?
47+
9. Do tests protect behavior rather than implementation details?
48+
10. Is the complexity justified by a real requirement, and would another engineer know
49+
where to modify this behavior six months from now?

0 commit comments

Comments
 (0)