agent-quality-kit 0.8.0 → 0.10.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/README.md +154 -12
- package/README.ru.md +185 -27
- package/kit/docs/ai/index.md +1 -0
- package/kit/docs/ai/project-baseline.md +14 -0
- package/kit/docs/api-e2e.md +214 -0
- package/kit/docs/ready-made-rules.md +188 -0
- package/kit/gates/README.md +22 -0
- package/kit/gates/api-contract-has-arbiter/README.md +63 -0
- package/kit/gates/api-contract-has-arbiter/check.sh +117 -0
- package/kit/gates/api-contract-has-arbiter/gate.yml +15 -0
- package/kit/gates/api-contract-has-arbiter/green/.github/workflows/ci.yml +12 -0
- package/kit/gates/api-contract-has-arbiter/green/openapi.yaml +18 -0
- package/kit/gates/api-contract-has-arbiter/red/.github/workflows/ci.yml +11 -0
- package/kit/gates/api-contract-has-arbiter/red/openapi.yaml +18 -0
- package/kit/gates/ci-actually-fails/check.sh +9 -1
- package/kit/gates/color-from-token/check.sh +5 -1
- package/kit/gates/commit-explains-itself/check.sh +15 -0
- package/kit/gates/complexity-limit/red/deep.go +17 -0
- package/kit/gates/complexity-limit/red/deep.rs +17 -0
- package/kit/gates/gate-not-weakened/red/suppress.go +5 -0
- package/kit/gates/gate-not-weakened/red/suppress.rs +3 -0
- package/kit/gates/lesson-has-outcome/check.sh +5 -1
- package/kit/gates/mcp-server-resolves/README.md +62 -0
- package/kit/gates/mcp-server-resolves/check.sh +110 -0
- package/kit/gates/mcp-server-resolves/gate.yml +18 -0
- package/kit/gates/mcp-server-resolves/green/.mcp.json +20 -0
- package/kit/gates/mcp-server-resolves/red/.mcp.json +16 -0
- package/kit/gates/protection-not-removed/README.md +67 -0
- package/kit/gates/protection-not-removed/check.sh +92 -0
- package/kit/gates/protection-not-removed/gate.yml +10 -0
- package/kit/gates/protection-not-removed/green/.aqk.yml +7 -0
- package/kit/gates/protection-not-removed/green/gates-declared.txt +4 -0
- package/kit/gates/protection-not-removed/red/.aqk.yml +7 -0
- package/kit/gates/protection-not-removed/red/gates-declared.txt +4 -0
- package/kit/gates/secrets-not-in-code/red/leak.go +9 -0
- package/kit/gates/secrets-not-in-code/red/leak.rs +5 -0
- package/kit/gates/todo-without-task/red/later.go +6 -0
- package/kit/gates/todo-without-task/red/later.rs +4 -0
- package/llms.txt +25 -4
- package/package.json +3 -6
- package/tool/commands/context.mjs +37 -6
- package/tool/commands/doctor.mjs +139 -16
- package/tool/commands/probe.mjs +228 -0
- package/tool/commands/project.mjs +18 -2
- package/tool/commands/prove.mjs +1 -0
- package/tool/commands/vitals.mjs +167 -0
- package/tool/i18n/en-docs.mjs +48 -0
- package/tool/i18n/en-gates.mjs +309 -0
- package/tool/i18n/en.mjs +26 -279
- package/tool/i18n/index.mjs +36 -3
- package/tool/i18n/ru-docs.mjs +48 -0
- package/tool/i18n/ru-gates.mjs +311 -0
- package/tool/i18n/ru.mjs +26 -278
- package/tool/lib/banner.mjs +59 -0
- package/tool/lib/brief.mjs +192 -0
- package/tool/lib/cadence.mjs +57 -0
- package/tool/lib/core.mjs +3 -0
- package/tool/lib/history.mjs +82 -0
- package/tool/lib/manifest.mjs +146 -15
- package/tool/lib/prove.mjs +11 -1
- package/tool/lib/repo.mjs +43 -3
- package/tool/program.mjs +33 -0
- package/tool/selfcheck/smoke/_fixture.mjs +89 -0
- package/tool/selfcheck/smoke/api-contract.test.mjs +79 -0
- package/tool/selfcheck/smoke/commit-report.test.mjs +47 -0
- package/tool/selfcheck/smoke/verdict.test.mjs +40 -0
- package/tool/selfcheck/smoke.sh +528 -6
- package/tool/selfcheck/units-banner.mjs +65 -0
- package/tool/selfcheck/units-brief.mjs +97 -0
- package/tool/selfcheck/units-cadence.mjs +69 -0
- package/tool/selfcheck/units-context.mjs +3 -1
- package/tool/selfcheck/units-level.mjs +147 -1
- package/tool/selfcheck/units-probe.mjs +100 -0
- package/tool/selfcheck/units-repo.mjs +164 -0
- package/tool/selfcheck/units-vitals.mjs +81 -0
- package/tool/selfcheck/units.mjs +3 -75
package/README.md
CHANGED
|
@@ -22,6 +22,12 @@ npx agent-quality-kit start # no code yet: day-zero guards, right away
|
|
|
22
22
|
`doctor` only reads. It writes no file and sends nothing anywhere — safe to point at a repository
|
|
23
23
|
you have decided nothing about yet. Nothing to install: `npx` fetches the package (230 KB).
|
|
24
24
|
|
|
25
|
+
The one exception, named here because it is the only one: with `--brief` (how the hooks run it)
|
|
26
|
+
`doctor` asks the npm registry for its own latest version — **at most once a day, never in CI**,
|
|
27
|
+
with a 3-second timeout, silent on any failure, and never affecting the exit code. Turn it off
|
|
28
|
+
with `AQK_UPDATE=0`. There is no auto-update: a tool that silently replaces itself while
|
|
29
|
+
standing on the commit gate is exactly the door this kit teaches you to close.
|
|
30
|
+
|
|
25
31
|
### Works with any agent, any language
|
|
26
32
|
|
|
27
33
|
**Any agent.** Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Windsurf, Aider, OpenCode
|
|
@@ -81,6 +87,8 @@ aqk why <name> what failure this guard was written for
|
|
|
81
87
|
|
|
82
88
|
aqk prove run every declared gate against its own samples:
|
|
83
89
|
red on the red one, quiet on the green one
|
|
90
|
+
aqk probe what the declared checks CANNOT see: plant a defect
|
|
91
|
+
into files the fix history calls hot
|
|
84
92
|
aqk report the report form, assembled by a run
|
|
85
93
|
aqk report --since main ...plus what proves this diff, file by file
|
|
86
94
|
aqk badge write the level badge into the README
|
|
@@ -88,6 +96,8 @@ aqk badge --check fail if the badge disagrees with a run
|
|
|
88
96
|
|
|
89
97
|
aqk context the repository state in one block, for an agent's context:
|
|
90
98
|
level, what is red now, rules nobody enforces, ratchets
|
|
99
|
+
aqk vitals is what the kit runs on wired up: gate tools, hooks, freshness
|
|
100
|
+
aqk doctor --run --brief one line on success, the whole run on failure — for hooks
|
|
91
101
|
aqk context --full the same plus the command map and the rulebook verbatim (~7000
|
|
92
102
|
tokens against ~375: the price of an agent that does not guess)
|
|
93
103
|
aqk context --install put a SessionStart hook into .claude/settings.json
|
|
@@ -166,11 +176,15 @@ aqk: 1
|
|
|
166
176
|
entry: [AGENTS.md] # what the agent reads first
|
|
167
177
|
rules: .aqk/rules # where the standards live
|
|
168
178
|
docs: .aqk/docs # where the guides live (optional; this is the default)
|
|
179
|
+
lang: en # output language for THIS repo, over the machine locale
|
|
169
180
|
gates: # what must pass — as commands, not as prose
|
|
170
181
|
lint: "npm run lint"
|
|
171
182
|
secrets-not-in-code: "bash gates/secrets-not-in-code/check.sh ."
|
|
183
|
+
covers: # what a declared gate already holds — not counted as debt
|
|
184
|
+
lint: [no-print-in-prod, swallowed-error]
|
|
172
185
|
samples: gates # a red and a green sample for every entry
|
|
173
186
|
ratchets: ratchets # debt registries: the list may only get shorter
|
|
187
|
+
probe: 100 # run the probe itself every N commits; 0 turns it off
|
|
174
188
|
lessons: incidents # where lessons accumulate
|
|
175
189
|
```
|
|
176
190
|
|
|
@@ -220,6 +234,93 @@ A hundred working checks with no manifest is AQK-0, and that is honest: nothing
|
|
|
220
234
|
aqk doctor --run --min 1 # in CI: fails below AQK-1 OR if any gate failed
|
|
221
235
|
```
|
|
222
236
|
|
|
237
|
+
### How a gate is proven — what `prove` actually does
|
|
238
|
+
|
|
239
|
+
Level AQK-2 and the badge rest on one command, so here it is in full: the first outside user
|
|
240
|
+
tripped over it three times, and all three times this page was to blame.
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
aqk prove
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
For every gate in `gates:` its samples are taken — `<samples>/<name>/red` and `/green` — and the
|
|
247
|
+
gate is run against each. **The directory is substituted for the LAST word of the command:**
|
|
248
|
+
catalogue recipes are written as `… {dir}`, and on install `{dir}` becomes `.`. Wrappers are
|
|
249
|
+
stripped first: `ratchet.sh` (otherwise the debt registry is rewritten with findings from the
|
|
250
|
+
sample) and `_native.sh` (otherwise the filter hides exactly what the sample must show).
|
|
251
|
+
|
|
252
|
+
Each entry gets one of three verdicts:
|
|
253
|
+
|
|
254
|
+
| Verdict | What it means |
|
|
255
|
+
|---|---|
|
|
256
|
+
| **proven** | exit ≠ 0 on `red/` and exit 0 on `green/` |
|
|
257
|
+
| **does not catch** | stayed quiet on the red one, or went red on the green one |
|
|
258
|
+
| **nothing to prove with** | four different reasons, and each is named out loud |
|
|
259
|
+
|
|
260
|
+
The four reasons: no samples · samples written for another recipe (`samples_for`) while a
|
|
261
|
+
different one is installed · the command does not end in a directory, so it was written by hand
|
|
262
|
+
and there is nowhere to substitute · **the program named in `requires:` is not on the machine.**
|
|
263
|
+
|
|
264
|
+
That last reason was added 2026-09-09 and deserves a word. A portable recipe is sometimes a
|
|
265
|
+
wrapper around a ready-made tool: the first word of the command is then `bash`, and nothing in it
|
|
266
|
+
shows what is missing. Without the program the wrapper goes red on **both** samples — and `prove`
|
|
267
|
+
declared a working gate broken, taking a level away from a project because somebody else's tool
|
|
268
|
+
was not installed. An accusation instead of a diagnosis; the same class as the Windows paths.
|
|
269
|
+
|
|
270
|
+
The level is granted when **no provable gate is broken AND at least one is proven**. The second
|
|
271
|
+
condition is not optional: a project where everything is unprovable has proven nothing — that is
|
|
272
|
+
exactly what the forgery with three `true` gates looks like.
|
|
273
|
+
|
|
274
|
+
### What your checks cannot see — `probe`
|
|
275
|
+
|
|
276
|
+
`doctor` says "held by a machine 21". **Twenty-one out of what?** There is no denominator: 21 is
|
|
277
|
+
what we happened to write into the catalogue, not what matters in your project. `prove` shows a
|
|
278
|
+
gate catches a defect **on its own** sample. Neither answers the owner's question: what here is
|
|
279
|
+
covered by nothing.
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
aqk probe
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Two sources, both facts rather than our taste: **your repository's history** (where defects come
|
|
286
|
+
back — fix commits) and the **red samples of the catalogue** (each one proven by a run). The
|
|
287
|
+
sample is placed in a temporary directory at the hot file's path, and **your declared** gates are
|
|
288
|
+
run against it.
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
src/mailer.py fixes in history: 3
|
|
292
|
+
✘ keys and passwords do not end up in the code NOTHING CATCHES IT
|
|
293
|
+
close it: aqk add secrets-not-in-code
|
|
294
|
+
✘ an error is not silently swallowed NOTHING CATCHES IT
|
|
295
|
+
close it: aqk add swallowed-error
|
|
296
|
+
✔ no "fix later" markers in finished code caught by: todo-without-task
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Coverage is not declared, it is proven by planting.** This is the kit's own principle turned on
|
|
300
|
+
the whole repository: a check that cannot go red is indistinguishable from an absent one. We
|
|
301
|
+
demand that of every catalogue entry — and until `probe` never demanded it of a project.
|
|
302
|
+
|
|
303
|
+
The measurement the command grew from, taken on the kit itself: a real source file, a swallowed
|
|
304
|
+
error and a debug print planted into a copy, 21 declared gates. **Red: none.**
|
|
305
|
+
|
|
306
|
+
Three states, and they do not merge: caught · **nothing catches it** · nothing to check with (the
|
|
307
|
+
gate did not run, or the catalogue has no sample for that extension). The working tree is not
|
|
308
|
+
touched and the exit code is always 0 — this is a look, not a threshold.
|
|
309
|
+
|
|
310
|
+
**The command does not need to be remembered — that is half the design.** Once every hundred
|
|
311
|
+
commits — or whatever `probe:` in the manifest says, `0` turning it off — `doctor --run` runs the
|
|
312
|
+
probe **itself**, unprompted. A command you have to remember is
|
|
313
|
+
the same class as a file you can fail to read: the agent will not recall it, and the human will
|
|
314
|
+
never learn it exists. The unit is commits, not days: a repository nobody touched for a month
|
|
315
|
+
needs no re-probe, a hundred commits in a day does. Turn it off with `AQK_PROBE=0`.
|
|
316
|
+
|
|
317
|
+
The result also lands in the state block the agent reads by construction, without knowing the
|
|
318
|
+
command. If no probe has ever run, it says **UNKNOWN** rather than staying silent: silence would
|
|
319
|
+
read as "everything is covered".
|
|
320
|
+
|
|
321
|
+
Your code is not touched — the sample lives in a temporary directory. The probe's own mark goes
|
|
322
|
+
to `.aqk/last-probe.md`, next to the run report; it is ephemeral, keep it in your `.gitignore`.
|
|
323
|
+
|
|
223
324
|
## The badge
|
|
224
325
|
|
|
225
326
|
```bash
|
|
@@ -239,7 +340,7 @@ Already using [pre-commit](https://pre-commit.com)? Three lines in the file you
|
|
|
239
340
|
```yaml
|
|
240
341
|
repos:
|
|
241
342
|
- repo: https://github.com/arsen-ask-lx/Agent_Quality_Kit
|
|
242
|
-
rev: v0.
|
|
343
|
+
rev: v0.10.0
|
|
243
344
|
hooks:
|
|
244
345
|
- id: aqk # runs what the repository declares; blocks below AQK-1
|
|
245
346
|
# - id: aqk-doctor # read-only: the level and what is missing, blocks nothing
|
|
@@ -260,7 +361,7 @@ layer AQK adds.
|
|
|
260
361
|
[](https://github.com/marketplace/actions/agent-quality-kit-aqk)
|
|
261
362
|
|
|
262
363
|
```yaml
|
|
263
|
-
- uses: arsen-ask-lx/Agent_Quality_Kit@v0.
|
|
364
|
+
- uses: arsen-ask-lx/Agent_Quality_Kit@v0.10.0
|
|
264
365
|
with:
|
|
265
366
|
min: 1 # the build fails below AQK-1, or if any declared gate failed
|
|
266
367
|
```
|
|
@@ -272,6 +373,26 @@ the same thing in a single line:
|
|
|
272
373
|
- run: npx agent-quality-kit doctor --run --min 1
|
|
273
374
|
```
|
|
274
375
|
|
|
376
|
+
## Without Node at all
|
|
377
|
+
|
|
378
|
+
A Python, Go or Rust project where nobody installed Node and nobody will:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/work" ghcr.io/arsen-ask-lx/aqk doctor
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
The image is pushed to the registry by the same run, from the same tag, that publishes the
|
|
385
|
+
package — there is nothing to build. You can still build it yourself: `docker build -t aqk .`
|
|
386
|
+
from this repository.
|
|
387
|
+
|
|
388
|
+
**The `--user` flag is not decoration.** Without it the container runs as root and the files
|
|
389
|
+
`init` writes end up owned by root — you cannot edit your own manifest. Measured 2026-09-09:
|
|
390
|
+
`.aqk.yml` and `AGENTS.md` came out `root:root`.
|
|
391
|
+
|
|
392
|
+
Debian-slim on purpose, not alpine: the gates are `sh`, `grep`, `awk`, `find`, and in alpine
|
|
393
|
+
those are busybox, whose `awk` differs. An image where the gates behave differently from the
|
|
394
|
+
machine the person is on is worse than no image: it hands out a green that means nothing.
|
|
395
|
+
|
|
275
396
|
## Installing a gate
|
|
276
397
|
|
|
277
398
|
```bash
|
|
@@ -316,8 +437,17 @@ advisory:
|
|
|
316
437
|
|
|
317
438
|
Declared in the manifest, not passed as a flag. A flag that says "fail nothing" downgrades every
|
|
318
439
|
check at once, is invisible in the diff, and is never named in the summary — that is
|
|
319
|
-
`continue-on-error`, which this tool marks red elsewhere.
|
|
320
|
-
|
|
440
|
+
`continue-on-error`, which this tool marks red elsewhere.
|
|
441
|
+
|
|
442
|
+
**An advisory gate is marked on EVERY run, including when it is green:**
|
|
443
|
+
|
|
444
|
+
```
|
|
445
|
+
✔ complexity-limit (advisory — cannot fail the run) 0.4s · …
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Otherwise a gate that cannot fail the build looks exactly like one that can, and you learn what
|
|
449
|
+
is in `advisory:` only on the day it goes red. Red ones are additionally named by name in the
|
|
450
|
+
summary: an advisory gate everyone forgot about is a switched-off check.
|
|
321
451
|
|
|
322
452
|
## When a bug slips past the guards
|
|
323
453
|
|
|
@@ -365,10 +495,10 @@ catalogue may grow to hundreds of entries; a given project still sees about a do
|
|
|
365
495
|
An entry is accepted only if its arbiter goes red on the red sample, stays quiet on the green
|
|
366
496
|
one, and names a real failure it caught. A machine checks this: `bash tool/selfcheck/gates.sh`.
|
|
367
497
|
|
|
368
|
-
###
|
|
498
|
+
### Five entries that watch the agent, not the code
|
|
369
499
|
|
|
370
500
|
Ruff, ESLint and gitleaks already find bad code, and AQK calls them where it can rather than
|
|
371
|
-
reinventing them. These
|
|
501
|
+
reinventing them. These five look elsewhere — at the moment the **signal** about bad code is
|
|
372
502
|
switched off, which is what a coding agent does when the task is phrased as "make it pass":
|
|
373
503
|
|
|
374
504
|
| Entry | What it catches |
|
|
@@ -377,8 +507,15 @@ switched off, which is what a coding agent does when the task is phrased as "mak
|
|
|
377
507
|
| `ci-actually-fails` | a pipeline step that renders a verdict but cannot fail — `run: pytest \|\| true`, `continue-on-error: true` |
|
|
378
508
|
| `test-has-assertion` | a test that cannot fail: empty body, `assert True`, a skip with no reason given |
|
|
379
509
|
| `promise-has-gate` | a rule in `AGENTS.md` with no enforcer named — neither a gate nor, honestly, a human |
|
|
510
|
+
| `protection-not-removed` | **the instrument itself was switched off**: a gate vanished from the manifest. The declared set may only grow; removing one is allowed, but must be named |
|
|
380
511
|
|
|
381
|
-
|
|
512
|
+
The fifth was added later, and from a bruise of our own. The first four catch the agent switching
|
|
513
|
+
off a **signal**. The master switch — the manifest itself — was guarded by nothing: a measurement
|
|
514
|
+
on 2026-09-09 showed that deleting one line from `.aqk.yml` turns the run green while a real
|
|
515
|
+
secret sits in the code, and neither `doctor`, `report --since`, `vitals` nor the state block the
|
|
516
|
+
agent reads noticed anything.
|
|
517
|
+
|
|
518
|
+
The first four were measured on nineteen third-party repositories (~25 000 files) before entering the
|
|
382
519
|
catalogue, and two further entries were **cancelled by that measurement**: one because
|
|
383
520
|
[`agents-lint`](https://github.com/giacomo/agents-lint) already does it better, one because
|
|
384
521
|
91 of its 120 findings turned out to be a legitimate pattern.
|
|
@@ -412,8 +549,13 @@ scenarios, the success criterion, and what is left.
|
|
|
412
549
|
|
|
413
550
|
Version 1, one author. The kit holds **AQK-3** on itself: everything declared is executed by CI
|
|
414
551
|
on every push, two debt registries under a ratchet — `node tool/program.mjs doctor --run --min 1`.
|
|
415
|
-
|
|
416
|
-
|
|
552
|
+
|
|
553
|
+
**The first outside user arrived on 2026-09-08** — ran the kit on their own project (28 gates,
|
|
554
|
+
AQK-1) and sent back a review. That review found two defects ninety-odd checks of our own had
|
|
555
|
+
missed: both live only on Windows, or only on somebody else's directory layout (bruise journal,
|
|
556
|
+
entry of 2026-09-08). That is exactly what an outsider is for — but it is one review, not settled
|
|
557
|
+
use. Until somebody comes back to the tool a second time, the standard is unproven on foreign
|
|
558
|
+
projects.
|
|
417
559
|
|
|
418
560
|
**A standard cannot be shipped first.** A specification ahead of practice is the thirty-first
|
|
419
561
|
abandoned repository with a manifest and zero users. The order is the other way round:
|
|
@@ -423,7 +565,7 @@ abandoned repository with a manifest and zero users. The order is the other way
|
|
|
423
565
|
| 1 | live by this on our own projects | ⬜ measured: three of our own projects have no manifest |
|
|
424
566
|
| 2 | `doctor` computes the level | ✅ done |
|
|
425
567
|
| 3 | what settled is written up as a short spec | ✅ [`SPEC.md`](SPEC.md) |
|
|
426
|
-
| 4 | a third project — **someone else's** |
|
|
568
|
+
| 4 | a third project — **someone else's** | 🟡 one outside run and review, 2026-09-08; no repeat use yet |
|
|
427
569
|
| 5 | badge, site, talking to people | ❌ only after step four |
|
|
428
570
|
|
|
429
571
|
## The work queue
|
|
@@ -431,7 +573,7 @@ abandoned repository with a manifest and zero users. The order is the other way
|
|
|
431
573
|
Lives in one place — [`PROJECT.md` §9](PROJECT.md). It is not repeated here: two lists drift
|
|
432
574
|
apart within a month, and then nobody knows which is real.
|
|
433
575
|
|
|
434
|
-
What is missing: a second
|
|
435
|
-
exercised by a clean-folder run, but not individually)
|
|
576
|
+
What is missing: a user who came back a second time; per-command coverage of the commands that
|
|
577
|
+
write to disk (they are exercised by a clean-folder run, but not individually).
|
|
436
578
|
|
|
437
579
|
MIT.
|
package/README.ru.md
CHANGED
|
@@ -23,6 +23,13 @@ npx agent-quality-kit start # кода ещё нет: сторожа дня
|
|
|
23
23
|
направить на репозиторий, о котором ещё ничего не решено. Ставить ничего не нужно, `npx` скачает
|
|
24
24
|
пакет сам (230 КБ).
|
|
25
25
|
|
|
26
|
+
Единственное исключение, и названо оно здесь именно потому, что единственное: с `--brief`
|
|
27
|
+
(так его запускают хуки) `doctor` спрашивает у реестра npm свою последнюю версию — **не чаще
|
|
28
|
+
раза в сутки и никогда в конвейере**, с таймаутом в три секунды, молча при любой ошибке и
|
|
29
|
+
не влияя на код возврата. Выключается `AQK_UPDATE=0`. Автообновления нет: инструмент,
|
|
30
|
+
который молча подменяет себя, стоя на воротах коммита, — ровно та дверь, которую комплект
|
|
31
|
+
учит закрывать.
|
|
32
|
+
|
|
26
33
|
### Работает с любым агентом и любым языком
|
|
27
34
|
|
|
28
35
|
**Любой агент.** Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, Windsurf, Aider,
|
|
@@ -82,6 +89,8 @@ aqk why <имя> какой отказ этот гейт поймал
|
|
|
82
89
|
|
|
83
90
|
aqk prove прогнать каждый объявленный гейт по его образцам:
|
|
84
91
|
красный на красном, тишина на зелёном
|
|
92
|
+
aqk probe чего объявленные проверки НЕ видят: подсадка брака
|
|
93
|
+
в файлы, горячие по истории починок
|
|
85
94
|
aqk report форма отчёта, собранная прогоном
|
|
86
95
|
aqk report --since main ...и чем доказан этот диф, файл за файлом
|
|
87
96
|
aqk badge вписать значок уровня в README
|
|
@@ -89,6 +98,8 @@ aqk badge --check упасть, если значок расходится
|
|
|
89
98
|
|
|
90
99
|
aqk context состояние репозитория одним блоком, для контекста агента:
|
|
91
100
|
уровень, что красное сейчас, правила без арбитра, храповики
|
|
101
|
+
aqk vitals подключено ли то, чем комплект работает: инструменты, хуки, свежесть
|
|
102
|
+
aqk doctor --run --brief одна строка на успехе, весь прогон при провале — для хуков
|
|
92
103
|
aqk context --full то же плюс карта команд и свод правил дословно (≈7000 токенов
|
|
93
104
|
против ≈375 — плата за то, чтобы агент не догадывался)
|
|
94
105
|
aqk context --install поставить хук SessionStart в .claude/settings.json
|
|
@@ -167,11 +178,15 @@ aqk: 1
|
|
|
167
178
|
entry: [AGENTS.md] # что агент читает первым
|
|
168
179
|
rules: .aqk/rules # где стандарты
|
|
169
180
|
docs: .aqk/docs # где методички (необязательно, это и есть умолчание)
|
|
181
|
+
lang: ru # язык вывода для ЭТОГО репозитория, поверх локали машины
|
|
170
182
|
gates: # что обязано пройти — командами, не словами
|
|
171
183
|
lint: "npm run lint"
|
|
172
184
|
secrets-not-in-code: "bash gates/secrets-not-in-code/check.sh ."
|
|
185
|
+
covers: # что уже держит объявленный гейт — в долг не пишется
|
|
186
|
+
lint: [no-print-in-prod, swallowed-error]
|
|
173
187
|
samples: gates # красный и зелёный образец каждой записи
|
|
174
188
|
ratchets: ratchets # реестры долга: список может только укорачиваться
|
|
189
|
+
probe: 100 # раз во столько коммитов проба делается сама; 0 — не делать
|
|
175
190
|
lessons: incidents # где копятся уроки
|
|
176
191
|
```
|
|
177
192
|
|
|
@@ -221,6 +236,93 @@ flowchart LR
|
|
|
221
236
|
aqk doctor --run --min 1 # в конвейере: ошибка, если ниже AQK-1 ИЛИ упал хоть один гейт
|
|
222
237
|
```
|
|
223
238
|
|
|
239
|
+
### Как гейт доказывается — устройство `prove`
|
|
240
|
+
|
|
241
|
+
Ступень AQK-2 и значок держатся на одной команде, поэтому она описана здесь целиком: первый
|
|
242
|
+
чужой пользователь споткнулся об неё трижды, и все три раза виновата была эта страница.
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
aqk prove
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Для каждого гейта из `gates:` берутся его образцы — `<samples>/<имя>/red` и `/green` — и гейт
|
|
249
|
+
запускается по каждому. **Каталог подставляется на место ПОСЛЕДНЕГО слова команды:** рецепты
|
|
250
|
+
каталога пишутся как `… {dir}`, и при установке `{dir}` превращается в `.`. Обёртки снимаются
|
|
251
|
+
заранее: `ratchet.sh` (иначе реестр долга перепишется находками из образца) и `_native.sh`
|
|
252
|
+
(иначе фильтр спрячет ровно то, что образец обязан показать).
|
|
253
|
+
|
|
254
|
+
Вердикт у каждой записи один из трёх:
|
|
255
|
+
|
|
256
|
+
| Вердикт | Что значит |
|
|
257
|
+
|---|---|
|
|
258
|
+
| **доказан** | код ≠ 0 на `red/` и код 0 на `green/` |
|
|
259
|
+
| **не ловит** | промолчал на красном, либо покраснел на зелёном |
|
|
260
|
+
| **доказывать нечем** | и вот здесь четыре разные причины, и они называются вслух |
|
|
261
|
+
|
|
262
|
+
Причин «доказывать нечем» четыре: образцов нет · образцы написаны под другой рецепт
|
|
263
|
+
(`samples_for`), а в проекте стоит не он · команда не кончается каталогом — значит написана
|
|
264
|
+
руками, и подставлять некуда · **программы, названной в `requires:`, нет на машине.**
|
|
265
|
+
|
|
266
|
+
Последняя причина заведена 2026-09-09 и стоит отдельного слова. Переносимый рецепт бывает
|
|
267
|
+
обёрткой вокруг готового инструмента: первое слово команды тогда `bash`, и по нему не видно,
|
|
268
|
+
чего не хватает. Без программы обёртка краснеет на **обоих** образцах — и `prove` объявлял
|
|
269
|
+
исправный гейт сломанным, отбирая у проекта ступень за то, что на машине нет чужого
|
|
270
|
+
инструмента. Обвинение вместо диагноза; ровно тот же класс, что windows-пути.
|
|
271
|
+
|
|
272
|
+
Ступень берётся, когда **ни один доказуемый гейт не сломан И доказан хотя бы один**. Второе
|
|
273
|
+
условие обязательно: проект, у которого все гейты недоказуемы, не доказал ничего — именно так
|
|
274
|
+
выглядит подделка с тремя гейтами `true`.
|
|
275
|
+
|
|
276
|
+
### Чего ваши проверки не видят — `probe`
|
|
277
|
+
|
|
278
|
+
`doctor` говорит «держит машина 21». **Двадцать один из чего?** Знаменателя нет: 21 — это то,
|
|
279
|
+
что мы успели написать в каталог, а не то, что важно в вашем проекте. `prove` доказывает, что
|
|
280
|
+
гейт ловит брак **на своём** образце. Ни один из них не отвечает на вопрос владельца: что здесь
|
|
281
|
+
не прикрыто ничем.
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
aqk probe
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Два источника, и оба — факты, а не наш вкус: **история вашего репозитория** (где брак
|
|
288
|
+
возвращается — коммиты-починки) и **красные образцы каталога** (каждый доказан прогоном).
|
|
289
|
+
Образец кладётся во временный каталог по пути горячего файла, и по нему прогоняются
|
|
290
|
+
**объявленные вами** гейты.
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
src/mailer.py починок в истории: 3
|
|
294
|
+
✘ ключи и пароли не попадают в код НЕ ЛОВИТ НИКТО
|
|
295
|
+
закрыть: aqk add secrets-not-in-code
|
|
296
|
+
✘ ошибка не глушится молча НЕ ЛОВИТ НИКТО
|
|
297
|
+
закрыть: aqk add swallowed-error
|
|
298
|
+
✔ маркеров «доделать потом» нет в готовом коде ловит: todo-without-task
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Покрытие не заявлено, а доказано подсадкой.** Это наш собственный принцип, наведённый на весь
|
|
302
|
+
репозиторий: проверка, которая не может покраснеть, неотличима от отсутствующей. Мы требуем
|
|
303
|
+
этого от каждой записи каталога — и до `probe` ни разу не потребовали от проекта целиком.
|
|
304
|
+
|
|
305
|
+
Замер, с которого команда началась, — на самом комплекте: настоящий файл, подсаженные
|
|
306
|
+
проглоченная ошибка и отладочная печать, 21 объявленный гейт. **Покраснело: ноль.**
|
|
307
|
+
|
|
308
|
+
Три состояния, и они не сливаются: ловит · **не ловит никто** · нечем проверить (гейт не
|
|
309
|
+
состоялся, или в каталоге нет образца под это расширение). Рабочее дерево не трогается, код
|
|
310
|
+
возврата всегда 0 — это осмотр, а не порог.
|
|
311
|
+
|
|
312
|
+
**Команду не нужно помнить — и это половина замысла.** Раз в сто коммитов (`probe:` в манифесте — своё число, `0` — не делать) `doctor --run`
|
|
313
|
+
запускает пробу **сам**, без напоминания. Команда, о которой надо вспомнить, — тот же класс,
|
|
314
|
+
что файл, который можно не прочитать: агент не вспомнит, а человек не узнает, что она есть.
|
|
315
|
+
Единица — коммиты, а не сутки: репозиторий, в котором месяц не работали, перепроверять незачем,
|
|
316
|
+
а сто коммитов за день — надо. Выключается `AQK_PROBE=0`.
|
|
317
|
+
|
|
318
|
+
Результат попадает и в блок состояния для агента: он читает его по построению, не зная про
|
|
319
|
+
команду. Пробы не было — там сказано **НЕИЗВЕСТНО**, а не пропущено: молчание прочиталось бы
|
|
320
|
+
как «всё прикрыто».
|
|
321
|
+
|
|
322
|
+
Ваш код проба не трогает: образец живёт во временном каталоге. Своя отметка ложится в
|
|
323
|
+
`.aqk/last-probe.md` — там же, где отчёт прогона; файл эфемерный, в `.gitignore` его стоит
|
|
324
|
+
держать самому.
|
|
325
|
+
|
|
224
326
|
## Значок
|
|
225
327
|
|
|
226
328
|
```bash
|
|
@@ -241,7 +343,7 @@ aqk badge --check # в конвейере: код 1 в тот день, ког
|
|
|
241
343
|
```yaml
|
|
242
344
|
repos:
|
|
243
345
|
- repo: https://github.com/arsen-ask-lx/Agent_Quality_Kit
|
|
244
|
-
rev: v0.
|
|
346
|
+
rev: v0.10.0
|
|
245
347
|
hooks:
|
|
246
348
|
- id: aqk # запускает объявленное; роняет коммит ниже AQK-1
|
|
247
349
|
# - id: aqk-doctor # только осмотр: уровень и чего не хватает, ничего не роняет
|
|
@@ -260,7 +362,7 @@ repos:
|
|
|
260
362
|
[](https://github.com/marketplace/actions/agent-quality-kit-aqk)
|
|
261
363
|
|
|
262
364
|
```yaml
|
|
263
|
-
- uses: arsen-ask-lx/Agent_Quality_Kit@v0.
|
|
365
|
+
- uses: arsen-ask-lx/Agent_Quality_Kit@v0.10.0
|
|
264
366
|
with:
|
|
265
367
|
min: 1 # сборка падает ниже AQK-1 или если упал любой объявленный гейт
|
|
266
368
|
```
|
|
@@ -272,6 +374,25 @@ repos:
|
|
|
272
374
|
- run: npx agent-quality-kit doctor --run --min 1
|
|
273
375
|
```
|
|
274
376
|
|
|
377
|
+
## Без Node вовсе
|
|
378
|
+
|
|
379
|
+
Проект на Python, Go или Rust, где Node никто не ставил и не поставит:
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/work" ghcr.io/arsen-ask-lx/aqk doctor
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Образ выкладывается в реестр тем же прогоном и из того же тега, что и пакет, — собирать ничего
|
|
386
|
+
не нужно. Собрать у себя тоже можно: `docker build -t aqk .` из этого репозитория.
|
|
387
|
+
|
|
388
|
+
**Ключ `--user` не украшение.** Без него контейнер работает от root, и файлы, которые пишет
|
|
389
|
+
`init`, достаются root — человек не может править собственный манифест. Проверено 2026-09-09:
|
|
390
|
+
`.aqk.yml` и `AGENTS.md` вышли с владельцем `root:root`.
|
|
391
|
+
|
|
392
|
+
Образ на debian-slim намеренно, а не на alpine: гейты — это `sh`, `grep`, `awk`, `find`, а в
|
|
393
|
+
alpine это busybox, и его `awk` другой. Образ, в котором гейты ведут себя не так, как на машине
|
|
394
|
+
человека, хуже отсутствия образа: он даёт зелёное, которое ничего не значит.
|
|
395
|
+
|
|
275
396
|
## Поставить гейт
|
|
276
397
|
|
|
277
398
|
```bash
|
|
@@ -279,13 +400,55 @@ aqk find "печать в проде" # есть ли уже такой ге
|
|
|
279
400
|
aqk doctor # что применимо к этому репозиторию и чего нет
|
|
280
401
|
aqk add secrets-not-in-code # копирует проверку и образцы в проект, объявляет в манифесте
|
|
281
402
|
aqk doctor --run # запускает объявленные гейты и показывает результат
|
|
403
|
+
aqk doctor --run --since main # ...но только то, что внёс диф
|
|
282
404
|
aqk ratchet no-print-in-prod # старое — долг, новое не пускать
|
|
283
405
|
```
|
|
284
406
|
|
|
407
|
+
### Первый прогон на настоящем проекте
|
|
408
|
+
|
|
409
|
+
У сложившегося репозитория за плечами годы долга. Прогони все гейты по всему коду — получишь
|
|
410
|
+
стену красного, которую никто не читает, и инструмент выключат. `--since <ref>` сужает вывод до
|
|
411
|
+
файлов, которых коснулся диф:
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
aqk doctor --run --since main # только то, что внесла эта ветка
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Три исхода, и все три названы вслух. Находки внутри дифа — красный, как обычно. Находки только
|
|
418
|
+
снаружи — зелёный, с числом того, что скрыто, а не молчаливое «всё чисто». А гейт, в выводе
|
|
419
|
+
которого путей нет вовсе (проверка сообщения коммита, проверка конфига конвейера), сузиться
|
|
420
|
+
**не может**: он остаётся красным и говорит почему. Назвать его зелёным потому, что сужать было
|
|
421
|
+
нечего, — ровно та тишина, ради устранения которой этот инструмент и написан.
|
|
422
|
+
|
|
285
423
|
Каждый `doctor --run` перезаписывает `.aqk/last-run.md` — короткий отчёт, что из объявленного
|
|
286
424
|
реально сработало и за сколько. Список гейтов в манифесте молчит о том, сколько из них живы
|
|
287
425
|
именно сейчас; отчёт — нет. Файл эфемерный, в `.gitignore` его стоит держать самому.
|
|
288
426
|
|
|
427
|
+
### Как ввести правило в живой проект
|
|
428
|
+
|
|
429
|
+
Три способа, и у каждого своя цена. Большая чистка откладывается навсегда, потому что она
|
|
430
|
+
большая. Храповик превращает старые нарушения в долг и блокирует новые — верно, когда правило
|
|
431
|
+
уже принято. А пока о правиле спорят, совещательный гейт показывает находки, не роняя прогон:
|
|
432
|
+
|
|
433
|
+
```yaml
|
|
434
|
+
advisory:
|
|
435
|
+
- complexity-limit
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Объявлением в манифесте, а не флагом. Флаг «не роняй ничего» понижает все проверки разом, не
|
|
439
|
+
виден в дифе и не назван в итоге — это тот самый `continue-on-error`, который мы сами красим.
|
|
440
|
+
|
|
441
|
+
**Совещательный помечается в КАЖДОМ прогоне, в том числе когда он зелёный:**
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
✔ complexity-limit (совещательный — уронить прогон не может) 0.4s · …
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
Иначе гейт, который уронить сборку не может, по выводу неотличим от того, который может, и о
|
|
448
|
+
списке `advisory:` человек узнаёт только в день, когда гейт покраснел. Покрасневшие вдобавок
|
|
449
|
+
названы в сводке поимённо: совещательный гейт, о котором забыли, — это выключенная проверка.
|
|
450
|
+
|
|
451
|
+
|
|
289
452
|
## Поймал ошибку, которую не поймал сторож
|
|
290
453
|
|
|
291
454
|
```bash
|
|
@@ -329,10 +492,10 @@ vendor/
|
|
|
329
492
|
Запись принимается, только если её арбитр краснеет на красном образце, молчит на зелёном и
|
|
330
493
|
назван реальный отказ, который она поймала. Проверяет это машина: `bash tool/selfcheck/gates.sh`.
|
|
331
494
|
|
|
332
|
-
###
|
|
495
|
+
### Пять записей, которые смотрят на агента, а не на код
|
|
333
496
|
|
|
334
497
|
Ruff, ESLint и gitleaks и так находят плохой код — AQK зовёт их, где может, вместо того чтобы
|
|
335
|
-
писать своё. Эти
|
|
498
|
+
писать своё. Эти пять смотрят в другое место: на момент, когда **сигнал** о плохом коде
|
|
336
499
|
выключают. Именно это делает агент, когда задача сформулирована как «сделай, чтобы прошло»:
|
|
337
500
|
|
|
338
501
|
| Запись | Что ловит |
|
|
@@ -341,28 +504,18 @@ Ruff, ESLint и gitleaks и так находят плохой код — AQK з
|
|
|
341
504
|
| `ci-actually-fails` | шаг конвейера, который выносит вердикт, но не может провалиться — `run: pytest \|\| true`, `continue-on-error: true` |
|
|
342
505
|
| `test-has-assertion` | тест, который не может провалиться: пустое тело, `assert True`, пропуск без причины |
|
|
343
506
|
| `promise-has-gate` | правило в `AGENTS.md`, у которого не назван сторож — ни гейт, ни, честно, человек |
|
|
507
|
+
| `protection-not-removed` | **сам прибор выключили**: гейт исчез из манифеста. Набор объявленной защиты может только расти; снять можно, но названно |
|
|
344
508
|
|
|
345
|
-
|
|
346
|
-
|
|
509
|
+
Пятая заведена позже остальных и по собственной шишке. Четыре первых ловят агента, когда он
|
|
510
|
+
выключает **сигнал**. А главный рубильник — сам манифест — не сторожил никто: замер 2026-09-09
|
|
511
|
+
показал, что удаление одной строки из `.aqk.yml` даёт зелёный прогон при секрете в коде, и этого
|
|
512
|
+
не заметили ни `doctor`, ни `report`, ни `vitals`, ни блок состояния для агента.
|
|
513
|
+
|
|
514
|
+
Первые четыре измерены на девятнадцати чужих репозиториях (~25 000 файлов) до внесения в каталог,
|
|
515
|
+
и ещё две записи этот же замер **отменил**: одну — потому что
|
|
347
516
|
[`agents-lint`](https://github.com/giacomo/agents-lint) делает это лучше, другую — потому что
|
|
348
517
|
91 находка из 120 оказалась законным приёмом.
|
|
349
518
|
|
|
350
|
-
### Как ввести правило в живой проект
|
|
351
|
-
|
|
352
|
-
Три способа, и у каждого своя цена. Большая чистка откладывается навсегда, потому что она
|
|
353
|
-
большая. Храповик превращает старые нарушения в долг и блокирует новые — верно, когда правило
|
|
354
|
-
уже принято. А пока о правиле спорят, совещательный гейт показывает находки, не роняя прогон:
|
|
355
|
-
|
|
356
|
-
```yaml
|
|
357
|
-
advisory:
|
|
358
|
-
- complexity-limit
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
Объявлением в манифесте, а не флагом. Флаг «не роняй ничего» понижает все проверки разом, не
|
|
362
|
-
виден в дифе и не назван в итоге — это тот самый `continue-on-error`, который мы сами красим.
|
|
363
|
-
Список печатается **каждый** прогон: совещательный гейт, о котором забыли, — это выключенная
|
|
364
|
-
проверка.
|
|
365
|
-
|
|
366
519
|
## Методички одним файлом
|
|
367
520
|
|
|
368
521
|
```bash
|
|
@@ -390,8 +543,13 @@ aqk note "гейт краснел на правильном коде" # за
|
|
|
390
543
|
|
|
391
544
|
Версия 1, один автор. Сам комплект держит **AQK-3**: всё объявленное прогоняется конвейером при
|
|
392
545
|
каждом пуше, два реестра долга под храповиком — `node tool/program.mjs doctor --run --min 1`.
|
|
393
|
-
|
|
394
|
-
|
|
546
|
+
|
|
547
|
+
**Первый посторонний пользователь появился 2026-09-08** — прогнал комплект на своём проекте
|
|
548
|
+
(28 гейтов, AQK-1) и прислал разбор. Он же нашёл два дефекта, которых не видели девяносто с
|
|
549
|
+
лишним наших собственных проверок: оба живут только на Windows или только на чужой раскладке
|
|
550
|
+
каталогов (журнал, запись от 2026-09-08). Это ровно то, ради чего нужен посторонний, — но это
|
|
551
|
+
один отзыв, а не сложившееся пользование. Пока за инструментом не вернулись второй раз, о
|
|
552
|
+
работоспособности стандарта на чужих проектах говорить рано.
|
|
395
553
|
|
|
396
554
|
**Стандарт нельзя выпустить первым.** Спецификация раньше практики — это тридцать первый
|
|
397
555
|
заброшенный репозиторий с манифестом и нулём пользователей. Порядок обратный:
|
|
@@ -401,7 +559,7 @@ aqk note "гейт краснел на правильном коде" # за
|
|
|
401
559
|
| 1 | живём по этому на своих проектах | ⬜ измерено: у трёх своих проектов манифеста нет, уровень не заведён |
|
|
402
560
|
| 2 | `doctor` считает уровень | ✅ сделано |
|
|
403
561
|
| 3 | сложившееся записано как короткая спецификация | ✅ [`SPEC.md`](SPEC.md) |
|
|
404
|
-
| 4 | третий проект — **чужой** |
|
|
562
|
+
| 4 | третий проект — **чужой** | 🟡 один посторонний прогон и разбор, 2026-09-08; повторного пользования ещё нет |
|
|
405
563
|
| 5 | значок, сайт, разговор с людьми | ❌ только после четвёртого шага |
|
|
406
564
|
|
|
407
565
|
## Очередь работ
|
|
@@ -409,7 +567,7 @@ aqk note "гейт краснел на правильном коде" # за
|
|
|
409
567
|
Живёт в одном месте — [`PROJECT.md` §9](PROJECT.md). Список здесь не повторяется: два списка через месяц
|
|
410
568
|
расходятся, и непонятно, какой настоящий.
|
|
411
569
|
|
|
412
|
-
Чего нет:
|
|
413
|
-
чистой папке, но не по отдельности)
|
|
570
|
+
Чего нет: пользователя, вернувшегося за инструментом второй раз; покрытия команд, которые пишут
|
|
571
|
+
на диск (проверены прогоном на чистой папке, но не по отдельности).
|
|
414
572
|
|
|
415
573
|
MIT.
|
package/kit/docs/ai/index.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
| хотите понять, **как работать каждый день** | [Плейбук харнеса](agent-harness-playbook.md), раздел 18 |
|
|
20
20
|
| хотите увидеть **процесс по этапам** | [SDLC эпохи агентов](ai-sdlc.md) |
|
|
21
21
|
| ищете **готовое правило**, прежде чем писать своё | [Готовые правила](../ready-made-rules.md) |
|
|
22
|
+
| делаете **e2e для API** и хотите, чтобы он что-то доказывал | [Контракт API и e2e](../api-e2e.md) |
|
|
22
23
|
| ставите **гейты** и хотите отличить работающий от мёртвого | `kit/gates/README.md` — норма записи, храповик, четыре способа вранья |
|
|
23
24
|
|
|
24
25
|
## 1. Наше — применяется в работе
|
|
@@ -189,6 +189,20 @@ tags:
|
|
|
189
189
|
40. **У агента есть способ проверить себя**: запустить тесты, поднять приложение, прочитать логи,
|
|
190
190
|
посмотреть метрики. Без этого он вынужден заканчивать словами «готово», и это слово ничего не
|
|
191
191
|
стоит.
|
|
192
|
+
|
|
193
|
+
**Если у проекта есть интерфейс — сюда же браузер.** Агент, который не может открыть страницу,
|
|
194
|
+
судит о своей работе по тому, что собралось; «собралось» и «работает» — разные утверждения,
|
|
195
|
+
и первое он выдаёт за второе не по злому умыслу, а потому что другого у него нет. Подключается
|
|
196
|
+
MCP-сервером, и это межвендорный протокол: одинаково работает с Claude Code, Cursor, Codex.
|
|
197
|
+
Два первых лица, оба проверены по реестру npm 2026-09-08:
|
|
198
|
+
[`chrome-devtools-mcp`](https://github.com/ChromeDevTools/chrome-devtools-mcp) от Google —
|
|
199
|
+
Lighthouse, трассировка производительности, сеть, консоль, память;
|
|
200
|
+
[`@playwright/mcp`](https://github.com/microsoft/playwright-mcp) от Microsoft — прогон
|
|
201
|
+
сценариев в трёх движках. Задачи разные, выбирает человек.
|
|
202
|
+
|
|
203
|
+
**Версию закрепить.** Сервер запускается командой вида `npx -y пакет@1.9.0`; без точной
|
|
204
|
+
версии при каждом запуске приезжает новая — а этому серверу отдан браузер со всем, что в нём
|
|
205
|
+
открыто. Это проверяет запись `mcp-server-resolves`.
|
|
192
206
|
41. **Сообщение об ошибке — это подсказка агенту.** Инструкция в тексте отказа стоит дешевле, чем
|
|
193
207
|
любые объяснения в документации: она приходит ровно в тот момент, когда нужна.
|
|
194
208
|
42. **Правила живут в репозитории и версионируются** вместе с кодом. Правило в переписке не
|