liteagents 3.7.0 → 3.8.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/CHANGELOG.md +24 -0
- package/package.json +1 -1
- package/packages/ampcode/skills/remember/AGENT_RULES.md +14 -6
- package/packages/claude/skills/remember/AGENT_RULES.md +14 -6
- package/packages/droid/commands/remember/AGENT_RULES.md +14 -6
- package/packages/opencode/command/remember/AGENT_RULES.md +14 -6
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [3.8.0] - 2026-09-13
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **`AGENT_RULES.md` gains five rules from fwdloop's m0a review**, in all four kits:
|
|
14
|
+
prove a test can fail (revert the fix, watch it go red, restore, rather than trust
|
|
15
|
+
a test that "reads right"); model output is untrusted input (schema-validate it and
|
|
16
|
+
key decisions on typed fields, never regex the model's prose); a warning nobody has
|
|
17
|
+
to act on is not a check (either it halts/reds the run, or it is counted and
|
|
18
|
+
surfaced where a human reads it — including recording the stop/finish reason of
|
|
19
|
+
every external or model call, since a cut-off answer is never the same as no
|
|
20
|
+
answer); meter the whole unit of work (cost sums every call; one unpriced call
|
|
21
|
+
makes the total unknown, not zero); and guard lookups keyed by an external string
|
|
22
|
+
against inherited map entries answering for a key the map never had.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **`AGENT_RULES.md` redundancy pass** (all four kits): secrets, vetted libraries, and
|
|
26
|
+
the review chain are now each stated once with pointers elsewhere instead of
|
|
27
|
+
repeated inline — the "Not courtesies" secrets bullet points at Security &
|
|
28
|
+
Robustness Invariants §1, and "Before deploy/merge" points at Operating Flow §2
|
|
29
|
+
instead of restating the `/branch-review` → `/security` → `/ship` chain. The
|
|
30
|
+
security section's "Also hold the line on" paragraph is now one bullet per rule.
|
|
31
|
+
A duplicated regression-test rule was trimmed from "Write tests for bugs" since
|
|
32
|
+
"Fails for the right reason" now covers it.
|
|
33
|
+
|
|
10
34
|
## [3.7.0] - 2026-09-11
|
|
11
35
|
|
|
12
36
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "liteagents",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "AI development toolkit with 10 specialized agents and 13 capabilities including live-canvas UI design with click-to-annotate feedback. Simple one-question installer for Claude, Opencode, Ampcode, and Droid.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -60,7 +60,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
60
60
|
|
|
61
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
62
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
|
|
63
|
-
- **Never**
|
|
63
|
+
- **Never** put secrets in the tree — see [Security & Robustness Invariants §1](#security--robustness-invariants)
|
|
64
64
|
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/branch-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
65
65
|
|
|
66
66
|
---
|
|
@@ -113,6 +113,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
113
113
|
- **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
|
|
114
114
|
- **Responsive web UI is mandatory in dev projects.** Any web UI must be usable on mobile by default — fluid layouts, viewport meta tag, breakpoints for narrow screens, no horizontal scroll. Test in DevTools device emulation before declaring a UI task done. POCs are exempt (validate the idea first), but the moment a POC graduates to a real project this becomes a hard requirement
|
|
115
115
|
- **Surgical changes only.** Touch what the task requires; nothing else. Don't "improve" adjacent code, comments, or formatting. Match existing style even if you'd do it differently. Only clean up orphans your own change created. Dead code, nits, bugs you pass on the way: if it's inside or affects the code you're already changing, and the fix changes no behavior, fix it and say so. Otherwise report it — say what it costs to leave it. "It would be nicer" is not a cost. Every changed line traces to the request or to a fix you named
|
|
116
|
+
- **Meter the whole unit of work.** Usage and cost sum every call a unit of work makes; the last call's number is never the total, and one unpriced call makes the total unknown, not zero
|
|
116
117
|
|
|
117
118
|
### Red Flags — Stop and Flag These
|
|
118
119
|
- Over-engineering simple problems
|
|
@@ -144,7 +145,7 @@ particular toolchain spells it.
|
|
|
144
145
|
|
|
145
146
|
- **After the design stabilizes, not during exploration.** Do not test a prototype — you will write tests for code you delete tomorrow. First make it work (POC), then make it right (tests), then make it fast
|
|
146
147
|
- **Tests first when you already know the contract.** Pure functions, algorithms, parsers, validators, data transformations — write the test, watch it fail, then implement. When you are still discovering the interface, that same discipline produces churn and false confidence
|
|
147
|
-
- **Write tests for bugs.** Every fix ships a regression test
|
|
148
|
+
- **Write tests for bugs.** Every fix ships a regression test — the highest-value test there is
|
|
148
149
|
- **Write tests before refactoring.** Characterization tests lock in current behavior first, then change the code
|
|
149
150
|
- **Write tests when the code has users.** Called by other modules or exposed externally means it needs tests; a helper serving one caller does not need its own file
|
|
150
151
|
- **Do not test glue code.** Something that only wires A to B to C is covered at the integration level
|
|
@@ -152,7 +153,7 @@ particular toolchain spells it.
|
|
|
152
153
|
### What makes a good test
|
|
153
154
|
|
|
154
155
|
- **Tests real behavior.** Call the public interface, assert on observable output. Never reach into internals
|
|
155
|
-
- **Fails for the right reason.** It breaks when the feature breaks, not when the implementation moves
|
|
156
|
+
- **Fails for the right reason — prove it.** It breaks when the feature breaks, not when the implementation moves. Revert the fix (or switch the check off), run the test, watch it go red, then restore it: a test you have never seen fail is unverified, however right it reads
|
|
156
157
|
- **Reads like a spec.** Someone new to the code should learn what the feature does by reading it
|
|
157
158
|
- **Self-contained.** Sets up its own state, runs, cleans up. No ordering dependencies, and no reliance on project directories, user config, or ambient environment
|
|
158
159
|
- **Deterministic.** Flaky tests erode trust. A dependency on timing, network, or global state is a defect in the test
|
|
@@ -186,15 +187,22 @@ Throwaway POCs are exempt while you validate logic (per **POC first** above) —
|
|
|
186
187
|
1. **No secrets in the repo.** Keys, tokens, and credentials load from the environment / a secret store at runtime — never hardcoded, never logged. `.env` is gitignored; only a value-less `.env.example` is committed. Scan history before trusting a repo. One leaked key is a breached database or a runaway bill.
|
|
187
188
|
2. **Scope every data access to its owner.** Each record read or written is constrained to the requesting principal — via DB-level rules (RLS / row policies) and/or an application-layer ownership check. Never trust a client-supplied id without a gate. If the storage layer offers row-level policies, enabling them is not optional, and "on but too broad" still fails.
|
|
188
189
|
3. **Bound every reachable endpoint.** Rate-limit public routes AND authenticated mutation/write routes AND abuse-prone inbound paths (mail, webhooks). An unbounded route is a free DoS and bill amplifier — a script in a loop should not be able to take the service down.
|
|
189
|
-
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch.
|
|
190
|
+
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch. A warning nobody has to act on is not a check — either it halts / reds the run, or it is counted and surfaced where a human reads it. Record what you asked a dependency for and what you got back. Read and record the stop/finish reason of every external or model call — a cut-off answer (length/max_tokens) is never the same as no answer.
|
|
190
191
|
5. **Authorization is not authentication.** "Logged in" never implies "allowed". Every state-changing or privileged action checks ownership AND role/permission. If swapping an id in a request would expose or mutate someone else's data, it's a bug — return 403.
|
|
191
192
|
6. **Data access scales.** No queries inside loops, no per-render repeated round-trips, indexes on every filtered/joined column. Code that's fine at 10 users and collapses at 1,000 is a latent outage.
|
|
192
193
|
|
|
193
|
-
Also hold the line on:
|
|
194
|
+
Also hold the line on:
|
|
195
|
+
|
|
196
|
+
- **Validate input at every trust boundary.** Untrusted uploads, inbound mail, webhooks, and spoofable headers like `X-Forwarded-For` — trust the latter only behind a vetted proxy.
|
|
197
|
+
- **Model output is untrusted input too.** Validate it against a schema and key every decision on a typed field — never regex-parse the model's prose for a number, id, or verdict.
|
|
198
|
+
- **Guard lookups keyed by an external string.** Look the key up only among the map's own entries, never inherited ones — an inherited member can otherwise answer for a key the map never had, so "not found → throw" is bypassed.
|
|
199
|
+
- **Parameterize every query.** Never string-build SQL.
|
|
200
|
+
- **Use vetted libraries for security-critical code** — see [External Dependency Checklist](#external-dependency-checklist).
|
|
201
|
+
- **Bind least-privilege.** Loopback, not `0.0.0.0`, unless the port is deliberately public.
|
|
194
202
|
|
|
195
203
|
**Verify at two moments, not one.**
|
|
196
204
|
- **While building** — this list shapes the code as it's written.
|
|
197
|
-
- **Before deploy/merge** —
|
|
205
|
+
- **Before deploy/merge** — see [Operating Flow §2](#operating-flow). A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run `/branch-review` whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
|
|
198
206
|
|
|
199
207
|
---
|
|
200
208
|
|
|
@@ -60,7 +60,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
60
60
|
|
|
61
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
62
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
|
|
63
|
-
- **Never**
|
|
63
|
+
- **Never** put secrets in the tree — see [Security & Robustness Invariants §1](#security--robustness-invariants)
|
|
64
64
|
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/branch-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
65
65
|
|
|
66
66
|
---
|
|
@@ -113,6 +113,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
113
113
|
- **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
|
|
114
114
|
- **Responsive web UI is mandatory in dev projects.** Any web UI must be usable on mobile by default — fluid layouts, viewport meta tag, breakpoints for narrow screens, no horizontal scroll. Test in DevTools device emulation before declaring a UI task done. POCs are exempt (validate the idea first), but the moment a POC graduates to a real project this becomes a hard requirement
|
|
115
115
|
- **Surgical changes only.** Touch what the task requires; nothing else. Don't "improve" adjacent code, comments, or formatting. Match existing style even if you'd do it differently. Only clean up orphans your own change created. Dead code, nits, bugs you pass on the way: if it's inside or affects the code you're already changing, and the fix changes no behavior, fix it and say so. Otherwise report it — say what it costs to leave it. "It would be nicer" is not a cost. Every changed line traces to the request or to a fix you named
|
|
116
|
+
- **Meter the whole unit of work.** Usage and cost sum every call a unit of work makes; the last call's number is never the total, and one unpriced call makes the total unknown, not zero
|
|
116
117
|
|
|
117
118
|
### Red Flags — Stop and Flag These
|
|
118
119
|
- Over-engineering simple problems
|
|
@@ -144,7 +145,7 @@ particular toolchain spells it.
|
|
|
144
145
|
|
|
145
146
|
- **After the design stabilizes, not during exploration.** Do not test a prototype — you will write tests for code you delete tomorrow. First make it work (POC), then make it right (tests), then make it fast
|
|
146
147
|
- **Tests first when you already know the contract.** Pure functions, algorithms, parsers, validators, data transformations — write the test, watch it fail, then implement. When you are still discovering the interface, that same discipline produces churn and false confidence
|
|
147
|
-
- **Write tests for bugs.** Every fix ships a regression test
|
|
148
|
+
- **Write tests for bugs.** Every fix ships a regression test — the highest-value test there is
|
|
148
149
|
- **Write tests before refactoring.** Characterization tests lock in current behavior first, then change the code
|
|
149
150
|
- **Write tests when the code has users.** Called by other modules or exposed externally means it needs tests; a helper serving one caller does not need its own file
|
|
150
151
|
- **Do not test glue code.** Something that only wires A to B to C is covered at the integration level
|
|
@@ -152,7 +153,7 @@ particular toolchain spells it.
|
|
|
152
153
|
### What makes a good test
|
|
153
154
|
|
|
154
155
|
- **Tests real behavior.** Call the public interface, assert on observable output. Never reach into internals
|
|
155
|
-
- **Fails for the right reason.** It breaks when the feature breaks, not when the implementation moves
|
|
156
|
+
- **Fails for the right reason — prove it.** It breaks when the feature breaks, not when the implementation moves. Revert the fix (or switch the check off), run the test, watch it go red, then restore it: a test you have never seen fail is unverified, however right it reads
|
|
156
157
|
- **Reads like a spec.** Someone new to the code should learn what the feature does by reading it
|
|
157
158
|
- **Self-contained.** Sets up its own state, runs, cleans up. No ordering dependencies, and no reliance on project directories, user config, or ambient environment
|
|
158
159
|
- **Deterministic.** Flaky tests erode trust. A dependency on timing, network, or global state is a defect in the test
|
|
@@ -186,15 +187,22 @@ Throwaway POCs are exempt while you validate logic (per **POC first** above) —
|
|
|
186
187
|
1. **No secrets in the repo.** Keys, tokens, and credentials load from the environment / a secret store at runtime — never hardcoded, never logged. `.env` is gitignored; only a value-less `.env.example` is committed. Scan history before trusting a repo. One leaked key is a breached database or a runaway bill.
|
|
187
188
|
2. **Scope every data access to its owner.** Each record read or written is constrained to the requesting principal — via DB-level rules (RLS / row policies) and/or an application-layer ownership check. Never trust a client-supplied id without a gate. If the storage layer offers row-level policies, enabling them is not optional, and "on but too broad" still fails.
|
|
188
189
|
3. **Bound every reachable endpoint.** Rate-limit public routes AND authenticated mutation/write routes AND abuse-prone inbound paths (mail, webhooks). An unbounded route is a free DoS and bill amplifier — a script in a loop should not be able to take the service down.
|
|
189
|
-
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch.
|
|
190
|
+
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch. A warning nobody has to act on is not a check — either it halts / reds the run, or it is counted and surfaced where a human reads it. Record what you asked a dependency for and what you got back. Read and record the stop/finish reason of every external or model call — a cut-off answer (length/max_tokens) is never the same as no answer.
|
|
190
191
|
5. **Authorization is not authentication.** "Logged in" never implies "allowed". Every state-changing or privileged action checks ownership AND role/permission. If swapping an id in a request would expose or mutate someone else's data, it's a bug — return 403.
|
|
191
192
|
6. **Data access scales.** No queries inside loops, no per-render repeated round-trips, indexes on every filtered/joined column. Code that's fine at 10 users and collapses at 1,000 is a latent outage.
|
|
192
193
|
|
|
193
|
-
Also hold the line on:
|
|
194
|
+
Also hold the line on:
|
|
195
|
+
|
|
196
|
+
- **Validate input at every trust boundary.** Untrusted uploads, inbound mail, webhooks, and spoofable headers like `X-Forwarded-For` — trust the latter only behind a vetted proxy.
|
|
197
|
+
- **Model output is untrusted input too.** Validate it against a schema and key every decision on a typed field — never regex-parse the model's prose for a number, id, or verdict.
|
|
198
|
+
- **Guard lookups keyed by an external string.** Look the key up only among the map's own entries, never inherited ones — an inherited member can otherwise answer for a key the map never had, so "not found → throw" is bypassed.
|
|
199
|
+
- **Parameterize every query.** Never string-build SQL.
|
|
200
|
+
- **Use vetted libraries for security-critical code** — see [External Dependency Checklist](#external-dependency-checklist).
|
|
201
|
+
- **Bind least-privilege.** Loopback, not `0.0.0.0`, unless the port is deliberately public.
|
|
194
202
|
|
|
195
203
|
**Verify at two moments, not one.**
|
|
196
204
|
- **While building** — this list shapes the code as it's written.
|
|
197
|
-
- **Before deploy/merge** —
|
|
205
|
+
- **Before deploy/merge** — see [Operating Flow §2](#operating-flow). A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run `/branch-review` whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
|
|
198
206
|
|
|
199
207
|
---
|
|
200
208
|
|
|
@@ -60,7 +60,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
60
60
|
|
|
61
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
62
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
|
|
63
|
-
- **Never**
|
|
63
|
+
- **Never** put secrets in the tree — see [Security & Robustness Invariants §1](#security--robustness-invariants)
|
|
64
64
|
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/branch-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
65
65
|
|
|
66
66
|
---
|
|
@@ -113,6 +113,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
113
113
|
- **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
|
|
114
114
|
- **Responsive web UI is mandatory in dev projects.** Any web UI must be usable on mobile by default — fluid layouts, viewport meta tag, breakpoints for narrow screens, no horizontal scroll. Test in DevTools device emulation before declaring a UI task done. POCs are exempt (validate the idea first), but the moment a POC graduates to a real project this becomes a hard requirement
|
|
115
115
|
- **Surgical changes only.** Touch what the task requires; nothing else. Don't "improve" adjacent code, comments, or formatting. Match existing style even if you'd do it differently. Only clean up orphans your own change created. Dead code, nits, bugs you pass on the way: if it's inside or affects the code you're already changing, and the fix changes no behavior, fix it and say so. Otherwise report it — say what it costs to leave it. "It would be nicer" is not a cost. Every changed line traces to the request or to a fix you named
|
|
116
|
+
- **Meter the whole unit of work.** Usage and cost sum every call a unit of work makes; the last call's number is never the total, and one unpriced call makes the total unknown, not zero
|
|
116
117
|
|
|
117
118
|
### Red Flags — Stop and Flag These
|
|
118
119
|
- Over-engineering simple problems
|
|
@@ -144,7 +145,7 @@ particular toolchain spells it.
|
|
|
144
145
|
|
|
145
146
|
- **After the design stabilizes, not during exploration.** Do not test a prototype — you will write tests for code you delete tomorrow. First make it work (POC), then make it right (tests), then make it fast
|
|
146
147
|
- **Tests first when you already know the contract.** Pure functions, algorithms, parsers, validators, data transformations — write the test, watch it fail, then implement. When you are still discovering the interface, that same discipline produces churn and false confidence
|
|
147
|
-
- **Write tests for bugs.** Every fix ships a regression test
|
|
148
|
+
- **Write tests for bugs.** Every fix ships a regression test — the highest-value test there is
|
|
148
149
|
- **Write tests before refactoring.** Characterization tests lock in current behavior first, then change the code
|
|
149
150
|
- **Write tests when the code has users.** Called by other modules or exposed externally means it needs tests; a helper serving one caller does not need its own file
|
|
150
151
|
- **Do not test glue code.** Something that only wires A to B to C is covered at the integration level
|
|
@@ -152,7 +153,7 @@ particular toolchain spells it.
|
|
|
152
153
|
### What makes a good test
|
|
153
154
|
|
|
154
155
|
- **Tests real behavior.** Call the public interface, assert on observable output. Never reach into internals
|
|
155
|
-
- **Fails for the right reason.** It breaks when the feature breaks, not when the implementation moves
|
|
156
|
+
- **Fails for the right reason — prove it.** It breaks when the feature breaks, not when the implementation moves. Revert the fix (or switch the check off), run the test, watch it go red, then restore it: a test you have never seen fail is unverified, however right it reads
|
|
156
157
|
- **Reads like a spec.** Someone new to the code should learn what the feature does by reading it
|
|
157
158
|
- **Self-contained.** Sets up its own state, runs, cleans up. No ordering dependencies, and no reliance on project directories, user config, or ambient environment
|
|
158
159
|
- **Deterministic.** Flaky tests erode trust. A dependency on timing, network, or global state is a defect in the test
|
|
@@ -186,15 +187,22 @@ Throwaway POCs are exempt while you validate logic (per **POC first** above) —
|
|
|
186
187
|
1. **No secrets in the repo.** Keys, tokens, and credentials load from the environment / a secret store at runtime — never hardcoded, never logged. `.env` is gitignored; only a value-less `.env.example` is committed. Scan history before trusting a repo. One leaked key is a breached database or a runaway bill.
|
|
187
188
|
2. **Scope every data access to its owner.** Each record read or written is constrained to the requesting principal — via DB-level rules (RLS / row policies) and/or an application-layer ownership check. Never trust a client-supplied id without a gate. If the storage layer offers row-level policies, enabling them is not optional, and "on but too broad" still fails.
|
|
188
189
|
3. **Bound every reachable endpoint.** Rate-limit public routes AND authenticated mutation/write routes AND abuse-prone inbound paths (mail, webhooks). An unbounded route is a free DoS and bill amplifier — a script in a loop should not be able to take the service down.
|
|
189
|
-
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch.
|
|
190
|
+
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch. A warning nobody has to act on is not a check — either it halts / reds the run, or it is counted and surfaced where a human reads it. Record what you asked a dependency for and what you got back. Read and record the stop/finish reason of every external or model call — a cut-off answer (length/max_tokens) is never the same as no answer.
|
|
190
191
|
5. **Authorization is not authentication.** "Logged in" never implies "allowed". Every state-changing or privileged action checks ownership AND role/permission. If swapping an id in a request would expose or mutate someone else's data, it's a bug — return 403.
|
|
191
192
|
6. **Data access scales.** No queries inside loops, no per-render repeated round-trips, indexes on every filtered/joined column. Code that's fine at 10 users and collapses at 1,000 is a latent outage.
|
|
192
193
|
|
|
193
|
-
Also hold the line on:
|
|
194
|
+
Also hold the line on:
|
|
195
|
+
|
|
196
|
+
- **Validate input at every trust boundary.** Untrusted uploads, inbound mail, webhooks, and spoofable headers like `X-Forwarded-For` — trust the latter only behind a vetted proxy.
|
|
197
|
+
- **Model output is untrusted input too.** Validate it against a schema and key every decision on a typed field — never regex-parse the model's prose for a number, id, or verdict.
|
|
198
|
+
- **Guard lookups keyed by an external string.** Look the key up only among the map's own entries, never inherited ones — an inherited member can otherwise answer for a key the map never had, so "not found → throw" is bypassed.
|
|
199
|
+
- **Parameterize every query.** Never string-build SQL.
|
|
200
|
+
- **Use vetted libraries for security-critical code** — see [External Dependency Checklist](#external-dependency-checklist).
|
|
201
|
+
- **Bind least-privilege.** Loopback, not `0.0.0.0`, unless the port is deliberately public.
|
|
194
202
|
|
|
195
203
|
**Verify at two moments, not one.**
|
|
196
204
|
- **While building** — this list shapes the code as it's written.
|
|
197
|
-
- **Before deploy/merge** —
|
|
205
|
+
- **Before deploy/merge** — see [Operating Flow §2](#operating-flow). A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run `/branch-review` whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
|
|
198
206
|
|
|
199
207
|
---
|
|
200
208
|
|
|
@@ -60,7 +60,7 @@ Not courtesies. These bind you as written, whether or not your tool enforces the
|
|
|
60
60
|
|
|
61
61
|
- **Always** identify affected files before making changes, and explain what will change and why
|
|
62
62
|
- **Ask first** — stop and get explicit sign-off — before modifying authentication systems, database schema or migrations, CI workflows, or `.claude/settings.json`
|
|
63
|
-
- **Never**
|
|
63
|
+
- **Never** put secrets in the tree — see [Security & Robustness Invariants §1](#security--robustness-invariants)
|
|
64
64
|
- **Never** commit to `main`. Commit to a new branch (name doesn't matter), then propose `/branch-review` followed by `/release`; merging and releasing are my call, made by name — "approve", "good", or "go" on a draft is not that call
|
|
65
65
|
|
|
66
66
|
---
|
|
@@ -113,6 +113,7 @@ Before adding any external dependency, all of these must be true:
|
|
|
113
113
|
- **Containerize only when necessary.** Start with a virtualenv or bare metal. Docker adds value for deployment parity and isolation — not for running a script
|
|
114
114
|
- **Responsive web UI is mandatory in dev projects.** Any web UI must be usable on mobile by default — fluid layouts, viewport meta tag, breakpoints for narrow screens, no horizontal scroll. Test in DevTools device emulation before declaring a UI task done. POCs are exempt (validate the idea first), but the moment a POC graduates to a real project this becomes a hard requirement
|
|
115
115
|
- **Surgical changes only.** Touch what the task requires; nothing else. Don't "improve" adjacent code, comments, or formatting. Match existing style even if you'd do it differently. Only clean up orphans your own change created. Dead code, nits, bugs you pass on the way: if it's inside or affects the code you're already changing, and the fix changes no behavior, fix it and say so. Otherwise report it — say what it costs to leave it. "It would be nicer" is not a cost. Every changed line traces to the request or to a fix you named
|
|
116
|
+
- **Meter the whole unit of work.** Usage and cost sum every call a unit of work makes; the last call's number is never the total, and one unpriced call makes the total unknown, not zero
|
|
116
117
|
|
|
117
118
|
### Red Flags — Stop and Flag These
|
|
118
119
|
- Over-engineering simple problems
|
|
@@ -144,7 +145,7 @@ particular toolchain spells it.
|
|
|
144
145
|
|
|
145
146
|
- **After the design stabilizes, not during exploration.** Do not test a prototype — you will write tests for code you delete tomorrow. First make it work (POC), then make it right (tests), then make it fast
|
|
146
147
|
- **Tests first when you already know the contract.** Pure functions, algorithms, parsers, validators, data transformations — write the test, watch it fail, then implement. When you are still discovering the interface, that same discipline produces churn and false confidence
|
|
147
|
-
- **Write tests for bugs.** Every fix ships a regression test
|
|
148
|
+
- **Write tests for bugs.** Every fix ships a regression test — the highest-value test there is
|
|
148
149
|
- **Write tests before refactoring.** Characterization tests lock in current behavior first, then change the code
|
|
149
150
|
- **Write tests when the code has users.** Called by other modules or exposed externally means it needs tests; a helper serving one caller does not need its own file
|
|
150
151
|
- **Do not test glue code.** Something that only wires A to B to C is covered at the integration level
|
|
@@ -152,7 +153,7 @@ particular toolchain spells it.
|
|
|
152
153
|
### What makes a good test
|
|
153
154
|
|
|
154
155
|
- **Tests real behavior.** Call the public interface, assert on observable output. Never reach into internals
|
|
155
|
-
- **Fails for the right reason.** It breaks when the feature breaks, not when the implementation moves
|
|
156
|
+
- **Fails for the right reason — prove it.** It breaks when the feature breaks, not when the implementation moves. Revert the fix (or switch the check off), run the test, watch it go red, then restore it: a test you have never seen fail is unverified, however right it reads
|
|
156
157
|
- **Reads like a spec.** Someone new to the code should learn what the feature does by reading it
|
|
157
158
|
- **Self-contained.** Sets up its own state, runs, cleans up. No ordering dependencies, and no reliance on project directories, user config, or ambient environment
|
|
158
159
|
- **Deterministic.** Flaky tests erode trust. A dependency on timing, network, or global state is a defect in the test
|
|
@@ -186,15 +187,22 @@ Throwaway POCs are exempt while you validate logic (per **POC first** above) —
|
|
|
186
187
|
1. **No secrets in the repo.** Keys, tokens, and credentials load from the environment / a secret store at runtime — never hardcoded, never logged. `.env` is gitignored; only a value-less `.env.example` is committed. Scan history before trusting a repo. One leaked key is a breached database or a runaway bill.
|
|
187
188
|
2. **Scope every data access to its owner.** Each record read or written is constrained to the requesting principal — via DB-level rules (RLS / row policies) and/or an application-layer ownership check. Never trust a client-supplied id without a gate. If the storage layer offers row-level policies, enabling them is not optional, and "on but too broad" still fails.
|
|
188
189
|
3. **Bound every reachable endpoint.** Rate-limit public routes AND authenticated mutation/write routes AND abuse-prone inbound paths (mail, webhooks). An unbounded route is a free DoS and bill amplifier — a script in a loop should not be able to take the service down.
|
|
189
|
-
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch.
|
|
190
|
+
4. **Handle the unhappy path.** Every IO / network / DB / third-party call has an explicit failure path. Nothing fails silently. Internal detail (stack traces, queries, secrets) never reaches the client. Async/background work carries its own catch. A warning nobody has to act on is not a check — either it halts / reds the run, or it is counted and surfaced where a human reads it. Record what you asked a dependency for and what you got back. Read and record the stop/finish reason of every external or model call — a cut-off answer (length/max_tokens) is never the same as no answer.
|
|
190
191
|
5. **Authorization is not authentication.** "Logged in" never implies "allowed". Every state-changing or privileged action checks ownership AND role/permission. If swapping an id in a request would expose or mutate someone else's data, it's a bug — return 403.
|
|
191
192
|
6. **Data access scales.** No queries inside loops, no per-render repeated round-trips, indexes on every filtered/joined column. Code that's fine at 10 users and collapses at 1,000 is a latent outage.
|
|
192
193
|
|
|
193
|
-
Also hold the line on:
|
|
194
|
+
Also hold the line on:
|
|
195
|
+
|
|
196
|
+
- **Validate input at every trust boundary.** Untrusted uploads, inbound mail, webhooks, and spoofable headers like `X-Forwarded-For` — trust the latter only behind a vetted proxy.
|
|
197
|
+
- **Model output is untrusted input too.** Validate it against a schema and key every decision on a typed field — never regex-parse the model's prose for a number, id, or verdict.
|
|
198
|
+
- **Guard lookups keyed by an external string.** Look the key up only among the map's own entries, never inherited ones — an inherited member can otherwise answer for a key the map never had, so "not found → throw" is bypassed.
|
|
199
|
+
- **Parameterize every query.** Never string-build SQL.
|
|
200
|
+
- **Use vetted libraries for security-critical code** — see [External Dependency Checklist](#external-dependency-checklist).
|
|
201
|
+
- **Bind least-privilege.** Loopback, not `0.0.0.0`, unless the port is deliberately public.
|
|
194
202
|
|
|
195
203
|
**Verify at two moments, not one.**
|
|
196
204
|
- **While building** — this list shapes the code as it's written.
|
|
197
|
-
- **Before deploy/merge** —
|
|
205
|
+
- **Before deploy/merge** — see [Operating Flow §2](#operating-flow). A Critical/High finding blocks the ship; lower-severity findings get logged and triaged, not silently shipped. Proactively remind the user to run `/branch-review` whenever a change touches auth, data access, endpoints, secrets, or untrusted input.
|
|
198
206
|
|
|
199
207
|
---
|
|
200
208
|
|