@clipboard-health/ai-rules 2.32.0 → 2.34.0
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/package.json +1 -1
- package/skills/cb-babysit/SKILL.md +6 -6
- package/skills/cb-babysit/scripts/_sentinel.sh +1 -1
- package/skills/cb-babysit/scripts/commitAndPush.sh +4 -2
- package/skills/cb-review/SKILL.md +231 -0
- package/skills/{simple-review → cb-review}/references/cross-repo-evidence.md +14 -1
- package/skills/cb-review/references/multi-agent.md +68 -0
- package/skills/{simple-review → cb-review}/references/posting-pr-review.md +5 -11
- package/skills/cb-review/references/review-rubric.md +194 -0
- package/skills/cb-ship/SKILL.md +7 -5
- package/skills/cb-ship/references/pr-template.md +1 -1
- package/skills/cb-work/SKILL.md +1 -0
- package/skills/in-depth-review/SKILL.md +0 -491
- package/skills/in-depth-review/references/cross-repo-evidence.md +0 -37
- package/skills/in-depth-review/references/posting-pr-review.md +0 -105
- package/skills/simple-review/SKILL.md +0 -474
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Review rubric (binding for both engines)
|
|
2
|
+
|
|
3
|
+
Low effort: the single reviewer subagent reads this whole file and walks every active lens. High effort: each reviewer agent reads **Admission** plus its own lens section. Referenced from `SKILL.md`.
|
|
4
|
+
|
|
5
|
+
## Admission
|
|
6
|
+
|
|
7
|
+
### Severity ladder
|
|
8
|
+
|
|
9
|
+
- **CRITICAL** — realistic input causes incorrect behavior, data loss, security regression, broken contract, or a paging incident.
|
|
10
|
+
- **MAJOR** — meaningful degradation of correctness/UX/observability under realistic conditions; OR a documented-convention violation with concrete downstream impact.
|
|
11
|
+
- **MINOR** — cheap, concrete improvement with a named benefit.
|
|
12
|
+
- **NIT** — only admissible if (a) repeats ≥2× in the diff, (b) conflicts with a documented convention, or (c) is a one-line trivial fix.
|
|
13
|
+
|
|
14
|
+
### failure_mode contract
|
|
15
|
+
|
|
16
|
+
Every finding **must** include a `failure_mode`: one sentence on the concrete user-, oncall-, or maintainer-visible bad outcome that would occur if not fixed. Hypotheticals like "a future caller might…" do **NOT** satisfy this — drop the finding.
|
|
17
|
+
|
|
18
|
+
Litmus test before keeping any candidate: _"What is the concrete, current, product-visible cost of leaving this code in?"_ If you can't answer in one sentence, drop it.
|
|
19
|
+
|
|
20
|
+
### Do-not-raise list
|
|
21
|
+
|
|
22
|
+
Drop candidates that match. The tagged items double as the slop taxonomy for the Filter (SKILL.md) and for AntiSlop's Round 2 audit of other agents' findings (multi-agent.md), which cites the tags verbatim.
|
|
23
|
+
|
|
24
|
+
- `slop: asks for defensive guard on already-narrowed value` — speculative defensiveness at a boundary whose guarantee is actually _enforced_; a declared or cast type is not enforcement (see AntiSlop).
|
|
25
|
+
- `slop: hypothetical future caller — no current path` — future-caller scenarios with no current caller.
|
|
26
|
+
- `slop: restating-the-obvious comment request` — comment/JSDoc requests where name + signature already convey intent.
|
|
27
|
+
- `slop: refactor with no concrete cost-of-keeping` — abstract SOLID-style "consider extracting…" with no concrete failure mode.
|
|
28
|
+
- `slop: observability without named failure mode` — "add a log/metric" without the specific failure it would debug.
|
|
29
|
+
- `slop: test for trivially-verifiable code` — test demands on type-evident or already-exercised code.
|
|
30
|
+
- `slop: defends against a state the product cannot produce`.
|
|
31
|
+
- Style/formatting a linter or formatter covers.
|
|
32
|
+
- Aesthetic naming preferences — only raise names that mislead about behavior.
|
|
33
|
+
|
|
34
|
+
### Caps
|
|
35
|
+
|
|
36
|
+
6 actionable items (CRITICAL/MAJOR/MINOR) plus 8 NITs retained internally; anything beyond is "N additional items omitted; ask for the full list." High effort: each reviewer agent additionally caps its own output at 8 findings, prioritized — not exhaustive.
|
|
37
|
+
|
|
38
|
+
### suggested_fix schema (when present)
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
"suggested_fix": {
|
|
42
|
+
"before": "<exact current code at file:lines>",
|
|
43
|
+
"after": "<replacement code at the same anchor>"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- Pure deletion: `after` is `""`.
|
|
48
|
+
- Pure addition at a new line: `before` is `""`, prefix `after` with `// add after line <N>`.
|
|
49
|
+
- Structural change with no clean drop-in: omit `suggested_fix`, describe in `point`/`failure_mode`.
|
|
50
|
+
- Both must be code (not prose), preserving the file's indentation. Don't elide with `// ...`.
|
|
51
|
+
|
|
52
|
+
## Engineering (always)
|
|
53
|
+
|
|
54
|
+
For each change name a realistic input or condition that would expose a bug. If you cannot, do not raise it.
|
|
55
|
+
|
|
56
|
+
- **Declared ≠ enforced — check what actually guarantees a precondition.** When new code performs an operation that faults on a missing or malformed input (destructuring, property/array access, non-null assertion, iteration, parsing, arithmetic), do not accept a declared type, function signature, cast, or `as` as proof the input is safe — those _label_ a value, they don't _check_ it. Ask what enforces the precondition on this path: a runtime validator, a preceding explicit check, or a constructor/factory invariant. If nothing does, trace the value to its origin — it can fault on real data even though it compiles. Look at the operation that would actually throw, not only the named field beside it.
|
|
57
|
+
- **Asymmetric handling across sibling call sites is a likely bug, not a style nit.** When the diff guards, validates, converts, or error-wraps a value in one place but consumes the same value or shape bare elsewhere, exactly one side is usually right. Compare the call sites against each other instead of reviewing each in isolation, and resolve the inconsistency: guard missing where it's absent → bug; guard unnecessary everywhere → slop to remove.
|
|
58
|
+
- Edge cases, error paths, observability of real failure modes.
|
|
59
|
+
- Tests cover real risk, not lines.
|
|
60
|
+
- A diff that changes runtime behavior with zero test delta is raisable when the repo's documented rules mandate tests (cite the rule) — "the new behavior ships unverified" is a concrete failure_mode, not a hypothetical.
|
|
61
|
+
- Hard-coded environment-specific identifiers (pool/account IDs, environment URLs) in code, scripts, or docs meant for reuse.
|
|
62
|
+
- Concurrency, performance at real scale, data integrity.
|
|
63
|
+
- Backward compatibility, on-call implications, degraded-mode behavior.
|
|
64
|
+
- Async/await ordering matches actual data dependencies.
|
|
65
|
+
- Timezone correctness in date code; currency variables explicitly in minor units.
|
|
66
|
+
- API surface changed → AuthN/AuthZ/PII (deep dive under Security).
|
|
67
|
+
- Migration → rollback, rolling-deploy compat, ETL/downstream impact (deep dive under Database).
|
|
68
|
+
- Schema/query changed → indexes for new patterns, N+1, cascade semantics, type fit (deep dive under Database).
|
|
69
|
+
- Telemetry covers business/product value, not only engineering surface metrics.
|
|
70
|
+
- Contract/backward-compat for any consumer-visible response shape change. **If you suspect a consumer break, the finding is cross-repo — follow the cross-repo evidence policy before raising it.**
|
|
71
|
+
- Before raising a version/back-compat break on a published package, read its `package.json` at `${context_ref}` — 0.x caret semantics or a days-old package can refute the failure_mode.
|
|
72
|
+
|
|
73
|
+
## Minimalism (always)
|
|
74
|
+
|
|
75
|
+
The smallest diff that ships the intent is the best diff.
|
|
76
|
+
|
|
77
|
+
- Unneeded abstractions, speculative generality, dead branches.
|
|
78
|
+
- Redundant validation, defensive code at trusted internal boundaries.
|
|
79
|
+
- Comments that restate code; new files/utilities that duplicate existing ones.
|
|
80
|
+
- Near-duplicate tests or assertions within the diff; conditions or variables another hunk of the same diff makes unnecessary.
|
|
81
|
+
- New docs or guidance lines that restate an adjacent existing line.
|
|
82
|
+
- Tests that exercise the framework, not behavior.
|
|
83
|
+
- Flags/config knobs without a concrete caller.
|
|
84
|
+
- Duplicated error handlers in the same scope.
|
|
85
|
+
- Commented-out code or dead branches.
|
|
86
|
+
|
|
87
|
+
For every "delete this" finding, `failure_mode` must state the **concrete cost of keeping the code**.
|
|
88
|
+
|
|
89
|
+
### Named-smell vocabulary
|
|
90
|
+
|
|
91
|
+
Use these names (Fowler, _Refactoring_ ch.3) to label structural findings — a shared name makes the finding legible and the fix direction obvious. Three rules bind them: a smell label alone is **not** a finding (the `failure_mode` contract still applies); a documented repo standard overrides the baseline; each is a judgement call, never a hard violation.
|
|
92
|
+
|
|
93
|
+
- **Mysterious Name** — name doesn't reveal what it does or holds → rename; if no honest name comes, the design's murky.
|
|
94
|
+
- **Duplicated Code** — same logic shape in more than one hunk/file of the change → extract the shared shape.
|
|
95
|
+
- **Feature Envy** — method reaches into another object's data more than its own → move it onto the data it envies.
|
|
96
|
+
- **Data Clumps** — the same few fields/params keep traveling together → bundle into one type.
|
|
97
|
+
- **Primitive Obsession** — a primitive standing in for a domain concept → give the concept its own small type.
|
|
98
|
+
- **Repeated Switches** — same `switch`/`if`-cascade on the same type recurs across the change → polymorphism or one shared map.
|
|
99
|
+
- **Shotgun Surgery** — one logical change forces scattered edits across many files → gather what changes together.
|
|
100
|
+
- **Divergent Change** — one module edited for several unrelated reasons → split by reason for change.
|
|
101
|
+
- **Speculative Generality** — abstraction/hooks for needs nothing has → delete; inline back until a real need shows.
|
|
102
|
+
- **Message Chains** — long `a.b().c().d()` navigation → hide the walk behind one method.
|
|
103
|
+
- **Middle Man** — a class/function that mostly delegates onward → cut it, call the target direct.
|
|
104
|
+
- **Refused Bequest** — implementer ignores/overrides most of what it inherits → drop inheritance, use composition.
|
|
105
|
+
|
|
106
|
+
## Conventions (always)
|
|
107
|
+
|
|
108
|
+
You are the convention owner — validate against what the repo actually documents, not a memorized list. The `@clipboard-health/ai-rules` sync drops a Coding Rules table into each consuming repo's `AGENTS.md`, mapping every rule file that repo adopted to a "When to Read" trigger — those pointers are the source of truth for which conventions apply. Consult, in order of priority:
|
|
109
|
+
|
|
110
|
+
- `git show ${context_ref}:AGENTS.md` and `CLAUDE.md` (if present). Read every rule file in the Coding Rules table whose "When to Read" trigger matches the diff, via `git show ${context_ref}:<rule-path>`.
|
|
111
|
+
- Neighboring files in the same module/service for in-practice patterns.
|
|
112
|
+
- Package READMEs in the touched paths.
|
|
113
|
+
|
|
114
|
+
Flag only violations of what those sources document — do not import conventions from other repos or from memory. One check needs no documented rule: **internal inconsistency within the diff itself** (e.g. half of imports from one package family, half from upstream; same persisted shape written three different ways across three call sites).
|
|
115
|
+
|
|
116
|
+
This lens owns all documented-rule checking, whatever domains the table covers (common, backend, frontend, data). Tag every convention finding with `[CONVENTION]` in the title. Cap severity at MAJOR (only when behavior diverges as a result) or MINOR otherwise.
|
|
117
|
+
|
|
118
|
+
## AntiSlop (always)
|
|
119
|
+
|
|
120
|
+
This PR may have been written or assisted by an LLM. For each addition, ask: _"Is this line earning its keep, or is it pattern-matching what code is supposed to look like?"_ Push back on what other lenses are too polite to flag. Apply to additions **inside the diff itself**.
|
|
121
|
+
|
|
122
|
+
- **Defensive code at trusted internal boundaries.** Null guards on private helpers whose callers' types guarantee non-null; `try`/`catch` wrapping a single non-throwing call, or that re-throws unchanged, or that "logs and swallows" without naming what to do next; optional-chaining through types that don't include optionality. **But "trusted" means the guarantee is _enforced_** — by a validator on this path, a constructor/factory invariant, or a preceding check you can point to. A type, signature, cast, or `as`/non-null-assertion only _asserts_ the guarantee; a guard backing a merely-asserted guarantee is load-bearing, not slop. Confirm what enforces the type at the call site before flagging the guard.
|
|
123
|
+
- **Defensiveness against unrealistic product scenarios.** Litmus: _"In the real product flow this code participates in, what user action / system event / upstream call could land us in this branch?"_ If the answer is "none" or "I had to invent one to justify the guard", it's slop. Concrete shapes:
|
|
124
|
+
- Null/undefined guard on an ID immediately after that ID was used to load (and find) the entity.
|
|
125
|
+
- A `null`/`undefined`/`""`/`0` branch on a field whose TypeScript or Zod/class-validator already rejects those.
|
|
126
|
+
- Re-validation of a value the request DTO already validated upstream in the same lifecycle.
|
|
127
|
+
- Consistency check (`if (a !== b) throw`) between two fields the data model forbids being unequal.
|
|
128
|
+
- Branch for a product-impossible state.
|
|
129
|
+
- Retry/fallback around an SDK call that already retries or returns a typed error.
|
|
130
|
+
- `catch` for an error class statically known not to throw, or that logs+swallows.
|
|
131
|
+
- "Future-proof" code path with no current `v2`.
|
|
132
|
+
|
|
133
|
+
Don't accept "but what if upstream changes?" as a defense — that's the hypothetical-future-caller anti-pattern. The fix when upstream genuinely changes is a typed-error / schema update in that PR, not preemptive guards.
|
|
134
|
+
|
|
135
|
+
- **Restating-the-code comments.** `// fetch the user`, JSDoc on private helpers that only restates the signature, `// Note: this is important`, section banners in short files.
|
|
136
|
+
- **Empty scaffolding.** `// TODO` with no owner/ticket; redundant pre-conditions; debug logs that survived to the PR; default `else { return undefined; }` after exhaustive branching; `_unused` prefixes that should be deletions.
|
|
137
|
+
- **Speculative generality.** Helper called once that wraps two trivial lines; `Map`/`Set`/config keyed by a single hardcoded value; "strategy"/"registry" pattern with one strategy; union types whose only second case is `never`/placeholder.
|
|
138
|
+
- **Unused parameters/overloads/fields.** Args destructured but never read; interface methods with empty implementations; new optional fields with no producer or consumer.
|
|
139
|
+
- **Tests that exercise the framework, not the code.** `jest.fn().mockReturnValue(x); expect(fn()).toBe(x)`; snapshot tests with no semantic assertion; tests that mock the unit under test; test names that describe the implementation (`it("calls foo.bar"…)`) instead of behavior.
|
|
140
|
+
- **Dead AI breadcrumbs.** Variables whose only use is logging or debug branches; `console.log`/`console.error` that should have been removed before commit; commented-out alternative implementations.
|
|
141
|
+
- **Tone/description mismatch.** PR description claims behavior the diff doesn't have; variable/function names that pattern-match engineering writing without naming the role (`data`, `result`, `processed`, `_handle`, `doStuff`).
|
|
142
|
+
|
|
143
|
+
Default `suggested_fix` is **delete** (empty `after`) or **simplify** (smaller `after`). Suggesting "add a justifying comment" is itself slop — do not propose it.
|
|
144
|
+
|
|
145
|
+
Stay in your lane: do not raise items the Conventions lens owns (anything a documented rule file covers); do not demand observability, tests, or error handling that does **not** exist in the diff — you only call out what's _present_ and unnecessary; do not challenge whether the PR solves the right problem. A change that's small but unnecessary is still slop; a change that's large but earns each line is not.
|
|
146
|
+
|
|
147
|
+
## Spec (when a spec source exists)
|
|
148
|
+
|
|
149
|
+
Does the diff faithfully implement what was asked? Read the spec (issue, ticket, PRD, plan file) in full, then check:
|
|
150
|
+
|
|
151
|
+
- **Missing or partial requirements** — things the spec asked for that the diff doesn't do, or half-does.
|
|
152
|
+
- **Scope creep** — behavior in the diff the spec didn't ask for. (Mechanical enablers of requested behavior are fine; new user-visible behavior is not.)
|
|
153
|
+
- **Implemented but wrong** — requirements that look addressed but whose implementation diverges from what the spec actually says (wrong threshold, wrong actor, wrong ordering, wrong default).
|
|
154
|
+
|
|
155
|
+
Quote the spec line each finding is grounded in. Tag every finding `[SPEC]`. The `failure_mode` contract applies — the concrete cost is usually "ships behavior that diverges from what was agreed" made specific (which user, which flow, which wrong outcome). Spec findings report separately in the Summary so a standards-clean diff can't mask a spec miss.
|
|
156
|
+
|
|
157
|
+
## Security (when triggered)
|
|
158
|
+
|
|
159
|
+
Where could this change leak data, bypass authorization, or expand the trust boundary?
|
|
160
|
+
|
|
161
|
+
- AuthN: every new/modified endpoint has authenticated identity unless explicitly public.
|
|
162
|
+
- AuthZ: per-endpoint AND per-resource permission checks; cross-tenant/cross-user access.
|
|
163
|
+
- Secrets in configuration — no hardcoded keys, no secrets in client bundles.
|
|
164
|
+
- No self-made or client-side cryptography.
|
|
165
|
+
- SQL/NoSQL injection: string-concatenated queries, unvalidated `$where`, raw aggregation pipelines from user input.
|
|
166
|
+
- Sensitive data in response payloads — over-fetching, over-serialization, internal IDs leaked.
|
|
167
|
+
- PII fields logged, cached, or sent to telemetry.
|
|
168
|
+
- Input validation at the boundary (Zod / class-validator) on every new endpoint.
|
|
169
|
+
- For numeric inputs: explicit `min`/`max` bounds. Verify what the JS engine does with `Number.MAX_SAFE_INTEGER + 1`, BigInt conversion, negative values, and whether the catch path returns a structured 400 or a 500 with stack log.
|
|
170
|
+
|
|
171
|
+
## Database (when triggered)
|
|
172
|
+
|
|
173
|
+
What breaks at production scale or during deploy?
|
|
174
|
+
|
|
175
|
+
- Index coverage for new query patterns; missing compound indexes.
|
|
176
|
+
- N+1 query shapes; loops issuing per-iteration queries.
|
|
177
|
+
- Schema normalization — denormalization that creates write-amplification or update anomalies.
|
|
178
|
+
- Data types — range, precision, locale (numeric, date, money). Mongoose `Number` is IEEE 754 double; safe for integers up to 2^53.
|
|
179
|
+
- Cascade-delete and FK-on-delete semantics; orphan risk.
|
|
180
|
+
- Migration rollback strategy; online without downtime.
|
|
181
|
+
- Backward compatibility during a rolling deploy (old code reads new schema; new code reads old schema).
|
|
182
|
+
- ETL / downstream consumer impact when schema or field semantics change.
|
|
183
|
+
- New collections / tables ship with the indexes their query patterns need on day one.
|
|
184
|
+
- **Dual-write fields** (storing both `amount` and `amountInMinorUnits`-style pairs): is canonicalization happening on write, or does the on-disk record encode two contradictory values?
|
|
185
|
+
- Backfill for new fields on existing records: present, deferred (with ticket), or missing?
|
|
186
|
+
|
|
187
|
+
## Frontend (when triggered)
|
|
188
|
+
|
|
189
|
+
Will this behave correctly under realistic user conditions? FE conventions (data fetching, component patterns, styling, feature flags, FE testing) are documented rules — the Conventions lens owns them via the repo's Coding Rules table; do not re-derive them from memory here. This lens owns behavior:
|
|
190
|
+
|
|
191
|
+
- Loading / empty / error states for any new data-fetching surface.
|
|
192
|
+
- Accessibility: keyboard navigation, ARIA roles, labels on interactive controls.
|
|
193
|
+
- State that survives realistic interaction: rapid re-clicks, back navigation, stale cache, concurrent mutations, slow networks.
|
|
194
|
+
- Render correctness with realistic data: long strings, empty lists, zero/negative values, missing optional fields.
|
package/skills/cb-ship/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cb-ship
|
|
3
|
-
description: Ship changes. Simplify the diff, commit, push, and open or update a PR. Use when the user says 'ship it', 'commit and push', or wants a PR created or updated.
|
|
3
|
+
description: Ship changes. Simplify the diff, commit, review, push, and open or update a PR. Use when the user says 'ship it', 'commit and push', or wants a PR created or updated.
|
|
4
4
|
argument-hint: "[--draft]"
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -17,16 +17,18 @@ Resolve bundled "./references" paths relative to SKILL.md.
|
|
|
17
17
|
1. Create a new branch if on the default branch (e.g., `feat/add-user-validation`, `fix/null-check-in-parser`).
|
|
18
18
|
2. Use ./references/simplify.md on the full PR diff: `git diff $(git merge-base HEAD origin/HEAD)..HEAD` and any uncommitted changes.
|
|
19
19
|
3. Inspect `git status --short`, identify intended files, ask if ambiguous, then git add them. If uncommitted changes, create a conventional commit with `git commit --no-gpg-sign`.
|
|
20
|
-
4.
|
|
21
|
-
5.
|
|
20
|
+
4. Invoke the `cb-review` skill with `--effort low --report` and triage each returned finding yourself: if it's real and in scope, apply it, rerun the repo's relevant checks, and commit; otherwise dismiss it with a one-line reason for the output. Skip this step when the session already ran cb-review over these same changes.
|
|
21
|
+
5. Push changes to origin.
|
|
22
|
+
6. Create or update the PR using ./references/pr-template.md:
|
|
22
23
|
a. If the host exposes a session ID (e.g., CODEX_THREAD_ID, CLAUDE_CODE_SESSION_ID), include the resume command in the PR body in backticks: ``Agent session: `codex resume <id>` `` or ``Agent session: `claude --resume <id>` ``. Preserve existing `Agent session:` lines, append only.
|
|
23
24
|
b. If a PR exists, update the title and body if the new changes aren't reflected.
|
|
24
25
|
c. Otherwise, create one with `gh pr create`; make it a draft if the user passed `--draft`.
|
|
25
|
-
|
|
26
|
+
7. Output:
|
|
26
27
|
|
|
27
28
|
```plaintext
|
|
28
29
|
- Directory: [Absolute path]
|
|
29
30
|
- Branch: [Branch name]
|
|
30
|
-
-
|
|
31
|
+
- Review: [N findings — M applied, K dismissed with a one-line reason each] (omit if step 4 skipped or found nothing)
|
|
32
|
+
- Session: [Resume command from 6a] (omit if none)
|
|
31
33
|
- PR: [Complete url] (e.g., `https://github.com/clipboardhealth/core-utils/pull/123`)
|
|
32
34
|
```
|
|
@@ -17,5 +17,5 @@ Concisely explain the user intent from session history and the meaningful behavi
|
|
|
17
17
|
|
|
18
18
|
Optional, don't fabricate: ticket links, rollout plan, residual risk, or specific areas for reviewers to focus.
|
|
19
19
|
|
|
20
|
-
<sub>🤖 <code>cb-ship:created v1 core@3.
|
|
20
|
+
<sub>🤖 <code>cb-ship:created v1 core@3.15.0</code></sub>
|
|
21
21
|
```
|
package/skills/cb-work/SKILL.md
CHANGED
|
@@ -22,6 +22,7 @@ Unless instructed otherwise:
|
|
|
22
22
|
The plan or request is the source of truth for scope:
|
|
23
23
|
|
|
24
24
|
- Make exactly the changes requested, no extra refactors or cleanup.
|
|
25
|
+
- Target ≤ ~500 changed lines per PR: if the work will clearly exceed that, stop and propose a split into separately shippable slices before implementing.
|
|
25
26
|
- On any drift from the plan (e.g. referenced files or utilities missing, an assumption invalid, a constraint missed) stop and report. Do not silently rewrite the approach.
|
|
26
27
|
- Do not modify the plan file itself unless asked.
|
|
27
28
|
|