cursordoctrine 0.5.1 → 0.5.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 +2 -2
- package/linux/hooks/final-review.md +41 -14
- package/linux/hooks/final-review.sh +3 -2
- package/linux/hooks/subagent-stop-review.sh +2 -2
- package/package.json +1 -1
- package/skills/anti-slop/SKILL.md +2 -2
- package/windows/hooks/final-review.md +35 -0
- package/windows/hooks/final-review.ps1 +3 -2
- package/windows/hooks/subagent-stop-review.ps1 +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Cursor hooks that make the agent review its own edits without bolting a static-a
|
|
|
26
26
|
3. **Hand the model its own edits back** (reactive) — after each agent edit, a self-review prompt goes into a pending file (plus semantic-density, scope-gate, and anti-slop advisories when they trip). Next turn the model reads its diff, fixes real bugs, stays quiet otherwise.
|
|
27
27
|
4. **Gate blast radius** — one permission gate denies a short explicit list of dangerous commands (`rm -rf /`, `curl | sh`, force-push, `npm publish`, ...). Everything else passes.
|
|
28
28
|
|
|
29
|
-
When an implementation finishes, the stop hook runs one final review over everything that changed, then stops.
|
|
29
|
+
When an implementation finishes, the stop hook runs one final review over everything that changed, then stops. Seven axes. The first is **intent trace**: the hook pulls your last user message from the transcript and prepends it to the review so the model has to tie every diff hunk to a concrete request. Anything it can't trace is a hallucinated requirement and gets reverted. The last is **mechanics & stack integrity** (N+1, idempotency, transactions, boundary validation, zombie listeners, god components, determinism) — patterns the regex scanner can't catch because they need semantic judgement. That's the only check that catches "clean code, wrong feature" — linters and later axes miss it.
|
|
30
30
|
|
|
31
31
|
Subagents get the same treatment. If a delegated run edited files, it reviews its own work before the result goes back to the parent. Those edits fold into the parent's final review. Every bound is enforced twice: in the script and in `hooks.json`.
|
|
32
32
|
|
|
@@ -114,7 +114,7 @@ Crucially, `intent-anchor` carries the **semantic** contract (`intent`/`acceptan
|
|
|
114
114
|
| Session | `sessionStart` | `inject-doctrine` reads doctrine + user rules + declared-editing + **pre-compile** and emits them as `additional_context`. |
|
|
115
115
|
| Every turn | `postToolUse` | **`intent-anchor`** (registered first) re-injects `.scope.json` into `additional_context` at the first tool boundary of each turn — the anti-Salience-Dilution move that keeps `intent` + `acceptance` in the model's attentional focus before edits pile up. If the prompt changed since last turn, it demands the contract be updated. Then `post-tool-use` folds subagent markers and drains the feedback file. |
|
|
116
116
|
| Shell | `beforeShellExecution` | `permission-gate` checks the command against a deny list. Allow by default, deny by list, fail open. |
|
|
117
|
-
| Edit | `afterFileEdit` + `stop` | **Proactive:** `intent-anchor` (`postToolUse`) scaffolds `.scope.json` per prompt and re-injects it each turn. **Reactive:** `self-review-trigger` stashes the review prompt per edit; `semantic-density-audit`, `scope-gate-audit` (opt-in, audits `.scope.json`), and `anti-slop-audit` append advisories when they trip; `final-review` fires one end-of-implementation
|
|
117
|
+
| Edit | `afterFileEdit` + `stop` | **Proactive:** `intent-anchor` (`postToolUse`) scaffolds `.scope.json` per prompt and re-injects it each turn. **Reactive:** `self-review-trigger` stashes the review prompt per edit; `semantic-density-audit`, `scope-gate-audit` (opt-in, audits `.scope.json`), and `anti-slop-audit` append advisories when they trip; `final-review` fires one end-of-implementation seven-axis pass. |
|
|
118
118
|
| Subagent | `subagentStop` | `subagent-stop-review` fires one in-subagent final review when a delegated run edited files, before the result returns to the parent. Marker-gated and flag-braked like `final-review`. |
|
|
119
119
|
|
|
120
120
|
## Layout
|
|
@@ -56,26 +56,18 @@ Step A — mechanical scan (if available):
|
|
|
56
56
|
Step B — canonical checklist (always):
|
|
57
57
|
Read `~/.agents/hooks/anti-slop.md` and apply ALL 13 items to every hunk you
|
|
58
58
|
changed this session. That file is the single source of truth for slop
|
|
59
|
-
detection —
|
|
60
|
-
|
|
61
|
-
surface. Fix every hit; consolidate clones to one source of truth.
|
|
59
|
+
detection — it is NOT repeated here. Fix every hit; consolidate clones to one
|
|
60
|
+
source of truth.
|
|
62
61
|
|
|
63
62
|
Step C — session footprint (also in the header above):
|
|
64
63
|
If "Session footprint" shows >5 files or the request was simple, justify each
|
|
65
64
|
file or trim. Unjustified files are slop.
|
|
66
65
|
|
|
67
|
-
Step D — declared scope (closing gate for Compuerta 1):
|
|
68
|
-
If `.scope.json` exists in the repo root, run the session's full diff against
|
|
69
|
-
the declared contract. In your shell:
|
|
70
|
-
for f in $(git diff --name-only HEAD); do
|
|
71
|
-
python ~/.cursor/skills/anti-slop/scripts/scope_match.py --path "$f" --patterns-file .scope.json
|
|
72
|
-
done
|
|
73
|
-
Any file reporting `"in_scope": false` is a scope violation you must justify
|
|
74
|
-
(add to .scope.json with a one-line reason) or revert. If `.scope.json` does
|
|
75
|
-
not exist, this step is skipped — the declared-editing ladder and the
|
|
76
|
-
per-edit scope-gate-audit hook are the opt-in discipline.
|
|
77
|
-
|
|
78
66
|
Fix with edits now; re-run the scan (if Step A ran) and the tests; then stop.
|
|
67
|
+
(The per-edit `scope-gate-audit` hook already checks `.scope.json` files[] on
|
|
68
|
+
every edit — Step D of older versions ran that loop again here. Removed: it
|
|
69
|
+
duplicated the live hook and burned tokens. If `.scope.json` exists, trust the
|
|
70
|
+
per-edit gate; the intent trace in axis 0 is the whole-session backstop.)
|
|
79
71
|
|
|
80
72
|
## 5. Wiring completeness
|
|
81
73
|
For every user-visible behavior you added or changed (button, form submit, API
|
|
@@ -97,3 +89,38 @@ faked, either wire it now or remove the dead half so the diff does not ship
|
|
|
97
89
|
scaffolding that looks complete but does nothing. Stubs you intend to wire later
|
|
98
90
|
must be marked with a `TODO(wire):` comment naming what is missing; unmarked
|
|
99
91
|
dead ends are failures.
|
|
92
|
+
|
|
93
|
+
## 6. Mechanics & Stack Integrity
|
|
94
|
+
Stateless, cheap mechanical checks. These are patterns the regex scanner CANNOT
|
|
95
|
+
catch (they need semantic/transversal judgement), so do them by reading the
|
|
96
|
+
diff. If a pattern below is present, FIX it — do not explain, delete and write
|
|
97
|
+
the correct pattern.
|
|
98
|
+
|
|
99
|
+
Backend / DB:
|
|
100
|
+
- N+1 query: a query/fetch inside a loop over a list -> batch it or join.
|
|
101
|
+
- Non-idempotent mutation: a POST/PUT that double-applies on retry -> make it
|
|
102
|
+
idempotent (idempotency-key) or wrap in a transaction.
|
|
103
|
+
- Transactional integrity: multi-write ops (DB/API/files) without rollback or
|
|
104
|
+
a compensating action on partial failure -> wrap in a transaction or Saga.
|
|
105
|
+
- Missing boundary validation: external input (API/params/DB/URL) trusted
|
|
106
|
+
without a schema (Zod/Pydantic/Joi) -> validate at the boundary; never
|
|
107
|
+
hand-validate deeper in the logic.
|
|
108
|
+
|
|
109
|
+
Frontend (React / Next / Astro / Tailwind):
|
|
110
|
+
- Zombie listener: a useEffect that adds a listener/subscription/timer
|
|
111
|
+
without a cleanup `return` -> add it.
|
|
112
|
+
- God component: a single file doing fetch + state + business logic + JSX
|
|
113
|
+
(>150 lines) -> split hooks / logic / render.
|
|
114
|
+
- Tailwind soup & magic tokens: a className with >~6 utilities repeated across
|
|
115
|
+
elements, or hardcoded hex / z-[9999] -> extract to a component or cva,
|
|
116
|
+
use design tokens.
|
|
117
|
+
- Index-as-key in non-static lists -> use a unique id.
|
|
118
|
+
|
|
119
|
+
Determinism / purity:
|
|
120
|
+
- Date.now(), Math.random(), process.env read inline in business logic ->
|
|
121
|
+
inject them (param or a context module) so the function is pure & testable.
|
|
122
|
+
- In-place mutation of shared state (arr.push, obj.prop =) when a caller holds
|
|
123
|
+
a reference -> return new structures ([...arr, x], .map/.filter).
|
|
124
|
+
|
|
125
|
+
You do NOT need to run a tool for these — read the diff and apply the named fix.
|
|
126
|
+
If none apply, say so in one line.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# final-review.sh - stop hook (Cursor, Linux).
|
|
3
3
|
#
|
|
4
|
-
# ONE comprehensive end-of-implementation review across
|
|
5
|
-
# intent, correctness, reliability, coverage, anti-slop,
|
|
4
|
+
# ONE comprehensive end-of-implementation review across seven axes:
|
|
5
|
+
# intent, correctness, reliability, coverage, anti-slop, wiring completeness,
|
|
6
|
+
# and mechanics & stack integrity. When the agent finishes
|
|
6
7
|
# an implementation that touched files, Cursor auto-submits this hook's
|
|
7
8
|
# `followup_message` as the next user turn, so the model re-audits everything
|
|
8
9
|
# it changed this session and FIXES what fails.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Counterpart of final-review.sh for delegated work. afterFileEdit DOES fire
|
|
5
5
|
# inside subagents (verified: a subagent run left its edits in
|
|
6
6
|
# session-edits-<subagent-cid>.txt), but subagents get no `stop` event, so
|
|
7
|
-
# that marker is never drained and the
|
|
7
|
+
# that marker is never drained and the seven-axis review never fires for
|
|
8
8
|
# delegated implementations. This hook closes the loop: when a subagent
|
|
9
9
|
# finishes and ITS conversation has a session-edits marker, return ONE
|
|
10
10
|
# followup_message so the subagent audits its own implementation before the
|
|
@@ -76,7 +76,7 @@ body=""
|
|
|
76
76
|
[ -f "$prompt_file" ] && body="$(cat "$prompt_file")"
|
|
77
77
|
if [ -z "$body" ]; then
|
|
78
78
|
body='Audit everything you changed in this run and FIX what fails (do NOT revert the
|
|
79
|
-
behaviour the task asked for).
|
|
79
|
+
behaviour the task asked for). Seven axes, in order:
|
|
80
80
|
0. Intent trace - tie every diff hunk back to your original task. Untraceable = hallucinated.
|
|
81
81
|
1. Correctness - logic, edge cases (null/empty/zero/boundary), language traps, security.
|
|
82
82
|
2. Reliability - error paths handled, no swallowed errors, resources released.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursordoctrine",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Thin self-review hooks for Cursor — the model is the auditor. Pruned + deduplicated: intent-anchor (auto-scaffolded .scope.json per prompt + per-turn re-injection against Salience Dilution), intent-trace final review, unified anti-slop checklist as single source of truth.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cursordoctrine": "bin/cli.mjs"
|
|
@@ -228,7 +228,7 @@ The `stop` hook (`~/.agents/hooks/final-review.ps1` on Windows,
|
|
|
228
228
|
`~/.agents/hooks/final-review.sh` on Linux) fires after the agent finishes an
|
|
229
229
|
implementation that edited files. It extracts the last `<user_query>` from the
|
|
230
230
|
session transcript (Tier 0 intent trace), reports session footprint (Tier 5),
|
|
231
|
-
and auto-submits a `followup_message` so the model audits
|
|
231
|
+
and auto-submits a `followup_message` so the model audits seven axes: intent,
|
|
232
232
|
correctness, reliability, coverage, anti-slop, wiring completeness. Axis 4 delegates to this skill's
|
|
233
233
|
scanner (`scan_slop.py --all`) and the canonical checklist at
|
|
234
234
|
`~/.agents/hooks/anti-slop.md` (13 items, including semantic contracts,
|
|
@@ -276,6 +276,6 @@ low-density identifiers per edit — shares `low_density.py` with this scanner's
|
|
|
276
276
|
(`scope-gate-audit.ps1` / `.sh`, Compuerta 1 — opt-in declared-scope gate
|
|
277
277
|
that flags edits outside `.scope.json`; shares `scope_match.py` with the
|
|
278
278
|
**stop hook** (`final-review.ps1` / `.sh`,
|
|
279
|
-
|
|
279
|
+
seven-axis session review incl. intent trace, wiring completeness, and mechanics & stack integrity), and
|
|
280
280
|
**declared-editing** (YAGNI ultra ladder injected at session start).
|
|
281
281
|
This skill is the active "delete it now" layer those only nudge toward.
|
|
@@ -89,3 +89,38 @@ faked, either wire it now or remove the dead half so the diff does not ship
|
|
|
89
89
|
scaffolding that looks complete but does nothing. Stubs you intend to wire later
|
|
90
90
|
must be marked with a `TODO(wire):` comment naming what is missing; unmarked
|
|
91
91
|
dead ends are failures.
|
|
92
|
+
|
|
93
|
+
## 6. Mechanics & Stack Integrity
|
|
94
|
+
Stateless, cheap mechanical checks. These are patterns the regex scanner CANNOT
|
|
95
|
+
catch (they need semantic/transversal judgement), so do them by reading the
|
|
96
|
+
diff. If a pattern below is present, FIX it — do not explain, delete and write
|
|
97
|
+
the correct pattern.
|
|
98
|
+
|
|
99
|
+
Backend / DB:
|
|
100
|
+
- N+1 query: a query/fetch inside a loop over a list -> batch it or join.
|
|
101
|
+
- Non-idempotent mutation: a POST/PUT that double-applies on retry -> make it
|
|
102
|
+
idempotent (idempotency-key) or wrap in a transaction.
|
|
103
|
+
- Transactional integrity: multi-write ops (DB/API/files) without rollback or
|
|
104
|
+
a compensating action on partial failure -> wrap in a transaction or Saga.
|
|
105
|
+
- Missing boundary validation: external input (API/params/DB/URL) trusted
|
|
106
|
+
without a schema (Zod/Pydantic/Joi) -> validate at the boundary; never
|
|
107
|
+
hand-validate deeper in the logic.
|
|
108
|
+
|
|
109
|
+
Frontend (React / Next / Astro / Tailwind):
|
|
110
|
+
- Zombie listener: a useEffect that adds a listener/subscription/timer
|
|
111
|
+
without a cleanup `return` -> add it.
|
|
112
|
+
- God component: a single file doing fetch + state + business logic + JSX
|
|
113
|
+
(>150 lines) -> split hooks / logic / render.
|
|
114
|
+
- Tailwind soup & magic tokens: a className with >~6 utilities repeated across
|
|
115
|
+
elements, or hardcoded hex / z-[9999] -> extract to a component or cva,
|
|
116
|
+
use design tokens.
|
|
117
|
+
- Index-as-key in non-static lists -> use a unique id.
|
|
118
|
+
|
|
119
|
+
Determinism / purity:
|
|
120
|
+
- Date.now(), Math.random(), process.env read inline in business logic ->
|
|
121
|
+
inject them (param or a context module) so the function is pure & testable.
|
|
122
|
+
- In-place mutation of shared state (arr.push, obj.prop =) when a caller holds
|
|
123
|
+
a reference -> return new structures ([...arr, x], .map/.filter).
|
|
124
|
+
|
|
125
|
+
You do NOT need to run a tool for these — read the diff and apply the named fix.
|
|
126
|
+
If none apply, say so in one line.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# final-review.ps1 - stop hook (Cursor).
|
|
2
2
|
#
|
|
3
|
-
# ONE comprehensive end-of-implementation review across
|
|
4
|
-
# intent, correctness, reliability, coverage, anti-slop,
|
|
3
|
+
# ONE comprehensive end-of-implementation review across seven axes:
|
|
4
|
+
# intent, correctness, reliability, coverage, anti-slop, wiring completeness,
|
|
5
|
+
# and mechanics & stack integrity. When the agent finishes an
|
|
5
6
|
# implementation that touched files, Cursor auto-submits this hook's
|
|
6
7
|
# `followup_message` as the next user turn, so the model re-audits everything it
|
|
7
8
|
# changed this session and FIXES what fails - the model-as-auditor pattern over
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Counterpart of final-review.ps1 for delegated work. afterFileEdit DOES fire
|
|
4
4
|
# inside subagents (verified: a poteto subagent run left ~58 entries in
|
|
5
5
|
# session-edits-<subagent-cid>.txt), but subagents get no `stop` event, so
|
|
6
|
-
# that marker is never drained and the
|
|
6
|
+
# that marker is never drained and the seven-axis review never fires for
|
|
7
7
|
# delegated implementations. This hook closes the loop: when a subagent
|
|
8
8
|
# finishes and ITS conversation has a session-edits marker, return ONE
|
|
9
9
|
# followup_message so the subagent audits its own implementation before the
|
|
@@ -76,7 +76,7 @@ if (Test-Path $promptFile) { $body = Get-Content -Raw $promptFile }
|
|
|
76
76
|
if (-not $body) {
|
|
77
77
|
$body = @'
|
|
78
78
|
Audit everything you changed in this run and FIX what fails (do NOT revert the
|
|
79
|
-
behaviour the task asked for).
|
|
79
|
+
behaviour the task asked for). Seven axes, in order:
|
|
80
80
|
0. Intent trace - tie every diff hunk back to your original task. Untraceable = hallucinated.
|
|
81
81
|
1. Correctness - logic, edge cases (null/empty/zero/boundary), language traps, security.
|
|
82
82
|
2. Reliability - error paths handled, no swallowed errors, resources released.
|